Skip to content

Commit

Permalink
feat: ajout d'options dans le widget (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
K4ST0R authored Aug 20, 2024
1 parent 5633f9e commit c04f888
Show file tree
Hide file tree
Showing 21 changed files with 118 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,10 @@ SecRule REQUEST_FILENAME "@beginsWith /metabase" \
pass,\
nolog,\
ctl:ruleRemoveById=949110-949110"

SecRule REQUEST_FILENAME "@beginsWith /api" \
"id:1008,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=942100-942100"
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ map $http_upgrade $connection_upgrade {
'' close;
}

map $http_host $robots {
default "";
"~*recette" "noindex, nofollow, nosnippet, noarchive";
"~*sandbox" "noindex, nofollow, nosnippet, noarchive";
}


server {
listen 443 ssl default_server;
ssl_reject_handshake on;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ more_clear_headers "X-Powered-By";
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade";
add_header Content-Security-Policy "default-src 'self' https://www.notion.so/ https://plausible.io/ https://*.inserjeunes.beta.gouv.fr/ 'unsafe-inline' data:;";
add_header Content-Security-Policy "default-src 'self' https://www.notion.so/ https://plausible.io/ https://openmaptiles.github.io/ https://*.inserjeunes.beta.gouv.fr/ https://*.beta.gouv.fr/ https://*.data.gouv.fr/ 'unsafe-inline' data: blob:;";
add_header X-Robots-Tag $robots;
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ proxy_cache off;
proxy_buffering off;
proxy_connect_timeout 60s;
proxy_read_timeout 36000s;
proxy_send_timeout 600s;
send_timeout 600s;

proxy_redirect off;


proxy_pass_header Authorization;
proxy_pass $upstream;
4 changes: 4 additions & 0 deletions server/src/common/utils/dateUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { DateTime } from "luxon";
import moment from "moment-timezone";
moment.tz.setDefault("Europe/Paris");

export function parseAsUTCDate(string) {
if (!string) {
Expand All @@ -7,3 +9,5 @@ export function parseAsUTCDate(string) {

return DateTime.fromFormat(string, "dd/MM/yyyy", { zone: "utc" }).toJSDate();
}

export default moment;
5 changes: 4 additions & 1 deletion server/src/http/routes/certificationsRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export default () => {
"/api/inserjeunes/certifications/:codes_certifications/widget/:hash",
authMiddleware("public"),
tryCatch(async (req, res) => {
const { hash, theme, codes_certifications, millesime, vue } = await validate(
const { hash, theme, codes_certifications, millesime, vue, ...options } = await validate(
{ ...req.params, ...req.query },
{
hash: Joi.string(),
Expand All @@ -178,6 +178,7 @@ export default () => {
hash,
name: "stats",
theme,
options,
data,
plausibleCustomProperties: {
type: "certifications",
Expand All @@ -196,6 +197,7 @@ export default () => {
hash,
name: "stats",
theme,
options,
data,
plausibleCustomProperties: {
type: "certification",
Expand All @@ -211,6 +213,7 @@ export default () => {
hash,
name: "error",
theme,
options,
data: {
error: err.name,
millesimes: formatMillesime(millesime).split("_"),
Expand Down
3 changes: 3 additions & 0 deletions server/src/http/routes/formationsRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export default () => {
uai,
code_certification,
millesime: millesimeBase,
...options
} = await validate(
{ ...req.params, ...req.query },
{
Expand All @@ -218,6 +219,7 @@ export default () => {
hash,
name: "stats",
theme,
options,
data,
plausibleCustomProperties: {
type: "formation",
Expand All @@ -234,6 +236,7 @@ export default () => {
hash,
name: "error",
theme,
options,
data: {
error: err.name,
millesimes: formatMillesime(millesime).split("_"),
Expand Down
5 changes: 4 additions & 1 deletion server/src/http/routes/regionalesRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export default () => {
"/api/inserjeunes/regionales/:region/certifications/:codes_certifications/widget/:hash",
authMiddleware("public"),
tryCatch(async (req, res) => {
const { hash, theme, region, codes_certifications, millesime, vue } = await validate(
const { hash, theme, region, codes_certifications, millesime, vue, ...options } = await validate(
{ ...req.params, ...req.query },
{
hash: Joi.string(),
Expand All @@ -217,6 +217,7 @@ export default () => {
hash,
name: "stats",
theme,
options,
data,
plausibleCustomProperties: {
type: "regionales",
Expand All @@ -236,6 +237,7 @@ export default () => {
hash,
name: "stats",
theme,
options,
data,
plausibleCustomProperties: {
type: "regionale",
Expand All @@ -252,6 +254,7 @@ export default () => {
hash,
name: "error",
theme,
options,
data: {
error: err.name,
millesimes: formatMillesime(millesime).split("_"),
Expand Down
20 changes: 17 additions & 3 deletions server/src/http/utils/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { mapValues } from "lodash-es";
import { getRegions, findRegionByCodePostal, getAcademies } from "#src/services/regions.js";
import { formatArrayParameters } from "./formatters.js";
import { WIDGETS } from "#src/services/widget/widget.js";
import { ANCIENS_NIVEAUX_MAPPER } from "#src/services/bcn.js";

const UAI_PATTERN = /^[0-9]{7}[A-Z]{1}$/;
export const CFD_PATTERN = /^(?:CFD:)?([0-9]{8})$/;
Expand Down Expand Up @@ -129,6 +130,18 @@ export function codesCertifications() {
};
}

export function cfds() {
return {
cfds: arrayOf(Joi.string().pattern(CFD_PATTERN).required()).default([]),
};
}

export function codesDiplome() {
return {
codesDiplome: arrayOf(Joi.string().valid(...Object.values(ANCIENS_NIVEAUX_MAPPER))).default([]),
};
}

export function regions() {
return {
regions: arrayOf(customJoi.postalCodeToRegion().valid(...getRegions().map((r) => r.code))).default([]),
Expand Down Expand Up @@ -157,10 +170,10 @@ export function exports() {
};
}

export function pagination() {
export function pagination({ items_par_page, page } = {}) {
return {
items_par_page: Joi.number().default(10),
page: Joi.number().default(1),
items_par_page: Joi.number().default(items_par_page ?? 10),
page: Joi.number().default(page ?? 1),
};
}

Expand All @@ -184,6 +197,7 @@ export function widget(type) {

return value;
}),
...(WIDGETS[type] && WIDGETS[type].options ? WIDGETS[type].options : {}),
};
}

Expand Down
2 changes: 1 addition & 1 deletion server/src/services/bcn.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fetchStream } from "#src/common/utils/httpUtils.js";
import iconv from "iconv-lite";
import { parseCsv } from "#src/common/utils/csvUtils.js";

const ANCIENS_NIVEAUX_MAPPER = {
export const ANCIENS_NIVEAUX_MAPPER = {
5: "3", // CAP
4: "4", // BAC
3: "5", // BTS
Expand Down
2 changes: 1 addition & 1 deletion server/src/services/widget/templates/common/header.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<script>
setInterval(() => {
document.body && parent.postMessage(document.body.offsetHeight, '*');
document.documentElement && parent.postMessage(document.documentElement.offsetHeight, '*');
}, 50);
function collapse(id, btnExpandId, btnCollapseId) {
Expand Down
2 changes: 1 addition & 1 deletion server/src/services/widget/templates/common/title.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="icon-spacing fr-icon-map-pin-2-fill" aria-hidden="true"></div>
<div><%= data.region.nom %></div>
</div>
<% } else { %>
<% } else if (!data.uai) { %>
<div class="subTitle blue-marine grid">
<div class="icon-spacing fr-icon-map-pin-2-fill" aria-hidden="true"></div>
<div>France</div>
Expand Down
21 changes: 19 additions & 2 deletions server/src/services/widget/templates/error/error.1.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,36 @@
.margin {
margin-top: 20px;
}
a:not([href]),
audio:not([href]),
button:disabled,
input:disabled,
input[type=checkbox]:disabled,
input[type=checkbox]:disabled+label,
input[type=radio]:disabled,
input[type=radio]:disabled+label,
textarea:disabled,
video:not([href]).link-internal {
color: var(--text-default-grey);
}
</style>
</head>

<body style="margin: 0; padding: 0;">
<%- await include('../assets/remixicon.light.symbol.svg'); %>

<div class="container">
<% if (!options?.noTitle) { %>
<%- await include('../common/title.ejs'); %>
<% } %>
<div class="card">
<div class="card-data">
<div class="bodies">
<div>Oups, nous n'avons pas cette information. <a onclick="collapse('#no-data-description', '#no-data-description-expand', '#no-data-description-collapse')">
<div>
<a class="link-internal" onclick="collapse('#no-data-description', '#no-data-description-expand', '#no-data-description-collapse')">
Oups, nous n'avons pas cette information.
<svg id="no-data-description-expand" class="icon">
<use xlink:href="#ri-arrow-down-s-line" />
</svg>
Expand Down Expand Up @@ -90,7 +107,7 @@
cette formation vient d'être créée. Nous aurons donc les résultats plus tard, lorsqu'une première promotion aura fini la formation.</div>
</div>
<div class="grid">
<div class="grid-number bold">3.</div>
<div class="grid-number bold">2.</div>
<div><span class="bold">FORMATION NON DISPONIBLE : </span>l'établissement ne propose pas cette formation. </div>
</div>
</div>
Expand Down
18 changes: 16 additions & 2 deletions server/src/services/widget/templates/stats/default.1.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,13 @@
padding-top: 15px;
}
@media screen and (min-width: 40em) {
@media screen and (max-width: 40em) {
.blocks {
gap: 5px;
}
}
@media screen and (min-width: <%=options.responsiveWidth %>) {
.bodies {
display: flex;
align-items: center;
Expand All @@ -210,7 +216,7 @@
}
}
@media screen and (max-width: 40em) {
@media screen and (max-width: <%=options.responsiveWidth %>) {
:root {
--body-width: min(calc(var(--widget-width) * 0.8 / <%=maxEleves %>), 30px);
--body-height: calc(var(--body-width) * 1.8125);
Expand Down Expand Up @@ -243,6 +249,12 @@
display: none;
}
}
@media screen and (max-width: 30em) {
.block-title {
font-size: 12px;
}
}
</style>
</head>
Expand Down Expand Up @@ -316,7 +328,9 @@
</div>

<div class="container">
<% if (!options?.noTitle) { %>
<%- await include('../common/title.ejs'); %>
<% } %>
<!-- <div class="badge">
<div class="label">CAP EN 2 ANS</div>
</div> -->
Expand Down
17 changes: 14 additions & 3 deletions server/src/services/widget/widget.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from "path";
import Joi from "joi";
import { isNil } from "lodash-es";
import { getDirname } from "#src/common/utils/esmUtils.js";
import ejs from "ejs";
Expand All @@ -23,6 +24,12 @@ export const WIDGETS = {
],
},
},
options: {
noTitle: Joi.boolean().default(false),
responsiveWidth: Joi.string()
.regex(/^[0-9]+(em|px)/)
.default("40em"),
},
validator: (data) => {
const isInvalid = (taux) => !taux || !!taux.find(({ value }) => isNil(value));

Expand Down Expand Up @@ -51,6 +58,9 @@ export const WIDGETS = {
],
},
},
options: {
noTitle: Joi.boolean().default(false),
},
validator: () => true,
},
};
Expand All @@ -63,7 +73,7 @@ function getVersion(widget, version = null) {
return template;
}

function getBaseData({ widget, plausibleCustomProperties = {} }) {
function getBaseData({ widget, plausibleCustomProperties = {}, options = {} }) {
const base64Font = loadBase64Font();

return {
Expand All @@ -76,6 +86,7 @@ function getBaseData({ widget, plausibleCustomProperties = {} }) {
},
base64Font,
version: widget.template.version,
options,
};
}

Expand All @@ -97,14 +108,14 @@ export function getWidget({ widgets = WIDGETS, name = null, theme = null, versio
return { widget, template, theme: widgetTheme, name: widgetName };
}

export async function renderWidget({ widget, data = {}, plausibleCustomProperties = {} }) {
export async function renderWidget({ widget, data = {}, options = {}, plausibleCustomProperties = {} }) {
if (!widget.widget.validator(data)) {
throw new ErrorWidgetInvalidData();
}

return ejs.renderFile(
widget.template.template,
{ ...getBaseData({ widget, plausibleCustomProperties }), data },
{ ...getBaseData({ widget, plausibleCustomProperties, options }), data },
{ async: true }
);
}
2 changes: 2 additions & 0 deletions server/src/services/widget/widgetUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export async function getUserWidget({
name,
theme = "default",
data = {},
options = {},
plausibleCustomProperties = {},
}) {
const user = await UserRepository.first({ "widget.hash": hash });
Expand Down Expand Up @@ -55,6 +56,7 @@ export async function getUserWidget({
return renderWidget({
widget: widget,
data,
options,
plausibleCustomProperties: {
user: user.username,
...plausibleCustomProperties,
Expand Down
Loading

0 comments on commit c04f888

Please sign in to comment.