diff --git a/.kontinuous/values.yaml b/.kontinuous/values.yaml index 10aafa30b..d61021d8f 100644 --- a/.kontinuous/values.yaml +++ b/.kontinuous/values.yaml @@ -29,14 +29,6 @@ jobs: with: imagePackage: export dockerfile: targets/export-elasticsearch/Dockerfile - build-contributions: - use: build - with: - imagePackage: contributions - dockerfile: targets/contributions/Dockerfile - buildArgs: - NODE_ENV: production - CDTN_API_URL: https://cdtn-api.fabrique.social.gouv.fr build-hasura: use: build with: @@ -74,30 +66,6 @@ www: runAsUser: 1000 runAsGroup: 1000 -contributions: - ~chart: app - ~needs: [build-contributions] - probesPath: / - imagePackage: contributions - containerPort: 3200 - envFrom: - - configMapRef: - name: contributions - - secretRef: - name: contributions - resources: - limits: - cpu: "100m" - memory: "256Mi" - requests: - cpu: "50m" - memory: "128Mi" - replicas: 1 - securityContext: - fsGroup: 1000 - runAsUser: 1000 - runAsGroup: 1000 - export: ~chart: app ~needs: [build-export] diff --git a/docker-compose.yml b/docker-compose.yml index 63ba7ec95..8007d13d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,21 +49,6 @@ services: environment: HASURA_GRAPHQL_ENDPOINT: "http://hasura:8080/v1/graphql" - contributions: - build: - context: . - dockerfile: targets/contributions/Dockerfile - shm_size: 512m - depends_on: - - hasura - - www - ports: - - "3200:3200" - environment: - API_URI: http://www - env_file: - - .env - ingester: build: context: . diff --git a/package-scripts.yml b/package-scripts.yml index 09db3d45e..faa406eed 100644 --- a/package-scripts.yml +++ b/package-scripts.yml @@ -1,6 +1,6 @@ scripts: build: - default: lerna run --stream build --ignore @socialgouv/contibutions + default: lerna run --stream build internals: lerna run --stream --scope shared* build targets: lerna run --stream --scope frontend --scope alert-cli build diff --git a/package.json b/package.json index e8e317d0f..a8ec5b1fb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "private": true, "scripts": { "build": "nps build", - "build:watch": "lerna run --stream build:watch --ignore @socialgouv/contibutions", + "build:watch": "lerna run --stream build:watch", "dev": "nps dev", "lint": "nps lint", "start": "nps", diff --git a/targets/alert-cli/src/diff/dila/extractReferences/contribution/__tests__/getOldContrib.test.ts b/targets/alert-cli/src/diff/dila/extractReferences/contribution/__tests__/getOldContrib.test.ts deleted file mode 100644 index ef48778f0..000000000 --- a/targets/alert-cli/src/diff/dila/extractReferences/contribution/__tests__/getOldContrib.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { expect, test } from "@jest/globals"; - -import type { Contrib } from "../getOldContribRef"; -import { extractContributionsRef, getOldContribRef } from "../getOldContribRef"; - -jest.mock("../../../../shared/getAllDocumentsBySource", () => { - return { - getAllDocumentsBySource: () => mockContributions, - }; -}); - -//using name starting with mock allow jest to hoist variable and then mock -const mockContributions: Contrib[] = [ - { - cdtnId: "contrib-1", - document: { - answers: { - conventions: [ - { - id: "id-answer-123", - idcc: "123", - markdown: "## markdown answer", - references: [ - { - category: "agreement", - dila_cid: "c123", - dila_container_id: "kalicont123", - dila_id: "125", - title: "accord c123", - url: "url/c123", - }, - { - category: "agreement", - dila_cid: "ext", - dila_container_id: "kalicont123", - dila_id: "ext125", - title: "accord c125", - url: "url/c125", - }, - { - category: "agreement", - dila_cid: "4", - dila_container_id: "kalicont42", - dila_id: "4", - title: "accord 42", - url: "url/42", - }, - ], - }, - ], - generic: { - description: "desc", - id: "id-generic", - markdown: "##markdown", - references: [ - { - category: "agreement", - dila_cid: "c1", - dila_container_id: "kalicont123", - dila_id: "1", - title: "Accord du 4 juin", - url: "legifrance.url/kalicont123", - }, - { - category: "agreement", - dila_cid: "3", - dila_container_id: "kalicont42", - dila_id: "3", - title: "Accord du 3 novembre", - url: "legifrance.url/kalicont42", - }, - ], - text: "text", - }, - }, - description: "description contrib", - index: 1, - split: false, - }, - initialId: "answer1", - source: "contributions", - title: "question1", - }, -]; - -const expected = [ - { - document: { - id: "answer1", - source: "contributions", - title: "question1", - }, - references: [ - { - dila_cid: "c1", - dila_container_id: "kalicont123", - dila_id: "1", - title: "Accord du 4 juin", - url: "legifrance.url/kalicont123", - }, - { - dila_cid: "3", - dila_container_id: "kalicont42", - dila_id: "3", - title: "Accord du 3 novembre", - url: "legifrance.url/kalicont42", - }, - ], - }, - { - document: { - id: "id-answer-123", - source: "contributions", - title: "question1", - }, - references: [ - { - dila_cid: "c123", - dila_container_id: "kalicont123", - dila_id: "125", - title: "accord c123", - url: "url/c123", - }, - { - dila_cid: "ext", - dila_container_id: "kalicont123", - dila_id: "ext125", - title: "accord c125", - url: "url/c125", - }, - { - dila_cid: "4", - dila_container_id: "kalicont42", - dila_id: "4", - title: "accord 42", - url: "url/42", - }, - ], - }, -]; - -test("extractContributionRef should return an array of references", () => { - expect(extractContributionsRef(mockContributions)).toEqual(expected); -}); - -test("default export should return an array of references", async () => { - expect(await getOldContribRef()).toEqual(expected); -}); diff --git a/targets/alert-cli/src/diff/dila/extractReferences/contribution/getOldContribRef.ts b/targets/alert-cli/src/diff/dila/extractReferences/contribution/getOldContribRef.ts deleted file mode 100644 index 96bd8d49b..000000000 --- a/targets/alert-cli/src/diff/dila/extractReferences/contribution/getOldContribRef.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { - ContributionComplete, - ContributionFiltered, - DocumentReferences, -} from "@shared/types"; -import { SOURCES } from "@socialgouv/cdtn-sources"; - -import { getAllDocumentsBySource } from "../../../shared/getAllDocumentsBySource"; - -export type Contrib = Pick< - ContributionComplete | ContributionFiltered, - "document" | "source" | "title" -> & { - initialId: string; - cdtnId: string; -}; - -export function extractContributionsRef( - questions: Contrib[] -): DocumentReferences[] { - const refs: DocumentReferences[] = []; - - for (const question of questions) { - if ("answers" in question.document) { - refs.push({ - document: { - id: question.initialId, - source: SOURCES.CONTRIBUTIONS, - title: question.title, - }, - references: question.document.answers.generic.references.flatMap( - (ref) => { - if (ref.category === null) { - return []; - } - return [ - { - dila_cid: ref.dila_cid, - dila_container_id: ref.dila_container_id, - dila_id: ref.dila_id, - title: ref.title, - url: ref.url, - }, - ]; - } - ), - }); - if ("conventionAnswer" in question.document.answers) { - continue; - } - if (question.document.split) { - continue; - } - question.document.answers.conventions.forEach((answer) => - refs.push({ - document: { - id: answer.id, - source: SOURCES.CONTRIBUTIONS, - title: question.title, - }, - references: answer.references.flatMap((ref) => { - if (ref.category === null) return []; - return [ - { - dila_cid: ref.dila_cid, - dila_container_id: ref.dila_container_id, - dila_id: ref.dila_id, - title: ref.title, - url: ref.url, - }, - ]; - }), - }) - ); - } - } - return refs; -} - -export async function getOldContribRef() { - const contributions = (await getAllDocumentsBySource([ - SOURCES.CONTRIBUTIONS, - ])) as Contrib[]; - return extractContributionsRef(contributions); -} diff --git a/targets/alert-cli/src/diff/dila/extractReferences/contribution/index.ts b/targets/alert-cli/src/diff/dila/extractReferences/contribution/index.ts index 1fb27ba83..dc2fd3867 100644 --- a/targets/alert-cli/src/diff/dila/extractReferences/contribution/index.ts +++ b/targets/alert-cli/src/diff/dila/extractReferences/contribution/index.ts @@ -1,13 +1,11 @@ import type { DocumentReferences } from "@shared/types"; import memoizee from "memoizee"; import { getContributionsReferences } from "./getContributionsReferences"; -import { getOldContribRef } from "./getOldContribRef"; async function getContributionReferences(): Promise { const references = await getContributionsReferences(); - const oldReferences = await getOldContribRef(); - return [...references, ...oldReferences]; + return [...references]; } export default memoizee(getContributionReferences, { promise: true }); diff --git a/targets/contributions/.babelrc b/targets/contributions/.babelrc deleted file mode 100644 index c0e09b2e0..000000000 --- a/targets/contributions/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["next/babel"], - "plugins": [["@emotion"]] -} diff --git a/targets/contributions/.browserslistrc b/targets/contributions/.browserslistrc deleted file mode 100644 index 49dac8329..000000000 --- a/targets/contributions/.browserslistrc +++ /dev/null @@ -1,3 +0,0 @@ -last 2 Chrome versions -last 2 Edge versions -last 2 Firefox versions diff --git a/targets/contributions/.dockerignore b/targets/contributions/.dockerignore deleted file mode 100644 index aab51031a..000000000 --- a/targets/contributions/.dockerignore +++ /dev/null @@ -1,11 +0,0 @@ -.next/ -__tests__/ -node_modules/ -tests/ - -*.d.ts -*.md - -jest.config.js -LICENSE - diff --git a/targets/contributions/.gitignore b/targets/contributions/.gitignore deleted file mode 100644 index 991dcb7e9..000000000 --- a/targets/contributions/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.env.production -.eslintcache -.next -*.DS_Store -data/* -node_modules diff --git a/targets/contributions/CHANGELOG.md b/targets/contributions/CHANGELOG.md deleted file mode 100644 index 2efa2b3a3..000000000 --- a/targets/contributions/CHANGELOG.md +++ /dev/null @@ -1,542 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.40.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.40.1...v2.40.2) (2024-04-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.40.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.40.0...v2.40.1) (2024-04-03) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.40.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.7...v2.40.0) (2024-04-02) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.7](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.6...v2.39.7) (2024-03-28) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.6](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.5...v2.39.6) (2024-03-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.5](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.4...v2.39.5) (2024-03-26) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.3...v2.39.4) (2024-03-26) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.2...v2.39.3) (2024-03-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.1...v2.39.2) (2024-03-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.39.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.39.0...v2.39.1) (2024-03-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.39.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.38.0...v2.39.0) (2024-03-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.38.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.37.1...v2.38.0) (2024-03-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.37.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.37.0...v2.37.1) (2024-03-13) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.37.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.36.0...v2.37.0) (2024-03-13) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.36.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.35.1...v2.36.0) (2024-03-08) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.35.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.35.0...v2.35.1) (2024-03-05) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.35.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.34.4...v2.35.0) (2024-03-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.34.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.34.3...v2.34.4) (2024-02-19) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.34.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.34.2...v2.34.3) (2024-02-19) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.34.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.34.1...v2.34.2) (2024-02-16) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.34.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.34.0...v2.34.1) (2024-02-14) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.34.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.33.0...v2.34.0) (2024-02-14) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.33.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.32.1...v2.33.0) (2024-02-06) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.32.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.32.0...v2.32.1) (2024-01-26) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.32.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.31.1...v2.32.0) (2024-01-23) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.31.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.31.0...v2.31.1) (2024-01-19) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.31.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.30.3...v2.31.0) (2024-01-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.30.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.30.2...v2.30.3) (2024-01-11) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.30.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.30.1...v2.30.2) (2024-01-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.30.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.30.0...v2.30.1) (2024-01-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.30.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.29.1...v2.30.0) (2024-01-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.29.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.29.0...v2.29.1) (2023-12-28) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.29.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.28.4...v2.29.0) (2023-12-27) - -### Features - -- **export:** ajout du code du `@shared/elastic-document-adapter` dans le code de l'`export-elasticsearch` ([#1183](https://github.com/SocialGouv/cdtn-admin/issues/1183)) ([f6919b4](https://github.com/SocialGouv/cdtn-admin/commit/f6919b427befcc3a298aec3ac4182b2d392b8e34)) - -## [2.28.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.28.3...v2.28.4) (2023-12-21) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.28.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.28.2...v2.28.3) (2023-12-20) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.28.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.28.1...v2.28.2) (2023-12-19) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.28.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.28.0...v2.28.1) (2023-12-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.28.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.27.2...v2.28.0) (2023-12-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.27.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.27.1...v2.27.2) (2023-12-08) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.27.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.27.0...v2.27.1) (2023-12-08) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.27.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.26.2...v2.27.0) (2023-12-07) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.26.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.26.1...v2.26.2) (2023-12-05) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.26.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.26.0...v2.26.1) (2023-12-05) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.26.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.25.1...v2.26.0) (2023-12-04) - -### Features - -- **contributions:** ajout des contributions à l'api publish ([#1110](https://github.com/SocialGouv/cdtn-admin/issues/1110)) ([2ed595c](https://github.com/SocialGouv/cdtn-admin/commit/2ed595cf98720e960dc7d74f28da1a8c3a1b3bd4)), closes [#1113](https://github.com/SocialGouv/cdtn-admin/issues/1113) - -## [2.25.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.25.0...v2.25.1) (2023-11-29) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.25.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.24.2...v2.25.0) (2023-11-24) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.24.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.24.1...v2.24.2) (2023-11-20) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.24.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.24.0...v2.24.1) (2023-11-20) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.24.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.23.0...v2.24.0) (2023-11-15) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.23.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.22.0...v2.23.0) (2023-11-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.22.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.21.0...v2.22.0) (2023-11-08) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.21.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.20.1...v2.21.0) (2023-10-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.20.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.20.0...v2.20.1) (2023-10-23) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.20.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.19.1...v2.20.0) (2023-10-19) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.19.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.19.0...v2.19.1) (2023-10-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.19.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.18.0...v2.19.0) (2023-10-09) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.18.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.9...v2.18.0) (2023-10-09) - -### Bug Fixes - -- **dependencies:** remove un-used dependencies ([#1034](https://github.com/SocialGouv/cdtn-admin/issues/1034)) ([529ffb4](https://github.com/SocialGouv/cdtn-admin/commit/529ffb40bcf79738494d745b0bb756ebd43ab3a4)) - -## [2.17.9](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.8...v2.17.9) (2023-09-29) - -### Bug Fixes - -- **dev:** correction du probleme de socket en phase de dev en HMR + suppression de sentry ([#1045](https://github.com/SocialGouv/cdtn-admin/issues/1045)) ([d371ec1](https://github.com/SocialGouv/cdtn-admin/commit/d371ec1e7e15b3bd4a017f021099ca0edc9c7911)) - -## [2.17.8](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.7...v2.17.8) (2023-09-28) - -### Bug Fixes - -- **export:** add missing cdtn-elasticsearch to Dockerfile ([#1038](https://github.com/SocialGouv/cdtn-admin/issues/1038)) ([390e646](https://github.com/SocialGouv/cdtn-admin/commit/390e64660fcb8a7143970a20928e98d6da05c22f)) - -## [2.17.7](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.6...v2.17.7) (2023-09-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.17.6](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.5...v2.17.6) (2023-09-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.17.5](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.4...v2.17.5) (2023-09-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.17.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.3...v2.17.4) (2023-09-27) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.17.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.2...v2.17.3) (2023-09-27) - -### Bug Fixes - -- yarn berry + fetch + docker opti + sec ([#1012](https://github.com/SocialGouv/cdtn-admin/issues/1012)) ([81bce48](https://github.com/SocialGouv/cdtn-admin/commit/81bce4838781e60c05a084769a35cf0d2a26609c)) - -## [2.17.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.1...v2.17.2) (2023-09-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.17.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.17.0...v2.17.1) (2023-09-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.17.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.16.1...v2.17.0) (2023-09-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.16.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.16.0...v2.16.1) (2023-09-20) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.16.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.15.1...v2.16.0) (2023-09-18) - -### Features - -- **contribs:** add global stats on contrib page ([#1017](https://github.com/SocialGouv/cdtn-admin/issues/1017)) ([a522361](https://github.com/SocialGouv/cdtn-admin/commit/a522361b83b6dc0f31914289b78ac62336db7cfd)) - -## [2.15.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.15.0...v2.15.1) (2023-09-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.15.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.14.0...v2.15.0) (2023-09-15) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.14.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.13.0...v2.14.0) (2023-09-05) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.13.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.12.1...v2.13.0) (2023-08-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.12.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.12.0...v2.12.1) (2023-08-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.12.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.11.4...v2.12.0) (2023-08-02) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.11.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.11.3...v2.11.4) (2023-07-31) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.11.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.11.2...v2.11.3) (2023-07-28) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.11.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.11.1...v2.11.2) (2023-07-25) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.11.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.11.0...v2.11.1) (2023-07-18) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.11.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.10.2...v2.11.0) (2023-07-12) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.10.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.10.1...v2.10.2) (2023-07-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.10.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.10.0...v2.10.1) (2023-07-03) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.10.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.9.1...v2.10.0) (2023-07-03) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.9.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.9.0...v2.9.1) (2023-06-26) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.9.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.8.0...v2.9.0) (2023-06-26) - -### Bug Fixes - -- **lerna:** modify internals dependencies ([c39b77d](https://github.com/SocialGouv/cdtn-admin/commit/c39b77d65692619463f96b3f5eb51e7b1ea976ef)) - -### Features - -- **dep:** update package.json ([69c69ac](https://github.com/SocialGouv/cdtn-admin/commit/69c69ac26b7ac857d1a06c8bbb80e73811460038)) - -# [2.8.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.7.1...v2.8.0) (2023-06-26) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.7.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.7.0...v2.7.1) (2023-06-01) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.7.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.6.1...v2.7.0) (2023-05-30) - -### Bug Fixes - -- **ingester:** clean-up ingester always download packages and add feature to force update ([#910](https://github.com/SocialGouv/cdtn-admin/issues/910)) ([639784a](https://github.com/SocialGouv/cdtn-admin/commit/639784ae72d9f5924d3ec9499945b0c7bc96699b)) - -### Features - -- implementation contribution list ([#897](https://github.com/SocialGouv/cdtn-admin/issues/897)) ([1643d85](https://github.com/SocialGouv/cdtn-admin/commit/1643d853ab9cfbb61bde03394aaf60adade968d4)), closes [#912](https://github.com/SocialGouv/cdtn-admin/issues/912) [#907](https://github.com/SocialGouv/cdtn-admin/issues/907) [#913](https://github.com/SocialGouv/cdtn-admin/issues/913) [#915](https://github.com/SocialGouv/cdtn-admin/issues/915) [#916](https://github.com/SocialGouv/cdtn-admin/issues/916) - -## [2.6.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.6.0...v2.6.1) (2023-05-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.6.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.5.4...v2.6.0) (2023-05-04) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.5.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.5.3...v2.5.4) (2023-03-23) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.5.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.5.2...v2.5.3) (2023-03-02) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.5.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.5.1...v2.5.2) (2023-02-23) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.5.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.5.0...v2.5.1) (2023-02-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.5.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.5...v2.5.0) (2023-02-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.4.5](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.4...v2.4.5) (2022-12-28) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.4.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.3...v2.4.4) (2022-12-16) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.4.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.2...v2.4.3) (2022-12-16) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.4.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.1...v2.4.2) (2022-12-15) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.4.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.4.0...v2.4.1) (2022-12-15) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.4.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.8...v2.4.0) (2022-12-15) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.8](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.7...v2.3.8) (2022-12-07) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.7](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.6...v2.3.7) (2022-12-06) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.6](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.5...v2.3.6) (2022-12-06) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.5](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.4...v2.3.5) (2022-11-08) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.4](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.3...v2.3.4) (2022-10-13) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.3](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.2...v2.3.3) (2022-10-12) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.2](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.1...v2.3.2) (2022-10-12) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [2.3.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.3.0...v2.3.1) (2022-10-10) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.3.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.2.0...v2.3.0) (2022-10-06) - -### Bug Fixes - -- **contrib:** bug sur l'ajout d'un commentaire et suppression d'une réf ([#818](https://github.com/SocialGouv/cdtn-admin/issues/818)) ([971cf8f](https://github.com/SocialGouv/cdtn-admin/commit/971cf8f9244f8d30977a2f49bf6e5c6847ad5332)) - -### Features - -- use super user instead of hasura admin role ([#812](https://github.com/SocialGouv/cdtn-admin/issues/812)) ([5c9ba5b](https://github.com/SocialGouv/cdtn-admin/commit/5c9ba5bbff245d832a6e3bffbd3afce6278d82d0)) - -# [2.2.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.1.0...v2.2.0) (2022-09-05) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.1.0](https://github.com/SocialGouv/cdtn-admin/compare/v2.0.1...v2.1.0) (2022-09-02) - -### Features - -- **headers:** add security headers to frontend and contributions ([#802](https://github.com/SocialGouv/cdtn-admin/issues/802)) ([11381f2](https://github.com/SocialGouv/cdtn-admin/commit/11381f23b30f341b3c665ad6be68c2edf5c45cb1)) - -## [2.0.1](https://github.com/SocialGouv/cdtn-admin/compare/v2.0.0...v2.0.1) (2022-08-29) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [2.0.0](https://github.com/SocialGouv/cdtn-admin/compare/v1.20.0...v2.0.0) (2022-08-17) - -- feat(contribution)!: the generic answer has a null agreement id (#778) ([9776b8c](https://github.com/SocialGouv/cdtn-admin/commit/9776b8ca541d3a79ef0b714d598e2cb32414490e)), closes [#778](https://github.com/SocialGouv/cdtn-admin/issues/778) - -### BREAKING CHANGES - -- database schema - -# [1.20.0](https://github.com/SocialGouv/cdtn-admin/compare/v1.19.2...v1.20.0) (2022-08-17) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [1.19.2](https://github.com/SocialGouv/cdtn-admin/compare/v1.19.1...v1.19.2) (2022-07-21) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [1.19.1](https://github.com/SocialGouv/cdtn-admin/compare/v1.19.0...v1.19.1) (2022-07-21) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [1.19.0](https://github.com/SocialGouv/cdtn-admin/compare/v1.18.2...v1.19.0) (2022-07-08) - -### Bug Fixes - -- **contribution:** correction sur les échecs d'authentification ([#782](https://github.com/SocialGouv/cdtn-admin/issues/782)) ([6e714ae](https://github.com/SocialGouv/cdtn-admin/commit/6e714aed9db6ad633edbf8b862c302ca093d9740)) - -## [1.18.2](https://github.com/SocialGouv/cdtn-admin/compare/v1.18.1...v1.18.2) (2022-06-16) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [1.18.1](https://github.com/SocialGouv/cdtn-admin/compare/v1.18.0...v1.18.1) (2022-06-09) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [1.18.0](https://github.com/SocialGouv/cdtn-admin/compare/v1.17.2...v1.18.0) (2022-06-07) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [1.17.2](https://github.com/SocialGouv/cdtn-admin/compare/v1.17.1...v1.17.2) (2022-06-06) - -**Note:** Version bump only for package @socialgouv/contibutions - -## [1.17.1](https://github.com/SocialGouv/cdtn-admin/compare/v1.17.0...v1.17.1) (2022-06-02) - -**Note:** Version bump only for package @socialgouv/contibutions - -# [1.17.0](https://github.com/SocialGouv/cdtn-admin/compare/v1.16.8...v1.17.0) (2022-06-01) - -### Features - -- migration de l'outil de contrib ([#766](https://github.com/SocialGouv/cdtn-admin/issues/766)) ([3fe04a7](https://github.com/SocialGouv/cdtn-admin/commit/3fe04a7bfb7f58b3a0227a18a1999aebabe109c5)) diff --git a/targets/contributions/Dockerfile b/targets/contributions/Dockerfile deleted file mode 100644 index 146d2280f..000000000 --- a/targets/contributions/Dockerfile +++ /dev/null @@ -1,54 +0,0 @@ -ARG NODE_VERSION=14.21.3 - -FROM node:$NODE_VERSION AS deps - -WORKDIR /app - -COPY yarn.lock .yarnrc.yml ./ -COPY .yarn .yarn - -# hadolint ignore=SC2046 -RUN yarn fetch workspaces focus @socialgouv/contibutions - -FROM deps AS build-types -COPY shared/types ./shared/types/ -RUN yarn workspace @shared/types build - -FROM deps AS build-utils -COPY --from=build-types /app/shared/types /app/shared/types -COPY shared/utils ./shared/utils -RUN yarn workspace @shared/utils build - -FROM deps as dist - -COPY --from=build-utils /app/shared/utils /app/shared/utils -COPY targets/contributions ./targets/contributions - -ARG CDTN_API_URL -ENV CDTN_API_URL=$CDTN_API_URL -RUN yarn workspace @socialgouv/contibutions build - -RUN yarn workspaces focus --production @socialgouv/contibutions && yarn cache clean -RUN mkdir -p /app/targets/contributions/node_modules - -FROM node:$NODE_VERSION - -WORKDIR /app - -COPY --from=dist /app/shared/utils/build /app/shared/utils/build -COPY --from=dist /app/shared/utils/package.json /app/shared/utils/package.json -COPY --from=dist /app/targets/contributions/package.json /app/targets/contributions/package.json -COPY --from=dist /app/targets/contributions/next.config.js /app/targets/contributions/next.config.js -COPY --from=dist /app/targets/contributions/public /app/targets/contributions/public -COPY --from=dist /app/targets/contributions/server /app/targets/contributions/server -COPY --from=dist /app/targets/contributions/.next /app/targets/contributions/.next -COPY --from=dist /app/targets/contributions/node_modules /app/targets/contributions/node_modules -COPY --from=dist /app/node_modules /app/node_modules - -USER 1000 - -ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 - -WORKDIR /app/targets/contributions -CMD ["yarn","start"] diff --git a/targets/contributions/LICENSE b/targets/contributions/LICENSE deleted file mode 100644 index 32700c5b2..000000000 --- a/targets/contributions/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019-present, Fabrique numérique des Ministères Sociaux. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/targets/contributions/jest.config.js b/targets/contributions/jest.config.js deleted file mode 100644 index a8d0c6f41..000000000 --- a/targets/contributions/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -const pack = require("./package"); - -module.exports = { - bail: 1, - clearMocks: true, - displayName: pack.name, - moduleNameMapper: { - "\\.(jpg|jpeg|png|gif|eot|svg|ttf|woff|woff2)$": - "/packages/app/tests/mappers/fileTransformer.js", - "\\.css$": "identity-obj-proxy", - }, - rootDir: "../..", - roots: [`/packages/app`], - // https://github.com/facebook/create-react-app/issues/2007#issuecomment-296694661 - setupFilesAfterEnv: ["/packages/app/tests/jest.setup.js"], - snapshotSerializers: ["@emotion/jest"], - watchPathIgnorePatterns: ["/packages/app/.next/"], -}; diff --git a/targets/contributions/next.config.js b/targets/contributions/next.config.js deleted file mode 100644 index a64f4f4dc..000000000 --- a/targets/contributions/next.config.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - publicRuntimeConfig: { - // Will be available on both server and client - CDTN_API_URL: - process.env.CDTN_API_URL || "https://cdtn-api.fabrique.social.gouv.fr", - API_URL: process.env.API_URL || "http://localhost:8080", - }, - async headers() { - return [ - { - // Apply these headers to all routes in your application. - source: "/:path*", - headers: [ - { - key: "X-Frame-Options", - value: "deny" - }, - { key: "X-XSS-Protection", value: "1; mode=block" }, - { key: "X-Content-Type-Options", value: "nosniff" } - ], - }, - ]; - }, -}; diff --git a/targets/contributions/package.json b/targets/contributions/package.json deleted file mode 100644 index ea3f5bdee..000000000 --- a/targets/contributions/package.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "name": "@socialgouv/contibutions", - "description": "Application de contributions aux données du code du travail numérique.", - "version": "2.40.2", - "license": "Apache-2.0", - "private": true, - "scripts": { - "build": "next build", - "build:docker": "node --max-old-space-size=1024 ./node_modules/.bin/next build", - "clean": "rimraf ./.next", - "dev": "nodemon --exec \"node --inspect -r dotenv/config ./server dotenv_config_path=../../.env\" --watch ./server", - "start": "node ./server", - "start:docker": "yarn build:docker && yarn start" - }, - "dependencies": { - "@emotion/babel-plugin": "11.1.2", - "@emotion/react": "11.1.4", - "@emotion/styled": "11.0.0", - "@fortawesome/fontawesome-svg-core": "1.2.32", - "@fortawesome/free-solid-svg-icons": "5.15.1", - "@fortawesome/react-fontawesome": "0.1.14", - "@koa/router": "10.0.0", - "@shared/utils": "workspace:^", - "@urql/core": "^2.4.4", - "axios": "^0.24.0", - "colors": "1.4.0", - "diff": "5.0.0", - "emotion": "11.0.0", - "emotion-server": "11.0.0", - "http-proxy-middleware": "2.0.6", - "isomorphic-unfetch": "3.1.0", - "js-cookie": "3.0.1", - "jsonwebtoken": "8.5.1", - "koa": "2.13.1", - "koa-body": "^5.0.0", - "koa-proxies": "^0.12.2", - "lodash.debounce": "4.0.8", - "moment-timezone": "0.5.35", - "next": "11.1.2", - "next-cookies": "2.0.3", - "next-redux-saga": "4.1.2", - "next-redux-wrapper": "7.0.5", - "numeral": "2.0.6", - "password-generator": "2.3.2", - "pg": "8.5.1", - "postgrester": "1.5.0", - "prop-types": "15.7.2", - "quill": "1.3.7", - "ramda": "0.27.1", - "react": "17.0.2", - "react-diff-viewer": "3.1.1", - "react-dom": "17.0.2", - "react-form": "4.0.1", - "react-medixtor": "0.1.0-alpha.16", - "react-onclickoutside": "6.9.0", - "react-redux": "7.2.2", - "react-select": "3.1.1", - "react-table": "6.11.5", - "react-tag-autocomplete": "6.1.0", - "react-toastify": "6.2.0", - "react-tooltip": "4.2.11", - "rebass": "4.0.7", - "redux": "4.0.5", - "redux-devtools-extension": "2.13.8", - "redux-saga": "1.1.3", - "rehype-parse": "7.0.1", - "rehype-remark": "8.0.0", - "rehype-sanitize": "4.0.0", - "rehype-stringify": "8.0.0", - "remark-parse": "9.0.0", - "remark-rehype": "8.0.0", - "remark-stringify": "9.0.1", - "ua-parser-js": "0.7.33", - "unified": "9.2.0", - "unist-util-find": "1.0.2", - "unist-util-parents": "1.0.3", - "unist-util-remove": "3.0.0" - }, - "devDependencies": { - "@emotion/jest": "11.1.0", - "@socialgouv/kali-data": "2.30.0", - "@socialgouv/legi-data": "2.24.0", - "@testing-library/jest-dom": "5.11.8", - "@testing-library/react": "12.1.2", - "@types/hast": "2.3.1", - "@types/node": "17.0.0", - "@types/ramda": "0.27.34", - "@types/react": "17.0.37", - "@types/react-test-renderer": "17.0.0", - "dotenv": "10.0.0", - "identity-obj-proxy": "3.0.0", - "mutationobserver-shim": "0.3.7", - "nodemon": "2.0.7", - "react-test-renderer": "17.0.1", - "rimraf": "3.0.2", - "waait": "1.0.5", - "zxcvbn": "4.4.2" - } -} diff --git a/targets/contributions/pages/404.js b/targets/contributions/pages/404.js deleted file mode 100644 index 8b69db72d..000000000 --- a/targets/contributions/pages/404.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import css from "styled-jsx/css"; - -import Main from "../src/layouts/Main"; - -const styles = css` - .Container { - align-items: center; - display: flex; - flex-grow: 1; - justify-content: center; - } -`; - -export default function NotFound() { - return ( -
- -
{`Cette page n'existe pas ou plus.`}
-
- ); -} diff --git a/targets/contributions/pages/_app.js b/targets/contributions/pages/_app.js deleted file mode 100644 index 4429dedae..000000000 --- a/targets/contributions/pages/_app.js +++ /dev/null @@ -1,48 +0,0 @@ -import App from "next/app"; -import React from "react"; - -import Login from "../src/blocks/Login"; -import cache from "../src/cache"; -import getMe from "../src/libs/getMe"; -import { wrapper } from "../src/store"; - -// https://github.com/zeit/next.js/blob/canary/examples/with-redux-saga/pages/_app.js -class MainApp extends App { - static async getInitialProps({ Component, ctx }) { - const pageProps = Component.getInitialProps ? await Component.getInitialProps({ ctx }) : {}; - pageProps.id = ctx.query.id; - pageProps.me = await getMe(ctx); - - return { pageProps }; - } - - constructor(props) { - super(props); - - const { - pageProps: { me }, - } = props; - - cache.set("me", me); - } - - async login() { - window.location.reload(); - } - - render() { - const me = cache.get("me"); - const { Component, pageProps } = this.props; - const { statusCode } = pageProps; - - const hasError = statusCode !== undefined && statusCode >= 400; - - if (hasError || me.isAuthenticated) { - return ; - } - - return ; - } -} - -export default wrapper.withRedux(MainApp); diff --git a/targets/contributions/pages/_document.js b/targets/contributions/pages/_document.js deleted file mode 100644 index 9bad4669f..000000000 --- a/targets/contributions/pages/_document.js +++ /dev/null @@ -1,30 +0,0 @@ -import Document, { Head, Html, Main, NextScript } from "next/document"; -import React from "react"; - -class MyDocument extends Document { - render() { - return ( - - - - {/* - We use this meta to block this website from being referenced in search engines: - DO NOT ADD A "robot.txt"! - https://support.google.com/webmasters/answer/6062608 - */} - - - - - - - -
- - - - ); - } -} - -export default MyDocument; diff --git a/targets/contributions/pages/_error.js b/targets/contributions/pages/_error.js deleted file mode 100644 index 6ffef617b..000000000 --- a/targets/contributions/pages/_error.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from "react"; -import css from "styled-jsx/css"; - -import Main from "../src/layouts/Main"; - -const styles = css` - .Container { - align-items: center; - display: flex; - flex-grow: 1; - justify-content: center; - } -`; - -function Error({ statusCode }) { - let message; - switch (true) { - case statusCode >= 500: - message = "Une erreur serveur s'est produite."; - break; - - case statusCode === 404: - message = "Cette page n'existe pas ou plus."; - break; - - default: - message = "Une erreur inattendue s'est produite."; - break; - } - - return ( -
- -
{message}
-
- ); -} - -Error.getInitialProps = ({ res, err }) => { - const statusCode = res ? res.statusCode : err ? err.statusCode : 404; - - return { statusCode }; -}; - -export default Error; diff --git a/targets/contributions/pages/admin/agreements/edit.js b/targets/contributions/pages/admin/agreements/edit.js deleted file mode 100644 index 8a183156c..000000000 --- a/targets/contributions/pages/admin/agreements/edit.js +++ /dev/null @@ -1,45 +0,0 @@ -import withAdminEdit from "../../../src/templates/withAdminEdit"; - -const componentDidMount = async (api, id) => { - const agreements = await api.fetchAll("/agreements", { id }); - const allAgreements = await api.fetchAll("/agreements"); - - const fields = [ - { - label: "Nom", - name: "name", - type: "input", - }, - { - label: "IDCC", - name: "idcc", - type: "input", - }, - { - label: "Convention parente", - name: "parent_id", - options: allAgreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "select", - }, - ]; - - return { - defaultData: agreements[0], - fields, - }; -}; - -const AdminAgreementsEditPage = withAdminEdit( - { - apiPath: "/agreements", - i18nIsFeminine: true, - i18nSubject: "convention", - indexPath: "/agreements", - }, - componentDidMount -); - -export default AdminAgreementsEditPage; diff --git a/targets/contributions/pages/admin/agreements/index.js b/targets/contributions/pages/admin/agreements/index.js deleted file mode 100644 index a823afb41..000000000 --- a/targets/contributions/pages/admin/agreements/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; - -import AdminIndex from "../../../src/components/AdminIndex"; -import shortenAgreementName from "../../../src/helpers/shortenAgreementName"; - -const COLUMNS = [ - { - Header: "Nom", - accessor: ({ name }) => shortenAgreementName(name), - id: "name", - }, - { - Header: "IDCC", - accessor: "idcc", - style: { textAlign: "center" }, - width: 64, - }, -]; - -const AdminAgreementIndexPage = () => ( - -); - -export default AdminAgreementIndexPage; diff --git a/targets/contributions/pages/admin/agreements/new.jsx b/targets/contributions/pages/admin/agreements/new.jsx deleted file mode 100644 index 495565f5f..000000000 --- a/targets/contributions/pages/admin/agreements/new.jsx +++ /dev/null @@ -1,72 +0,0 @@ -import { useRouter } from "next/router"; -import React from "react"; - -import { addAgreement } from "../../../src/api"; -import AdminForm from "../../../src/components/AdminForm"; -import AdminMain from "../../../src/layouts/AdminMain"; -import toast from "../../../src/libs/toast"; -import { GraphQLApi } from "../../../src/libs/GraphQLApi"; - -export default function AdminNew() { - const [isLoading, setIsLoading] = React.useState(true); - const [fields, setFields] = React.useState([]); - const { back } = useRouter(); - - React.useEffect(() => { - async function init() { - const api = new GraphQLApi(); - const agreements = await api.fetchAll("/agreements"); - const fields = [ - { - label: "Nom", - name: "name", - type: "input", - }, - { - label: "IDCC", - name: "idcc", - type: "input", - }, - { - label: "Convention parente", - name: "parent_id", - options: agreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "select", - }, - ]; - setFields(fields); - setIsLoading(false); - } - - init(); - }, []); - - const onSubmit = async (data) => { - try { - await addAgreement(data.name, data.idcc, data.parent_id); - back(); - } catch (e) { - toast.error(e.message); - } - }; - - return ( - <> - {isLoading ? ( - - ) : ( - - )} - - ); -} diff --git a/targets/contributions/pages/admin/answers-references/index.js b/targets/contributions/pages/admin/answers-references/index.js deleted file mode 100644 index 2af9e1e96..000000000 --- a/targets/contributions/pages/admin/answers-references/index.js +++ /dev/null @@ -1,217 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import React from "react"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../../src/actions"; -import LegalReferenceTag from "../../../src/components/LegalReferences/Tag"; -import Pagination from "../../../src/components/Pagination"; -import * as C from "../../../src/constants"; -import Button from "../../../src/elements/Button"; -import Idcc from "../../../src/elements/Idcc"; -import Input from "../../../src/elements/Input"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import Select from "../../../src/elements/Select"; -import Title from "../../../src/elements/Title"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import customNumeral from "../../../src/libs/customNumeral"; -import T from "../../../src/texts"; - -const Container = styled(Flex)` - flex-grow: 1; - margin: 0 1rem 1rem; -`; - -const FiltersContainer = styled(Flex)` - border-bottom: solid 1px var(--color-border); - padding: 0.5rem 0; - - > * { - flex-grow: 0.25; - } -`; -const InfoContainer = styled(Flex)` - background-color: var(--color-alice-blue); - border-bottom: solid 1px var(--color-border); - padding: 0.5rem 1rem; -`; - -const List = styled(Flex)` - flex-grow: 1; - padding-right: 0.5rem; - min-height: 0; - overflow-y: auto; -`; -const ListRow = styled(Flex)` - background-color: white; - border: solid 1px var(--color-border); - border-radius: 0.4rem; - margin-top: 0.5rem; - padding: 0 0.75rem 0.5rem; -`; -export const OpenButton = styled(Button)` - font-size: 0.875rem; - - padding: 0.325rem 0.375rem 0.375rem 0.5rem; -`; - -export class AdminAnswersReferencesIndexPage extends React.Component { - get queryFilter() { - return this.$queryFilter !== undefined && this.$queryFilter !== null - ? this.$queryFilter.value - : ""; - } - - constructor(props) { - super(props); - - this.setCategoryFilter = this.setCategoryFilter.bind(this); - this.setPageIndex = this.setPageIndex.bind(this); - this.setQueryFilter = debounce(this.setQueryFilter, 250).bind(this); - this.setStatesFilter = this.setStatesFilter.bind(this); - } - - componentDidMount() { - this.props.dispatch(actions.answersReferences.setFilter("pageLength", 10)); - } - - open(answerId) { - window.open(`/admin/answers/${answerId}`, "_blank"); - } - - setPageIndex(pageIndex) { - const { answersReferences, dispatch } = this.props; - if (answersReferences.isLoading) return; - - dispatch(actions.answersReferences.load(pageIndex)); - } - - setQueryFilter() { - this.props.dispatch(actions.answersReferences.setFilter("query", this.queryFilter)); - } - - setCategoryFilter(selectedOption) { - this.props.dispatch(actions.answersReferences.setFilter("category", selectedOption.value)); - } - - setStatesFilter(_selectedOptions) { - const selectedOptions = _selectedOptions ?? []; - const nextStates = selectedOptions.map(({ value }) => value); - - this.props.dispatch(actions.answersReferences.setFilter("states", nextStates)); - } - - getSelectedCategoryOption() { - const { - answersReferences: { - filters: { category }, - }, - } = this.props; - - return C.ANSWER_REFERENCE_CATEGORY_OPTIONS.find(({ value }) => category.includes(value)); - } - - getSelectedStatesOptions() { - const { - answersReferences: { - filters: { states }, - }, - } = this.props; - - return C.ANSWER_REFERENCE_STATE_OPTIONS.filter(({ value }) => states.includes(value)); - } - - renderAnswerReferencesList() { - const { answers, list, isLoading } = this.props.answersReferences; - - if (list.length === 0) { - return ( - - {isLoading ? : T.ADMIN_ANSWERS_INFO_NO_DATA} - - ); - } - - return ( - - {list.map(answerReference => { - const answer = answers.find(({ id }) => id === answerReference.answer_id); - - return ( - - {answer.agreement !== undefined ? ( - - ) : ( - - )} - - - this.open(answerReference.answer_id)} - /> - - ); - })} - - ); - } - - render() { - const { answersReferences } = this.props; - - return ( - - - - Références légales - - - - (this.$queryFilter = node)} - /> - - - - - {`${customNumeral(answersReferences.length).format("0,0")} résultats.`} - - - {this.renderAnswerReferencesList()} - - - - - ); - } -} - -export default connect(({ answersReferences }) => ({ - answersReferences, -}))(AdminAnswersReferencesIndexPage); diff --git a/targets/contributions/pages/admin/answers/edit.js b/targets/contributions/pages/admin/answers/edit.js deleted file mode 100644 index 998a1721b..000000000 --- a/targets/contributions/pages/admin/answers/edit.js +++ /dev/null @@ -1,741 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import React from "react"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../../src/actions"; -import Comment from "../../../src/components/Comment"; -import LegalReferences from "../../../src/components/LegalReferences"; -import * as C from "../../../src/constants"; -import Button from "../../../src/elements/Button"; -import Hr from "../../../src/elements/Hr"; -import Icon from "../../../src/elements/Icon"; -import Idcc from "../../../src/elements/Idcc"; -import Input from "../../../src/elements/Input"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import MarkdownEditor from "../../../src/elements/MarkdownEditor"; -import Radio from "../../../src/elements/Radio"; -import Select from "../../../src/elements/Select"; -import Subtitle from "../../../src/elements/Subtitle"; -import Textarea from "../../../src/elements/Textarea"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import { api } from "../../../src/libs/GraphQLApi"; -import T from "../../../src/texts"; -import { - createAnswerReference, - deleteAnswerReference, - updateAnswersStates, -} from "../../../src/libs/graphql"; - -const Container = styled(Flex)` - height: 100%; -`; -const Content = styled(Flex)` - flex-grow: 1; - overflow-y: scroll; - padding: 1rem; -`; -const Sidebar = styled(Flex)` - display: ${({ isHidden }) => (isHidden ? "none" : "flex")}; - padding: 1rem; - position: relative; - right: 0; - min-width: 23rem; -`; - -const Question = styled(Subtitle)` - margin: 0; - user-select: text; -`; - -const Loaditor = styled(Flex)` - min-height: 30rem; -`; -const Preditor = styled(MarkdownEditor)` - border-right: 0 !important; - min-height: 30rem; - - .editor { - background-color: rgba(0, 0, 0, 0.025); - border: 0 !important; - cursor: text; - } - .editor-status { - display: none; - } - - .preview { - background-color: rgba(0, 0, 0, 0.025); - } -`; -const Editor = styled(MarkdownEditor)` - min-height: 30rem; - - .editor { - border: 0 !important; - } -`; -const Strong = styled.p` - font-weight: 600; - margin: ${(props) => (props.isFirst ? "0 0 0.5rem" : "1rem 0 0.5rem")}; -`; -const Form = styled.form` - display: flex; - flex-direction: column; -`; -const FormHiddenSubmit = styled.button` - height: 1px; - visibility: hidden; - width: 1px; -`; - -const Comments = styled(Flex)` - flex-grow: 1; - margin-top: 0.5rem; - max-height: 100%; - overflow-y: auto; -`; -const CommentEditor = styled(Textarea)` - background: ${({ isPrivate }) => - !isPrivate - ? "white" - : `repeating-linear-gradient( - 45deg, - #f4f4f4, - #f4f4f4 10px, - #ffffff 10px, - #ffffff 20px - )`}; - border-radius: 0.25rem; - font-size: 0.75rem; - opacity: ${(props) => (props.disabled ? 0.25 : 1)}; - margin-top: 1rem; - max-height: 10rem; - padding: 0.5rem; - width: 100%; -`; -const CommentEditorIcon = styled(Icon)` - align-self: flex-end; - cursor: pointer; - margin-top: 0.25rem; - opacity: 0.25; - - :hover { - opacity: 0.5; - } -`; - -export class AdminAnwsersEditPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - agreementReferenceValueInputKey: 0, - isFirstLoad: true, - isSidebarHidden: true, - otherReferenceUrlInputKey: 0, - otherReferenceValueInputKey: 2, - selectedAgreementIdcc: null, - }; - - this.isGeneric = Boolean(props.isGeneric); - this.originalPrevalue = ""; - this.originalValue = ""; - - this.updateAnswerValue = debounce(this._updateAnswerValue.bind(this), 500); - this.loadLegalReferences = debounce( - this.loadLegalReferences.bind(this), - 250 - ); - } - - componentDidMount() { - const { dispatch, id: answerId } = this.props; - - dispatch(actions.answers.loadOne(answerId)); - dispatch(actions.comments.load(answerId)); - } - - componentDidUpdate() { - const { answers, comments } = this.props; - const { isFirstLoad } = this.state; - - if (isFirstLoad && !answers.isLoading) { - const { prevalue, value } = answers.data; - this.originalPrevalue = prevalue; - this.originalValue = value; - - this.setState({ - isFirstLoad: false, - selectedAgreementIdcc: !this.isGeneric - ? answers.data.agreement.idcc - : null, - }); - } - - if (!answers.isLoading && !comments.isLoading) { - this.$commentsContainer.scrollTo(0, this.$commentsContainer.scrollHeight); - } - } - - load() { - const { dispatch, id: answerId } = this.props; - - dispatch(actions.answers.loadOne(answerId)); - dispatch(actions.comments.load(answerId)); - } - - getReferences(category) { - const { answers } = this.props; - - if (answers.isLoading) { - return []; - } - - return answers.data.references.filter( - (reference) => reference.category === category - ); - } - - async _updateAnswerValue({ source }) { - try { - const value = source.trim(); - const { state } = this.props.answers.data; - const data = { value }; - - // An answer can't have a "to do" state with a non-empty value: - if (state === C.ANSWER_STATE.TO_DO && value.length > 0) { - data.state = C.ANSWER_STATE.UNDER_REVIEW; - } - - await api.update(updateAnswersStates, { data, ids: [this.props.id] }); - } catch (err) { - console.warn(err); - } - } - - updateAnswerState({ value }) { - const { id } = this.props; - - this.props.dispatch( - actions.answers.updateState([id], value, () => window.location.reload()) - ); - } - - updateGenericReference(generic_reference) { - const { dispatch, id } = this.props; - - dispatch( - actions.answers.updateGenericReference( - [id], - generic_reference, - this.load.bind(this) - ) - ); - } - - async createReference(reference) { - try { - const { state } = this.props.answers.data; - - // An answer can't have a reference and be generic at the same time: - const answersData = { - generic_reference: null, - }; - - // An answer can't have a "to do" state with a reference: - if (state === C.ANSWER_STATE.TO_DO) { - answersData.state = C.ANSWER_STATE.UNDER_REVIEW; - } - - const answersReferencesData = { - answer_id: this.props.id, - ...reference, - }; - - await api.update(updateAnswersStates, { - data: answersData, - ids: [this.props.id], - }); - await api.create(createAnswerReference, answersReferencesData); - } catch (err) { - console.warn(err); - } - - await this.load(); - } - - async deleteReference(id) { - try { - await api.delete(deleteAnswerReference, { ids: [id] }); - } catch (err) { - console.warn(err); - } - - await this.load(); - } - - submitReference(event, category = null) { - event.preventDefault(); - - let reference; - if (category === "agreement") { - reference = { - category, - value: this.$agreementReferenceValueInput.value.trim(), - }; - } else { - const url = this.$otherReferenceUrlInput.value.trim(); - reference = { - category, - url: url.length !== 0 ? url : null, - value: this.$otherReferenceValueInput.value.trim(), - }; - - this.setState({ - otherReferenceUrlInputKey: this.state.otherReferenceUrlInputKey + 1, - otherReferenceValueInputKey: this.state.otherReferenceValueInputKey + 1, - }); - } - - this.createReference(reference); - } - - toggleSidebar() { - this.setState({ isSidebarHidden: !this.state.isSidebarHidden }); - } - - handleCommentField(event) { - if (event.which !== 13) return; - - if (event.shiftKey) { - event.preventDefault(); - this.props.dispatch(actions.comments.toggleOnePrivacy()); - - return; - } - - const value = this.$commentTextarea.value.trim(); - if (value.length === 0) return; - - if (event.ctrlKey) { - this.props.dispatch( - actions.comments.addOne( - value, - this.props.comments.currentIsPrivate, - this.props.id - ) - ); - } - } - - removeComment(id) { - this.props.dispatch(actions.comments._delete([id], this.props.id)); - } - - loadLegalReferences(category, query) { - const { dispatch, legalReferences } = this.props; - const { selectedAgreementIdcc } = this.state; - if (legalReferences.isLoading) return; - - if (category === C.LEGAL_REFERENCE_CATEGORY.AGREEMENT) { - dispatch( - actions.legalReferences.load(category, query, selectedAgreementIdcc) - ); - - return; - } - - dispatch(actions.legalReferences.load(category, query)); - } - - async addReference(category, legalReference) { - const { dispatch, id: answer_id } = this.props; - - const answerReference = { - answer_id, - category, - dila_cid: legalReference.cid, - dila_container_id: legalReference.containerId, - dila_id: legalReference.id, - value: legalReference.name, - }; - - dispatch( - actions.answers.addReferences([answerReference], this.load.bind(this)) - ); - } - - updateReference(data) { - const { dispatch } = this.props; - - dispatch(actions.answers.updateReferences([data], this.load.bind(this))); - } - - removeReference(answerReferenceId) { - const { dispatch } = this.props; - - dispatch( - actions.answers.removeReferences( - [answerReferenceId], - this.load.bind(this) - ) - ); - } - - renderTop() { - const { answers, comments } = this.props; - const { isFirstLoad } = this.state; - - const stateActionDefaultValue = !isFirstLoad - ? C.ANSWER_STATE_OPTIONS.find(({ value }) => value === answers.data.state) - : undefined; - - return ( - - (this.$otherReferenceValueInput = node)} - /> - (this.$otherReferenceUrlInput = node)} - style={{ marginTop: "0.5rem" }} - /> - - - )} - this.addReference(null, data)} - onChange={this.updateReference.bind(this)} - onRemove={this.removeReference.bind(this)} - references={this.getReferences(null)} - /> - - - ); - } - - renderGenericReference() { - const { answers } = this.props; - const { isFirstLoad } = this.state; - - if (isFirstLoad) { - return null; - } - - const { data, isLoading } = answers; - const { state, generic_reference } = data; - - if ( - [C.ANSWER_STATE.VALIDATED, C.ANSWER_STATE.PUBLISHED].includes(state) && - generic_reference === null - ) { - return null; - } - - return ( -
-
- Renvoi - {![C.ANSWER_STATE.VALIDATED, C.ANSWER_STATE.PUBLISHED].includes( - state - ) && ( - - )} -
- ); - } - - renderSidebar() { - const { comments } = this.props; - - const { isSidebarHidden } = this.state; - - return ( - - Commentaires - (this.$commentsContainer = node)} - > - {this.renderComments()} - - - (this.$commentTextarea = node)} - rows={10} - /> - - this.props.dispatch(actions.comments.toggleOnePrivacy()) - } - /> - - - ); - } - - renderComments() { - const { comments } = this.props; - - return comments.list.map(({ id, is_private, value }, index) => ( - this.removeComment(id)} - value={value} - /> - )); - } - - render() { - return ( - - - - {this.renderTop()} -
- {this.renderHead()} -
- - {this.renderEditor()} -
- - {this.renderReferences()} - - {this.renderGenericReference()} -
- - {this.renderSidebar()} -
-
- ); - } -} - -export default connect(({ answers, comments, legalReferences }) => ({ - answers, - comments, - legalReferences, -}))(AdminAnwsersEditPage); diff --git a/targets/contributions/pages/admin/answers/index.js b/targets/contributions/pages/admin/answers/index.js deleted file mode 100644 index 415ee6ae6..000000000 --- a/targets/contributions/pages/admin/answers/index.js +++ /dev/null @@ -1,287 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import Router from "next/router"; -import React from "react"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../../src/actions"; -import Answer from "../../../src/components/Answer"; -import Pagination from "../../../src/components/Pagination"; -import * as C from "../../../src/constants"; -import Button from "../../../src/elements/Button"; -import Checkbox from "../../../src/elements/Checkbox"; -import Input from "../../../src/elements/Input"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import Select from "../../../src/elements/Select"; -import Title from "../../../src/elements/Title"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import T from "../../../src/texts"; - -const Container = styled(Flex)` - flex-grow: 1; - margin: 0 1rem 1rem; -`; - -const List = styled(Flex)` - flex-grow: 1; - padding-right: 1rem; - min-height: 0; - overflow-y: auto; -`; - -const FiltersContainer = styled(Flex)` - border-bottom: solid 1px var(--color-border); - padding: 0.5rem 0; - - > * { - flex-grow: 0.25; - } -`; - -const ActionsContainer = styled(Flex)` - background-color: var(--color-alice-blue); - border-bottom: solid 1px var(--color-border); - padding: 0.5rem 0.5rem 0.5rem 1rem; -`; - -export class AdminAnswersIndexPage extends React.Component { - get queryFilter() { - return this.$queryFilter !== undefined && this.$queryFilter !== null - ? this.$queryFilter.value - : ""; - } - - constructor(props) { - super(props); - - this.setPageIndex = this.setPageIndex.bind(this); - this.setQueryFilter = debounce(this.setQueryFilter, 250).bind(this); - } - - componentDidMount() { - const { isGeneric } = this.props; - - this.props.dispatch(actions.agreements.load()); - this.props.dispatch(actions.questions.load()); - this.props.dispatch( - actions.answers.setFilters({ - isGeneric, - }), - ); - } - - getCheckableAnswerIds() { - const { answers } = this.props; - - return answers.list.map(({ id }) => id).filter(id => !answers.checked.includes(id)); - } - - setAgreeementsFilter(selected) { - const agreements = selected !== null ? selected : []; - this.props.dispatch(actions.answers.setFilter("agreements", agreements)); - } - - setPageIndex(pageIndex) { - const { answers, dispatch } = this.props; - if (answers.isLoading) return; - - dispatch(actions.answers.load(pageIndex)); - } - - setQuestionsFilter(selected) { - const questions = selected !== null ? selected : []; - this.props.dispatch(actions.answers.setFilter("questions", questions)); - } - - setQueryFilter() { - this.props.dispatch(actions.answers.setFilter("query", this.queryFilter)); - } - - setStatesFilter(selected) { - const states = selected !== null ? selected : []; - this.props.dispatch(actions.answers.setFilter("states", states)); - } - - check(id) { - this.props.dispatch(actions.answers.toggleCheck([id])); - } - - checkAll() { - const { dispatch } = this.props; - const ids = this.getCheckableAnswerIds(); - - dispatch(actions.answers.toggleCheck(ids)); - } - - uncheckAll() { - const { dispatch, answers } = this.props; - - dispatch(actions.answers.toggleCheck(answers.checked)); - } - - setCheckedAnswersState() { - const { checked } = this.props.answers; - const { value } = this.$newState.state.value; - - this.props.dispatch( - actions.answers.updateState(checked, value, () => - this.props.dispatch(actions.answers.load()), - ), - ); - } - - printAnswers() { - const { isGeneric } = this.props; - const path = isGeneric ? "generic-answers" : "answers"; - - window.open(`/admin/${path}/print`, "_blank"); - } - - editAnswer(id) { - const path = this.props.isGeneric ? "generic-answers" : "answers"; - - if (process.env.NODE_ENV !== "development") { - window.open(`/admin/${path}/${id}`, "_blank"); - - return; - } - - Router.push(`/admin/${path}/${id}`); - } - - renderAnswersList() { - const { checked, list, isLoading } = this.props.answers; - - if (list.length === 0) { - return ( - - {isLoading ? : T.ADMIN_ANSWERS_INFO_NO_DATA} - - ); - } - - return ( - - {list.map(answer => ( - - ))} - - ); - } - - render() { - const { agreements, answers, isGeneric, questions } = this.props; - - const isLoading = isGeneric - ? answers.isLoading - : agreements.isLoading || answers.isLoading || questions.isLoading; - const stateFilterAgreements = agreements.list.map(({ id, idcc, name }) => ({ - label: `[${idcc}] ${name}`, - value: id, - })); - const stateFilterQuestions = questions.list.map(({ id, index, value }) => ({ - label: `${index}) ${value}`, - value: id, - })); - - return ( - - - - {`Réponses${isGeneric ? " génériques" : ""}`} - - - - - {/* Filters */} - {!isGeneric && ( - - (this.$queryFilter = node)} - /> - - (this.$newState = node)} - /> - - - - - {this.renderAnswersList()} - - - - - ); - } -} - -export default connect(({ agreements, answers, questions }) => ({ - agreements, - answers, - isGeneric: false, - questions, -}))(AdminAnswersIndexPage); diff --git a/targets/contributions/pages/admin/answers/print.js b/targets/contributions/pages/admin/answers/print.js deleted file mode 100644 index 835bc57ef..000000000 --- a/targets/contributions/pages/admin/answers/print.js +++ /dev/null @@ -1,95 +0,0 @@ -import styled from "@emotion/styled"; -import React from "react"; -import { connect } from "react-redux"; - -import * as actions from "../../../src/actions"; -import markdown from "../../../src/libs/markdown"; - -const Container = styled.div` - height: 100vh; - overflow-y: auto; - padding: 1rem; - - @media print { - height: auto; - padding: 0; - } -`; - -const Answer = styled.div` - @media print { - page-break-inside: avoid; - } -`; -const Content = styled.p` - font-size: 1.1rem; - margin-bottom: 1rem; - white-space: normal; -`; -const List = styled.ul` - font-size: 0.875rem; - list-style-type: square; - padding-inline-start: 0; - padding-left: 1.5rem; -`; - -export class AdminAnswersPrintPage extends React.Component { - componentDidMount() { - const { isGeneric } = this.props; - - this.props.dispatch( - actions.answers.setFilters({ - isGeneric, - pageLength: 100, - }), - ); - } - - componentDidUpdate() { - const { isLoading } = this.props.answers; - - if (!isLoading) window.print(); - } - - renderValue(value) { - return { __html: markdown.toHtml(value) }; - } - - renderAnswers() { - const { list } = this.props.answers; - - return list.map(({ agreement_idcc, id, question_index, question_value, references, value }) => ( - -

