diff --git a/.kontinuous/env/dev/templates/www.configmap.yaml b/.kontinuous/env/dev/templates/www.configmap.yaml index f944770de..df8dcceff 100644 --- a/.kontinuous/env/dev/templates/www.configmap.yaml +++ b/.kontinuous/env/dev/templates/www.configmap.yaml @@ -7,6 +7,3 @@ data: MATOMO_URL: "https://matomo.fabrique.social.gouv.fr/" NODE_ENV: "production" URL_EXPORT: "http://export" - BUCKET_PUBLIC_ENDPOINT: "https://cdtn-dev-public.s3.gra.io.cloud.ovh.net" - BUCKET_DEFAULT_FOLDER: "default" - BUCKET_DRAFT_FOLDER: "draft" diff --git a/.kontinuous/env/dev/values.yaml b/.kontinuous/env/dev/values.yaml index 4ec6da5b2..fc4d23cf2 100644 --- a/.kontinuous/env/dev/values.yaml +++ b/.kontinuous/env/dev/values.yaml @@ -4,6 +4,9 @@ jobs: with: buildArgs: NEXT_PUBLIC_BASE_PATH: https://www-{{.Values.global.host}} + BUCKET_PUBLIC_ENDPOINT: "https://cdtn-dev-public.s3.gra.io.cloud.ovh.net" + BUCKET_DEFAULT_FOLDER: "default" + BUCKET_DRAFT_FOLDER: "draft" post-restore: ~needs: [ pg, hasura ] use: psql diff --git a/.kontinuous/env/preprod/templates/www.configmap.yaml b/.kontinuous/env/preprod/templates/www.configmap.yaml index f944770de..df8dcceff 100644 --- a/.kontinuous/env/preprod/templates/www.configmap.yaml +++ b/.kontinuous/env/preprod/templates/www.configmap.yaml @@ -7,6 +7,3 @@ data: MATOMO_URL: "https://matomo.fabrique.social.gouv.fr/" NODE_ENV: "production" URL_EXPORT: "http://export" - BUCKET_PUBLIC_ENDPOINT: "https://cdtn-dev-public.s3.gra.io.cloud.ovh.net" - BUCKET_DEFAULT_FOLDER: "default" - BUCKET_DRAFT_FOLDER: "draft" diff --git a/.kontinuous/env/preprod/values.yaml b/.kontinuous/env/preprod/values.yaml index f9b64d9e4..26a229461 100644 --- a/.kontinuous/env/preprod/values.yaml +++ b/.kontinuous/env/preprod/values.yaml @@ -4,6 +4,9 @@ jobs: with: buildArgs: NEXT_PUBLIC_BASE_PATH: https://cdtn-admin-preprod.ovh.fabrique.social.gouv.fr + NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT: "https://cdtn-dev-public.s3.gra.io.cloud.ovh.net" + NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER: "default" + NEXT_PUBLIC_BUCKET_DRAFT_FOLDER: "draft" post-restore: ~needs: [ pg, hasura ] use: psql diff --git a/.kontinuous/env/prod/templates/www.configmap.yaml b/.kontinuous/env/prod/templates/www.configmap.yaml index e13dd7931..afcbf08c2 100644 --- a/.kontinuous/env/prod/templates/www.configmap.yaml +++ b/.kontinuous/env/prod/templates/www.configmap.yaml @@ -9,6 +9,3 @@ data: NODE_ENV: "production" PRODUCTION: "true" URL_EXPORT: "http://export" - BUCKET_PUBLIC_ENDPOINT: "https://cdtn-prod-public.s3.gra.io.cloud.ovh.net" - BUCKET_DEFAULT_FOLDER: "default" - BUCKET_DRAFT_FOLDER: "draft" diff --git a/.kontinuous/env/prod/values.yaml b/.kontinuous/env/prod/values.yaml index ed6a32e7e..d01bc2d81 100644 --- a/.kontinuous/env/prod/values.yaml +++ b/.kontinuous/env/prod/values.yaml @@ -4,6 +4,9 @@ jobs: with: buildArgs: NEXT_PUBLIC_BASE_PATH: https://cdtn-admin.fabrique.social.gouv.fr + NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT: "https://cdtn-prod-public.s3.gra.io.cloud.ovh.net" + NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER: "default" + NEXT_PUBLIC_BUCKET_DRAFT_FOLDER: "draft" www: autoscale: diff --git a/targets/export-elasticsearch/src/server.ts b/targets/export-elasticsearch/src/server.ts index efd5c0292..283555c3d 100644 --- a/targets/export-elasticsearch/src/server.ts +++ b/targets/export-elasticsearch/src/server.ts @@ -44,7 +44,7 @@ rootContainer .toConstantValue(process.env.BUCKET_SECRET_KEY ?? ""); rootContainer .bind(S3Parameters.BUCKET_DRAFT_FOLDER) - .toConstantValue(process.env.BUCKET_DRAFT_FOLDER ?? `draft`); + .toConstantValue(process.env.NEXT_PUBLIC_BUCKET_DRAFT_FOLDER ?? `draft`); rootContainer .bind(S3Parameters.BUCKET_PUBLISHED_FOLDER) .toConstantValue(process.env.BUCKET_PUBLISHED_FOLDER ?? `published`); @@ -53,7 +53,7 @@ rootContainer .toConstantValue(process.env.BUCKET_PREVIEW_FOLDER ?? `preview`); rootContainer .bind(S3Parameters.BUCKET_DEFAULT_FOLDER) - .toConstantValue(process.env.BUCKET_DEFAULT_FOLDER ?? `default`); + .toConstantValue(process.env.NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER ?? `default`); /* REPOSITORIES */ rootContainer.bind(getName(S3Repository)).to(S3Repository); rootContainer diff --git a/targets/frontend/Dockerfile b/targets/frontend/Dockerfile index 0cd95fd16..a26f7384e 100644 --- a/targets/frontend/Dockerfile +++ b/targets/frontend/Dockerfile @@ -25,6 +25,12 @@ FROM deps as dist ARG NEXT_PUBLIC_BASE_PATH ENV NEXT_PUBLIC_BASE_PATH=$NEXT_PUBLIC_BASE_PATH +ARG NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT +ENV NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT=$NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT +ARG NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER +ENV NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER=$NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER +ARG NEXT_PUBLIC_BUCKET_DRAFT_FOLDER +ENV NEXT_PUBLIC_BUCKET_DRAFT_FOLDER=$NEXT_PUBLIC_BUCKET_DRAFT_FOLDER COPY --from=build-types /app/shared/types /app/shared/types COPY --from=build-utils /app/shared/utils /app/shared/utils diff --git a/targets/frontend/src/components/forms/EditionField/Editor.tsx b/targets/frontend/src/components/forms/EditionField/Editor.tsx index 2b638642a..a32b62478 100644 --- a/targets/frontend/src/components/forms/EditionField/Editor.tsx +++ b/targets/frontend/src/components/forms/EditionField/Editor.tsx @@ -36,6 +36,7 @@ export type EditorProps = { onUpdate: (content: string) => void; disabled?: boolean; isError?: boolean; + infographicBaseUrl: string; }; const emptyHtml = "

