Skip to content

Commit

Permalink
✨ Ajout du lien vers la liste des dépôts en cours des GF (#1692)
Browse files Browse the repository at this point in the history
* ♻️ Better split in permissions gf

* 🎨 Add menu link for depot in progress in SSR

* 🎨 Conditionnal display link to legacy pages or new page based on feature flag

* 🎨 Conditionnal link on legacy app

* 🚩 Update name of gf feature flag

* Change permission legacy

* Update packages/libraries/routes/src/garanties-financières/garantiesFinancières.routes.ts

Co-authored-by: HanaeY <[email protected]>

* 🔥 Remove feature flags from .envs

* 🎨 Add @potentiel-applications/feature-flags and use it in legacy / ssr

* 📦️ Update lock

* 🐛 Fix bad package name

---------

Co-authored-by: HanaeY <[email protected]>
  • Loading branch information
HubM and HanaeY authored Apr 4, 2024
1 parent f0b1396 commit 43e8cf8
Show file tree
Hide file tree
Showing 23 changed files with 436 additions and 546 deletions.
471 changes: 139 additions & 332 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"./packages/applications/scheduled-tasks",
"./packages/applications/notifications",
"./packages/applications/projectors",
"./packages/applications/feature-flags/",
"./packages/applications/bootstrap",
"./packages/applications/ssr",
"./packages/applications/legacy",
Expand Down
18 changes: 18 additions & 0 deletions packages/applications/feature-flags/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@potentiel-applications/feature-flags",
"version": "0.0.0",
"description": "Feature flag system",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"private": true,
"scripts": {
"build": "tsc"
},
"devDependencies": {
"@potentiel-config/tsconfig": "*"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.405.0",
"@aws-sdk/lib-storage": "^3.405.0"
}
}
7 changes: 7 additions & 0 deletions packages/applications/feature-flags/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type FeatureFlags = {
SHOW_GARANTIES_FINANCIERES?: true;
};

export const featureFlags: FeatureFlags = {
SHOW_GARANTIES_FINANCIERES: true,
};
8 changes: 8 additions & 0 deletions packages/applications/feature-flags/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "@potentiel-config/tsconfig/tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"references": []
}
2 changes: 1 addition & 1 deletion packages/applications/legacy/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ NEXT_AUTH_SESSION_TOKEN_COOKIE_NAME=next-auth.session-token
SENTRY_DSN=

# UMAMI
TRACKER_WEBSITE_ID=
TRACKER_WEBSITE_ID=
1 change: 1 addition & 0 deletions packages/applications/legacy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@potentiel-infrastructure/pg-event-sourcing": "*",
"@potentiel-domain/laureat": "*",
"@potentiel-domain/reseau": "*",
"@potentiel-applications/feature-flags": "*",
"aws-sdk": "^2.1450.0",
"cookie-parser": "^1.4.6",
"connect-session-sequelize": "^7.1.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ const getGarantiesFinancieresPage = asyncHandler(async (request, response) => {

v1Router.get(
routes.ADMIN_GARANTIES_FINANCIERES,
ensureRole(['dreal']),
ensureRole(['dreal', 'dgec-validateur', 'admin']),
getGarantiesFinancieresPage,
);
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Project } from '../../infra/sequelize';
import { Abandon, GarantiesFinancières } from '@potentiel-domain/laureat';
import { IdentifiantProjet } from '@potentiel-domain/common';
import { Raccordement } from '@potentiel-domain/reseau';