{`[IDCC: ${agreement_idcc}] ${question_index}) ${question_value}`}

-

Réponse corrigée:

- - {references.length !== 0 && ( -
-

Références:

- - {references.map(({ id, value }) => ( -
  • {value}
  • - ))} -
    -
    - )} -
    -
    - )); - } - - render() { - const { isLoading } = this.props.answers; - - if (isLoading) { - return Chargement…; - } - - return {this.renderAnswers()}; - } -} - -export default connect(({ answers }) => ({ - answers, - isGeneric: false, -}))(AdminAnswersPrintPage); diff --git a/targets/contributions/pages/admin/generic-answers/edit.js b/targets/contributions/pages/admin/generic-answers/edit.js deleted file mode 100644 index e4914b4d5..000000000 --- a/targets/contributions/pages/admin/generic-answers/edit.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from "react-redux"; - -import { AdminAnwsersEditPage } from "../answers/edit"; - -class AdminGenericAnwsersEditPage extends AdminAnwsersEditPage {} - -export default connect(({ answers, comments, legalReferences }) => ({ - answers, - comments, - isGeneric: true, - legalReferences, -}))(AdminGenericAnwsersEditPage); diff --git a/targets/contributions/pages/admin/generic-answers/index.js b/targets/contributions/pages/admin/generic-answers/index.js deleted file mode 100644 index 66cb14ef1..000000000 --- a/targets/contributions/pages/admin/generic-answers/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from "react-redux"; - -import { AdminAnswersIndexPage } from "../answers/index"; - -class AdminGenericAnswersIndexPage extends AdminAnswersIndexPage {} - -export default connect(({ agreements, answers, questions }) => ({ - agreements, - answers, - isGeneric: true, - questions, -}))(AdminGenericAnswersIndexPage); diff --git a/targets/contributions/pages/admin/generic-answers/print.js b/targets/contributions/pages/admin/generic-answers/print.js deleted file mode 100644 index 4ea82f75f..000000000 --- a/targets/contributions/pages/admin/generic-answers/print.js +++ /dev/null @@ -1,10 +0,0 @@ -import { connect } from "react-redux"; - -import { AdminAnswersPrintPage } from "../answers/print"; - -class AdminGenericAnswersPrintPage extends AdminAnswersPrintPage {} - -export default connect(({ answers }) => ({ - answers, - isGeneric: true, -}))(AdminGenericAnswersPrintPage); diff --git a/targets/contributions/pages/admin/index.js b/targets/contributions/pages/admin/index.js deleted file mode 100644 index cc44b3a74..000000000 --- a/targets/contributions/pages/admin/index.js +++ /dev/null @@ -1,354 +0,0 @@ -import styled from "@emotion/styled"; -import React from "react"; -import { Flex } from "rebass"; - -import { ANSWER_STATE } from "../../src/constants"; -import Button from "../../src/elements/Button"; -import ContentTitle from "../../src/elements/ContentTitle"; -import Subtitle from "../../src/elements/Subtitle"; -import _Table from "../../src/elements/Table"; -import Title from "../../src/elements/Title"; -import shortenAgreementName from "../../src/helpers/shortenAgreementName"; -import AdminMainLayout from "../../src/layouts/AdminMain"; -import numeral from "../../src/libs/customNumeral"; -import { GraphQLApi } from "../../src/libs/GraphQLApi"; -import { getAnswerStats, getLocationStats } from "../../src/libs/graphql"; - -// TODO Clean these columns. -/* eslint-disable react/display-name */ -const COLUMNS = [ - { - Cell: ({ value }) => {value}, - Header: "Nom", - accessor: "name", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "À rédiger", - accessor: "todo", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "En cours de rédaction", - accessor: "draft", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "À valider", - accessor: "pendingReview", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "En cours de validation", - accessor: "underReview", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "Validées", - accessor: "validated", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "Publiées", - accessor: "published", - }, -]; -const PERCENTAGE_COLUMNS = [ - { ...COLUMNS[0] }, - { - ...COLUMNS[1], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, - { - ...COLUMNS[2], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, - { - ...COLUMNS[3], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, - { - ...COLUMNS[4], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, - { - ...COLUMNS[5], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, - { - ...COLUMNS[6], - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0.00%")), - }, -]; -/* eslint-enable react/display-name */ - -const Container = styled(Flex)` - margin: 0 1rem 1rem; -`; -const Table = styled(_Table)` - font-size: 0.875rem; - - .rt-tr > .rt-th, - .rt-tr > .rt-td { - :first-of-type { - width: 30% !important; - } - :not(:first-of-type) { - width: 10% !important; - } - } - - .rt-tr > .rt-td { - :first-of-type { - cursor: help; - } - :not(:first-of-type) { - text-align: right; - } - } -`; - -const REFRESH_DELAY = 30000; - -const StatsTable = ({ data, isPercentage, ...props }) => ( - -); - -export default class AdminIndexPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - agreementsStats: [], - globalStats: [], - isCalculating: true, - isLoading: true, - isPercentage: true, - }; - } - - async componentDidMount() { - this.isUmounted = false; - this.api = new GraphQLApi(); - - await this.initializeStats(); - await this.updateStats(); - } - - componentWillUnmount() { - this.isUmounted = true; - - if (this.timeout === undefined) { - return; - } - - clearTimeout(this.timeout); - } - - async fetchLocations() { - const data = await this.api.fetch(getLocationStats); - return data.map((item) => ({ - ...item, - agreements: item.agreements.map((element) => ({ ...element.agreement })), - })); - } - - async fetchAnswersForAgreement(agreementId) { - const answers = await this.api.fetch(getAnswerStats, { - agreement_id: agreementId, - }); - return answers; - } - - async initializeStats() { - const locations = await this.fetchLocations(); - - const agreementsStats = locations - .reduce((prev, { agreements }) => [...prev, ...agreements], []) - .map(({ id, idcc, name, parent_id }) => ({ - id, - isNational: parent_id === null, - name: `[${idcc}] ${shortenAgreementName(name)}`, - totals: [0, 0, 0, 0, 0, 0, 0], - })); - - this.setState({ - agreementsStats, - isLoading: false, - }); - } - - async updateStats() { - const { agreementsStats } = this.state; - - const nextAgreementsStats = []; - for (const agreementStatsEntry of agreementsStats) { - if (this.isUmounted) { - break; - } - - const { id: agreementId } = agreementStatsEntry; - const answers = await this.fetchAnswersForAgreement(agreementId); - - const totals = answers.reduce( - (totals, { state }) => { - switch (state) { - case ANSWER_STATE.TO_DO: - totals[0] += 1; - break; - - case ANSWER_STATE.DRAFT: - totals[1] += 1; - break; - - case ANSWER_STATE.PENDING_REVIEW: - totals[2] += 1; - break; - - case ANSWER_STATE.UNDER_REVIEW: - totals[3] += 1; - break; - - case ANSWER_STATE.VALIDATED: - totals[4] += 1; - break; - - case ANSWER_STATE.PUBLISHED: - totals[5] += 1; - break; - } - - totals[6] += 1; - - return totals; - }, - [0, 0, 0, 0, 0, 0, 0] - ); - - nextAgreementsStats.push({ - ...agreementStatsEntry, - totals, - }); - } - - const nextGlobalStats = nextAgreementsStats.reduce( - (globalTotals, { totals }) => [ - globalTotals[0] + totals[0], - globalTotals[1] + totals[1], - globalTotals[2] + totals[2], - globalTotals[3] + totals[3], - globalTotals[4] + totals[4], - globalTotals[5] + totals[5], - globalTotals[6] + totals[6], - ], - [0, 0, 0, 0, 0, 0, 0] - ); - - if (this.isUmounted) { - return; - } - - this.setState({ - agreementsStats: nextAgreementsStats, - globalStats: nextGlobalStats, - isCalculating: false, - }); - - this.timeout = setTimeout(this.updateStats.bind(this), REFRESH_DELAY); - } - - generateDataRow(name, stats, isCalculating) { - const { isPercentage } = this.state; - - if (isCalculating) { - return { - draft: -1, - name, - pendingReview: -1, - published: -1, - todo: -1, - underReview: -1, - validated: -1, - }; - } - - return { - draft: isPercentage ? stats[1] / stats[6] : stats[1], - name, - pendingReview: isPercentage ? stats[2] / stats[6] : stats[2], - published: isPercentage ? stats[5] / stats[6] : stats[5], - todo: isPercentage ? stats[0] / stats[6] : stats[0], - underReview: isPercentage ? stats[3] / stats[6] : stats[3], - validated: isPercentage ? stats[4] / stats[6] : stats[4], - }; - } - - renderGlobalStats() { - const { globalStats, isCalculating, isPercentage } = this.state; - const data = [this.generateDataRow("Total", globalStats, isCalculating)]; - - return ( - - ); - } - - renderAgreementsStats(isNational = false) { - const { agreementsStats, isCalculating, isPercentage } = this.state; - const data = agreementsStats - .filter((agreement) => agreement.isNational === isNational) - .map(({ name, totals }) => - this.generateDataRow(name, totals, isCalculating) - ); - - return ( - - ); - } - - render() { - const { isLoading, isPercentage } = this.state; - - return ( - - - - Tableau de bord - - - - Global - {isLoading ?

    Calcul en cours…

    : this.renderGlobalStats()} - - Par convention collective - Conventions nationales - {isLoading ? ( -

    Calcul en cours…

    - ) : ( - this.renderAgreementsStats(true) - )} - Conventions locales - {isLoading ?

    Calcul en cours…

    : this.renderAgreementsStats()} -
    -
    - ); - } -} diff --git a/targets/contributions/pages/admin/legacy-tracker/agreement.js b/targets/contributions/pages/admin/legacy-tracker/agreement.js deleted file mode 100644 index dc0b33043..000000000 --- a/targets/contributions/pages/admin/legacy-tracker/agreement.js +++ /dev/null @@ -1,174 +0,0 @@ -import styled from "@emotion/styled"; -import React from "react"; -import { Flex } from "rebass"; - -import LegalReferenceTag from "../../../src/components/LegalReferences/Tag"; -import * as C from "../../../src/constants"; -import Button from "../../../src/elements/Button"; -import Idcc from "../../../src/elements/Idcc"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import Title from "../../../src/elements/Title"; -import shortenAgreementName from "../../../src/helpers/shortenAgreementName"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import cdtnApi from "../../../src/libs/cdtnApi"; -import customPostgrester from "../../../src/libs/customPostgrester"; -import T from "../../../src/texts"; - -const Container = styled(Flex)` - margin: 0 1rem 1rem; -`; - -const List = styled(Flex)` - flex-grow: 1; - padding-right: 0.5rem; - min-height: 0; - overflow-y: auto; -`; -const ListRow = styled(Flex)` - background-color: white; - border: solid 1px var(--color-border); - border-radius: 0.4rem; - margin-top: 0.5rem; - padding: 0 0.75rem 0.5rem; -`; -export const OpenButton = styled(Button)` - font-size: 0.875rem; - - padding: 0.325rem 0.375rem 0.375rem 0.5rem; -`; - -class AdminTrackerAgreementIdPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - agreement: null, - answers: [], - answersReferences: [], - isLoading: true, - }; - } - - async componentDidMount() { - this.postgrest = customPostgrester(); - - const { id: agreementId } = this.props; - const { data: agreements } = await this.postgrest.eq("id", agreementId).get("/agreements"); - const agreement = agreements[0]; - - this.setState({ agreement }); - - const { data: answers } = await this.postgrest - .select("*") - .select("question(index)") - .eq("agreement_id", agreementId) - .orderBy("question.index") - .get("/answers"); - - this.setState({ answers }); - - const answerIds = answers.map(({ id }) => id); - - const { data: answersReferences } = await this.postgrest - .in("answer_id", answerIds) - .get("/answers_references"); - - this.setState({ - answersReferences, - isLoading: false, - }); - } - - async fetchAnswersForAgreement(agreementId) { - const { data: answers } = await this.postgrest.eq("agreement_id", agreementId).get("/answers"); - - return answers; - } - - async findObsoleteAnswersReferences(answersReferences) { - // TODO Remove `dila_cid !== null` check once all the references are cleaned. - const localAgreementAnswersReferences = answersReferences.filter( - ({ category, dila_cid }) => - category === C.ANSWER_REFERENCE_CATEGORY.AGREEMENT && dila_cid !== null, - ); - - const obsoleteAgreementAnswersReference = []; - for (const localAgreementAnswerReference of localAgreementAnswersReferences) { - try { - const { dila_id } = localAgreementAnswerReference; - await cdtnApi.get(`/agreement/articles?articleIdsOrCids=${dila_id}`); - } catch (err) { - obsoleteAgreementAnswersReference.push(localAgreementAnswerReference); - } - } - - return [...obsoleteAgreementAnswersReference]; - } - - open(answerId) { - window.open(`/admin/answers/${answerId}`, "_blank"); - } - - renderAnswerReferences() { - const { answers, answersReferences, isLoading } = this.state; - - if (isLoading) { - return ( - - - - ); - } - - if (answersReferences.length === 0) { - return ( - - {T.ADMIN_TRACKER_INFO_NO_DATA} - - ); - } - - return ( - - {answersReferences.map(answerReference => { - const answer = answers.find(({ id }) => id === answerReference.answer_id); - - return ( - - - - this.open(answerReference.answer_id)} - /> - - ); - })} - - ); - } - - render() { - const { agreement } = this.state; - - return ( - - - - {agreement === null && Tableau de veille » …} - {agreement !== null && ( - {`Tableau de veille » [${agreement.idcc}] ${shortenAgreementName( - agreement.name, - )}`} - )} - - - {this.renderAnswerReferences()} - - - ); - } -} - -export default AdminTrackerAgreementIdPage; diff --git a/targets/contributions/pages/admin/legacy-tracker/index.js b/targets/contributions/pages/admin/legacy-tracker/index.js deleted file mode 100644 index d30d3e7f6..000000000 --- a/targets/contributions/pages/admin/legacy-tracker/index.js +++ /dev/null @@ -1,239 +0,0 @@ -import styled from "@emotion/styled"; -import React from "react"; -import { Flex } from "rebass"; - -import * as C from "../../../src/constants"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import _Table from "../../../src/elements/Table"; -import Title from "../../../src/elements/Title"; -import shortenAgreementName from "../../../src/helpers/shortenAgreementName"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import cdtnApi from "../../../src/libs/cdtnApi"; -import numeral from "../../../src/libs/customNumeral"; -import customPostgrester from "../../../src/libs/customPostgrester"; - -const Container = styled(Flex)` - margin: 0 1rem 1rem; -`; - -const Table = styled(_Table)` - display: fles; - flex-grow: 1; - font-size: 0.875rem; - margin-top: 0.5rem; - overflow-y: auto; - - .rt-tr > .rt-th, - .rt-tr > .rt-td { - :first-of-type { - width: 50% !important; - } - :not(:first-of-type) { - width: 50% !important; - } - } - - .rt-tr > .rt-td { - :first-of-type { - cursor: pointer; - } - :not(:first-of-type) { - text-align: right; - } - } -`; - -// TODO Clean these columns. -/* eslint-disable react/display-name */ -const DASHBOARD_TABLE_COLUMNS = [ - { - Cell: ({ row, value }) => { - return ( - window.open(`/admin/tracker/${row._original.id}`)} - onKeyPress={() => window.open(`/admin/tracker/${row._original.id}`)} - role="link" - tabIndex="0" - title={value} - > - {value} - - ); - }, - Header: "Convention", - accessor: "name", - }, - { - Cell: ({ value }) => (value === -1 ? "…" : numeral(value).format("0,0")), - Header: "Nombre de références obsolètes", - accessor: "total", - }, -]; -/* eslint-enable react/display-name */ - -class AdminTrackerPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - answersReferencesStats: [], - isLoading: true, - selectedAgreementOption: null, - }; - } - - async componentDidMount() { - this.isUmounted = false; - this.postgrest = customPostgrester(); - - await this.initializeStats(); - await this.updateStats(); - } - - componentWillUnmount() { - this.isUmounted = true; - } - - async initializeStats() { - const { data: locations } = await this.postgrest - .select("*") - .select("agreements(id,idcc,name,parent_id)") - .get("/locations"); - - const answersReferencesStats = locations - .reduce((prev, { agreements }) => [...prev, ...agreements], []) - .filter(({ parent_id }) => parent_id === null) - .map(({ id, idcc, name }) => ({ - id, - name: `[${idcc}] ${shortenAgreementName(name)}`, - total: -1, - })); - - this.setState({ - answersReferencesStats: [ - { - id: null, - name: `[Code du travail] Réponses génériques`, - total: -1, - }, - ...answersReferencesStats, - ], - isLoading: false, - }); - } - - async fetchAnswersForAgreement(agreementId) { - const { data: answers } = await this.postgrest.eq("agreement_id", agreementId).get("/answers"); - - return answers; - } - - async findObsoleteAnswersReferences(answersReferences) { - // TODO Remove `dila_cid !== null` check once all the references are cleaned. - const localAgreementAnswersReferences = answersReferences.filter( - ({ category, dila_cid }) => - category === C.ANSWER_REFERENCE_CATEGORY.AGREEMENT && dila_cid !== null, - ); - const localCodeAnswersReferences = answersReferences.filter( - ({ category, dila_cid }) => - category === C.ANSWER_REFERENCE_CATEGORY.LABOR_CODE && dila_cid !== null, - ); - - const obsoleteAgreementAnswersReference = []; - for (const localAgreementAnswerReference of localAgreementAnswersReferences) { - try { - const { dila_id } = localAgreementAnswerReference; - await cdtnApi.get(`/agreement/articles?articleIdsOrCids=${dila_id}`); - } catch (err) { - obsoleteAgreementAnswersReference.push(localAgreementAnswerReference); - } - } - const obsoleteCodeAnswersReference = []; - for (const localCodeAnswerReference of localCodeAnswersReferences) { - try { - const { dila_id } = localCodeAnswerReference; - await cdtnApi.get(`/code/articles?articleIdsOrCids=${dila_id}`); - } catch (err) { - obsoleteAgreementAnswersReference.push(localCodeAnswerReference); - } - } - - return [...obsoleteAgreementAnswersReference, ...obsoleteCodeAnswersReference]; - } - - async updateStats() { - const { answersReferencesStats } = this.state; - - const { length } = answersReferencesStats; - let index = -1; - while (++index < length) { - if (this.isUmounted) { - break; - } - - const { answersReferencesStats } = this.state; - const nextAnswersReferencesStats = [...answersReferencesStats]; - const { id: agreementId } = answersReferencesStats[index]; - - const { data: answers } = - agreementId !== null - ? await this.postgrest.eq("agreement_id", agreementId).get("/answers") - : await this.postgrest.is("agreement_id", null).get("/answers"); - - const answerIds = answers.map(({ id }) => id); - const { data: answersReferences } = await this.postgrest - .in("answer_id", answerIds) - .get("/answers_references"); - - const obsoleteAnswersReferences = await this.findObsoleteAnswersReferences(answersReferences); - - nextAnswersReferencesStats[index].total = obsoleteAnswersReferences.length; - - if (this.isUmounted) { - return; - } - - this.setState({ - answersReferencesStats: nextAnswersReferencesStats, - }); - } - } - - renderDashboard() { - const { answersReferencesStats, isLoading } = this.state; - - if (isLoading) { - return ( - - - - ); - } - - return ( -
    - ); - } - - render() { - return ( - - - Tableau de veille - {this.renderDashboard()} - - - ); - } -} - -export default AdminTrackerPage; diff --git a/targets/contributions/pages/admin/locations/edit.js b/targets/contributions/pages/admin/locations/edit.js deleted file mode 100644 index fc208c03d..000000000 --- a/targets/contributions/pages/admin/locations/edit.js +++ /dev/null @@ -1,48 +0,0 @@ -import withAdminEdit from "../../../src/templates/withAdminEdit"; -import { FIELDS } from "./new"; - -const componentDidMount = async (api, id) => { - const { data: locations } = await api - .eq("id", id) - .select("*") - .select("agreements(*)") - .get("/locations"); - const { data: agreements } = await api.get("/agreements"); - - const defaultData = { - ...locations[0], - agreements: locations[0].agreements.map(agreement => ({ - id: agreement.id, - value: `${agreement.idcc} - ${agreement.name}`, - })), - }; - - const fields = [ - ...FIELDS, - { - apiPath: "/locations_agreements", - label: "Conventions", - name: "agreements", - tags: agreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "tags", - }, - ]; - - return { defaultData, fields }; -}; - -const AdminLocationsEditPage = withAdminEdit( - { - apiPath: "/locations", - i18nIsFeminine: true, - i18nSubject: "unité", - indexPath: "/locations", - name: "locations", - }, - componentDidMount, -); - -export default AdminLocationsEditPage; diff --git a/targets/contributions/pages/admin/locations/index.js b/targets/contributions/pages/admin/locations/index.js deleted file mode 100644 index a423b5fb9..000000000 --- a/targets/contributions/pages/admin/locations/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; - -import AdminIndex from "../../../src/components/AdminIndex"; - -const COLUMNS = [ - { - Header: "Nom", - accessor: "name", - }, -]; - -const AdminLocationsIndexPage = () => ( - -); - -export default AdminLocationsIndexPage; diff --git a/targets/contributions/pages/admin/locations/new.js b/targets/contributions/pages/admin/locations/new.js deleted file mode 100644 index cda82fbf3..000000000 --- a/targets/contributions/pages/admin/locations/new.js +++ /dev/null @@ -1,43 +0,0 @@ -import withAdminNew from "../../../src/templates/withAdminNew"; - -export const FIELDS = [ - { - label: "Nom", - name: "name", - type: "input", - }, -]; - -const componentDidMount = async api => { - const { data: agreements } = await api.get("/agreements"); - - const fields = [ - ...FIELDS, - { - apiPath: "/locations_agreements", - ariaName: "la convention", - label: "Conventions", - name: "agreements", - tags: agreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "tags", - }, - ]; - - return { fields }; -}; - -const AdminLocationsNewPage = withAdminNew( - { - apiPath: "/locations", - i18nIsFeminine: true, - i18nSubject: "unité", - indexPath: "/locations", - name: "locations", - }, - componentDidMount, -); - -export default AdminLocationsNewPage; diff --git a/targets/contributions/pages/admin/logs/index.js b/targets/contributions/pages/admin/logs/index.js deleted file mode 100644 index 12e2c3da8..000000000 --- a/targets/contributions/pages/admin/logs/index.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; - -import * as actions from "../../../src/actions"; -import { Container, Head } from "../../../src/components/AdminIndex/styles"; -import Button from "../../../src/elements/Button"; -import Table from "../../../src/elements/Table"; -import Title from "../../../src/elements/Title"; -import capitalize from "../../../src/helpers/capitalize"; -import humanizeLogAction from "../../../src/helpers/humanizeLogAction"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import moment from "../../../src/libs/customMoment"; - -// TODO Clean these columns. -/* eslint-disable react/display-name */ -const COLUMNS = [ - { - Cell: ({ value }) => (value !== null ? value.name : "N/A"), - Header: "Nom", - accessor: "user", - }, - { - Cell: ({ value }) => (value !== null ? capitalize(value.role) : "N/A"), - Header: "Role", - accessor: "user", - }, - { - Header: "IP", - accessor: "ip", - }, - { - Cell: ({ original: { method, path } }) => humanizeLogAction(method, path), - Header: "Action", - accessor: "method", - }, - { - Header: "Chemin", - accessor: "path", - }, - { - Cell: ({ value }) => (value !== null ? {value} : "N/A"), - Header: "Corps", - accessor: "body", - }, - { - Cell: ({ value }) => moment(value).format("L HH:mm:ss"), - Header: "Date", - accessor: "created_at", - }, -]; -/* eslint-enable react/display-name */ - -class AdminLogsIndexPage extends React.Component { - componentDidMount() { - this.props.dispatch(actions.logs.load({ pageIndex: -1 })); - } - - deleteOlderThanOneWeek() { - this.props.dispatch(actions.logs.deleteOlderThanOneWeek()); - } - - render() { - const { logs } = this.props; - - return ( - - - - Logs - - -
    - - - ); - } -} - -export default connect(({ logs }) => ({ - logs, -}))(AdminLogsIndexPage); diff --git a/targets/contributions/pages/admin/migrations/edit.js b/targets/contributions/pages/admin/migrations/edit.js deleted file mode 100644 index b132e7d36..000000000 --- a/targets/contributions/pages/admin/migrations/edit.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from "react"; - -import AdminForm from "../../../src/components/AdminForm"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import api from "../../../src/libs/api"; - -const FIELDS = [ - { - label: "Nom", - name: "name", - type: "input", - }, -]; - -export default class AdminQuestionsEditPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - isLoading: true, - }; - } - - async componentDidMount() { - try { - const uri = `/administrator_migrations?id=eq.${this.props.id}`; - - const migrations = await api.get(uri); - - this.setState({ - data: migrations[0], - isLoading: false, - }); - } catch (err) { - if (err !== undefined) console.warn(err); - } - } - - render() { - if (this.state.isLoading) return ; - - return ( - - ); - } -} diff --git a/targets/contributions/pages/admin/migrations/index.js b/targets/contributions/pages/admin/migrations/index.js deleted file mode 100644 index 2532216bf..000000000 --- a/targets/contributions/pages/admin/migrations/index.js +++ /dev/null @@ -1,38 +0,0 @@ -import moment from "moment-timezone"; -import React from "react"; - -import AdminIndex from "../../../src/components/AdminIndex"; - -const COLUMNS = [ - { - Header: "Index", - accessor: "id", - }, - { - Header: "Nom", - accessor: "name", - }, - { - Header: "Créé le", - accessor: data => moment(data.migration_time).tz("Europe/Paris").format("YYYY-MM-DD HH:mm"), - filterable: false, - id: "createdAt", - style: { textAlign: "center" }, - width: 160, - }, -]; - -const AdminMigrationsIndexPage = () => ( - -); - -export default AdminMigrationsIndexPage; diff --git a/targets/contributions/pages/admin/questions/edit.js b/targets/contributions/pages/admin/questions/edit.js deleted file mode 100644 index 3b2206282..000000000 --- a/targets/contributions/pages/admin/questions/edit.js +++ /dev/null @@ -1,36 +0,0 @@ -import withAdminEdit from "../../../src/templates/withAdminEdit"; - -const FIELDS = [ - { - inputType: "number", - label: "Index", - name: "index", - type: "input", - }, - { - label: "Intitulé", - name: "value", - type: "text", - }, -]; - -const componentDidMount = async (api, id) => { - const questions = await api.fetchAll("/questions", { id }); - - return { - defaultData: questions[0], - fields: FIELDS, - }; -}; - -const AdminDefinitionsEditPage = withAdminEdit( - { - apiPath: "/questions", - i18nIsFeminine: true, - i18nSubject: "question", - indexPath: "/questions", - }, - componentDidMount, -); - -export default AdminDefinitionsEditPage; diff --git a/targets/contributions/pages/admin/questions/index.js b/targets/contributions/pages/admin/questions/index.js deleted file mode 100644 index 0d19e95cb..000000000 --- a/targets/contributions/pages/admin/questions/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; - -import AdminIndex from "../../../src/components/AdminIndex"; - -const COLUMNS = [ - { - Header: "Index", - accessor: "index", - style: { textAlign: "right" }, - width: 80, - }, - { - Header: "Intitulé", - accessor: "value", - }, -]; - -const QuestionsIndexPage = () => ( - -); - -export default QuestionsIndexPage; diff --git a/targets/contributions/pages/admin/questions/new.jsx b/targets/contributions/pages/admin/questions/new.jsx deleted file mode 100644 index 0960e140c..000000000 --- a/targets/contributions/pages/admin/questions/new.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import { useRouter } from "next/router"; -import React from "react"; - -import { addQuestion } from "../../../src/api"; -import AdminForm from "../../../src/components/AdminForm"; - -const FIELDS = [ - { - inputType: "number", - label: "Index", - name: "index", - type: "input", - }, - { - label: "Intitulé", - name: "value", - type: "text", - }, -]; - -export default function AdminNew() { - const { back } = useRouter(); - const [isSubmitting, submitting] = React.useState(false); - const [error, setError] = React.useState(); - - const onSubmit = async data => { - try { - submitting(true); - setError(null); - await addQuestion(data.index, data.value); - back(); - } catch (err) { - if ( - err !== undefined && - err.response !== undefined && - err.response.data !== undefined && - typeof err.response.data.message === "string" - ) { - setError(`Erreur: ${err.response.data.message}.`); - } else { - setError(`Erreur: ${err}`); - if (err !== undefined) console.warn(err); - } - } finally { - submitting(false); - } - }; - - return ( - - ); -} diff --git a/targets/contributions/pages/admin/tracker/index.js b/targets/contributions/pages/admin/tracker/index.js deleted file mode 100644 index 094fcbe0e..000000000 --- a/targets/contributions/pages/admin/tracker/index.js +++ /dev/null @@ -1,193 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import React from "react"; -import ReactDiffViewer from "react-diff-viewer"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../../src/actions"; -import Tree from "../../../src/components/Tree"; -import Button from "../../../src/elements/Button"; -import Icon from "../../../src/elements/Icon"; -import LoadingSpinner from "../../../src/elements/LoadingSpinner"; -import MarkdownEditor from "../../../src/elements/MarkdownEditor"; -import Subtitle from "../../../src/elements/Subtitle"; -import Title from "../../../src/elements/Title"; -import AdminMainLayout from "../../../src/layouts/AdminMain"; -import api from "../../../src/libs/api"; - -const Container = styled(Flex)` - margin: 0 1rem 1rem; -`; - -const TreeContainer = styled(Flex)` - max-width: 20rem; - min-width: 20rem; -`; - -const Editor = styled(MarkdownEditor)` - max-height: 100%; - min-height: 100%; - - .editor { - border: 0 !important; - } -`; - -export class AdminTrackerIndexPage extends React.Component { - constructor(props) { - super(props); - - this.selectAnswer = this.selectAnswer.bind(this); - this.updateAnswerValue = debounce(this._updateAnswerValue.bind(this), 500).bind(this); - - this.state = { - selectedReferenceDiff: null, - }; - } - - componentDidMount() { - this.props.dispatch(actions.answers.toggleIsLoading()); - this.props.dispatch(actions.alerts.load()); - } - - selectAnswer({ key }) { - this.props.dispatch(actions.alerts.selectOne(key)); - } - - async _updateAnswerValue({ source }) { - try { - const { - answers: { - data: { id }, - }, - } = this.props; - const value = source.trim(); - const uri = `/answers?id=eq.${id}`; - const data = { value }; - - await api.patch(uri, data); - } catch (err) { - console.warn(err); - } - } - - openAnswerInNewTab(id) { - window.open(`/admin/answers/${id}`, "_blank"); - } - - processAnswer() { - this.props.dispatch(actions.alerts.processOne()); - } - - renderDiff() { - const { - alerts: { - diff: { etat, texts }, - }, - } = this.props; - - return ( - - - État : {etat.previous} ► {etat.current} - - {texts.length !== 0 && ( - - )} - - ); - } - - renderTree() { - const { alerts } = this.props; - const { isLoading, selectedKey, tree } = alerts; - - if (isLoading) { - return ( - - - - ); - } - - return ( - - Tableau de veille - - - ); - } - - renderEditor() { - const { - alerts: { isLoading: alertsIsLoading }, - answers: { data: answersData, isLoading: answersIsLoading }, - } = this.props; - - if (alertsIsLoading || answersIsLoading) { - return ( - - - - ); - } - - if (answersData === null) { - return ( -

    - - Sélectionnez une réponse parmi les alertes pour la traiter. -

    - ); - } - - const { id, value } = answersData; - - return ( - - - {this.renderDiff()} - - - - - - - - - - ); - } - - render() { - return ( - - - {this.renderTree()} - {this.renderEditor()} - - - ); - } -} - -export default connect(({ alerts, answers, legalReferences }) => ({ - alerts, - answers, - legalReferences, -}))(AdminTrackerIndexPage); diff --git a/targets/contributions/pages/admin/users/edit.js b/targets/contributions/pages/admin/users/edit.js deleted file mode 100644 index 6836b649d..000000000 --- a/targets/contributions/pages/admin/users/edit.js +++ /dev/null @@ -1,54 +0,0 @@ -import withAdminEdit from "../../../src/templates/withAdminEdit"; -import { FIELDS } from "./new"; - -const componentDidMount = async (api, id) => { - const { data: users } = await api.eq("id", id).get("/administrator_users"); - const { data: agreements } = await api.get("/agreements"); - const { data: locations } = await api.get("/locations"); - - const defaultData = { - ...users[0], - agreements: users[0].agreements.map(agreement => ({ - id: agreement.id, - value: `${agreement.idcc} - ${agreement.name}`, - })), - }; - - const fields = [ - ...FIELDS, - { - label: "Unité", - name: "location_id", - options: locations.map(({ id: value, name: label }) => ({ - label, - value, - })), - type: "select", - }, - { - label: "Conventions", - name: "agreements", - tags: agreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "tags", - }, - ]; - - return { - defaultData, - fields, - }; -}; - -const AdminUsersEditPage = withAdminEdit( - { - apiPath: "/rpc/update_user", - i18nSubject: "utilisateur", - indexPath: "/users", - }, - componentDidMount, -); - -export default AdminUsersEditPage; diff --git a/targets/contributions/pages/admin/users/index.js b/targets/contributions/pages/admin/users/index.js deleted file mode 100644 index 234e1796f..000000000 --- a/targets/contributions/pages/admin/users/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; - -import AdminIndex from "../../../src/components/AdminIndex"; - -const COLUMNS = [ - { - Header: "Nom", - accessor: "name", - }, - { - Header: "E-mail", - accessor: "email", - }, - { - Header: "Rôle", - accessor: "role", - }, - { - Header: "Conventions", - accessor: data => data.agreements.map(({ idcc }) => idcc).join(", "), - id: "idccs", - width: 160, - }, -]; - -const AdminUsersIndexPage = () => ( - -); - -export default AdminUsersIndexPage; diff --git a/targets/contributions/pages/admin/users/new.js b/targets/contributions/pages/admin/users/new.js deleted file mode 100644 index 669368dc3..000000000 --- a/targets/contributions/pages/admin/users/new.js +++ /dev/null @@ -1,83 +0,0 @@ -import generatePassword from "../../../src/libs/generatePassword"; -import withAdminNew from "../../../src/templates/withAdminNew"; - -const PASSWORD_LENGTH = 16; - -export const FIELDS = [ - { - label: "Nom", - name: "name", - type: "input", - }, - { - label: "Rôle", - name: "role", - options: [ - { label: "Administrateur", value: "administrator" }, - { label: "Administrateur régional", value: "regional_administrator" }, - { label: "Contributeur", value: "contributor" }, - ], - type: "select", - }, - { - inputType: "email", - label: "E-mail", - name: "email", - type: "input", - }, - { - button: { - handler: () => generatePassword(PASSWORD_LENGTH), - icon: "sync", - title: "Bouton générant un mot de passe aléatoire", - }, - label: "Mot-de-passe", - name: "password", - type: "input", - }, -]; - -const componentDidMount = async api => { - const { data: agreements } = await api.get("/agreements"); - const { data: locations } = await api.get("/locations"); - - const defaultData = { - password: generatePassword(PASSWORD_LENGTH), - }; - - const fields = [ - ...FIELDS, - { - label: "Unité", - name: "location_id", - options: locations.map(({ id: value, name: label }) => ({ - label, - value, - })), - type: "select", - }, - { - ariaName: "la convention", - label: "Conventions", - name: "agreements", - tags: agreements.map(({ id, idcc, name }) => ({ - label: `${idcc} - ${name}`, - value: id, - })), - type: "tags", - }, - ]; - - return { defaultData, fields }; -}; - -const AdminUsersNewPage = withAdminNew( - { - apiPath: "/rpc/create_user", - i18nSubject: "utilisateur", - indexPath: "/users", - }, - componentDidMount, -); - -export default AdminUsersNewPage; diff --git a/targets/contributions/pages/answers/edit.js b/targets/contributions/pages/answers/edit.js deleted file mode 100644 index 4a289fb1a..000000000 --- a/targets/contributions/pages/answers/edit.js +++ /dev/null @@ -1,293 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import Router from "next/router"; -import React from "react"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../src/actions"; -import AnswerEditionContentBlock from "../../src/blocks/AnswerEditionContent"; -import AnswerEditionHeadBlock from "../../src/blocks/AnswerEditionHead"; -import { TABS } from "../../src/blocks/AnswerEditionHead/Tabs"; -import AnswerEditionReferencesBlock from "../../src/blocks/AnswerEditionReferences"; -import { ANSWER_STATE } from "../../src/constants"; -import SavingSpinner from "../../src/elements/SavingSpinner"; -import Main from "../../src/layouts/Main"; -import { api } from "../../src/libs/GraphQLApi"; -import getCurrentUser from "../../src/libs/getCurrentUser"; -import makeApiFilter from "../../src/libs/makeApiFilter"; -import { - getAnswerReferences, - updateAnswerReference, - updateAnswersStates, -} from "../../src/libs/graphql"; - -const Container = styled(Main)` - overflow-x: hidden; -`; -const Content = styled(Flex)` - flex-grow: 1; - overflow-y: auto; -`; -const ContentInfo = styled(Flex)` - color: var(--color-shadow); - font-size: 1rem; - margin-top: 0.5rem; - position: absolute; - right: 1rem; - width: 12.5rem; -`; - -class AnswersEditPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - currentTab: TABS.EDITOR, - hasSavingSpinner: false, - isLoading: true, - isSaving: false, - me: null, - references: [], - savingSpinnerTimeout: 0, - }; - - this.prevalue = null; - this.newPrevalue = null; - - this.createReference = debounce(this._createReference.bind(this), 500); - this.deleteReference = debounce(this._deleteReference.bind(this), 500); - this.updatePrevalue = debounce(this._updatePrevalue.bind(this), 500); - } - - async componentDidMount() { - const { id } = this.props; - const me = getCurrentUser(); - - this.load(); - - try { - const references = await api.fetch(getAnswerReferences, { - answer_id: id, - }); - - this.setState({ - isLoading: false, - me, - references, - }); - } catch (err) { - console.warn(err); - } - } - - componentDidUpdate() { - if (!this.props.answers.isLoading) { - if (this.prevalue === null) { - this.prevalue = this.props.answers.data.prevalue; - this.newPrevalue = this.props.answers.data.prevalue; - this.forceUpdate(); - } - } - } - - load() { - const { dispatch, id } = this.props; - - dispatch(actions.answers.loadOne(id)); - } - - async cancel() { - if (this.state.isSaving) return; - - this.props.dispatch( - actions.modal.open( - `Êtes-vous sûr d'annuler cette réponse (son contenu sera supprimé) ?`, - () => - actions.answers.cancel([this.props.id], () => - Router.push("/answers/draft/1") - ) - ) - ); - } - - async requestForAnswerValidation() { - if (this.state.isSaving) return; - - this.props.dispatch( - actions.modal.open( - `Êtes-vous sûr d'envoyer cette réponse en validation ?`, - () => - actions.answers.updateState( - [this.props.id], - ANSWER_STATE.PENDING_REVIEW, - () => Router.push("/answers/draft/1") - ) - ) - ); - } - - async _updatePrevalue(value) { - this.setState({ isSaving: true }); - this.showSavingSpinner(); - - try { - const data = { - prevalue: value, - state: "draft", - user_id: this.state.me.id, - }; - - await api.update(updateAnswersStates, { data, ids: [this.props.id] }); - this.newPrevalue = value; - } catch (err) { - console.warn(err); - } - - this.setState({ isSaving: false }); - } - - async _createReference(reference) { - this.setState({ isSaving: true }); - - try { - const answersData = { - state: "draft", - user_id: this.state.me.id, - }; - const answersReferencesData = { - answer_id: this.props.id, - ...reference, - }; - - await api.update(updateAnswersStates, { - data: answersData, - ids: [this.props.id], - }); - - const { id, ...data } = answersReferencesData; - await api.update(updateAnswerReference, { id, data }); - } catch (err) { - console.warn(err); - } - - this.setState({ - isSaving: false, - references: [...this.state.references, reference], - }); - } - - async _deleteReference(_value) { - this.setState({ isSaving: true }); - - try { - const uri = makeApiFilter("/answers_references", { - answer_id: this.props.id, - value: _value, - }); - - // TODO await api.delete(deleteAnswerReference, {}) - await api.delete(uri); - } catch (err) { - console.warn(err); - } - - this.setState({ - isSaving: false, - references: this.state.references.filter(({ value }) => value !== _value), - }); - } - - showSavingSpinner() { - if (this.state.hasSavingSpinner) { - clearTimeout(this.state.savingSpinnerTimeout); - } - - this.setState({ - hasSavingSpinner: true, - savingSpinnerTimeout: setTimeout( - () => - this.setState({ - hasSavingSpinner: false, - savingSpinnerTimeout: 0, - }), - 2000 - ), - }); - } - - switchTab(nextTab) { - if (nextTab === this.state.currentTab) return; - - if (nextTab === TABS.EDITOR) { - this.prevalue = this.newPrevalue; - } - - this.setState({ currentTab: nextTab }); - } - - renderTab() { - const { prevalue } = this; - const { references } = this.state; - - switch (this.state.currentTab) { - case TABS.REFERENCES: - return ( - - ); - - case TABS.EDITOR: - default: - return ( - - ); - } - } - - render() { - const { prevalue } = this; - const { answers } = this.props; - const { isLoading, references } = this.state; - - if (isLoading || answers.isLoading || prevalue === null) { - return
    ; - } - - const { agreement, question } = answers.data; - - return ( - - this.cancel()} - onSubmit={() => this.requestForAnswerValidation()} - onTabChange={this.switchTab.bind(this)} - question={question} - referencesCount={references.length} - /> - - {this.state.hasSavingSpinner && ( - - - Sauvegarde en cours… - - )} - - {this.renderTab()} - - - ); - } -} - -export default connect(({ answers }) => ({ answers }))(AnswersEditPage); diff --git a/targets/contributions/pages/answers/index.js b/targets/contributions/pages/answers/index.js deleted file mode 100644 index 491bbb9a0..000000000 --- a/targets/contributions/pages/answers/index.js +++ /dev/null @@ -1,219 +0,0 @@ -import styled from "@emotion/styled"; -import debounce from "lodash.debounce"; -import Router, { withRouter } from "next/router"; -import React from "react"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../src/actions"; -import AnswerBlock from "../../src/blocks/Answer"; -import { ANSWER_STATE } from "../../src/constants"; -import Input from "../../src/elements/Input"; -import Subtitle from "../../src/elements/Subtitle"; -import Main from "../../src/layouts/Main"; -import T from "../../src/texts"; - -const Content = styled(Flex)` - flex-grow: 1; - padding: 0 1rem 1rem; -`; -const List = styled(Flex)` - flex-grow: 1; - min-height: 0; - overflow-y: auto; -`; - -const Text = styled.p` - margin-bottom: 0.5rem; -`; -const InfoText = styled(Text)` - color: var(--color-dark-slate-gray); -`; -const ErrorText = styled(Text)` - color: var(--color-text-red); - font-weight: 600; -`; -const HelpText = styled(Text)` - font-size: 0.875rem; -`; - -const FilterInputContainer = styled.div` - margin-right: 13rem; -`; -const FilterInput = styled(Input)` - margin: 0.5rem 0; -`; - -class AnswersIndexPage extends React.Component { - get query() { - return this.$query !== undefined && this.$query !== null ? this.$query.value : ""; - } - - constructor(props) { - super(props); - - this.state = { - me: null, - }; - - this.load = debounce(this._load.bind(this), 500); - } - - componentDidMount() { - this.load(); - } - - componentDidUpdate(prevProps) { - const { - router: { - query: { page: prevPage, state: prevState }, - }, - } = prevProps; - const { - router: { - query: { page, state }, - }, - } = this.props; - - if (page !== prevPage || state !== prevState) { - this.load(); - } - } - - _load() { - const { - router: { - query: { page, state }, - }, - } = this.props; - - const pageIndex = Number(page) - 1; - const states = - state === ANSWER_STATE.UNDER_REVIEW - ? [ANSWER_STATE.PENDING_REVIEW, ANSWER_STATE.UNDER_REVIEW] - : [state]; - - const meta = { - pageIndex, - query: this.query, - states, - }; - - this.props.dispatch(actions.answers.load(meta)); - } - - goToPage({ selected }) { - const { - router: { - query: { state }, - }, - } = this.props; - - const href = `/answers?state=${state}&page=${selected + 1}`; - const as = `/answers/${state}/${selected + 1}`; - Router.push(href, as, { shallow: true }); - } - - cancel(id) { - const action = () => actions.answers.cancel([id], this.load.bind(this)); - - this.props.dispatch(actions.modal.open(T.ANSWERS_INDEX_MODAL_CANCEL, action)); - } - - updateGenericReference(id, genericReference) { - this.props.dispatch( - actions.answers.updateGenericReference([id], genericReference, this.load.bind(this)), - ); - } - - openAnswer(id) { - const { - router: { - query: { state }, - }, - } = this.props; - - if ([ANSWER_STATE.TO_DO, ANSWER_STATE.DRAFT].includes(state)) { - Router.push(`/answers/edit/${id}`); - - return; - } - - Router.push(`/answers/view/${id}`); - } - - renderAnswers() { - const { - answers, - router: { - query: { state }, - }, - } = this.props; - const { list, error } = answers; - - if (error !== null) { - return {error}; - } - - if (list.length === 0) { - if (this.query.length !== 0) { - return {T.ANSWERS_INDEX_INFO_NO_SEARCH_RESULT}; - } - - return {T.ANSWERS_INDEX_INFO_NO_DATA(state)}; - } - - return list.map(answer => [ - , - ]); - } - - render() { - const { - answers, - router: { - query: { state }, - }, - } = this.props; - const { isLoading, list } = answers; - - return ( -
    - - {T.ANSWERS_INDEX_TITLE(state)} - - this.load()} - placeholder={T.ANSWERS_INDEX_SEARCH_PLACEHOLDER} - ref={node => (this.$query = node)} - /> - - {isLoading && ( - - Chargement… - - )} - {!isLoading && ( - - {state === ANSWER_STATE.TO_DO && list.length !== 0 && ( - {T.ANSWERS_INDEX_HELP_TO_DO} - )} - {this.renderAnswers()} - - )} - -
    - ); - } -} - -export default connect(({ answers }) => ({ - answers, -}))(withRouter(AnswersIndexPage)); diff --git a/targets/contributions/pages/answers/view.js b/targets/contributions/pages/answers/view.js deleted file mode 100644 index f2f34f5e1..000000000 --- a/targets/contributions/pages/answers/view.js +++ /dev/null @@ -1,230 +0,0 @@ -import styled from "@emotion/styled"; -import React from "react"; -import Medixtor from "react-medixtor"; -import { connect } from "react-redux"; -import { Flex } from "rebass"; - -import * as actions from "../../src/actions"; -import LegalReferences from "../../src/components/LegalReferences"; -import { ANSWER_STATE } from "../../src/constants"; -import Hr from "../../src/elements/Hr"; -import Idcc from "../../src/elements/Idcc"; -import Subtitle from "../../src/elements/Subtitle"; -import Title from "../../src/elements/Title"; -import Main from "../../src/layouts/Main"; -import { api } from "../../src/libs/GraphQLApi"; -import { getAnswerReferences } from "../../src/libs/graphql"; - -const Container = styled(Main)` - overflow-y: auto; - padding: 1rem; -`; - -const AnswerEditor = styled(Medixtor)` - border: solid 1px var(--color-border) !important; - border-radius: 0.25rem; - flex-grow: unset; - min-height: 15rem; - - .editor { - background-color: white; - } - .editor-status { - display: none; - } - - .preview { - background-color: white; - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - line-height: 1.4; - min-width: 100% !important; - overflow-y: auto; - padding-top: 0 !important; - width: 100% !important; - - a { - color: #0053b3; - - :after { - content: ""; - position: relative; - top: 1px; - display: inline-block; - width: 15px; - height: 15px; - margin-left: 5px; - background: url("/static/assets/icons/external-link.svg") 100% 50% / - 15px no-repeat; - } - - :hover { - text-decoration: none; - } - } - - h2, - h3, - h4, - h5, - h6 { - color: #006ab2; - } - h2 { - font-size: 1.875rem; - } - h3 { - font-size: 1.625rem; - } - h4 { - font-size: 1.375rem; - } - h5 { - font-size: 1.125rem; - } - h6 { - font-size: 1rem; - } - - p { - color: #434956; - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0; - margin-inline-end: 0; - } - - ul { - list-style-type: disc; - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px; - padding-inline-start: 20px; - - li { - display: list-item; - } - - ul { - list-style-type: circle; - } - } - } -`; - -const Strong = styled.p` - font-weight: 600; - margin: ${(props) => (props.isFirst ? "0 0 0.5rem" : "1rem 0 0.5rem")}; -`; - -class AnswersViewPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - isLoading: true, - references: [], - }; - } - - async componentDidMount() { - this.load(); - await this.loadReferences(); - } - - load() { - const { dispatch, id } = this.props; - - dispatch(actions.answers.loadOne(id)); - } - - async loadReferences() { - try { - const references = await api.fetch(getAnswerReferences, { - answer_id: this.props.id, - }); - - this.setState({ - isLoading: false, - references, - }); - } catch (err) { - if (err !== undefined) console.warn(err); - } - } - - renderReferences(category = null) { - const references = this.state.references.filter( - ({ category: _category }) => _category === category - ); - - return ( - - ); - } - - render() { - const { answers } = this.props; - const { isLoading } = this.state; - - if (isLoading || answers.isLoading) { - return
    ; - } - - const { - agreement, - generic_reference, - prevalue, - question, - state, - value, - } = answers.data; - - const finalValue = state === ANSWER_STATE.VALIDATED ? value : prevalue; - const valueTitle = - state === ANSWER_STATE.VALIDATED ? "Réponse validée" : "Réponse proposée"; - - return ( - - - {this.isGeneric ? ( - - ) : ( - - )} - {`${question.index}) ${question.value}`} - -
    - - {valueTitle} - - - Références juridiques - Convention collective - {this.renderReferences("agreement")} - Code du travail - {this.renderReferences("labor_code")} - Autres - {this.renderReferences()} -
    - - Renvoi - { - { - labor_code: "Renvoyée au texte Code du Travail.", - national_agreement: "Renvoyée au texte de la CCN.", - null: "Aucun renvoi.", - }[String(generic_reference)] - } -
    - ); - } -} - -export default connect(({ answers }) => ({ answers }))(AnswersViewPage); diff --git a/targets/contributions/pages/api/graphql.js b/targets/contributions/pages/api/graphql.js deleted file mode 100644 index 415bc2bf2..000000000 --- a/targets/contributions/pages/api/graphql.js +++ /dev/null @@ -1,27 +0,0 @@ -import { createProxyMiddleware } from "http-proxy-middleware"; - -export const config = { - api: { - bodyParser: false, - }, - externalResolver: true, -}; - -const proxy = createProxyMiddleware({ - changeOrigin: true, - followRedirects: true, - logLevel: "debug", - onError: (err, req, res) => { - res.writeHead(500, { - "Content-Type": "text/plain", - }); - res.end("Something went wrong. We've been notified."); - }, - pathRewrite: { "^/api/graphql": "/v1/graphql" }, - prependPath: false, - target: process.env.HASURA_GRAPHQL_ENDPOINT, - ws: true, - xfwd: true, // proxy websockets -}); - -export default proxy; diff --git a/targets/contributions/pages/charter.js b/targets/contributions/pages/charter.js deleted file mode 100644 index c184aa952..000000000 --- a/targets/contributions/pages/charter.js +++ /dev/null @@ -1,38 +0,0 @@ -// import { Flex } from "rebass"; -import styled from "@emotion/styled"; -import React from "react"; - -import Main from "../src/layouts/Main"; - -const IFrame = styled.iframe` - flex-grow: 1; -`; - -export default class CharterPage extends React.Component { - constructor(props) { - super(props); - - this.state = { - isLoading: true, - }; - } - - componentDidMount() { - this.setState({ isLoading: false }); - } - - render() { - if (this.state.isLoading) return
    ; - - return ( -
    -