Skip to content

Commit

Permalink
fix(contributions): ajout d'un selecteur de references pour les fiche…
Browse files Browse the repository at this point in the history
…s SP (#1029)
  • Loading branch information
maxgfr authored Sep 27, 2023
1 parent 81bce48 commit c57d763
Show file tree
Hide file tree
Showing 20 changed files with 499 additions and 348 deletions.
111 changes: 55 additions & 56 deletions targets/frontend/next.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
// Use the hidden-source-map option when you don't want the source maps to be
// publicly available on the servers, only to the error reporting
const withSourceMaps = require("@zeit/next-source-maps")();
const withTM = require("next-transpile-modules")([
"@shared/graphql-client",
"@shared/id-generator",
"@socialgouv/cdtn-ui",
"@codegouvfr/react-dsfr",
]);

const basePath = "";

Expand All @@ -19,53 +13,58 @@ const securityHeaders = [
{ key: "X-Content-Type-Options", value: "nosniff" },
];

module.exports = withTM(
withSourceMaps({
basePath,
async headers() {
return [
{
headers: securityHeaders,
// Apply these headers to all routes in your application.
source: "/:path*",
},
];
},
poweredByHeader: false,
serverRuntimeConfig: {
rootDir: __dirname,
},
webpack: (config, { isServer, dev }) => {
config.output.chunkFilename = isServer
? `${dev ? "[name]" : "[name].[fullhash]"}.js`
: `static/chunks/${dev ? "[name]" : "[name].[fullhash]"}.js`;
config.module.rules.push({
exclude: /node_modules/,
loader: "graphql-tag/loader",
test: /\.(graphql|gql)$/,
});
// In `pages/_app.js`, Sentry is imported from @sentry/node. While
// @sentry/browser will run in a Node.js environment, @sentry/node will use
// Node.js-only APIs to catch even more unhandled exceptions.
//
// This works well when Next.js is SSRing your page on a server with
// Node.js, but it is not what we want when your client-side bundle is being
// executed by a browser.
//
// Luckily, Next.js will call this webpack function twice, once for the
// server and once for the client. Read more:
// https://nextjs.org/docs#customizing-webpack-config
//
// So ask Webpack to replace @sentry/node imports with @sentry/browser when
// building the browser's bundle
if (!isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/browser";
}
config.module.rules.push({
test: /\.woff2$/,
type: "asset/resource",
});
return config;
},
})
);
module.exports = withSourceMaps({
basePath,
async headers() {
return [
{
headers: securityHeaders,
// Apply these headers to all routes in your application.
source: "/:path*",
},
];
},
poweredByHeader: false,
serverRuntimeConfig: {
rootDir: __dirname,
},
webpack: (config, { isServer, dev }) => {
config.output.chunkFilename = isServer
? `${dev ? "[name]" : "[name].[fullhash]"}.js`
: `static/chunks/${dev ? "[name]" : "[name].[fullhash]"}.js`;
config.module.rules.push({
exclude: /node_modules/,
loader: "graphql-tag/loader",
test: /\.(graphql|gql)$/,
});
// In `pages/_app.js`, Sentry is imported from @sentry/node. While
// @sentry/browser will run in a Node.js environment, @sentry/node will use
// Node.js-only APIs to catch even more unhandled exceptions.
//
// This works well when Next.js is SSRing your page on a server with
// Node.js, but it is not what we want when your client-side bundle is being
// executed by a browser.
//
// Luckily, Next.js will call this webpack function twice, once for the
// server and once for the client. Read more:
// https://nextjs.org/docs#customizing-webpack-config
//
// So ask Webpack to replace @sentry/node imports with @sentry/browser when
// building the browser's bundle
if (!isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/browser";
}
config.module.rules.push({
test: /\.woff2$/,
type: "asset/resource",
});
return config;
},
transpilePackages: [
"@shared/graphql-client",
"@shared/id-generator",
"@socialgouv/cdtn-ui",
"@codegouvfr/react-dsfr",
"tss-react",
],
});
12 changes: 6 additions & 6 deletions targets/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"dependencies": {
"@azure/abort-controller": "^1.0.4",
"@azure/storage-blob": "^12.7.0",
"@codegouvfr/react-dsfr": "^0.74.2",
"@codegouvfr/react-dsfr": "^0.76.4",
"@elastic/elasticsearch": "^7.14.1",
"@emotion/react": "11.10.6",
"@emotion/server": "^11.11.0",
"@emotion/styled": "11.10.6",
"@hapi/boom": "^9.1.4",
"@hookform/error-message": "^2.0.0",
"@mui/icons-material": "5.11.16",
"@mui/material": "5.12.0",
"@mui/material": "5.14.11",
"@reach/accordion": "^0.16.1",
"@reach/dialog": "^0.16.0",
"@reach/menu-button": "^0.16.1",
Expand Down Expand Up @@ -55,9 +55,8 @@
"lodash.get": "^4.4.2",
"memoizee": "^0.4.15",
"micromark": "^2.11.4",
"next": "13.2.4",
"next": "13.5.3",
"next-remove-imports": "^1.0.11",
"next-transpile-modules": "^10.0.0",
"next-urql": "^3.2.1",
"nodemailer": "^6.6.5",
"p-limit": "^4.0.0",
Expand All @@ -82,6 +81,7 @@
"serialize-error": "^9.1.1",
"strip-markdown": "^4.2.0",
"swr": "^1.0.1",
"tss-react": "^4.9.2",
"unified": "^9.2.2",
"unist-util-parents": "^1.0.3",
"unist-util-select": "^4.0.1",
Expand Down Expand Up @@ -120,8 +120,8 @@
"main": "index.js",
"private": true,
"scripts": {
"build": "next build",
"dev": "next dev",
"build": "yarn prebuild && next build",
"dev": "yarn predev && next dev",
"lint": "next lint",
"precommit": "lint-staged",
"start": "next start",
Expand Down
20 changes: 8 additions & 12 deletions targets/frontend/src/components/contributions/answers/Answer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { statusesMapping } from "../status/data";
import { getNextStatus, getPrimaryButtonLabel } from "../status/utils";
import { SnackBar } from "../../utils/SnackBar";
import { Breadcrumb, BreadcrumbLink } from "src/components/utils";
import { FicheSpDocumentInput } from "./references/FicheSpDocumentInput";

export type ContributionsAnswerProps = {
id: string;
Expand Down Expand Up @@ -62,6 +63,7 @@ export const ContributionsAnswer = ({
kaliReferences: [],
otherReferences: [],
cdtnReferences: [],
contentFichesSpDocument: answer?.contentFichesSpDocument ? {} : undefined,
},
});
const updateAnswer = useContributionAnswerUpdateMutation();
Expand Down Expand Up @@ -97,7 +99,7 @@ export const ContributionsAnswer = ({
contentType: data.contentType,
status: newStatus,
userId: user?.id,
urlSp: data.urlSp,
contentServicePublicCdtnId: data.contentFichesSpDocument?.cdtnId,
kaliReferences: data.kaliReferences,
legiReferences: data.legiReferences,
cdtnReferences: data.cdtnReferences,
Expand Down Expand Up @@ -206,17 +208,11 @@ export const ContributionsAnswer = ({
/>
)}
{answer && isCodeDuTravail(answer) && (
<FormControl>
<FormTextField
label="Url Service public"
name="urlSp"
disabled={isNotEditable(answer)}
control={control}
rules={{
required: answer && answer.contentType === "SP",
}}
/>
</FormControl>
<FicheSpDocumentInput
name="contentFichesSpDocument"
control={control}
disabled={isNotEditable(answer)}
/>
)}
{answer && !isCodeDuTravail(answer) && (
<KaliReferenceInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
} from "./answerReferences";

export const contributionAnswerUpdateMutation = `
mutation contributionAnswerUpdate($id: uuid!, $content: String, $contentType: String, $status: statustype!, $userId: uuid!, $urlSp: String, $kaliReferences: [contribution_answer_kali_references_insert_input!]!, $legiReferences: [contribution_answer_legi_references_insert_input!]!, $otherReferences: [contribution_answer_other_references_insert_input!]!, $cdtnReferences: [contribution_answer_cdtn_references_insert_input!]!) {
update_contribution_answers_by_pk(pk_columns: {id: $id}, _set: {content: $content, content_type: $contentType, url_sp: $urlSp}) {
mutation contributionAnswerUpdate($id: uuid!, $content: String, $contentType: String, $status: statustype!, $userId: uuid!, $contentServicePublicCdtnId: String, $kaliReferences: [contribution_answer_kali_references_insert_input!]!, $legiReferences: [contribution_answer_legi_references_insert_input!]!, $otherReferences: [contribution_answer_other_references_insert_input!]!, $cdtnReferences: [contribution_answer_cdtn_references_insert_input!]!) {
update_contribution_answers_by_pk(pk_columns: {id: $id}, _set: {content: $content, content_type: $contentType, content_service_public_cdtn_id: $contentServicePublicCdtnId}) {
__typename
}
insert_contribution_answer_statuses_one(object: {status: $status, user_id: $userId, answer_id: $id}) {
Expand Down Expand Up @@ -49,7 +49,7 @@ export type MutationProps = Pick<
Answer,
| "id"
| "contentType"
| "urlSp"
| "contentServicePublicCdtnId"
| "content"
| "kaliReferences"
| "legiReferences"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ query contribution_answer($id: uuid) {
content
contentType: content_type
updatedAt: updated_at
urlSp: url_sp
contentServicePublicCdtnId: content_service_public_cdtn_id
question {
id
content
Expand Down Expand Up @@ -69,6 +69,12 @@ query contribution_answer($id: uuid) {
slug
}
}
contentFichesSpDocument: document {
cdtnId: cdtn_id
title
source
slug
}
}
}
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const CdtnReferenceInput = ({
disabled = false,
}: Props): React.ReactElement => (
<ReferenceInput<CdtnReference>
isMultiple={true}
label={`Contenus liés`}
color="info"
name={name}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getRouteBySource } from "@socialgouv/cdtn-sources";
import { Control } from "react-hook-form";
import { Document } from "../../type";
import { ReferenceInput } from "./ReferenceInput";
import { useFicheSpSearchCdtnReferencesQuery } from "./ficheSpReferenceSearch.query";

type Props = {
name: string;
control: Control<any>;
disabled?: boolean;
};

export const FicheSpDocumentInput = ({
name,
control,
disabled = false,
}: Props): React.ReactElement => (
<ReferenceInput<Document>
label={`Fiche service-public`}
color="info"
name={name}
disabled={disabled}
control={control}
fetcher={useFicheSpSearchCdtnReferencesQuery}
isEqual={(option, value) => value.cdtnId === option.cdtnId}
getLabel={(item) => `${item.title} (${item.slug})`}
onClick={(item) => {
const newWindow = window.open(
`https://code.travail.gouv.fr/${getRouteBySource(item.source)}/${
item.slug
}`,
"_blank",
"noopener,noreferrer"
);
if (newWindow) newWindow.opener = null;
}}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const LegiReferenceInput = ({
}: Props): React.ReactElement => {
return (
<ReferenceInput<LegiReference>
isMultiple={true}
label={`Références liées au code du travail`}
color="success"
name={name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Chip } from "@mui/material";
import { ReactElement, useEffect, useState } from "react";
import { Control } from "react-hook-form";

import { FormAutocompleteMultiple } from "../../../forms";
import { FormAutocomplete } from "../../../forms";
import { CombinedError } from "urql";

export type Result<Type> = {
Expand All @@ -28,6 +28,7 @@ type Props<Type> = {
| "success"
| "warning";
disabled: boolean;
isMultiple?: true;
};

export const ReferenceInput = <Type,>({
Expand All @@ -40,6 +41,7 @@ export const ReferenceInput = <Type,>({
onClick,
color,
disabled,
isMultiple,
}: Props<Type>): ReactElement | null => {
const [query, setQuery] = useState<string | undefined>();
const { data, fetching, error } = fetcher(query);
Expand All @@ -58,7 +60,8 @@ export const ReferenceInput = <Type,>({
}, [open]);

return (
<FormAutocompleteMultiple<Type>
<FormAutocomplete<Type>
multiple={isMultiple}
noOptionsText={"Aucun résultat trouvé"}
control={control}
getOptionLabel={getLabel}
Expand Down
Loading

0 comments on commit c57d763

Please sign in to comment.