import { featureFlags } from '@potentiel-applications/feature-flags';
const schema = yup.object({
params: yup.object({ projectId: yup.string().required() }),
});
Expand Down Expand Up @@ -143,7 +143,7 @@ v1Router.get(
let garantiesFinancières: ProjectDataForProjectPage['garantiesFinancières'] | undefined =
undefined;

if (projet.appelOffre.isSoumisAuxGF && process.env.FEATURE_FLAG_SHOW_GARANTIES_FINANCIERES) {
if (projet.appelOffre.isSoumisAuxGF && featureFlags.SHOW_GARANTIES_FINANCIERES) {
garantiesFinancières = await getGarantiesFinancières(identifiantProjetValueType);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { Header } from './Header';
import { DropdownMenu } from '../molecules/dropdowns/DropdownMenu';
import { UtilisateurReadModel } from '../../../../modules/utilisateur/récupérer/UtilisateurReadModel';
import { Routes } from '@potentiel-applications/routes';
import { featureFlags } from '@potentiel-applications/feature-flags';

const routeListeGarantiesFinancières = featureFlags.SHOW_GARANTIES_FINANCIERES
? Routes.GarantiesFinancières.dépôt.lister
: routes.ADMIN_GARANTIES_FINANCIERES;

export const UserNavigation = ({
user,
Expand Down Expand Up @@ -86,6 +91,12 @@ const MenuAdmin = (currentPage?: string) => (
Abandons
</DropdownMenu.DropdownItem>
</DropdownMenu>
<Header.MenuItem
href={routeListeGarantiesFinancières}
{...(currentPage === 'list-garanties-financieres' && { isCurrent: true })}
>
Garanties Financières
</Header.MenuItem>
<DropdownMenu buttonChildren={'Imports'}>
<DropdownMenu.DropdownItem
href={routes.IMPORT_PROJECTS}
Expand Down Expand Up @@ -265,7 +276,7 @@ const MenuDreal = (currentPage?: string) => (
</DropdownMenu.DropdownItem>
</DropdownMenu>
<Header.MenuItem
href={routes.ADMIN_GARANTIES_FINANCIERES}
href={routeListeGarantiesFinancières}
{...(currentPage === 'list-garanties-financieres' && { isCurrent: true })}
>
Garanties Financières
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const dépôt = {
`/laureats/${encodeParameter(identifiantProjet)}/garanties-financieres/depot:soumettre`,
modifier: (identifiantProjet: string) =>
`/laureats/${encodeParameter(identifiantProjet)}/garanties-financieres/depot:modifier`,
lister: `/garanties-financieres/depots-en-cours`,
};

export const actuelles = {
Expand Down
2 changes: 0 additions & 2 deletions packages/applications/ssr/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=fake-secret
NEXT_AUTH_SESSION_TOKEN_COOKIE_NAME=next-auth.session-token

# Feature flags
FEATURE_FLAG_GARANTIES_FINANCIERES=true
1 change: 1 addition & 0 deletions packages/applications/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@emotion/styled": "*",
"@mui/lab": "*",
"@mui/material": "*",
"@potentiel-applications/feature-flags": "*",
"@potentiel-domain/appel-offre": "*",
"@potentiel-domain/candidature": "*",
"@potentiel-domain/document": "*",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { mediator } from 'mediateur';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';

import { ListerAppelOffreQuery } from '@potentiel-domain/appel-offre';
import { GarantiesFinancières } from '@potentiel-domain/laureat';
import { featureFlags } from '@potentiel-applications/feature-flags';

import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';
import {
GarantiesFinancièresDépôtsEnCoursListPage,
GarantiesFinancièresDépôtsEnCoursListProps,
} from '@/components/pages/garanties-financières/dépôt/lister/GarantiesFinancièresDépôtsEnCoursList.page';
import { getGarantiesFinancièresTypeLabel } from '@/components/pages/garanties-financières/getGarantiesFinancièresTypeLabel';
import { withUtilisateur } from '@/utils/withUtilisateur';

type PageProps = {
searchParams?: Record<string, string>;
};

export const metadata: Metadata = {
title: 'Garanties financières en cours - Potentiel',
description: 'Liste des garanties financières en cours',
};

export default async function Page({ searchParams }: PageProps) {
if (!featureFlags.SHOW_GARANTIES_FINANCIERES) {
return notFound();
}

return PageWithErrorHandling(async () =>
withUtilisateur(async (utilisateur) => {
const page = searchParams?.page ? parseInt(searchParams.page) : 1;
const appelOffre = searchParams?.appelOffre;

const dépôtsEnCoursGarantiesFinancières =
await mediator.send<GarantiesFinancières.ListerDépôtsEnCoursGarantiesFinancièresQuery>({
type: 'Lauréat.GarantiesFinancières.Query.ListerDépôtsEnCoursGarantiesFinancières',
data: {
utilisateur: {
email: utilisateur.identifiantUtilisateur.email,
rôle: utilisateur.role.nom,
},
...(appelOffre && { appelOffre }),
pagination: { page, itemsPerPage: 10 },
},
});

const appelOffres = await mediator.send<ListerAppelOffreQuery>({
type: 'AppelOffre.Query.ListerAppelOffre',
data: {},
});

const filters = [
{
label: `Appel d'offres`,
searchParamKey: 'appelOffre',
defaultValue: appelOffre,
options: appelOffres.items.map((appelOffre) => ({
label: appelOffre.id,
value: appelOffre.id,
})),
},
];

return (
<GarantiesFinancièresDépôtsEnCoursListPage
list={mapToListProps(dépôtsEnCoursGarantiesFinancières)}
filters={filters}
/>
);
}),
);
}

const mapToListProps = (
readModel: GarantiesFinancières.ListerDépôtsEnCoursGarantiesFinancièresReadModel,
): GarantiesFinancièresDépôtsEnCoursListProps['list'] => {
const items = readModel.items.map(
({
identifiantProjet,
appelOffre,
période,
famille,
nomProjet,
régionProjet,
dépôt: { type, dateÉchéance, dernièreMiseÀJour, statut },
}) => ({
identifiantProjet: identifiantProjet.formatter(),
nomProjet,
appelOffre,
période,
famille,
statut: statut.statut,
misÀJourLe: dernièreMiseÀJour.date.formatter(),
type: getGarantiesFinancièresTypeLabel(type.type),
dateÉchéance: dateÉchéance?.formatter(),
régionProjet,
}),
);

return {
items,
currentPage: readModel.currentPage,
itemsPerPage: readModel.itemsPerPage,
totalItems: readModel.totalItems,
};
};
109 changes: 7 additions & 102 deletions packages/applications/ssr/src/app/garanties-financieres/page.tsx
Original file line number Diff line number Diff line change
@@ -1,107 +1,12 @@
import { mediator } from 'mediateur';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { notFound, redirect } from 'next/navigation';

import { ListerAppelOffreQuery } from '@potentiel-domain/appel-offre';
import { GarantiesFinancières } from '@potentiel-domain/laureat';
import { featureFlags } from '@potentiel-applications/feature-flags';
import { Routes } from '@potentiel-applications/routes';

import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';
import {
GarantiesFinancièresDépôtsEnCoursListPage,
GarantiesFinancièresDépôtsEnCoursListProps,
} from '@/components/pages/garanties-financières/dépôt/lister/GarantiesFinancièresDépôtsEnCoursList.page';
import { getGarantiesFinancièresTypeLabel } from '@/components/pages/garanties-financières/getGarantiesFinancièresTypeLabel';
import { withUtilisateur } from '@/utils/withUtilisateur';

type PageProps = {
searchParams?: Record<string, string>;
};

export const metadata: Metadata = {
title: 'Garanties financières à traiter - Potentiel',
description: 'Liste des garanties financières à traiter',
};

export default async function Page({ searchParams }: PageProps) {
if (!process.env.FEATURE_FLAG_GARANTIES_FINANCIERES) {
return notFound();
export default async function Page() {
if (featureFlags.SHOW_GARANTIES_FINANCIERES) {
return redirect(Routes.GarantiesFinancières.dépôt.lister);
}

return PageWithErrorHandling(async () =>
withUtilisateur(async (utilisateur) => {
const page = searchParams?.page ? parseInt(searchParams.page) : 1;
const appelOffre = searchParams?.appelOffre;

const dépôtsEnCoursGarantiesFinancières =
await mediator.send<GarantiesFinancières.ListerDépôtsEnCoursGarantiesFinancièresQuery>({
type: 'Lauréat.GarantiesFinancières.Query.ListerDépôtsEnCoursGarantiesFinancières',
data: {
utilisateur: {
email: utilisateur.identifiantUtilisateur.email,
rôle: utilisateur.role.nom,
},
...(appelOffre && { appelOffre }),
pagination: { page, itemsPerPage: 10 },
},
});

const appelOffres = await mediator.send<ListerAppelOffreQuery>({
type: 'AppelOffre.Query.ListerAppelOffre',
data: {},
});

const filters = [
{
label: `Appel d'offres`,
searchParamKey: 'appelOffre',
defaultValue: appelOffre,
options: appelOffres.items.map((appelOffre) => ({
label: appelOffre.id,
value: appelOffre.id,
})),
},
];

return (
<GarantiesFinancièresDépôtsEnCoursListPage
list={mapToListProps(dépôtsEnCoursGarantiesFinancières)}
filters={filters}
/>
);
}),
);
return notFound();
}

const mapToListProps = (
readModel: GarantiesFinancières.ListerDépôtsEnCoursGarantiesFinancièresReadModel,
): GarantiesFinancièresDépôtsEnCoursListProps['list'] => {
const items = readModel.items.map(
({
identifiantProjet,
appelOffre,
période,
famille,
nomProjet,
régionProjet,
dépôt: { type, dateÉchéance, dernièreMiseÀJour, statut },
}) => ({
identifiantProjet: identifiantProjet.formatter(),
nomProjet,
appelOffre,
période,
famille,
statut: statut.statut,
misÀJourLe: dernièreMiseÀJour.date.formatter(),
type: getGarantiesFinancièresTypeLabel(type.type),
dateÉchéance: dateÉchéance?.formatter(),
régionProjet,
}),
);

return {
items,
currentPage: readModel.currentPage,
itemsPerPage: readModel.itemsPerPage,
totalItems: readModel.totalItems,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { mediator } from 'mediateur';
import { notFound } from 'next/navigation';

import { ConsulterCandidatureQuery } from '@potentiel-domain/candidature';
import { featureFlags } from '@potentiel-applications/feature-flags';

import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';
import { decodeParameter } from '@/utils/decodeParameter';
Expand All @@ -20,7 +21,7 @@ export const metadata: Metadata = {
};

export default async function Page({ params: { identifiant } }: IdentifiantParameter) {
if (!process.env.FEATURE_FLAG_GARANTIES_FINANCIERES) {
if (!featureFlags.SHOW_GARANTIES_FINANCIERES) {
return notFound();
}

Expand Down
Loading

0 comments on commit 43e8cf8

Please sign in to comment.