From fddffb7e576cadc55e8224cda53e80a17b605745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Bitard?= <bitard.michael@gmail.com> Date: Mon, 25 Sep 2023 15:02:26 +0200 Subject: [PATCH] =?UTF-8?q?fix(ui):=20je=20remplis=20plusieurs=20champs=20?= =?UTF-8?q?d'une=20activit=C3=A9=20=C3=A0=20la=20fois=20(#688)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierignore | 1 + packages/api/package.json | 1 + packages/api/src/api/graphql/resolvers.ts | 3 +- .../api/graphql/resolvers/titres-activites.ts | 37 +------- .../graphql/schemas/administrations.graphql | 1 - .../api/src/api/graphql/schemas/index.graphql | 3 - .../graphql/schemas/metas-activites.graphql | 2 - .../graphql/schemas/titres-activites.graphql | 4 - .../api/src/api/rest/activites.queries.ts | 32 ++++++- .../src/api/rest/activites.queries.types.ts | 29 +++++- packages/api/src/api/rest/activites.ts | 36 ++++++-- .../titre-activite-deletion-validate.ts | 11 --- .../queries/permissions/titres-activites.ts | 16 +--- .../database/queries/permissions/titres.ts | 3 +- .../src/database/queries/titres-activites.ts | 11 +-- packages/api/src/server/rest.ts | 4 +- .../api/src/tools/activites/tests-creation.ts | 46 ++++++++++ .../src/tools/documents/files-index-build.ts | 2 +- packages/common/.prettierignore | 1 + packages/common/src/activite.ts | 1 - packages/common/src/rest.ts | 2 +- .../activites.sections.json | 1 + .../sections.test.ts | 6 ++ .../sections.ts | 2 +- packages/ui/src/api/_client.js | 2 +- packages/ui/src/api/client-rest.ts | 2 +- .../ui/src/api/fragments/metas-activites.js | 16 ---- packages/ui/src/api/metas-activites.js | 18 ---- .../components/_common/new-sections-edit.tsx | 11 ++- .../components/activite-edition.stories.tsx | 31 +++---- ...ition.stories_snapshots_FullDeposable.html | 19 +--- ...e-edition.stories_snapshots_FullEmpty.html | 19 +--- ...pshots_FullEmptyWithMandatoryDocument.html | 3 +- .../ui/src/components/activite-edition.tsx | 88 +++++++++++++------ .../ui/src/components/activite.stories.tsx | 2 +- ...activite.stories_snapshots_ACompleter.html | 2 - .../activite.stories_snapshots_Deposable.html | 2 - ...ctivite.stories_snapshots_Supprimable.html | 2 - .../activite/activite-api-client.ts | 28 +++--- .../activite/activite-documents-edit.tsx | 82 +++++++++-------- .../activite/activite-documents.stories.tsx | 2 - ...napshots_AvecDesDocumentsDejaPresents.html | 2 - ...stories_snapshots_DocumentObligatoire.html | 1 - ...stories_snapshots_DocumentObligatoire.html | 32 +------ ...p.stories_snapshots_DocumentOptionnel.html | 32 +------ .../activite/add-activite-document-popup.tsx | 12 --- .../ui/src/components/activite/preview.tsx | 2 - packages/ui/src/components/etape-edition.vue | 6 +- packages/ui/src/components/titre.vue | 40 ++++++--- packages/ui/src/components/titre/demarche.vue | 5 -- packages/ui/src/store/document.js | 11 +-- packages/ui/src/store/metas-definitions.ts | 4 +- packages/ui/src/store/titre.js | 46 ---------- packages/ui/src/store/titre.test.js | 30 ------- 54 files changed, 340 insertions(+), 467 deletions(-) delete mode 100644 packages/api/src/business/validations/titre-activite-deletion-validate.ts create mode 100644 packages/api/src/tools/activites/tests-creation.ts create mode 100644 packages/common/.prettierignore create mode 100644 packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/activites.sections.json delete mode 100644 packages/ui/src/api/fragments/metas-activites.js delete mode 100644 packages/ui/src/api/metas-activites.js diff --git a/.prettierignore b/.prettierignore index 5fa56ce98..ac9915988 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,5 +8,6 @@ packages/api/node_modules packages/api/sources packages/api/CHANGELOG.md packages/api/**/*.json +packages/common/**/*.json packages/api/**/*.queries.types.ts packages/ui/src/**/*.html \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index d23044353..d272e5413 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -28,6 +28,7 @@ "test:unit": "vitest --environment node --root src/ --config ../vitest.unit.config.ts", "test:integration": "NODE_OPTIONS='--loader ts-node/esm/transpile-only' JWT_SECRET=secret-tests vitest --environment node --root src/ --config ../vitest.integration.config.ts", "test:generate-data": "node --loader ts-node/esm/transpile-only src/tools/demarches/tests-creation.ts", + "test:generate-sections-data": "node --loader ts-node/esm/transpile-only src/tools/activites/tests-creation.ts", "ci:lint": "prettier --check . && eslint .", "matrices": "node --loader ts-node/esm/transpile-only ./src/scripts/matrices.ts" }, diff --git a/packages/api/src/api/graphql/resolvers.ts b/packages/api/src/api/graphql/resolvers.ts index 06c6349b8..42a0845da 100644 --- a/packages/api/src/api/graphql/resolvers.ts +++ b/packages/api/src/api/graphql/resolvers.ts @@ -40,7 +40,7 @@ import { substances } from './resolvers/substances.js' import { entreprises, entreprisesTitresCreation } from './resolvers/entreprises.js' import { administration, administrations, administrationActiviteTypeEmailCreer, administrationActiviteTypeEmailSupprimer, administrationActivitesTypesEmails } from './resolvers/administrations.js' -import { activites, activiteSupprimer, activiteDeposer } from './resolvers/titres-activites.js' +import { activites, activiteDeposer } from './resolvers/titres-activites.js' import { statistiquesGlobales } from './resolvers/statistiques.js' import { titreDemandeCreer } from './resolvers/titre-demande.js' @@ -109,7 +109,6 @@ export default { documentCreer, documentModifier, documentSupprimer, - activiteSupprimer, activiteDeposer, newsletterInscrire, entreprisesTitresCreation, diff --git a/packages/api/src/api/graphql/resolvers/titres-activites.ts b/packages/api/src/api/graphql/resolvers/titres-activites.ts index 442c70e51..cc583c2b9 100644 --- a/packages/api/src/api/graphql/resolvers/titres-activites.ts +++ b/packages/api/src/api/graphql/resolvers/titres-activites.ts @@ -8,10 +8,9 @@ import { titreActiviteFormat } from '../../_format/titres-activites.js' import { fieldsBuild } from './_fields-build.js' -import { titreActiviteDelete, titreActiviteGet, titreActiviteUpdate as titreActiviteUpdateQuery, titresActivitesCount, titresActivitesGet } from '../../../database/queries/titres-activites.js' +import { titreActiviteGet, titreActiviteUpdate as titreActiviteUpdateQuery, titresActivitesCount, titresActivitesGet } from '../../../database/queries/titres-activites.js' import { utilisateursGet } from '../../../database/queries/utilisateurs.js' -import { titreActiviteDeletionValidate } from '../../../business/validations/titre-activite-deletion-validate.js' import { userSuper } from '../../../database/user-super.js' import { titreGet } from '../../../database/queries/titres.js' import { isBureauDEtudes, isEntreprise } from 'camino-common/src/roles.js' @@ -30,16 +29,6 @@ import { import { ActiviteId } from 'camino-common/src/activite.js' import { getSectionsWithValue } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.js' -/** - * Retourne une activité - * - * @param id - id de l'activité - * @param context - contexte utilisateur - * @param info - objet contenant les propriétés de la requête graphQl - * @returns une activité - * - */ - /** * Retourne les activités * @@ -246,27 +235,3 @@ export const activiteDeposer = async ({ id }: { id: ActiviteId }, { user, pool } throw e } } - -export const activiteSupprimer = async ({ id }: { id: ActiviteId }, { user }: Context) => { - try { - const oldTitreActivite = await titreActiviteGet(id, { fields: {} }, user) - - if (!oldTitreActivite) throw new Error("l'activité n'existe pas") - - if (!oldTitreActivite.suppression) throw new Error('droits insuffisants') - - const rulesErrors = titreActiviteDeletionValidate(oldTitreActivite) - - if (rulesErrors.length) { - throw new Error(rulesErrors.join(', ')) - } - - const activite = titreActiviteDelete(id, {}) - - return activite - } catch (e) { - console.error(e) - - throw e - } -} diff --git a/packages/api/src/api/graphql/schemas/administrations.graphql b/packages/api/src/api/graphql/schemas/administrations.graphql index 1665acfc6..f1b206932 100644 --- a/packages/api/src/api/graphql/schemas/administrations.graphql +++ b/packages/api/src/api/graphql/schemas/administrations.graphql @@ -3,7 +3,6 @@ # import * from 'utilisateurs.graphql' # import * from 'titres.graphql' # import * from 'metas.graphql' -# import * from 'metas-activites.graphql' # import * from 'territoires.graphql' type Administration { diff --git a/packages/api/src/api/graphql/schemas/index.graphql b/packages/api/src/api/graphql/schemas/index.graphql index d316cf3ab..7afce3fbe 100644 --- a/packages/api/src/api/graphql/schemas/index.graphql +++ b/packages/api/src/api/graphql/schemas/index.graphql @@ -240,9 +240,6 @@ type Mutation { "Dépose une activité" activiteDeposer(id: ID!): Activite - "Supprime une activité" - activiteSupprimer(id: ID!): Activite - administrationActiviteTypeEmailCreer(administrationActiviteTypeEmail: InputAdministrationActiviteTypeEmail!): Administration administrationActiviteTypeEmailSupprimer(administrationActiviteTypeEmail: InputAdministrationActiviteTypeEmail!): Administration diff --git a/packages/api/src/api/graphql/schemas/metas-activites.graphql b/packages/api/src/api/graphql/schemas/metas-activites.graphql index 0688d0b58..708a20108 100644 --- a/packages/api/src/api/graphql/schemas/metas-activites.graphql +++ b/packages/api/src/api/graphql/schemas/metas-activites.graphql @@ -17,6 +17,4 @@ type ActiviteType { delaiMois: Int! frequenceId: ID! sections: Json - lectureInterdit: Boolean - modificationInterdit: Boolean } diff --git a/packages/api/src/api/graphql/schemas/titres-activites.graphql b/packages/api/src/api/graphql/schemas/titres-activites.graphql index 1d6ad6d54..0848a6387 100644 --- a/packages/api/src/api/graphql/schemas/titres-activites.graphql +++ b/packages/api/src/api/graphql/schemas/titres-activites.graphql @@ -1,6 +1,5 @@ # import * from 'scalars.graphql' # import * from 'titres.graphql' -# import * from 'metas-activites.graphql' type Activites { elements: [Activite] @@ -14,7 +13,6 @@ type Activites { type Activite { id: ID! slug: String - type: ActiviteType! titre: Titre typeId: String! activiteStatutId: String! @@ -24,6 +22,4 @@ type Activite { annee: Int sections: Json contenu: Json - - suppression: Boolean } diff --git a/packages/api/src/api/rest/activites.queries.ts b/packages/api/src/api/rest/activites.queries.ts index 44658a84d..997ce9f07 100644 --- a/packages/api/src/api/rest/activites.queries.ts +++ b/packages/api/src/api/rest/activites.queries.ts @@ -13,6 +13,7 @@ import { IInsertActiviteDocumentInternalQuery, IUpdateActiviteDbQuery, IGetActivitesByTitreIdQueryQuery, + IActiviteDeleteDbQuery, } from './activites.queries.types.js' import { ActiviteDocument, @@ -138,6 +139,36 @@ LIMIT 1 const canDeleteActivite = (activite: DbActivite, user: User): boolean => { return isSuper(user) && activite.suppression } + +export const activiteDeleteQuery = async ( + activiteId: ActiviteId, + pool: Pool, + user: User, + titreTypeId: SimplePromiseFn<TitreTypeId>, + titresAdministrationsLocales: SimplePromiseFn<AdministrationId[]>, + entreprisesTitulairesOuAmodiataires: SimplePromiseFn<EntrepriseId[]> +): Promise<boolean> => { + const activite = await getActiviteById(activiteId, pool, user, titreTypeId, titresAdministrationsLocales, entreprisesTitulairesOuAmodiataires) + + if (activite !== null && activite.suppression) { + await dbQueryAndValidate(activiteDocumentDeleteDb, { activiteId }, pool, z.void()) + await dbQueryAndValidate(activiteDeleteDb, { activiteId }, pool, z.void()) + + return true + } + + return false +} + +const activiteDeleteDb = sql<Redefine<IActiviteDeleteDbQuery, { activiteId: ActiviteId }, void>>` +delete from titres_activites ta +where ta.id = $ activiteId ! +` + +const activiteDocumentDeleteDb = sql<Redefine<IActiviteDeleteDbQuery, { activiteId: ActiviteId }, void>>` +delete from activites_documents +where activite_id = $ activiteId ! +` export const getActivitesByTitreId = async ( titreId: TitreId, pool: Pool, @@ -234,7 +265,6 @@ const getActiviteDocumentsInternal = sql<Redefine<IGetActiviteDocumentsInternalQ select d.id, d.description, - d.date, d.activite_document_type_id from activites_documents d diff --git a/packages/api/src/api/rest/activites.queries.types.ts b/packages/api/src/api/rest/activites.queries.types.ts index 3ba89cc3a..64ae3e523 100644 --- a/packages/api/src/api/rest/activites.queries.types.ts +++ b/packages/api/src/api/rest/activites.queries.types.ts @@ -51,6 +51,34 @@ export interface IGetActiviteByIdQueryQuery { result: IGetActiviteByIdQueryResult; } +/** 'ActiviteDeleteDb' parameters type */ +export interface IActiviteDeleteDbParams { + activiteId: string; +} + +/** 'ActiviteDeleteDb' return type */ +export type IActiviteDeleteDbResult = void; + +/** 'ActiviteDeleteDb' query type */ +export interface IActiviteDeleteDbQuery { + params: IActiviteDeleteDbParams; + result: IActiviteDeleteDbResult; +} + +/** 'ActiviteDocumentDeleteDb' parameters type */ +export interface IActiviteDocumentDeleteDbParams { + activiteId: string; +} + +/** 'ActiviteDocumentDeleteDb' return type */ +export type IActiviteDocumentDeleteDbResult = void; + +/** 'ActiviteDocumentDeleteDb' query type */ +export interface IActiviteDocumentDeleteDbQuery { + params: IActiviteDocumentDeleteDbParams; + result: IActiviteDocumentDeleteDbResult; +} + /** 'GetActivitesByTitreIdQuery' parameters type */ export interface IGetActivitesByTitreIdQueryParams { titreId: string; @@ -137,7 +165,6 @@ export interface IGetActiviteDocumentsInternalParams { /** 'GetActiviteDocumentsInternal' return type */ export interface IGetActiviteDocumentsInternalResult { activite_document_type_id: string; - date: string; description: string | null; id: string; } diff --git a/packages/api/src/api/rest/activites.ts b/packages/api/src/api/rest/activites.ts index db6392c4f..1b0fdb709 100644 --- a/packages/api/src/api/rest/activites.ts +++ b/packages/api/src/api/rest/activites.ts @@ -1,7 +1,7 @@ import { CaminoRequest, CustomResponse } from './express-type.js' import { constants } from 'http2' import { Pool } from 'pg' -import { Activite, activiteDocumentIdValidator, activiteEditionValidator, activiteIdOrSlugValidator } from 'camino-common/src/activite.js' +import { Activite, activiteDocumentIdValidator, activiteEditionValidator, activiteIdOrSlugValidator, activiteIdValidator } from 'camino-common/src/activite.js' import { Contenu, administrationsLocalesByActiviteId, @@ -15,6 +15,7 @@ import { updateActiviteQuery, getActivitesByTitreId as getActivitesByTitreIdQuery, DbActivite, + activiteDeleteQuery, } from './activites.queries.js' import { NewDownload } from './fichiers.js' import { DeepReadonly, SimplePromiseFn, isNonEmptyArray, isNullOrUndefined, memoize } from 'camino-common/src/typescript-tools.js' @@ -31,6 +32,7 @@ import { User } from 'camino-common/src/roles.js' import { TitreTypeId } from 'camino-common/src/static/titresTypes.js' import { AdministrationId } from 'camino-common/src/static/administrations.js' import { EntrepriseId } from 'camino-common/src/entreprise.js' +import { getCurrent } from 'camino-common/src/date.js' const extractContenuFromSectionWithValue = (sections: DeepReadonly<Section[]>, sectionsWithValue: SectionWithValue[]): Contenu => { const contenu: Contenu = {} @@ -76,7 +78,7 @@ export const updateActivite = const result = await getActiviteById(activiteIdParsed.data, pool, user, titreTypeId, administrationsLocales, entreprisesTitulairesOuAmodiataires) - if (result === null || !canEditActivite(user, titreTypeId, administrationsLocales, entreprisesTitulairesOuAmodiataires, result.activite_statut_id)) { + if (result === null || !(await canEditActivite(user, titreTypeId, administrationsLocales, entreprisesTitulairesOuAmodiataires, result.activite_statut_id))) { res.sendStatus(constants.HTTP_STATUS_FORBIDDEN) } else { const parsed = activiteEditionValidator.safeParse(req.body) @@ -105,18 +107,19 @@ export const updateActivite = for (const document of activiteDocumentsToCreate) { const loid = await createLargeObject(pool, document.tempDocumentName) + const date = getCurrent() + await insertActiviteDocument(pool, { - id: newActiviteDocumentId(document.date, document.activite_document_type_id), + id: newActiviteDocumentId(date, document.activite_document_type_id), activite_document_type_id: document.activite_document_type_id, description: document.description ?? '', - date: document.date, + date, largeobject_id: loid, activite_id: result.id, }) } - // parsed.data - res.sendStatus(constants.HTTP_STATUS_OK) + res.sendStatus(constants.HTTP_STATUS_NO_CONTENT) } } } catch (e: any) { @@ -196,6 +199,27 @@ export const getActivite = } } +export const deleteActivite = + (pool: Pool) => + async (req: CaminoRequest, res: CustomResponse<void>): Promise<void> => { + const activiteIdParsed = activiteIdValidator.safeParse(req.params.activiteId) + if (!activiteIdParsed.success) { + res.sendStatus(constants.HTTP_STATUS_BAD_REQUEST) + } else { + const id = activiteIdParsed.data + const titreTypeId = memoize(() => titreTypeIdByActiviteId(id, pool)) + const administrationsLocales = memoize(() => administrationsLocalesByActiviteId(id, pool)) + const entreprisesTitulairesOuAmodiataires = memoize(() => entreprisesTitulairesOuAmoditairesByActiviteId(id, pool)) + + const isOk = await activiteDeleteQuery(id, pool, req.auth, titreTypeId, administrationsLocales, entreprisesTitulairesOuAmodiataires) + if (isOk) { + res.sendStatus(constants.HTTP_STATUS_NO_CONTENT) + } else { + res.sendStatus(constants.HTTP_STATUS_NOT_FOUND) + } + } + } + export const getActivitesByTitreId = (pool: Pool) => async (req: CaminoRequest, res: CustomResponse<ActivitesByTitre>): Promise<void> => { diff --git a/packages/api/src/business/validations/titre-activite-deletion-validate.ts b/packages/api/src/business/validations/titre-activite-deletion-validate.ts deleted file mode 100644 index 050ad013d..000000000 --- a/packages/api/src/business/validations/titre-activite-deletion-validate.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ITitreActivite } from '../../types.js' - -export const titreActiviteDeletionValidate = (titreActivite: ITitreActivite) => { - const errors = [] as string[] - - if (!titreActivite.suppression) { - errors.push(`impossible de supprimer cette activité`) - } - - return errors -} diff --git a/packages/api/src/database/queries/permissions/titres-activites.ts b/packages/api/src/database/queries/permissions/titres-activites.ts index cbe84a2ff..956f6ea21 100644 --- a/packages/api/src/database/queries/permissions/titres-activites.ts +++ b/packages/api/src/database/queries/permissions/titres-activites.ts @@ -75,10 +75,8 @@ export const titreActivitesCount = (q: QueryBuilder<Titres, Titres | Titres[]>, return q } -export const titresActivitesQueryModify = (q: QueryBuilder<TitresActivites, TitresActivites | TitresActivites[]>, user: User, select = true) => { - if (select) { - q.select('titresActivites.*') - } +export const titresActivitesQueryModify = (q: QueryBuilder<TitresActivites, TitresActivites | TitresActivites[]>, user: User) => { + q.select('titresActivites.*') q.leftJoinRelated('titre') @@ -107,13 +105,3 @@ export const titresActivitesQueryModify = (q: QueryBuilder<TitresActivites, Titr return q } - -export const titresActivitesPropsQueryModify = (q: QueryBuilder<TitresActivites, TitresActivites | TitresActivites[]>, user: User) => { - q.select('titresActivites.*') - if (!isSuper(user)) { - // Override le champ suppression qui est présent dans la table titres_activites... - q.select(raw('false').as('suppression')) - } - - return q -} diff --git a/packages/api/src/database/queries/permissions/titres.ts b/packages/api/src/database/queries/permissions/titres.ts index 827bc1017..1d7c31b92 100644 --- a/packages/api/src/database/queries/permissions/titres.ts +++ b/packages/api/src/database/queries/permissions/titres.ts @@ -5,7 +5,7 @@ import TitresDemarches from '../../models/titres-demarches.js' import TitresActivites from '../../models/titres-activites.js' import Entreprises from '../../models/entreprises.js' -import { titresActivitesQueryModify, titresActivitesPropsQueryModify, titreActivitesCount } from './titres-activites.js' +import { titresActivitesQueryModify, titreActivitesCount } from './titres-activites.js' import { titresDemarchesQueryModify } from './titres-demarches.js' import { administrationsTitresTypesTitresStatutsModify, administrationsTitresQuery } from './administrations.js' import { entreprisesQueryModify, entreprisesTitresQuery } from './entreprises.js' @@ -170,7 +170,6 @@ const titresQueryModify = (q: QueryBuilder<Titres, Titres | Titres[]>, user: Use // visibilité des activités q.modifyGraph('activites', b => { titresActivitesQueryModify(b as QueryBuilder<TitresActivites, TitresActivites | TitresActivites[]>, user) - titresActivitesPropsQueryModify(b as QueryBuilder<TitresActivites, TitresActivites | TitresActivites[]>, user) }) q.modifyGraph('titulaires', b => { diff --git a/packages/api/src/database/queries/titres-activites.ts b/packages/api/src/database/queries/titres-activites.ts index 56ee5538e..36b82125c 100644 --- a/packages/api/src/database/queries/titres-activites.ts +++ b/packages/api/src/database/queries/titres-activites.ts @@ -9,7 +9,7 @@ import graphBuild from './graph/build.js' import { titresFiltersQueryModify } from './_titres-filters.js' import TitresActivites from '../models/titres-activites.js' -import { titresActivitesQueryModify, titresActivitesPropsQueryModify } from './permissions/titres-activites.js' +import { titresActivitesQueryModify } from './permissions/titres-activites.js' import { isAdministrationAdmin, isAdministrationEditeur, User } from 'camino-common/src/roles.js' import { DepartementId } from 'camino-common/src/static/departement.js' import { ActiviteId } from 'camino-common/src/activite.js' @@ -109,7 +109,6 @@ const titreActivitesQueryBuild = ({ fields }: { fields?: IFields }, user: User) const q = TitresActivites.query().withGraphFetched(graph) titresActivitesQueryModify(q, user) - titresActivitesPropsQueryModify(q, user) // dans titresActivitesPropsQueryModify quand on est une administration on utilise les 3 colonnes suivantes pour une sous requête. if (isAdministrationAdmin(user) || isAdministrationEditeur(user)) { @@ -358,10 +357,4 @@ const titresActivitesUpsert = async (titreActivites: ITitreActivite[]) => const titreActiviteUpdate = async (id: ActiviteId, titreActivite: Partial<ITitreActivite>) => TitresActivites.query().patchAndFetchById(id, { ...titreActivite, id }) -const titreActiviteDelete = async (id: ActiviteId, { fields }: { fields?: IFields }) => { - const graph = fields ? graphBuild(fieldsTitreAdd(fields), 'activite', fieldsFormat) : options.titresActivites.graph - - return TitresActivites.query().withGraphFetched(graph).deleteById(id).returning('*') -} - -export { titreActiviteGet, titresActivitesCount, titresActivitesUpsert, titresActivitesGet, titreActiviteUpdate, titreActiviteDelete } +export { titreActiviteGet, titresActivitesCount, titresActivitesUpsert, titresActivitesGet, titreActiviteUpdate } diff --git a/packages/api/src/server/rest.ts b/packages/api/src/server/rest.ts index e48d9e32d..826efe051 100644 --- a/packages/api/src/server/rest.ts +++ b/packages/api/src/server/rest.ts @@ -57,7 +57,7 @@ import { getDemarche } from '../api/rest/demarches.js' import { z } from 'zod' import { getCommunes } from '../api/rest/communes.js' import { SendFileOptions } from 'express-serve-static-core' -import { activiteDocumentDownload, getActivite, getActivitesByTitreId, updateActivite } from '../api/rest/activites.js' +import { activiteDocumentDownload, getActivite, getActivitesByTitreId, updateActivite, deleteActivite } from '../api/rest/activites.js' interface IRestResolverResult { nom: string @@ -148,7 +148,7 @@ const restRouteImplementations: Readonly<{ [key in CaminoRestRoute]: Transform<k '/rest/entreprises/:entrepriseId/documents/:entrepriseDocumentId': { delete: deleteEntrepriseDocument }, '/rest/entreprises': { post: creerEntreprise }, '/rest/etapes/:etapeId/entrepriseDocuments': { get: getEtapeEntrepriseDocuments }, - '/rest/activites/:activiteId': { get: getActivite, put: updateActivite }, + '/rest/activites/:activiteId': { get: getActivite, put: updateActivite, delete: deleteActivite }, '/rest/communes': { get: getCommunes }, '/deconnecter': { get: logout }, '/changerMotDePasse': { get: resetPassword }, diff --git a/packages/api/src/tools/activites/tests-creation.ts b/packages/api/src/tools/activites/tests-creation.ts new file mode 100644 index 000000000..0a108dea3 --- /dev/null +++ b/packages/api/src/tools/activites/tests-creation.ts @@ -0,0 +1,46 @@ +import '../../init.js' +import { writeFileSync } from 'fs' +import { z } from 'zod' +import { knex } from '../../knex.js' +import { Section, sectionValidator } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.js' +import { ActiviteId } from 'camino-common/src/activite.js' + +const arraySectionValidator = z.array(sectionValidator) +const writeActivitesSectionsForTest = async () => { + const activitesSections: { + rows: { + id: ActiviteId + sections: Section[] + }[] + } = await knex.raw('select id, sections from titres_activites') + + const filteredSections = activitesSections.rows + .filter(activite => { + if (!arraySectionValidator.safeParse(activite.sections).success) { + console.warn(`sections non valides pour l'activité ${activite.id} `) + + return false + } + + return true + }) + .map(({ sections }) => sections) + + const duplicatesSection = filteredSections.reduce<Record<string, Section[]>>((acc, sections) => { + acc[JSON.stringify(sections)] = sections + JSON.stringify(sections) + + return acc + }, {}) + + writeFileSync(`../../packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/activites.sections.json`, JSON.stringify(Object.values(duplicatesSection))) +} + +writeActivitesSectionsForTest() + .then(() => { + process.exit() + }) + .catch(e => { + console.error(e) + process.exit(1) + }) diff --git a/packages/api/src/tools/documents/files-index-build.ts b/packages/api/src/tools/documents/files-index-build.ts index befe191bf..8a6fef967 100644 --- a/packages/api/src/tools/documents/files-index-build.ts +++ b/packages/api/src/tools/documents/files-index-build.ts @@ -4,7 +4,7 @@ import { basename } from 'path' import { Index } from '../../types.js' export const filesIndexBuild = (path = './files'): Index<string> => { - const filesNames = execSync(`find ${path} | grep -v entreprises | grep pdf`).toString().split('\n') + const filesNames = execSync(`find ${path} | grep -v entreprises | grep -v activites | grep pdf`).toString().split('\n') return filesNames.reduce((res: Index<string>, fileName) => { if (fileName) { diff --git a/packages/common/.prettierignore b/packages/common/.prettierignore new file mode 100644 index 000000000..b952da9b1 --- /dev/null +++ b/packages/common/.prettierignore @@ -0,0 +1 @@ +**/*.json \ No newline at end of file diff --git a/packages/common/src/activite.ts b/packages/common/src/activite.ts index 74a66d45e..858eb071b 100644 --- a/packages/common/src/activite.ts +++ b/packages/common/src/activite.ts @@ -21,7 +21,6 @@ export type ActiviteDocumentId = z.infer<typeof activiteDocumentIdValidator> export const activiteDocumentValidator = z.object({ id: activiteDocumentIdValidator, description: z.string().nullable(), - date: caminoDateValidator, activite_document_type_id: activiteDocumentTypeIdValidator, }) diff --git a/packages/common/src/rest.ts b/packages/common/src/rest.ts index 630d87053..5c2c6ad8d 100644 --- a/packages/common/src/rest.ts +++ b/packages/common/src/rest.ts @@ -135,7 +135,7 @@ export const CaminoRestRoutes = { '/rest/utilisateur/generateQgisToken': { post: { input: z.void(), output: qgisTokenValidator } }, '/rest/etapesTypes/:demarcheId/:date': { params: { demarcheId: demarcheIdValidator, date: caminoDateValidator }, get: { output: z.array(etapeTypeEtapeStatutWithMainStepValidator) } }, '/rest/etapes/:etapeId/entrepriseDocuments': { params: { etapeId: etapeIdValidator }, get: { output: z.array(etapeEntrepriseDocumentValidator) } }, - '/rest/activites/:activiteId': { params: { activiteId: activiteIdOrSlugValidator }, get: { output: activiteValidator }, put: { input: activiteEditionValidator, output: z.void() } }, + '/rest/activites/:activiteId': { params: { activiteId: activiteIdOrSlugValidator }, get: { output: activiteValidator }, put: { input: activiteEditionValidator, output: z.void() }, delete: true }, '/rest/communes': { get: { output: z.array(communeValidator) } }, '/deconnecter': { get: { output: z.string() } }, '/changerMotDePasse': { get: { output: z.string() } }, diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/activites.sections.json b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/activites.sections.json new file mode 100644 index 000000000..f1979b081 --- /dev/null +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/activites.sections.json @@ -0,0 +1 @@ +[[{"id":"indicateursFinanciersDepensesTotales","nom":"Indicateur financier global","elements":[{"id":"depensesTotales","nom":"Dépenses totales de prospection","type":"number","description":"Montant en euros de l'ensemble des dépenses effectuées au cours de l'année"}]},{"id":"indicateursFinanciersLevesTopographiques","nom":"Levés topographiques","elements":[{"id":"depensesLevesTopographiques","nom":"Dépenses de levés topographiques (euros)","type":"number","description":"Montant en euros des dépenses de levés topographiques au cours de l'année"}]},{"id":"indicateursFinanciersCartographieGeologique","nom":"Cartographie géologique","elements":[{"id":"depensesCartographie","nom":"Dépenses de cartographie géologique (euros)","type":"number","description":"Montant en euros des dépenses de cartographie géologique au cours de l'année"}]},{"id":"indicateursFinanciersLevesGeochimie","nom":"Levés géochimiques","elements":[{"id":"depensesLevesGeochimie","nom":"Dépenses de levés géochimiques (euros)","type":"number","description":"Montant en euros des dépenses de levés géochimiques au cours de l'année"}]},{"id":"indicateursFinanciersLevesGeophysique","nom":"Levés géophysique","elements":[{"id":"depensesLevesGeophysique","nom":"Dépenses de levés géophysique (euros)","type":"number","description":"Montant en euros des dépenses de levés géophysique au cours de l'année"}]},{"id":"indicateursFinanciersLevesTrancheesPuits","nom":"Tranchées et puits","elements":[{"id":"depensesLevesTrancheesPuits","nom":"Dépenses de tranchées et puits (euros)","type":"number","description":"Montant en euros des dépenses de tranchées et puits au cours de l'année"}]},{"id":"indicateursFinanciersSondages","nom":"Sondages","elements":[{"id":"depensesLevesSondagesTarieres","nom":"Dépenses de sondages tarières (euros)","type":"number","description":"Montant en euros des dépenses de sondages tarières au cours de l'année"},{"id":"depensesLevesSondagesDestructifs","nom":"Dépenses de sondages destructifs (euros)","type":"number","description":"Montant en euros des dépenses de sondages destructifs au cours de l'année"},{"id":"depensesLevesSondagesCarottés","nom":"Dépenses de sondages carottés (euros)","type":"number","description":"Montant en euros des dépenses de sondages carottés au cours de l'année"}]},{"id":"indicateursFinanciersAnalysesMultiElements","nom":"Analyses","elements":[{"id":"depensesAnalysesMultiElements","nom":"Dépenses d'analyses multi-éléments (euros)","type":"number","description":"Montant en euros des dépenses d'analyses multi-éléments au cours de l'année"},{"id":"depensesTraitementMineralurgiques","nom":"Dépenses de traitements minéralurgiques (euros)","type":"number","description":"Montant en euros des dépenses de traitements minéralurgiques au cours de l'année"}]},{"id":"indicateursFinanciersEtudes","nom":"Etudes","elements":[{"id":"depensesEtudeEnvironnementale","nom":"Dépenses d'étude environnementale (euros)","type":"number","description":"Montant en euros des dépenses d'études environnementales au cours de l'année"},{"id":"depensesEtudeEconomiquePreliminaire","nom":"Dépenses d'étude économique préliminaire (euros)","type":"number","description":"Montant en euros des dépenses d'étude économique préliminaire au cours de l'année"},{"id":"depensesEtudeEconomiquePreFaisabilite","nom":"Dépenses d'étude économique pré-faisabilité (euros)","type":"number","description":"Montant en euros des dépenses d'étude économique pré-faisabilité au cours de l'année"},{"id":"depensesEtudeEconomiqueFaisabilité","nom":"Dépenses d'étude économique faisabilité (euros)","type":"number","description":"Montant en euros des dépenses d'étude économique faisabilité au cours de l'année"},{"id":"depensesEtudeSociale","nom":"Dépenses d'étude sociale (euros)","type":"number","description":"Montant en euros des dépenses d'étude environnementales au cours de l'année"},{"id":"depensesEtudessautres","nom":"Dépenses d'études autres (euros)","type":"number","description":"Montant en euros des dépenses d'études autres au cours de l'année"}]},{"id":"indicateursFinanciersEnvironnement","nom":"Environnement","elements":[{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","description":"Montant en euros des investissements consentis au cours de l'année listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous être demandés par l’administration."}]},{"id":"indicateursFinanciersCommunication","nom":"Communication","elements":[{"id":"depensesCommunication","nom":"Dépenses de communication et d'information du public (euros)","type":"number","description":"Montant en euros des dépenses de communication et frais d'organisation de réunions publiques au cours de l'année"}]},{"id":"complementFinancier","nom":"Informations complémentaires","elements":[{"id":"depensesAutres","nom":"Autres dépenses (euros)","type":"number","description":"Montant en euros des autres dépenses au cours de l'année"},{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements financiers marquants de l'année."}]}],[{"id":"levesTopographiques","nom":"Levés topographiques","elements":[{"id":"typeLevesTopo","nom":"Types de levés ","type":"text","optionnel":true,"description":"Exemples : LIDAR, géomètre…"},{"id":"surfaceLevesTopo","nom":"Surface des levés(km²)","type":"number","optionnel":true,"description":"Surface du titre couverte par des levés topographiques"},{"id":"complementLevesTopo","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les levés topographiques"}]},{"id":"cartographieGeologique","nom":"Cartographie géologique","elements":[{"id":"surfaceCartographieGeologique","nom":"Surface cartographiée (km²)","type":"number","optionnel":true,"description":"Surface du titre dont la cartographie géologique a été effectuée au cours de l'année"},{"id":"complementCartographie","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les activités de cartographie"}]},{"id":"levesGeochimiques","nom":"Levés géochimiques","elements":[{"id":"surfaceLevesGeochimie","nom":"Surface des levés(km²)","type":"number","optionnel":true,"description":"Surface du titre couverte par des levés géochimiques"},{"id":"lineaireLevesGeochimie","nom":"Longueur de levés (km)","type":"number","optionnel":true,"description":"Longueur de layon couverte par des levés géochimiques"},{"id":"complementLevesGeochimie","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les levés géochimiques"}]},{"id":"levesGeophysiques","nom":"Levés géophysiques","elements":[{"id":"surfaceLevesMagnetisme","nom":"Surface des levés de magnétisme (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés de magnétisme "},{"id":"lineaireLevesMagnetisme","nom":"Longueur des levés de magnétisme (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés de magnétisme"},{"id":"typeLevesMagnetisme","nom":"Type de levés de magnétisme","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"surfaceLevesSpectrometrie","nom":"Surface des levés de spectrométrie (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés de spectrométrie"},{"id":"lineaireLevesSpectrometrie","nom":"Longueur des levés de spectrométrie (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés de spectrométrie"},{"id":"typeLevesSpectrometrie","nom":"Type de levés de spectrométrie ","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"surfaceLevesPolarisationProvoquee","nom":"Surface des levés de polarisation provoquée (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés de polarisation provoquée"},{"id":"lineaireLevesPolarisationProvoquee","nom":"Longueur des levés de polarisation provoquée (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés de polarisation provoquée"},{"id":"typeLevesPolarisationProvoquee","nom":"Type de levés de polarisation provoquée ","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"surfaceLevesSismiques","nom":"Surface des levés sismiques (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés sismiques"},{"id":"lineaireLevesSismiques","nom":"Longueur des levés sismiques (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés sismiques"},{"id":"typeLevesSismiques","nom":"Type de levés sismiques","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"surfaceLevesConductivite","nom":"Surface des levés de conductivité (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés de conductivité"},{"id":"lineaireLevesConductivite","nom":"Longueur des levés de conductivité (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés de conductivité"},{"id":"typeLevesConductivite","nom":"Type de levés de conductivité","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"surfaceLevesAutre","nom":"Surface des levés par d'autres méthodes (km²)","type":"number","optionnel":true,"description":"Surface du titre en kilomètre carré couverte par des levés par d'autres méthodes"},{"id":"lineaireLevesAutre","nom":"Longueur des levés par d'autres méthodes (km)","type":"number","optionnel":true,"description":"Longueur de layon en kilomètre couverte par des levés par d'autres méthodes"},{"id":"typeLevesAutre","nom":"Type de levés par d'autres méthodes","type":"checkboxes","options":[{"id":"auSol","nom":"au sol"},{"id":"aeroporte","nom":"aéroporté"}],"optionnel":true},{"id":"complementLevesGeochimie","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les levés géophysique"}]},{"id":"trancheesPuits","nom":"Tranchées et puits","elements":[{"id":"puits","nom":"Nombre de puits","type":"number","optionnel":true,"description":"Nombre de puits forés"},{"id":"lineaireTranchees","nom":"Longueur de tranchée (km)","type":"number","optionnel":true,"description":"Longueur de tranchée de prospection ouverte"},{"id":"complementTrancheesPuits","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les tranchées et puits"}]},{"id":"sondages","nom":"Sondages","elements":[{"id":"nombreSondagesTariere","nom":"Nombre de sondages tarière","type":"number","optionnel":true,"description":"Nombre de sondages effectués à l'aide d'une tarière"},{"id":"profondeurMaxSondagesTariere","nom":"Profondeur maximale des sondages tarière (m)","type":"number","optionnel":true,"description":"Profondeur maximale atteinte par les sondages tarière"},{"id":"profondeurMoySondagesTariere","nom":"Profondeur moyenne de sondages tarière (m)","type":"number","optionnel":true,"description":"Profondeur moyenne atteinte par les sondages tarière"},{"id":"lineaireSondagesTarieres","nom":"Longueur sondages tarière (m)","type":"number","optionnel":true,"description":"Longueur du linéaire de sondages tarière"},{"id":"nombreSondagesDestructifs","nom":"Nombre de sondages destructifs","type":"number","optionnel":true,"description":"Nombre de sondages effectués à l'aide d'une destructifs"},{"id":"profondeurMaxSondagesDestructifs","nom":"Profondeur maximale des sondages destructifs (m)","type":"number","optionnel":true,"description":"Profondeur maximale atteinte par les sondages destructifs"},{"id":"profondeurMoySondagesDestructifs","nom":"Profondeur moyenne de sondages destructifs (m)","type":"number","optionnel":true,"description":"Profondeur moyenne atteinte par les sondages destructifs"},{"id":"lineaireSondagesDestructifss","nom":"Longueur sondages destructifs (m)","type":"number","optionnel":true,"description":"Longueur du linéaire de sondages destructifs"},{"id":"nombreSondagesCarottes","nom":"Nombre de sondages carottés","type":"number","optionnel":true,"description":"Nombre de sondages effectués à l'aide d'une carottés"},{"id":"profondeurMaxSondagesCarottes","nom":"Profondeur maximale des sondages carottés (m)","type":"number","optionnel":true,"description":"Profondeur maximale atteinte par les sondages carottés"},{"id":"profondeurMoySondagesCarottes","nom":"Profondeur moyenne de sondages carottés (m)","type":"number","optionnel":true,"description":"Profondeur moyenne atteinte par les sondages carottés"},{"id":"lineaireSondagesCarottes","nom":"Longueur sondages carottés (m)","type":"number","optionnel":true,"description":"Longueur du linéaire de sondages carottés"},{"id":"complementSondages","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les sondages"}]},{"id":"Analyses","nom":"Analyses","elements":[{"id":"nombreAnalysesMultiElements","nom":"Nombre d'analyses multi-éléments","type":"number","optionnel":true,"description":"Nombre d'analyses multi-éléments"},{"id":"listeAnalysesMultiElements","nom":"Liste des éléments analysés","type":"textarea","optionnel":true,"description":"Précisions sur les éléments analysés et méthodes analytiques utilisées"},{"id":"listeTraitementMineralurgiques","nom":"Nature des traitements minéralurgiques","type":"checkboxes","options":[{"id":"analyseGranulometrie","nom":"analyse granulométrique"},{"id":"concassage","nom":"concassage"},{"id":"broyage","nom":"broyage"},{"id":"separationGravimetrique","nom":"séparation gravimétrique"},{"id":"flottation","nom":"flottation"},{"id":"cyanuration","nom":"cyanuration"},{"id":"testLixiviation","nom":"test de lixiviation"},{"id":"autre","nom":"autres"}],"optionnel":true},{"id":"complementAnalyses","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les analyses (volumes traités, nombre de tests...)"}]},{"id":"etudes","nom":"Etudes","elements":[{"id":"listeEtudes","nom":"Nature des études effectués","type":"checkboxes","options":[{"id":"environnementale","nom":"environnementale"},{"id":"economiquePreliminaire","nom":"économique préliminaire"},{"id":"economiquePreFaisabilite","nom":"économique pré-faisabilité"},{"id":"economiqueFaisabilité","nom":"économique faisabilité"},{"id":"sociale","nom":"sociale"},{"id":"autre","nom":"autres"}],"optionnel":true,"description":"Nature des études effectuées"},{"id":"complementEtudes","nom":"Informations complémentaires","type":"textarea","optionnel":true,"description":"Toute information complémentaire sur les études effectuées"}]}],[{"id":"renseignements","elements":[{"id":"orExtrait","nom":"Or extrait (g)","type":"number","description":"Masse d'or brut en sortie de mine, ou nette obtenue après traitement métallurgique, extrait au cours du trimestre."},{"id":"volumeMinerai","nom":"Minerai extrait (m3)","type":"number","description":"Volume en mètre cube de minerai extrait au cours du trimestre."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"depensesTotales","nom":"Dépenses totales (euros)","type":"number","description":"Montant en euros des dépenses sur l'exploitation."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"1","nom":"Janvier","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"2","nom":"Février","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"3","nom":"Mars","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"4","nom":"Avril","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"5","nom":"Mai","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"6","nom":"Juin","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"10","nom":"Octobre","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"11","nom":"Novembre","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"12","nom":"Décembre","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production d'or net."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"7","nom":"Juillet","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"8","nom":"Août","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]},{"id":"9","nom":"Septembre","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}]}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production d'or net."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","dateDebut":"2018-01-01","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","dateDebut":"2018-01-01","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","dateDebut":"2018-01-01","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","dateDebut":"2018-01-01","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","dateDebut":"2018-01-01","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"4","nom":"Avril","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2},{"id":"5","nom":"Mai","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2},{"id":"6","nom":"Juin","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","dateDebut":"2018-01-01","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"substancesFiscales","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production d'or net."}]}],[{"id":"indicateursEnvironnement","nom":"Indicateurs environnementaux","elements":[{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","description":"Volume total en litre de carburant détaxé consommé au cours de l'année par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours de l'année par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","description":"<b>Dans le cas d'un chantier alluvionnaire</b>, nombre d'heure de fonctionnement de pompes au cours de l'année sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","description":"<b>Dans le cas d'un chantier alluvionnaire</b>, nombre d'heure de fonctionnement de pelles mécaniques au cours de l'année sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"<b>En Guyane</b>, masse en gramme de l’ensemble des produits contaminés au mercure envoyés en traitement au cours de l'année."},{"id":"surfaceDeforestee","nom":"Surface déforestée (km²)","type":"number","description":"Surface déforestée en kilomètre carré au cours de l'année."}]},{"id":"complementEnvironnement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants l'année en matière de protection de l'environnement dont les actions entreprises pour réduire l'empreinte environnementale du projet."}]}],[{"id":"indicateursSocialEconomiqueDirect","nom":"Indicateurs sociaux et économiques sur les emplois directs","elements":[{"id":"emploisDirectsTotal","nom":"Emplois directs salariés","type":"number","description":"Nombre total de salariés de l'entreprise affectés aux activités sur le titre minier."},{"id":"etpDirectsTotal","nom":"Equivalents temps plein salariés","type":"number","description":"Nombre total d'équivalents temps plein salariés de l'entreprise affectés aux activités sur le titre minier."},{"id":"emploisDirectsResidents","nom":"Emplois directs salariés occupés par des résidents du département","type":"number","description":"Nombre de salariés de l'entreprise, <b>français ou étrangers, résidant fiscalement dans le département</b>, affectés aux activités sur le titre minier."},{"id":"etpDirectsResidents","nom":"Equivalents temps plein salariés occupés par des résidents du département","type":"number","description":"Nombre d'équivalents temps plein salariés de l'entreprise, occupés par des <b>français ou étrangers, résidant fiscalement dans le département</b>, affectés aux activités sur le titre minier."},{"id":"emploisDirectsFr","nom":"Emplois directs salariés de nationalité française","type":"number","description":"Nombre d'employés de <b>nationalité française</b> salariés de l'entreprise affectés aux activités sur le titre minier."},{"id":"etpDirectsFr","nom":"Equivalents temps plein salariés de nationalité française","type":"number","description":"Nombre d'équivalents temps plein salariés de l'entreprise occupés par des personnes de <b>nationalité française</b> affectés aux activités sur le titre minier."}]},{"id":"indicateursSocialEconomiqueInirects","nom":"Indicateurs sociaux et économiques sur la sous-traitance","elements":[{"id":"emploisIndirectsTotal","nom":"Emplois salariés des sous-traitants","type":"number","description":"Nombre total d'emplois salariés des sous-traitants et prestataires affectés aux activités sur le titre minier."},{"id":"etpIndirectsTotal","nom":"Equivalents temps plein salariés des sous-traitants","type":"number","description":"Nombre total d'équivalents temps plein salariés des sous-traitants et prestataires, affectés aux activités sur le titre minier."},{"id":"emploisIndirectsResidents","nom":"Emplois salariés résidents du département des sous-traitants","type":"number","description":"Nombre de salariés des sous-traitants et prestataires, <b>résidant fiscalement dans le département</b>, affectés aux activités sur le titre minier."},{"id":"etpIndirectsResidents","nom":"Equivalents temps plein des salariés des sous-traitants résidents du département","type":"number","description":"Nombre d'équivalents temps plein des sous-traitants et prestataires, <b>résidant fiscalement dans le département</b>, affectés aux activités sur le titre minier."},{"id":"emploisIndirectsFr","nom":"Emplois salariés de nationalité française des sous-traitants","type":"number","description":"Nombre d'employés de <b>nationalité française</b> salariés des sous-traitants et prestataires de l'entreprise, affectés aux activités sur le titre minier."},{"id":"etpIndirectsFr","nom":"Equivalents temps plein salariés de nationalité française des sous-traitants","type":"number","description":"Nombre d'équivalents temps plein occupés par des personnes de <b>nationalité française</b> salariées des sous-traitants et prestataires de l'entreprise, affectées aux activités sur le titre minier."}]},{"id":"indicateursConcertationAcceptabilite","nom":"Indicateurs de concertation et d'acceptabilité du projet","elements":[{"id":"reunionPublique","nom":"Réunions publiques","type":"number","description":"Nombre de réunions publiques consacrées aux projets sur le titre minier organisées au cours de l'année"},{"id":"priseContact","nom":"Rendez-vous","type":"number","description":"Nombre de rendez-vous avec les parties prenantes concernées par le titre minier organisés au cours de l'année"},{"id":"communicationLocale","nom":"Actions de communication à destination du public","type":"number","description":"Nombre d'actions de communication menées par le titulaire du titre à destination du public (hors publication et communication à destination des marchés) au cours de l'année"}]},{"id":"complementSocialEconomique","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants de nature sociale ou économique de l'année."}]}],[{"id":"substancesFiscales","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"naca","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait par abattage net livré","referenceUniteRatio":1000000},{"id":"nacb","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré raffiné","referenceUniteRatio":1000000},{"id":"nacc","nom":"sel (chlorure de sodium contenu)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré en dissolution","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"fluo","nom":"fluorine","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"kclx","nom":"oxyde de potassium","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> K2O contenu dans les sels de potassium","referenceUniteRatio":100000},{"id":"naca","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait par abattage net livré","referenceUniteRatio":1000000},{"id":"nacb","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré raffiné","referenceUniteRatio":1000000},{"id":"nacc","nom":"sel (chlorure de sodium contenu)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré en dissolution","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"naca","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait par abattage net livré","referenceUniteRatio":1000000},{"id":"nacb","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré raffiné","referenceUniteRatio":1000000},{"id":"nacc","nom":"sel (chlorure de sodium contenu)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré en dissolution","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"aloh","nom":"bauxite","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> bauxite nettes livrées","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]}],[{"id":"renseignementsProduction","nom":"Production annuelle","elements":[{"id":"volumeGranulatsExtrait","nom":"Volume de granulats marins extrait (m3)","type":"number","description":"Volume de granulats marins extrait, en mètre cube, au cours de l'année."}]},{"id":"complementInformation","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information sur les événements marquants de l'année (arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, accident, incident, etc.)."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"arge","nom":"argent","type":"number","uniteId":"mkc","description":"<b>x 100 kg (quintal)</b> contenu dans les minerais","referenceUniteRatio":100},{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"fluo","nom":"fluorine","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"hyda","nom":"calcaires et grès bitumineux ou asphaltiques","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré (non destinés à la distillation pour production d'huiles ou d'essences)","referenceUniteRatio":1000000},{"id":"hydb","nom":"schistes carbobitumineux et schistes bitumineux","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré (à traiter par distillation pour en extraire des huiles et des essences)","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"renseignements","elements":[{"id":"orBrut","nom":"Or brut extrait (g)","type":"number","dateDebut":"2018-01-01","description":"Masse d’or brut en sortie de mine extrait au cours du trimestre (exemple : masse sous la forme de concentré gravimétrique)."},{"id":"mercure","nom":"Mercure récupéré (g)","type":"number","description":"Masse en gramme de l’ensemble des produits contaminés envoyés en traitement au cours du trimestre."},{"id":"carburantDetaxe","nom":"Carburant détaxé (l)","type":"number","dateDebut":"2018-01-01","description":"Volume total en litre de carburant détaxé consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"carburantConventionnel","nom":"Carburant conventionnel (l)","type":"number","description":"Volume total en litre de carburant conventionnel consommé au cours du trimestre par les travaux réalisés sur le chantier."},{"id":"pompes","nom":"Pompes actives","type":"number","dateDebut":"2018-01-01","description":"Nombre moyen de pompes actives au cours du trimestre utilisées sur le chantier (pompe à gravier, pompe de relevage…)."},{"id":"pelles","nom":"Pelles actives","type":"number","dateDebut":"2018-01-01","description":"Nombre moyen de pelles actives au cours du trimestre utilisées sur le chantier (aménagement, exploitation, réhabilitation)."},{"id":"effectifs","nom":"Effectifs","type":"number","description":"Nombre moyen de salariés sur le chantier au cours du trimestre."},{"id":"environnement","nom":"Dépenses relatives à la protection de l’environnement (euros)","type":"number","dateDebut":"2018-01-01","description":"Montant en euros des investissements consentis au cours du trimestre listés à l’<a href=\"https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000021850940&cidTexte=LEGITEXT000006069569\" target=\"_blank\" title=\"Page de l’article - site externe\" rel=\"noopener noreferrer\">article 318 C de l’annexe II du code général des impôts</a>. Afin de bénéficier des déductions fiscales afférentes, les justificatifs attestant de la réalisation effective des investissements sont susceptibles de vous êtres demandés par l’administration."}]},{"id":"travaux","nom":"Statut des travaux","elements":[{"id":"4","nom":"Avril","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2},{"id":"5","nom":"Mai","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2},{"id":"6","nom":"Juin","type":"checkboxes","options":[{"id":"nonDebutes","nom":"non débutés"},{"id":"exploitationEnCours","nom":"exploitation en cours"},{"id":"arretTemporaire","nom":"arrêt temporaire"},{"id":"rehabilitation","nom":"réhabilitation"},{"id":"arretDefinitif","nom":"arrêt définitif (après réhabilitation)"}],"dateDebut":"2018-01-01","periodeId":2}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","dateDebut":"2018-01-01","optionnel":true,"description":"Toute information sur les événements marquants du trimestre (accident, incident, arrêt ou suspension d’activité en précisant les raisons, évolution de l’exploitation, difficultés rencontrées, etc.)."}]}],[{"id":"substancesFiscales","elements":[{"id":"aloh","nom":"bauxite","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> bauxite nettes livrées","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"hyda","nom":"calcaires et grès bitumineux ou asphaltiques","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré (non destinés à la distillation pour production d'huiles ou d'essences)","referenceUniteRatio":1000000},{"id":"hydb","nom":"schistes carbobitumineux et schistes bitumineux","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré (à traiter par distillation pour en extraire des huiles et des essences)","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"coox","nom":"gaz carbonique","type":"number","uniteId":"vmd","description":"<b>x 100 000 m³ (100 000 mètres cubes)</b> extrait à 1 bar et 15 °C","referenceUniteRatio":100000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"kclx","nom":"oxyde de potassium","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> K2O contenu dans les sels de potassium","referenceUniteRatio":100000},{"id":"naca","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait par abattage net livré","referenceUniteRatio":1000000},{"id":"nacb","nom":"sel (chlorure de sodium)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré raffiné","referenceUniteRatio":1000000},{"id":"nacc","nom":"sel (chlorure de sodium contenu)","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> extrait en dissolution par sondage et livré en dissolution","referenceUniteRatio":1000000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001},{"id":"arge","nom":"argent","type":"number","uniteId":"mkc","description":"<b>x 100 kg (quintal)</b> contenu dans les minerais","referenceUniteRatio":100},{"id":"cuiv","nom":"cuivre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais","referenceUniteRatio":1000},{"id":"fera","nom":"pyrite de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"ferb","nom":"minerais de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"plom","nom":"plomb","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000},{"id":"souf","nom":"soufre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais de soufre autres que les pyrites de fer","referenceUniteRatio":1000},{"id":"zinc","nom":"zinc","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","elements":[{"id":"arge","nom":"argent","type":"number","uniteId":"mkc","description":"<b>x 100 kg (quintal)</b> contenu dans les minerais","referenceUniteRatio":100},{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001},{"id":"cuiv","nom":"cuivre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais","referenceUniteRatio":1000},{"id":"fera","nom":"pyrite de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"ferb","nom":"minerais de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"plom","nom":"plomb","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000},{"id":"souf","nom":"soufre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais de soufre autres que les pyrites de fer","referenceUniteRatio":1000},{"id":"zinc","nom":"zinc","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}],[{"id":"substancesFiscales","nom":"Production annuelle","elements":[{"id":"arge","nom":"argent","type":"number","uniteId":"mkc","description":"<b>x 100 kg (quintal)</b> contenu dans les minerais","referenceUniteRatio":100},{"id":"auru","nom":"or","type":"number","uniteId":"mgr","description":"<b>g (gramme)</b> contenu dans les minerais","referenceUniteRatio":0.001},{"id":"cuiv","nom":"cuivre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais","referenceUniteRatio":1000},{"id":"fera","nom":"pyrite de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"ferb","nom":"minerais de fer","type":"number","uniteId":"mtk","description":"<b>x 1000 t (millier de tonnes)</b> net livré","referenceUniteRatio":1000000},{"id":"plom","nom":"plomb","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000},{"id":"souf","nom":"soufre","type":"number","uniteId":"mtt","description":"<b>t (tonne)</b> contenu dans les minerais de soufre autres que les pyrites de fer","referenceUniteRatio":1000},{"id":"zinc","nom":"zinc","type":"number","uniteId":"mtc","description":"<b>x 100 t (centaine de tonnes)</b> contenu dans les minerais","referenceUniteRatio":100000}]},{"id":"complement","nom":"Informations complémentaires","elements":[{"id":"texte","type":"textarea","optionnel":true,"description":"Toute information utile à la compréhension de la production déclarée."}]}]] \ No newline at end of file diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts index 07da4651c..f1d5fad47 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts @@ -1,5 +1,6 @@ import { getSections, getSectionsWithValue, sectionValidator } from './sections.js' import { test, expect, describe } from 'vitest' +const activitesSectionsProd = require('./activites.sections.json') test('getSections erreurs', () => { expect(() => getSections(undefined, undefined, undefined)).toThrowErrorMatchingInlineSnapshot( @@ -418,3 +419,8 @@ describe('getSectionsWithValue', () => { `) }) }) + +// pour regénérer le fichier: `npm run test:generate-sections-data -w packages/api` +test.each(activitesSectionsProd as any[])("cas réel des sections d'activité N°$id", sections => { + sectionValidator.parse(sections) +}) diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts index dd3c342c8..c765b7ee9 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts @@ -894,7 +894,7 @@ export type RadioElement = z.infer<typeof radioElementValidator> export const checkboxesElementValidator = basicElementValidator.extend({ type: z.literal('checkboxes'), options: z.array(z.object({ id: z.string(), nom: z.string() })), - optionnel: z.literal(false).optional(), + optionnel: z.boolean().optional(), }) export type CheckboxesElement = z.infer<typeof checkboxesElementValidator> diff --git a/packages/ui/src/api/_client.js b/packages/ui/src/api/_client.js index 9b8a6518e..c95fe2d69 100644 --- a/packages/ui/src/api/_client.js +++ b/packages/ui/src/api/_client.js @@ -56,7 +56,7 @@ const apiGraphQLFetch = (query, cacheKey) => async variables => { try { return await graphQLCall(apiUrl, query, variables, cacheKey) } catch (e) { - if (e.status === 403 || e.message === 'HTTP 403 status.') { + if (e.status === 401 || e.message === 'HTTP 401 status.') { // si la session est expirée on doit réauthentifier l’utilisateur window.location.replace('/oauth2/sign_in?rd=' + encodeURIComponent(window.location.href)) } else { diff --git a/packages/ui/src/api/client-rest.ts b/packages/ui/src/api/client-rest.ts index 497793de0..c2c494419 100644 --- a/packages/ui/src/api/client-rest.ts +++ b/packages/ui/src/api/client-rest.ts @@ -52,7 +52,7 @@ const callFetch = async <T extends CaminoRestRoute>( } return } - if (fetched.status === 403) { + if (fetched.status === 401) { window.location.replace('/oauth2/sign_in?rd=' + encodeURIComponent(window.location.href)) } console.error(`Une erreur s'est produite lors de la récupération des données ${await fetched.text()}`) diff --git a/packages/ui/src/api/fragments/metas-activites.js b/packages/ui/src/api/fragments/metas-activites.js deleted file mode 100644 index 06e661ae6..000000000 --- a/packages/ui/src/api/fragments/metas-activites.js +++ /dev/null @@ -1,16 +0,0 @@ -import gql from 'graphql-tag' - -const fragmentActiviteType = gql` - fragment activiteType on ActiviteType { - id - nom - dateDebut - delaiMois - ordre - frequenceId - sections - description - } -` - -export { fragmentActiviteType } diff --git a/packages/ui/src/api/metas-activites.js b/packages/ui/src/api/metas-activites.js deleted file mode 100644 index 01d0f72d3..000000000 --- a/packages/ui/src/api/metas-activites.js +++ /dev/null @@ -1,18 +0,0 @@ -import gql from 'graphql-tag' -import { apiGraphQLFetch } from './_client' - -import { fragmentActiviteType } from './fragments/metas-activites' - -const activitesTypes = apiGraphQLFetch( - gql` - query ActivitesTypes { - activitesTypes { - ...activiteType - } - } - - ${fragmentActiviteType} - ` -) - -export { activitesTypes } diff --git a/packages/ui/src/components/_common/new-sections-edit.tsx b/packages/ui/src/components/_common/new-sections-edit.tsx index eb4e118f2..5a6465ba1 100644 --- a/packages/ui/src/components/_common/new-sections-edit.tsx +++ b/packages/ui/src/components/_common/new-sections-edit.tsx @@ -18,31 +18,34 @@ interface Props { } export const SectionsEdit = defineComponent<Props>(props => { + const sectionsWithValue = ref<SectionWithValue[]>([]) + watch( () => props.sectionsWithValue, () => { + sectionsWithValue.value = [...props.sectionsWithValue] props.completeUpdate(sectionsWithValueCompleteValidate(props.sectionsWithValue).length === 0, props.sectionsWithValue) }, { immediate: true } ) const onValueChange = (elementIndex: number, sectionIndex: number) => (elementWithValue: ElementWithValue) => { - const newSection = { ...props.sectionsWithValue[sectionIndex] } + const newSection = { ...sectionsWithValue.value[sectionIndex] } newSection.elements = [...newSection.elements] newSection.elements.splice(elementIndex, 1, elementWithValue) - const newSectionsWithValue: SectionWithValue[] = [...props.sectionsWithValue] + const newSectionsWithValue: SectionWithValue[] = [...sectionsWithValue.value] newSectionsWithValue.splice(sectionIndex, 1, newSection) const complete: boolean = sectionsWithValueCompleteValidate(newSectionsWithValue).length === 0 - + sectionsWithValue.value = newSectionsWithValue props.completeUpdate(complete, newSectionsWithValue) } return () => ( <div> - {props.sectionsWithValue.map((sectionWithValue, sectionIndex) => ( + {sectionsWithValue.value.map((sectionWithValue, sectionIndex) => ( <fieldset key={sectionWithValue.id} class="fr-fieldset" aria-labelledby={sectionWithValue.nom ? `${sectionWithValue.id}-legend` : undefined}> {sectionWithValue.nom ? ( <legend class="fr-fieldset__legend" id={`${sectionWithValue.id}-legend`}> diff --git a/packages/ui/src/components/activite-edition.stories.tsx b/packages/ui/src/components/activite-edition.stories.tsx index ae75d3fdb..68b1577ad 100644 --- a/packages/ui/src/components/activite-edition.stories.tsx +++ b/packages/ui/src/components/activite-edition.stories.tsx @@ -2,11 +2,9 @@ import { vueRouter } from 'storybook-vue3-router' import { PureActiviteEdition, Props } from './activite-edition' import { Meta, StoryFn } from '@storybook/vue3' import { action } from '@storybook/addon-actions' -import { ApiClient } from '@/api/api-client' import { tempDocumentNameValidator } from 'camino-common/src/document' import { toCaminoAnnee, toCaminoDate } from 'camino-common/src/date' -import { ActivitesTypesId } from 'camino-common/src/static/activitesTypes' -import { Activite, activiteIdValidator, activiteSlugValidator, TempActiviteDocument } from 'camino-common/src/activite' +import { Activite, activiteIdOrSlugValidator, activiteIdValidator, activiteSlugValidator } from 'camino-common/src/activite' const meta: Meta = { title: 'Components/Activite/Edition', @@ -19,7 +17,7 @@ export default meta const getActiviteAction = action('getActivite') const uploadTempDocumentAction = action('uploadTempDocument') const deposerActiviteAction = action('deposerActivite') -const onSaveAction = action('onSave') +const goBackAction = action('goBack') const activite: Activite = { id: activiteIdValidator.parse('activiteId'), @@ -180,38 +178,30 @@ const apiClient: Props['apiClient'] = { }, } -const onSave = (activiteTypeId: ActivitesTypesId) => { - onSaveAction(activiteTypeId) -} - -export const Loading: StoryFn = () => ( - <PureActiviteEdition apiClient={{ ...apiClient, getActivite: () => new Promise(() => ({})) }} route={{ name: 'activite', params: { activiteId: 'activiteId' } }} onSave={onSave} /> -) +const activiteId = activiteIdOrSlugValidator.parse('activiteId') +export const Loading: StoryFn = () => <PureActiviteEdition goBack={goBackAction} apiClient={{ ...apiClient, getActivite: () => new Promise(() => ({})) }} activiteId={activiteId} /> export const WithError: StoryFn = () => ( - <PureActiviteEdition - apiClient={{ ...apiClient, getActivite: () => Promise.reject(new Error('Une erreur est survenue')) }} - route={{ name: 'activite', params: { activiteId: 'activiteId' } }} - onSave={onSave} - /> + <PureActiviteEdition goBack={goBackAction} apiClient={{ ...apiClient, getActivite: () => Promise.reject(new Error('Une erreur est survenue')) }} activiteId={activiteId} /> ) -export const FullEmpty: StoryFn = () => <PureActiviteEdition apiClient={apiClient} route={{ name: 'activite', params: { activiteId: 'activiteId' } }} onSave={onSave} /> +export const FullEmpty: StoryFn = () => <PureActiviteEdition goBack={goBackAction} apiClient={apiClient} activiteId={activiteId} /> export const FullEmptyWithMandatoryDocument: StoryFn = () => ( <PureActiviteEdition + goBack={goBackAction} apiClient={{ ...apiClient, getActivite: () => { return Promise.resolve({ ...activite, type_id: 'wrp' }) }, }} - route={{ name: 'activite', params: { activiteId: 'activiteId' } }} - onSave={onSave} + activiteId={activiteId} /> ) export const FullDeposable: StoryFn = () => ( <PureActiviteEdition + goBack={goBackAction} apiClient={{ ...apiClient, getActivite: () => { @@ -251,7 +241,6 @@ export const FullDeposable: StoryFn = () => ( }) }, }} - route={{ name: 'activite', params: { activiteId: 'activiteId' } }} - onSave={onSave} + activiteId={activiteId} /> ) diff --git a/packages/ui/src/components/activite-edition.stories_snapshots_FullDeposable.html b/packages/ui/src/components/activite-edition.stories_snapshots_FullDeposable.html index 50cbb0ee4..2065eaa27 100644 --- a/packages/ui/src/components/activite-edition.stories_snapshots_FullDeposable.html +++ b/packages/ui/src/components/activite-edition.stories_snapshots_FullDeposable.html @@ -3,7 +3,7 @@ <div> <p><a href="/mocked-href" title="Retourner vers le titre Titre avec activité" class="fr-link" aria-label="Retourner vers le titre Titre avec activité">Titre avec activité</a></p> <div class="flex"> - <h2 class="mb-s"><span class="cap-first">rapport trimestriel d'exploitation d'or en Guyane</span> (<span>1er trimestre </span> 2023)</h2> + <h2 class="mb-s"><span>Rapport trimestriel d'exploitation d'or en Guyane</span> (<span>1er trimestre </span> 2023)</h2> </div> <div class="fr-alert fr-alert--info fr-mb-2w"> <h3 class="fr-alert__title">Besoin d'aide pour remplir ce rapport ?</h3> @@ -37,22 +37,7 @@ </div> </fieldset> </div> - <div class="fr-table"> - <table style="display: table;"> - <caption>Documents de l'activité </caption> - <thead> - <tr> - <th scope="col">Nom</th> - <th scope="col">Date</th> - <th scope="col">Description</th> - <th scope="col" style="display: flex; justify-content: end;"><button class="fr-btn fr-btn--primary fr-btn--md fr-icon-add-line" title="Ajouter un document" aria-label="Ajouter un document"> - <!----> - </button></th> - </tr> - </thead> - <tbody></tbody> - </table> - </div> + <!----> <!----> <div style="display: flex; flex-direction: row; justify-content: end;" class="fr-pb-2w"><button class="fr-btn fr-btn--secondary fr-btn--lg fr-mr-2w" title="Enregistrer" aria-label="Enregistrer">Enregistrer</button><button class="fr-btn fr-btn--primary fr-btn--lg" title="Enregistrer et déposer" aria-label="Enregistrer et déposer">Enregistrer et déposer</button></div> </div> diff --git a/packages/ui/src/components/activite-edition.stories_snapshots_FullEmpty.html b/packages/ui/src/components/activite-edition.stories_snapshots_FullEmpty.html index f58424e4b..81a662b30 100644 --- a/packages/ui/src/components/activite-edition.stories_snapshots_FullEmpty.html +++ b/packages/ui/src/components/activite-edition.stories_snapshots_FullEmpty.html @@ -3,7 +3,7 @@ <div> <p><a href="/mocked-href" title="Retourner vers le titre Titre avec activité" class="fr-link" aria-label="Retourner vers le titre Titre avec activité">Titre avec activité</a></p> <div class="flex"> - <h2 class="mb-s"><span class="cap-first">rapport trimestriel d'exploitation d'or en Guyane</span> (<span>1er trimestre </span> 2023)</h2> + <h2 class="mb-s"><span>Rapport trimestriel d'exploitation d'or en Guyane</span> (<span>1er trimestre </span> 2023)</h2> </div> <div class="fr-alert fr-alert--info fr-mb-2w"> <h3 class="fr-alert__title">Besoin d'aide pour remplir ce rapport ?</h3> @@ -197,22 +197,7 @@ </div> </fieldset> </div> - <div class="fr-table"> - <table style="display: table;"> - <caption>Documents de l'activité </caption> - <thead> - <tr> - <th scope="col">Nom</th> - <th scope="col">Date</th> - <th scope="col">Description</th> - <th scope="col" style="display: flex; justify-content: end;"><button class="fr-btn fr-btn--primary fr-btn--md fr-icon-add-line" title="Ajouter un document" aria-label="Ajouter un document"> - <!----> - </button></th> - </tr> - </thead> - <tbody></tbody> - </table> - </div> + <!----> <!----> <div style="display: flex; flex-direction: row; justify-content: end;" class="fr-pb-2w"><button class="fr-btn fr-btn--secondary fr-btn--lg fr-mr-2w" title="Enregistrer" aria-label="Enregistrer">Enregistrer</button><button class="fr-btn fr-btn--primary fr-btn--lg" disabled="" title="Enregistrer et déposer" aria-label="Enregistrer et déposer">Enregistrer et déposer</button></div> </div> diff --git a/packages/ui/src/components/activite-edition.stories_snapshots_FullEmptyWithMandatoryDocument.html b/packages/ui/src/components/activite-edition.stories_snapshots_FullEmptyWithMandatoryDocument.html index 14a406a25..5cb5a2239 100644 --- a/packages/ui/src/components/activite-edition.stories_snapshots_FullEmptyWithMandatoryDocument.html +++ b/packages/ui/src/components/activite-edition.stories_snapshots_FullEmptyWithMandatoryDocument.html @@ -3,7 +3,7 @@ <div> <p><a href="/mocked-href" title="Retourner vers le titre Titre avec activité" class="fr-link" aria-label="Retourner vers le titre Titre avec activité">Titre avec activité</a></p> <div class="flex"> - <h2 class="mb-s"><span class="cap-first">rapport d'exploitation (permis et concessions W)</span> (<span>année </span> 2023)</h2> + <h2 class="mb-s"><span>Rapport d'exploitation (permis et concessions W)</span> (<span>année </span> 2023)</h2> </div> <div class="fr-alert fr-alert--info fr-mb-2w"> <h3 class="fr-alert__title">Besoin d'aide pour remplir ce rapport ?</h3> @@ -206,7 +206,6 @@ <thead> <tr> <th scope="col">Nom</th> - <th scope="col">Date</th> <th scope="col">Description</th> <th scope="col" style="display: flex; justify-content: end;"><button class="fr-btn fr-btn--primary fr-btn--md fr-icon-add-line" title="Ajouter un document" aria-label="Ajouter un document"> <!----> diff --git a/packages/ui/src/components/activite-edition.tsx b/packages/ui/src/components/activite-edition.tsx index 0c9c9ff3e..2611c5dc0 100644 --- a/packages/ui/src/components/activite-edition.tsx +++ b/packages/ui/src/components/activite-edition.tsx @@ -2,8 +2,8 @@ import { ActiviteDocumentsEdit } from './activite/activite-documents-edit' import { getPeriode } from 'camino-common/src/static/frequence' import { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref } from 'vue' import { AsyncData } from '@/api/client-rest' -import { Activite, ActiviteDocumentId, ActiviteIdOrSlug, TempActiviteDocument, activiteIdOrSlugValidator } from 'camino-common/src/activite' -import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router' +import { Activite, ActiviteDocumentId, ActiviteId, ActiviteIdOrSlug, TempActiviteDocument, activiteIdOrSlugValidator } from 'camino-common/src/activite' +import { useRouter } from 'vue-router' import { LoadingElement } from './_ui/functional-loader' import { ActivitesTypes, ActivitesTypesId } from 'camino-common/src/static/activitesTypes' import { ActiviteDeposePopup } from './activite/depose-popup' @@ -18,25 +18,34 @@ export const ActiviteEdition = defineComponent(() => { const matomo = inject('matomo', null) const router = useRouter() + const activiteId = computed<ActiviteIdOrSlug>(() => { + return activiteIdOrSlugValidator.parse(router.currentRoute.value.params.activiteId) + }) + return () => ( <PureActiviteEdition - apiClient={apiClient} - route={router.currentRoute.value} - onSave={(activiteTypeId: ActivitesTypesId) => { - if (matomo) { - // @ts-ignore - matomo.trackEvent('activite', 'activite-enregistrer', ActivitesTypes[activiteTypeId].nom) - } - router.back() + apiClient={{ + ...apiClient, + updateActivite: async (activiteId, activiteTypeId, sectionsWithValue, activiteDocumentIds, newTempDocuments) => { + await apiClient.updateActivite(activiteId, activiteTypeId, sectionsWithValue, activiteDocumentIds, newTempDocuments) + if (matomo) { + // @ts-ignore + matomo.trackEvent('activite', 'activite-enregistrer', ActivitesTypes[activiteTypeId].nom) + } + }, }} + goBack={(activiteId: ActiviteId): void => { + router.push({ name: 'activite', params: { activiteId } }) + }} + activiteId={activiteId.value} /> ) }) export interface Props { apiClient: Pick<ApiClient, 'uploadTempDocument' | 'getActivite' | 'deposerActivite' | 'updateActivite'> - route: Pick<RouteLocationNormalizedLoaded, 'params' | 'name'> - onSave: (activiteTypeId: ActivitesTypesId) => void + activiteId: ActiviteIdOrSlug + goBack: (activiteId: ActiviteId) => void } export const PureActiviteEdition = defineComponent<Props>(props => { @@ -51,7 +60,8 @@ export const PureActiviteEdition = defineComponent<Props>(props => { const data = ref<AsyncData<Activite>>({ status: 'LOADING' }) const deposePopupVisible = ref(false) - const deposePopupOpen = () => { + const deposePopupOpen = async () => { + await save(false) deposePopupVisible.value = true } @@ -62,7 +72,7 @@ export const PureActiviteEdition = defineComponent<Props>(props => { const keyUp = (e: KeyboardEvent) => { if ((e.which || e.keyCode) === 13 && events.value.saveKeyUp && !deposePopupVisible.value && data.value.status === 'LOADED') { // $refs['save-button'].focus() - save() + save(true) } } @@ -75,14 +85,10 @@ export const PureActiviteEdition = defineComponent<Props>(props => { document.removeEventListener('keyup', keyUp) }) - const activiteId = computed<ActiviteIdOrSlug>(() => { - return activiteIdOrSlugValidator.parse(props.route.params.activiteId) - }) - const init = async () => { try { data.value = { status: 'LOADING' } - const result = await props.apiClient.getActivite(activiteId.value) + const result = await props.apiClient.getActivite(props.activiteId) data.value = { status: 'LOADED', value: result } } catch (e: any) { console.error('error', e) @@ -93,12 +99,26 @@ export const PureActiviteEdition = defineComponent<Props>(props => { } } - const save = async () => { + const save = async (goBack: boolean) => { if (data.value.status === 'LOADED') { - console.log(JSON.stringify(data.value.value)) - props.onSave(data.value.value.type_id) - - props.apiClient.updateActivite(data.value.value.id, sectionsComplete.value.sectionsWithValue, documentsComplete.value.activiteDocumentIds, documentsComplete.value.tempsDocuments) + try { + await props.apiClient.updateActivite( + data.value.value.id, + data.value.value.type_id, + sectionsComplete.value.sectionsWithValue, + documentsComplete.value.activiteDocumentIds, + documentsComplete.value.tempsDocuments + ) + if (goBack) { + props.goBack(data.value.value.id) + } + } catch (e: any) { + console.error('error', e) + data.value = { + status: 'ERROR', + message: e.message ?? "Une erreur s'est produite", + } + } } } @@ -131,7 +151,7 @@ export const PureActiviteEdition = defineComponent<Props>(props => { <div class="flex"> <h2 class="mb-s"> - <span class="cap-first">{ActivitesTypes[activite.type_id].nom}</span> ( + <span>{capitalize(ActivitesTypes[activite.type_id].nom)}</span> ( {activite.periode_id && ActivitesTypes[activite.type_id].frequenceId ? <span>{getPeriode(ActivitesTypes[activite.type_id].frequenceId, activite.periode_id)} </span> : null}{' '} {activite.annee}) </h2> @@ -161,7 +181,7 @@ export const PureActiviteEdition = defineComponent<Props>(props => { <ActiviteDocumentsEdit apiClient={props.apiClient} activiteDocuments={activite.activite_documents} activiteTypeId={activite.type_id} completeUpdate={activiteDocumentsCompleteUpdate} /> <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'end' }} class="fr-pb-2w"> - <DsfrButton title="Enregistrer" buttonType="secondary" buttonSize="lg" onClick={save} class="fr-mr-2w" /> + <DsfrButton title="Enregistrer" buttonType="secondary" buttonSize="lg" onClick={() => save(true)} class="fr-mr-2w" /> <DsfrButton title="Enregistrer et déposer" buttonType="primary" @@ -171,7 +191,19 @@ export const PureActiviteEdition = defineComponent<Props>(props => { /> </div> </div> - {deposePopupVisible.value ? <ActiviteDeposePopup close={closeDeposePopup} activite={activite} apiClient={props.apiClient} /> : null} + {deposePopupVisible.value ? ( + <ActiviteDeposePopup + close={closeDeposePopup} + activite={activite} + apiClient={{ + ...props.apiClient, + deposerActivite: async activiteId => { + await props.apiClient.deposerActivite(activiteId) + props.goBack(activiteId) + }, + }} + /> + ) : null} </> ) }} @@ -181,4 +213,4 @@ export const PureActiviteEdition = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -PureActiviteEdition.props = ['apiClient', 'route', 'onSave'] +PureActiviteEdition.props = ['apiClient', 'activiteId', 'goBack'] diff --git a/packages/ui/src/components/activite.stories.tsx b/packages/ui/src/components/activite.stories.tsx index b23145b40..c2b96c9f7 100644 --- a/packages/ui/src/components/activite.stories.tsx +++ b/packages/ui/src/components/activite.stories.tsx @@ -30,7 +30,7 @@ const activite: Activite = { annee: toCaminoAnnee(2022), periode_id: 1, sections_with_value: [{ id: 'Id', nom: 'Nom de section', elements: [{ type: 'radio', id: 'radio', value: true, nom: 'Un radio button' }] }], - activite_documents: [{ activite_document_type_id: 'ree', date: toCaminoDate('2022-01-01'), description: 'description', id: activiteDocumentIdValidator.parse('id1') }], + activite_documents: [{ activite_document_type_id: 'ree', description: 'description', id: activiteDocumentIdValidator.parse('id1') }], titre: { nom: 'Nom du titre', slug: 'slug-du-titre', diff --git a/packages/ui/src/components/activite.stories_snapshots_ACompleter.html b/packages/ui/src/components/activite.stories_snapshots_ACompleter.html index 85a1d8653..e5ac03712 100644 --- a/packages/ui/src/components/activite.stories_snapshots_ACompleter.html +++ b/packages/ui/src/components/activite.stories_snapshots_ACompleter.html @@ -58,14 +58,12 @@ <thead> <tr> <th scope="col" class="nowrap"><a class="fr-link" title="Nom" aria-label="Nom">Nom</a></th> - <th scope="col" class="nowrap"><a class="fr-link" title="Date" aria-label="Date">Date</a></th> <th scope="col" class="nowrap"><a class="fr-link" title="Description" aria-label="Description">Description</a></th> </tr> </thead> <tbody> <tr> <td class=""><a href="/apiUrl/download/activiteDocuments/id1" title="Télécharger le document Rapport environnemental d'exploration - nouvelle fenêtre" target="_blank" class="">Rapport environnemental d'exploration</a></td> - <td class=""><span class="">01-01-2022</span></td> <td class=""><span class="">description</span></td> </tr> </tbody> diff --git a/packages/ui/src/components/activite.stories_snapshots_Deposable.html b/packages/ui/src/components/activite.stories_snapshots_Deposable.html index c4852e19a..27591d4c6 100644 --- a/packages/ui/src/components/activite.stories_snapshots_Deposable.html +++ b/packages/ui/src/components/activite.stories_snapshots_Deposable.html @@ -57,14 +57,12 @@ <thead> <tr> <th scope="col" class="nowrap"><a class="fr-link" title="Nom" aria-label="Nom">Nom</a></th> - <th scope="col" class="nowrap"><a class="fr-link" title="Date" aria-label="Date">Date</a></th> <th scope="col" class="nowrap"><a class="fr-link" title="Description" aria-label="Description">Description</a></th> </tr> </thead> <tbody> <tr> <td class=""><a href="/apiUrl/download/activiteDocuments/id1" title="Télécharger le document Rapport environnemental d'exploration - nouvelle fenêtre" target="_blank" class="">Rapport environnemental d'exploration</a></td> - <td class=""><span class="">01-01-2022</span></td> <td class=""><span class="">description</span></td> </tr> </tbody> diff --git a/packages/ui/src/components/activite.stories_snapshots_Supprimable.html b/packages/ui/src/components/activite.stories_snapshots_Supprimable.html index 0f2216a7c..852ab30e6 100644 --- a/packages/ui/src/components/activite.stories_snapshots_Supprimable.html +++ b/packages/ui/src/components/activite.stories_snapshots_Supprimable.html @@ -59,14 +59,12 @@ <thead> <tr> <th scope="col" class="nowrap"><a class="fr-link" title="Nom" aria-label="Nom">Nom</a></th> - <th scope="col" class="nowrap"><a class="fr-link" title="Date" aria-label="Date">Date</a></th> <th scope="col" class="nowrap"><a class="fr-link" title="Description" aria-label="Description">Description</a></th> </tr> </thead> <tbody> <tr> <td class=""><a href="/apiUrl/download/activiteDocuments/id1" title="Télécharger le document Rapport environnemental d'exploration - nouvelle fenêtre" target="_blank" class="">Rapport environnemental d'exploration</a></td> - <td class=""><span class="">01-01-2022</span></td> <td class=""><span class="">description</span></td> </tr> </tbody> diff --git a/packages/ui/src/components/activite/activite-api-client.ts b/packages/ui/src/components/activite/activite-api-client.ts index d2c2fdd1d..60d3ef63e 100644 --- a/packages/ui/src/components/activite/activite-api-client.ts +++ b/packages/ui/src/components/activite/activite-api-client.ts @@ -4,7 +4,7 @@ import { CaminoAnnee } from 'camino-common/src/date' import { ActivitesStatutId } from 'camino-common/src/static/activitesStatuts' import { ActivitesTypesId } from 'camino-common/src/static/activitesTypes' import gql from 'graphql-tag' -import { getWithJson, putWithJson } from '../../api/client-rest' +import { deleteWithJson, getWithJson, putWithJson } from '../../api/client-rest' import { ActivitesByTitre, TitreId } from 'camino-common/src/titres' import { SectionWithValue } from 'camino-common/src/sections' @@ -30,7 +30,13 @@ export interface ActiviteApiClient { getActivitesByTitreId: (titreId: TitreId) => Promise<ActivitesByTitre> deposerActivite: (activiteId: ActiviteId) => Promise<void> supprimerActivite: (activiteId: ActiviteId) => Promise<void> - updateActivite: (activiteId: ActiviteId, sectionsWithValue: SectionWithValue[], activiteDocumentIds: ActiviteDocumentId[], newTempDocuments: TempActiviteDocument[]) => Promise<void> + updateActivite: ( + activiteId: ActiviteId, + activiteTypeId: ActivitesTypesId, + sectionsWithValue: SectionWithValue[], + activiteDocumentIds: ActiviteDocumentId[], + newTempDocuments: TempActiviteDocument[] + ) => Promise<void> } export type GetActivitesParams = { @@ -122,15 +128,17 @@ export const activiteApiClient: ActiviteApiClient = { `)({ id: activiteId }) }, supprimerActivite: async (activiteId: ActiviteId) => { - await apiGraphQLFetch(gql` - mutation ActiviteDeposer($id: ID!) { - activiteSupprimer(id: $id) { - id - } - } - `)({ id: activiteId }) + return deleteWithJson('/rest/activites/:activiteId', { + activiteId, + }) }, - updateActivite: async (activiteId: ActiviteId, sectionsWithValue: SectionWithValue[], activiteDocumentIds: ActiviteDocumentId[], newTempDocuments: TempActiviteDocument[]) => { + updateActivite: async ( + activiteId: ActiviteId, + _activiteTypeId: ActivitesTypesId, + sectionsWithValue: SectionWithValue[], + activiteDocumentIds: ActiviteDocumentId[], + newTempDocuments: TempActiviteDocument[] + ) => { return putWithJson( '/rest/activites/:activiteId', { diff --git a/packages/ui/src/components/activite/activite-documents-edit.tsx b/packages/ui/src/components/activite/activite-documents-edit.tsx index 051ee9ac6..1b4d34ee9 100644 --- a/packages/ui/src/components/activite/activite-documents-edit.tsx +++ b/packages/ui/src/components/activite/activite-documents-edit.tsx @@ -9,6 +9,7 @@ import { DsfrButtonIcon } from '../_ui/dsfr-button' import { ref, watch } from 'vue' import { isActiviteDocumentsComplete } from 'camino-common/src/permissions/activites' import { AddActiviteDocumentPopup } from './add-activite-document-popup' +import { activitesTypesDocumentsTypes } from 'camino-common/src/static/activitesTypesDocumentsTypes' interface Props { apiClient: Pick<ApiClient, 'uploadTempDocument'> @@ -34,6 +35,8 @@ export const ActiviteDocumentsEdit = caminoDefineComponent<Props>(['activiteDocu { immediate: true } ) + const hasDocumentTypes: boolean = activitesTypesDocumentsTypes[props.activiteTypeId].map(({ documentTypeId }) => documentTypeId).length > 0 + const notifyChange = () => { const tempActiviteDocuments = documents.value.filter(isTempActiviteDocument) const alreadyExistingActiviteDocumentIds = documents.value.filter(isActiviteDocument).map(({ id }) => id) @@ -42,47 +45,48 @@ export const ActiviteDocumentsEdit = caminoDefineComponent<Props>(['activiteDocu notifyChange() return () => ( <> - <div class="fr-table"> - <table style={{ display: 'table' }}> - <caption>Documents de l'activité {isNotMandatory ? '' : '*'}</caption> - <thead> - <tr> - <th scope="col">Nom</th> - <th scope="col">Date</th> - <th scope="col">Description</th> - <th scope="col" style={{ display: 'flex', justifyContent: 'end' }}> - <DsfrButtonIcon icon="fr-icon-add-line" title="Ajouter un document" onClick={() => (addPopup.value = true)} /> - </th> - </tr> - </thead> - <tbody> - {documents.value.map((item, index) => ( + {hasDocumentTypes ? ( + <div class="fr-table"> + <table style={{ display: 'table' }}> + <caption>Documents de l'activité {isNotMandatory ? '' : '*'}</caption> + <thead> <tr> - <td> - {isTempActiviteDocument(item) ? ( - <>{DocumentsTypes[item.activite_document_type_id].nom}</> - ) : ( - <ActiviteDocumentLink activiteDocumentId={item.id} activiteDocumentTypeId={item.activite_document_type_id} /> - )} - </td> - <td>{dateFormat(item.date)}</td> - <td>{item.description}</td> - <td> - <DsfrButtonIcon - icon="fr-icon-delete-bin-line" - buttonType="secondary" - title={`Supprimer le document ${DocumentsTypes[item.activite_document_type_id].nom}`} - onClick={() => { - documents.value.splice(index, 1) - notifyChange() - }} - /> - </td> + <th scope="col">Nom</th> + <th scope="col">Description</th> + <th scope="col" style={{ display: 'flex', justifyContent: 'end' }}> + <DsfrButtonIcon icon="fr-icon-add-line" title="Ajouter un document" onClick={() => (addPopup.value = true)} /> + </th> </tr> - ))} - </tbody> - </table> - </div> + </thead> + <tbody> + {documents.value.map((item, index) => ( + <tr> + <td> + {isTempActiviteDocument(item) ? ( + <>{DocumentsTypes[item.activite_document_type_id].nom}</> + ) : ( + <ActiviteDocumentLink activiteDocumentId={item.id} activiteDocumentTypeId={item.activite_document_type_id} /> + )} + </td> + <td>{item.description}</td> + <td> + <DsfrButtonIcon + icon="fr-icon-delete-bin-line" + buttonType="secondary" + title={`Supprimer le document ${DocumentsTypes[item.activite_document_type_id].nom}`} + onClick={() => { + documents.value.splice(index, 1) + notifyChange() + }} + /> + </td> + </tr> + ))} + </tbody> + </table> + </div> + ) : null} + {addPopup.value ? ( <AddActiviteDocumentPopup apiClient={props.apiClient} diff --git a/packages/ui/src/components/activite/activite-documents.stories.tsx b/packages/ui/src/components/activite/activite-documents.stories.tsx index 85d315bc5..ef22e9f8c 100644 --- a/packages/ui/src/components/activite/activite-documents.stories.tsx +++ b/packages/ui/src/components/activite/activite-documents.stories.tsx @@ -4,7 +4,6 @@ import { action } from '@storybook/addon-actions' import { tempDocumentNameValidator } from 'camino-common/src/document' import { activiteDocumentIdValidator } from 'camino-common/src/activite' import { ApiClient } from '@/api/api-client' -import { toCaminoDate } from 'camino-common/src/date' import { ACTIVITES_TYPES_IDS } from 'camino-common/src/static/activitesTypes' import { activitesTypesDocumentsTypes } from 'camino-common/src/static/activitesTypesDocumentsTypes' @@ -30,7 +29,6 @@ export const AvecDesDocumentsDejaPresents: StoryFn = () => ( activiteDocuments={[ { activite_document_type_id: activitesTypesDocumentsTypes[ACTIVITES_TYPES_IDS["rapport environnemental d'exploration"]][0].documentTypeId, - date: toCaminoDate('2023-01-01'), description: 'description', id: activiteDocumentIdValidator.parse('id1'), }, diff --git a/packages/ui/src/components/activite/activite-documents.stories_snapshots_AvecDesDocumentsDejaPresents.html b/packages/ui/src/components/activite/activite-documents.stories_snapshots_AvecDesDocumentsDejaPresents.html index 3916681e2..c56fada79 100644 --- a/packages/ui/src/components/activite/activite-documents.stories_snapshots_AvecDesDocumentsDejaPresents.html +++ b/packages/ui/src/components/activite/activite-documents.stories_snapshots_AvecDesDocumentsDejaPresents.html @@ -5,7 +5,6 @@ <thead> <tr> <th scope="col">Nom</th> - <th scope="col">Date</th> <th scope="col">Description</th> <th scope="col" style="display: flex; justify-content: end;"><button class="fr-btn fr-btn--primary fr-btn--md fr-icon-add-line" title="Ajouter un document" aria-label="Ajouter un document"> <!----> @@ -15,7 +14,6 @@ <tbody> <tr> <td><a href="/apiUrl/download/activiteDocuments/id1" title="Télécharger le document Rapport environnemental d'exploration - nouvelle fenêtre" target="_blank">Rapport environnemental d'exploration</a></td> - <td>01-01-2023</td> <td>description</td> <td><button class="fr-btn fr-btn--secondary fr-btn--md fr-icon-delete-bin-line" title="Supprimer le document Rapport environnemental d'exploration" aria-label="Supprimer le document Rapport environnemental d'exploration"> <!----> diff --git a/packages/ui/src/components/activite/activite-documents.stories_snapshots_DocumentObligatoire.html b/packages/ui/src/components/activite/activite-documents.stories_snapshots_DocumentObligatoire.html index 9366c2d67..bc1cea6d8 100644 --- a/packages/ui/src/components/activite/activite-documents.stories_snapshots_DocumentObligatoire.html +++ b/packages/ui/src/components/activite/activite-documents.stories_snapshots_DocumentObligatoire.html @@ -5,7 +5,6 @@ <thead> <tr> <th scope="col">Nom</th> - <th scope="col">Date</th> <th scope="col">Description</th> <th scope="col" style="display: flex; justify-content: end;"><button class="fr-btn fr-btn--primary fr-btn--md fr-icon-add-line" title="Ajouter un document" aria-label="Ajouter un document"> <!----> diff --git a/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentObligatoire.html b/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentObligatoire.html index 28ebc2782..201edeb11 100644 --- a/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentObligatoire.html +++ b/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentObligatoire.html @@ -10,43 +10,15 @@ <div class="fr-container"> <form> <!----> - <div class="dsfr"> - <fieldset class="fr-fieldset" id="add-activite-document-date-fieldset" role="group" aria-labelledby="add-activite-document-date-fieldset-legend"> - <legend class="fr-fieldset__legend" id="add-activite-document-date-fieldset-legend">Date du document - <!----> - </legend> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--number"> - <div class="fr-input-group"><label class="fr-label" for="input_271">Jour - <!----><span class="fr-hint-text">Exemple : 14</span> - </label><input class="fr-input" name="input_271" id="input_271" type="number" min="1" max="31"> - <!----> - </div> - </div> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--number"> - <div class="fr-input-group"><label class="fr-label" for="input_670">Mois - <!----><span class="fr-hint-text">Exemple : 12</span> - </label><input class="fr-input" name="input_670" id="input_670" type="number" min="1" max="12"> - <!----> - </div> - </div> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--inline-grow fr-fieldset__element--year"> - <div class="fr-input-group"><label class="fr-label" for="input_74">Année - <!----><span class="fr-hint-text">Exemple : 1984</span> - </label><input class="fr-input" name="input_74" id="input_74" type="number" min="1750" max="2099"> - <!----> - </div> - </div> - </fieldset> - </div> <fieldset class="fr-fieldset" id="text"> <div class="fr-fieldset__element"> <div class="fr-upload-group"><label class="fr-label" for="file-upload">Ajouter un fichier<span class="fr-hint-text">Taille maximale : 30 Mo. Formats supportés : pdf.</span></label><input class="fr-upload" type="file" id="file-upload" name="file-upload" accept=".pdf"></div> </div> <div class="fr-fieldset__element"> - <div class="fr-input-group"><label class="fr-label" for="input_878">Description + <div class="fr-input-group"><label class="fr-label" for="input_271">Description <!----> <!----> - </label><input class="fr-input" name="input_878" id="input_878" type="text"> + </label><input class="fr-input" name="input_271" id="input_271" type="text"> <!----> </div> </div> diff --git a/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentOptionnel.html b/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentOptionnel.html index e2119f39d..5a720c634 100644 --- a/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentOptionnel.html +++ b/packages/ui/src/components/activite/add-activite-document-popup.stories_snapshots_DocumentOptionnel.html @@ -10,43 +10,15 @@ <div class="fr-container"> <form> <!----> - <div class="dsfr"> - <fieldset class="fr-fieldset" id="add-activite-document-date-fieldset" role="group" aria-labelledby="add-activite-document-date-fieldset-legend"> - <legend class="fr-fieldset__legend" id="add-activite-document-date-fieldset-legend">Date du document - <!----> - </legend> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--number"> - <div class="fr-input-group"><label class="fr-label" for="input_271">Jour - <!----><span class="fr-hint-text">Exemple : 14</span> - </label><input class="fr-input" name="input_271" id="input_271" type="number" min="1" max="31"> - <!----> - </div> - </div> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--number"> - <div class="fr-input-group"><label class="fr-label" for="input_670">Mois - <!----><span class="fr-hint-text">Exemple : 12</span> - </label><input class="fr-input" name="input_670" id="input_670" type="number" min="1" max="12"> - <!----> - </div> - </div> - <div class="fr-fieldset__element fr-fieldset__element--inline fr-fieldset__element--inline-grow fr-fieldset__element--year"> - <div class="fr-input-group"><label class="fr-label" for="input_74">Année - <!----><span class="fr-hint-text">Exemple : 1984</span> - </label><input class="fr-input" name="input_74" id="input_74" type="number" min="1750" max="2099"> - <!----> - </div> - </div> - </fieldset> - </div> <fieldset class="fr-fieldset" id="text"> <div class="fr-fieldset__element"> <div class="fr-upload-group"><label class="fr-label" for="file-upload">Ajouter un fichier<span class="fr-hint-text">Taille maximale : 30 Mo. Formats supportés : pdf.</span></label><input class="fr-upload" type="file" id="file-upload" name="file-upload" accept=".pdf"></div> </div> <div class="fr-fieldset__element"> - <div class="fr-input-group"><label class="fr-label" for="input_878">Description + <div class="fr-input-group"><label class="fr-label" for="input_271">Description <!----> <!----> - </label><input class="fr-input" name="input_878" id="input_878" type="text"> + </label><input class="fr-input" name="input_271" id="input_271" type="text"> <!----> </div> </div> diff --git a/packages/ui/src/components/activite/add-activite-document-popup.tsx b/packages/ui/src/components/activite/add-activite-document-popup.tsx index d1f94ea87..a807651dd 100644 --- a/packages/ui/src/components/activite/add-activite-document-popup.tsx +++ b/packages/ui/src/components/activite/add-activite-document-popup.tsx @@ -2,8 +2,6 @@ import { caminoDefineComponent, updateFromEvent } from '@/utils/vue-tsx-utils' import { computed, ref } from 'vue' import { FunctionalPopup } from '../_ui/functional-popup' import { ActiviteDocumentTypeIds, DocumentsTypes } from 'camino-common/src/static/documentsTypes' -import { InputDate } from '../_ui/dsfr-input-date' -import { CaminoDate } from 'camino-common/src/date' import { InputFile } from '../_ui/dsfr-input-file' import { ApiClient } from '@/api/api-client' import { ActivitesTypes, ActivitesTypesId } from 'camino-common/src/static/activitesTypes' @@ -22,7 +20,6 @@ interface Props { export const AddActiviteDocumentPopup = caminoDefineComponent<Props>(['close', 'apiClient', 'activiteTypeId'], props => { const activiteDocumentTypes = activitesTypesDocumentsTypes[props.activiteTypeId].map(({ documentTypeId }) => documentTypeId) const activiteDocumentTypeId = ref<(typeof ActiviteDocumentTypeIds)[number] | null>(activiteDocumentTypes.length === 1 ? activiteDocumentTypes[0] : null) - const documentDate = ref<CaminoDate | null>(null) const activiteDocumentFile = ref<File | null>(null) const documentDescription = ref<string>('') const tempDocumentName = ref<TempDocumentName | null>(null) @@ -52,13 +49,6 @@ export const AddActiviteDocumentPopup = caminoDefineComponent<Props>(['close', ' </fieldset> )} - <InputDate - id="add-activite-document-date" - legend={{ main: 'Date du document' }} - dateChanged={date => { - documentDate.value = date - }} - /> <fieldset class="fr-fieldset" id="text"> <div class="fr-fieldset__element"> <InputFile @@ -78,7 +68,6 @@ export const AddActiviteDocumentPopup = caminoDefineComponent<Props>(['close', ' const canSave = computed<boolean>(() => { const tempDocument: Omit<Nullable<TempActiviteDocument>, 'tempDocumentName'> = { activite_document_type_id: activiteDocumentTypeId.value, - date: documentDate.value, description: documentDescription.value, } return tempActiviteDocumentValidator.omit({ tempDocumentName: true }).safeParse(tempDocument).success && activiteDocumentFile.value !== null @@ -94,7 +83,6 @@ export const AddActiviteDocumentPopup = caminoDefineComponent<Props>(['close', ' close={() => { const tempDocument: Nullable<TempActiviteDocument> = { activite_document_type_id: activiteDocumentTypeId.value, - date: documentDate.value, description: documentDescription.value, tempDocumentName: tempDocumentName.value, } diff --git a/packages/ui/src/components/activite/preview.tsx b/packages/ui/src/components/activite/preview.tsx index 56090a5bd..6a340ecc8 100644 --- a/packages/ui/src/components/activite/preview.tsx +++ b/packages/ui/src/components/activite/preview.tsx @@ -24,7 +24,6 @@ interface Props { const documentColumns = [ { id: 'activiteDocumentTypeId', name: 'Nom', noSort: true }, - { id: 'date', name: 'Date', noSort: true }, { id: 'description', name: 'Description', noSort: true }, ] as const satisfies readonly Column[] @@ -69,7 +68,6 @@ export const Preview = defineComponent<Props>(props => { props: { activiteDocumentId: document.id, activiteDocumentTypeId: document.activite_document_type_id }, value: document.activite_document_type_id, }, - date: { value: dateFormat(document.date) }, description: { value: document.description ?? '' }, }, })) diff --git a/packages/ui/src/components/etape-edition.vue b/packages/ui/src/components/etape-edition.vue index 7cec758aa..aa1666f8f 100644 --- a/packages/ui/src/components/etape-edition.vue +++ b/packages/ui/src/components/etape-edition.vue @@ -208,11 +208,7 @@ export default { }, async reroute(titreEtapeId) { - const tabId = this.demarcheType?.travaux === true ? 'travaux' : 'demarches' - - this.$store.commit('titre/open', { section: 'etapes', id: titreEtapeId }) - this.$store.commit('titre/openTab', tabId) - + // TODO 2023-09-21 il faut automatiquement déplier l'étape et aller sur l'ancre await this.$router.push({ name: 'titre', params: { id: this.titre.id }, diff --git a/packages/ui/src/components/titre.vue b/packages/ui/src/components/titre.vue index 0709f0ca9..cb8e70feb 100644 --- a/packages/ui/src/components/titre.vue +++ b/packages/ui/src/components/titre.vue @@ -69,6 +69,9 @@ import TitreDemarches from './titre/demarches.vue' import { TitreActivitesList } from './activites/titre-activites-list' import { defineAsyncComponent } from 'vue' import { apiClient } from '@/api/api-client' +import { canReadTitreActivites } from 'camino-common/src/permissions/activites' +import { isSuper } from 'camino-common/src/roles' +import { canCreateTravaux } from 'camino-common/src/permissions/titres-demarches' export default { components: { @@ -91,6 +94,8 @@ export default { return { geoTabId: 'carte', show: false, + tabs: [], + tabId: 'demarches', } }, @@ -107,14 +112,6 @@ export default { return !!this.titre }, - tabs() { - return this.$store.getters['titre/tabs'] - }, - - tabId() { - return this.$store.getters['titre/tabId'] - }, - demarches() { return this.$store.getters['titre/demarches'] }, @@ -130,8 +127,6 @@ export default { this.get() } }, - - user: 'get', }, async created() { @@ -160,6 +155,29 @@ export default { async get() { const titreId = this.$route.params.id await this.$store.dispatch('titre/get', titreId) + + this.tabs = [{ id: 'demarches', nom: 'Droits miniers' }] + + if (this.titre) { + if ( + await canReadTitreActivites( + this.user, + () => Promise.resolve(this.titre.typeId), + () => Promise.resolve(this.titre.administrations), + () => Promise.resolve([...this.titre.titulaires.map(({ id }) => id), ...this.titre.amodiataires.map(({ id }) => id)]) + ) + ) { + this.tabs.push({ id: 'activites', nom: 'Activités' }) + } + + if (this.travaux.length || canCreateTravaux(this.user, this.titre.typeId, this.titre.administrations)) { + this.tabs.push({ id: 'travaux', nom: 'Travaux' }) + } + } + + if (isSuper(this.user)) { + this.tabs.push({ id: 'journaux', nom: 'Journaux' }) + } }, tabUpdate(tabId) { @@ -169,7 +187,7 @@ export default { nom: this.$store.state.titre.element.id, }) - this.$store.commit('titre/openTab', tabId) + this.tabId = tabId }, geoTabUpdate(tabId) { diff --git a/packages/ui/src/components/titre/demarche.vue b/packages/ui/src/components/titre/demarche.vue index 91098f5cf..2bc5c1510 100644 --- a/packages/ui/src/components/titre/demarche.vue +++ b/packages/ui/src/components/titre/demarche.vue @@ -52,7 +52,6 @@ :titreAdministrations="titreAdministrations" :user="user" @event-track="eventTrack" - @close="etapeClose(etape.id)" @toggle="etapeToggle(etape.id)" /> @@ -188,10 +187,6 @@ export default { }) }, - etapeClose(id) { - this.$store.commit('titre/close', { section: 'etapes', id }) - }, - etapeToggle(id) { this.$store.commit('titre/toggle', { section: 'etapes', id }) }, diff --git a/packages/ui/src/store/document.js b/packages/ui/src/store/document.js index 6f6cf6896..24f023df7 100644 --- a/packages/ui/src/store/document.js +++ b/packages/ui/src/store/document.js @@ -85,18 +85,9 @@ const actions = { } }, - async refreshAfterUpsert({ commit, dispatch }, { route, idOld, titreEtapeId, document, action }) { + async refreshAfterUpsert({ dispatch }, { route, idOld, document, action }) { if (route) { await dispatch('reload', route, { root: true }) - - if (route.name === 'titre') { - const section = route.section - let id - - if (section === 'etapes') id = titreEtapeId - - commit('titre/open', { section, id }, { root: true }) - } } else if (action) { const params = { ...action.params, document } diff --git a/packages/ui/src/store/metas-definitions.ts b/packages/ui/src/store/metas-definitions.ts index b019be520..05ebc828c 100644 --- a/packages/ui/src/store/metas-definitions.ts +++ b/packages/ui/src/store/metas-definitions.ts @@ -1,6 +1,5 @@ import { etapesTypes, documentsTypes, titresTypesDemarchesTypesEtapesTypes, etapesTypesDocumentsTypes } from '@/api/metas' -import { activitesTypes } from '@/api/metas-activites' import { FREQUENCES_IDS } from 'camino-common/src/static/frequence' import { Domaines } from 'camino-common/src/static/domaines' import { TitresTypesTypes } from 'camino-common/src/static/titresTypesTypes' @@ -15,6 +14,7 @@ import { TDEDocumentsTypesMetas } from 'camino-common/src/static/titresTypes_dem import { EtapesStatuts } from 'camino-common/src/static/etapesStatuts' import { etapesTypesEtapesStatutsMetas } from 'camino-common/src/static/etapesTypesEtapesStatuts' import { TitresTypes } from 'camino-common/src/static/titresTypes' +import { sortedActivitesTypes } from 'camino-common/src/static/activitesTypes' const labelGet = (entity?: { id: string; nom: string }) => (entity ? `${entity.id} - ${entity.nom}` : '') @@ -357,7 +357,7 @@ export const metasIndex = { ], }, 'activites-types': { - get: activitesTypes, + get: () => sortedActivitesTypes, labelGet, nom: 'Types des activités', colonnes: [ diff --git a/packages/ui/src/store/titre.js b/packages/ui/src/store/titre.js index bcae2138c..d80c421a0 100644 --- a/packages/ui/src/store/titre.js +++ b/packages/ui/src/store/titre.js @@ -1,10 +1,7 @@ -import { canReadActivites } from 'camino-common/src/permissions/activites' import { titre, titreCreer } from '../api/titres' import router from '../router' -import { canCreateTravaux } from 'camino-common/src/permissions/titres-demarches' import { DemarchesTypes } from 'camino-common/src/static/demarchesTypes' -import { getDownloadRestRoute } from '@/api/client-rest' const state = { element: null, @@ -13,40 +10,9 @@ const state = { activites: {}, travaux: {}, }, - tabId: 'demarches', } const getters = { - tabId(state, getters) { - const tabIds = getters.tabs.map(({ id }) => id) - - if (!tabIds.includes(state.tabId)) { - return tabIds[0] - } - - return state.tabId - }, - - tabs(state, getters, rootState, rootGetters) { - const tabs = [{ id: 'demarches', nom: 'Droits miniers' }] - - if (state.element) { - if (canReadActivites(rootState.user.element)) { - tabs.push({ id: 'activites', nom: 'Activités' }) - } - - if (getters.travaux.length || canCreateTravaux(rootState.user.element, state.element.typeId, state.element.administrations)) { - tabs.push({ id: 'travaux', nom: 'Travaux' }) - } - } - - if (rootGetters['user/userIsSuper']) { - tabs.push({ id: 'journaux', nom: 'Journaux' }) - } - - return tabs - }, - demarches(state) { return state.element?.demarches?.filter(d => !DemarchesTypes[d.typeId].travaux) || [] }, @@ -112,14 +78,6 @@ const mutations = { state.element = null }, - open(state, { section, id }) { - if (!state.opened[section][id]) { - state.opened[section][id] = true - } - - state.tabId = section - }, - close(state, { section, id }) { if (state.opened[section][id]) { state.opened[section][id] = false @@ -129,10 +87,6 @@ const mutations = { toggle(state, { section, id }) { state.opened[section][id] = !state.opened[section][id] }, - - openTab(state, tabId) { - state.tabId = tabId - }, } export default { diff --git a/packages/ui/src/store/titre.test.js b/packages/ui/src/store/titre.test.js index e7e41dabc..f5c713430 100644 --- a/packages/ui/src/store/titre.test.js +++ b/packages/ui/src/store/titre.test.js @@ -106,24 +106,6 @@ describe('état du titre sélectionné', () => { expect(store.state.titre.element).toBeNull() }) - test('ouvre et ferme une section', () => { - store.commit('titre/open', { section: 'etapes', id: 'etape-id' }) - - expect(store.state.titre.opened.etapes['etape-id']).toBeTruthy() - - store.commit('titre/open', { section: 'etapes', id: 'etape-id' }) - - expect(store.state.titre.opened.etapes['etape-id']).toBeTruthy() - - store.commit('titre/close', { section: 'etapes', id: 'etape-id' }) - - expect(store.state.titre.opened.etapes['etape-id']).toBeFalsy() - - store.commit('titre/close', { section: 'etapes', id: 'etape-id' }) - - expect(store.state.titre.opened.etapes['etape-id']).toBeFalsy() - }) - test("permute l'ouverture une section", () => { expect(store.state.titre.opened.activites['activite-id']).toBeFalsy() store.commit('titre/toggle', { section: 'activites', id: 'activite-id' }) @@ -134,16 +116,4 @@ describe('état du titre sélectionné', () => { expect(store.state.titre.opened.activites['activite-id']).toBeFalsy() }) - - test('une seule tab est visible par défaut', () => { - expect(store.getters['titre/tabs']).toMatchObject([{ id: 'demarches' }]) - }) - - test('la tab des travaux est visible si il existe au moins un travaux', () => { - store.state.user = { ...testBlankUser, role: 'super' } - store.state.titre.element = { - demarches: [{ typeId: 'aom' }], - } - expect(store.getters['titre/tabs']).toMatchObject([{ id: 'demarches' }, { id: 'travaux' }]) - }) }) -- GitLab