"; @@ -47,18 +48,18 @@ const Creation: ModeCreation = { mode: 0 }; type ModeEdition = { mode: 1; - infoUrl: string; - pdfUrl: string; + infoName: string; + pdfName: string; pdfSize: string; }; const Edition = ( - infoUrl: string, - pdfUrl: string, + infoName: string, + pdfName: string, pdfSize: string ): ModeEdition => ({ mode: 1, - infoUrl, - pdfUrl, + infoName, + pdfName, pdfSize, }); @@ -74,6 +75,7 @@ export const Editor = ({ content, onUpdate, disabled, + infographicBaseUrl, isError = false, }: EditorProps) => { const [currentContent, setCurrentContent] = useState(content); @@ -117,7 +119,9 @@ export const Editor = ({ }), Alert, Title, - Infographic, + Infographic.configure({ + baseUrl: infographicBaseUrl, + }), ], onUpdate: ({ editor }) => { const html = editor.getHTML(); @@ -194,10 +198,10 @@ export const Editor = ({ onEdit={() => { const node = editor?.state.selection.$from.node(); if (node?.type.name === "infographic") { - const src = node.attrs.src; - const dataPdf = node.attrs.urlPdf; + const dataInfo = node.attrs.infoName; + const dataPdf = node.attrs.pdfName; const dataPdfSize = node.attrs.pdfSize; - setInfographicModal(Edition(src, dataPdf, dataPdfSize)); + setInfographicModal(Edition(dataInfo, dataPdf, dataPdfSize)); } }} onDelete={() => { @@ -229,17 +233,17 @@ export const Editor = ({ onSubmit: (event: React.FormEvent) => { event.preventDefault(); const formData = new FormData(event.currentTarget); - const { infoUrl, pdfUrl, pdfSize } = Object.fromEntries( + const { infoName, pdfName, pdfSize } = Object.fromEntries( (formData as any).entries() ); if (infographicModal.mode === Creation.mode) { editor ?.chain() .focus() - .setInfographic(infoUrl, pdfUrl, pdfSize) + .setInfographic(infoName, pdfName, pdfSize) .run(); } else { - editor?.commands.updateInfographicSrc(infoUrl, pdfUrl, pdfSize); + editor?.commands.updateInfographicSrc(infoName, pdfName, pdfSize); } setInfographicModal(Hide); }, @@ -255,11 +259,13 @@ export const Editor = ({ autoFocus required margin="dense" - id="infoUrl" - name="infoUrl" - label="URL vers l'infographie" + id="infoName" + name="infoName" + label="Nom de l'infographie" defaultValue={ - infographicModal.mode === 1 ? infographicModal.infoUrl : undefined + infographicModal.mode === 1 + ? infographicModal.infoName + : undefined } type="text" fullWidth @@ -268,11 +274,11 @@ export const Editor = ({ { infographic: { setInfographic: ( - src: string, - urlPdf: string, + infoName: string, + pdfName: string, sizePdf: string ) => ReturnType; updateInfographicSrc: ( - newSrc: string, - newUrlPdf: string, - newSizePdf: string + newInfoName: string, + newPdfName: string, + newPdfSize: string ) => ReturnType; removeInfographic: () => ReturnType; }; @@ -27,23 +29,24 @@ export const Infographic = Node.create({ addOptions() { return { HTMLAttributes: {}, + baseUrl: "", }; }, addAttributes() { return { - src: { + infoName: { parseHTML: (element) => - element.querySelector("img")?.getAttribute("src"), + element.querySelector("img")?.getAttribute("data-infographic"), renderHTML: (attributes) => { - return { src: attributes.src }; + return { "data-infographic": attributes.infoName }; }, }, - urlPdf: { + pdfName: { parseHTML: (element) => element.querySelector("div.infographic")?.getAttribute("data-pdf"), renderHTML: (attributes) => { - return { "data-pdf": attributes.urlPdf }; + return { "data-pdf": attributes.pdfName }; }, }, pdfSize: { @@ -69,8 +72,8 @@ export const Infographic = Node.create({ getAttrs: (element) => { const el = element as HTMLElement; return { - src: el.querySelector("img")?.getAttribute("src") || "", - urlPdf: el.getAttribute("data-pdf") || "", + infoName: el.getAttribute("data-infographic") || "", + pdfName: el.getAttribute("data-pdf") || "", pdfSize: el.getAttribute("data-pdf-size") || "", }; }, @@ -85,11 +88,12 @@ export const Infographic = Node.create({ class: "infographic", "data-pdf": HTMLAttributes["data-pdf"], "data-pdf-size": HTMLAttributes["data-pdf-size"], + "data-infographic": HTMLAttributes["data-infographic"], }, [ "img", { - src: HTMLAttributes.src, + src: `${this.options.baseUrl}/${HTMLAttributes["data-infographic"]}`, height: "auto", width: "500", }, @@ -101,11 +105,11 @@ export const Infographic = Node.create({ addCommands() { return { setInfographic: - (src: string, urlPdf: string, pdfSize: string) => + (infoName: string, pdfName: string, pdfSize: string) => ({ commands }) => { return commands.insertContent({ type: this.name, - attrs: { src, urlPdf, pdfSize }, + attrs: { infoName, pdfName, pdfSize }, content: [ { type: "details", @@ -140,7 +144,7 @@ export const Infographic = Node.create({ }, updateInfographicSrc: - (newSrc: string, newUrlPdf: string, newSizePdf: string) => + (newInfoName: string, newPdfName: string, newPdfSize: string) => ({ state, chain }) => { const { selection } = state; const node = selection.$anchor.node(); @@ -150,9 +154,9 @@ export const Infographic = Node.create({ } return chain() .updateAttributes("infographic", { - src: newSrc, - urlPdf: newUrlPdf, - pdfSize: newSizePdf, + infoName: newInfoName, + pdfName: newPdfName, + pdfSize: newPdfSize, }) .run(); }, diff --git a/targets/frontend/src/components/forms/EditionField/index.tsx b/targets/frontend/src/components/forms/EditionField/index.tsx index a4166be53..bc3de90a6 100644 --- a/targets/frontend/src/components/forms/EditionField/index.tsx +++ b/targets/frontend/src/components/forms/EditionField/index.tsx @@ -5,6 +5,7 @@ import { Controller } from "react-hook-form"; import { CommonFormProps } from "../type"; import { Editor } from "./Editor"; import { styled } from "@mui/system"; +import { buildFilePathUrl } from "../../utils"; type FormEditionProps = CommonFormProps; @@ -21,6 +22,7 @@ export const FormEditionField = (props: FormEditionProps) => { onUpdate={onChange} content={value} disabled={props.disabled} + infographicBaseUrl={buildFilePathUrl()} isError={!!error} /> {error && ( diff --git a/targets/frontend/src/components/utils/fileBaseUrl.ts b/targets/frontend/src/components/utils/fileBaseUrl.ts new file mode 100644 index 000000000..5c75dfc99 --- /dev/null +++ b/targets/frontend/src/components/utils/fileBaseUrl.ts @@ -0,0 +1,6 @@ +export const buildFilePathUrl = () => + `${ + process.env.NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT ?? "http://localhost:9000" + }/${process.env.NEXT_PUBLIC_BUCKET_DRAFT_FOLDER ?? "draft"}/${ + process.env.NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER ?? "default" + }`; diff --git a/targets/frontend/src/components/utils/index.ts b/targets/frontend/src/components/utils/index.ts index 096d75dce..1e703cfc2 100644 --- a/targets/frontend/src/components/utils/index.ts +++ b/targets/frontend/src/components/utils/index.ts @@ -1,2 +1,3 @@ export * from "./Pagination"; export * from "./BreadcrumbLink"; +export * from "./fileBaseUrl"; diff --git a/targets/frontend/src/lib/upload.ts b/targets/frontend/src/lib/upload.ts index a51c08b5a..f4c134cba 100644 --- a/targets/frontend/src/lib/upload.ts +++ b/targets/frontend/src/lib/upload.ts @@ -10,12 +10,14 @@ const mime = require("mime-types"); const region = process.env.BUCKET_REGION ?? "us-east-1"; const endpoint = process.env.BUCKET_ENDPOINT ?? "http://localhost:9000"; const publicEndpoint = - process.env.BUCKET_PUBLIC_ENDPOINT ?? "http://localhost:9000"; + process.env.NEXT_PUBLIC_BUCKET_PUBLIC_ENDPOINT ?? "http://localhost:9000"; const accessKeyId = process.env.BUCKET_ACCESS_KEY ?? "MINIO_ACCESS_KEY"; const secretAccessKey = process.env.BUCKET_SECRET_KEY ?? "MINIO_SECRET_KEY"; const bucketName = process.env.BUCKET_NAME ?? "cdtn"; -const bucketDraftFolder = process.env.BUCKET_DRAFT_FOLDER ?? "draft"; -const bucketDefaultFolder = process.env.BUCKET_DEFAULT_FOLDER ?? "default"; +const bucketDraftFolder = + process.env.NEXT_PUBLIC_BUCKET_DRAFT_FOLDER ?? "draft"; +const bucketDefaultFolder = + process.env.NEXT_PUBLIC_BUCKET_DEFAULT_FOLDER ?? "default"; const client = new S3Client({ region,