Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajoute le champ Priorité du plan d’action au tableau des mesures #1646

Merged
merged 8 commits into from
Jul 30, 2024
2 changes: 2 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ BALEEN_NAMESPACE = # L'identifiant de l'application Baleen

# Feature Flags
FEATURE_FLAG_VISITE_GUIDEE= # Pour activer la visite guidée. Supprimer la variable d'env pour désactiver la feature.
VITE_FEATURE_FLAG_AVEC_PLAN_ACTION= # 'true' pour activer le plan d'action sur les mesures.
ThibaudMZN marked this conversation as resolved.
Show resolved Hide resolved


# Crisp
CRISP_ID_SITE= # L'identifiant "WebsiteID" de MonServiceSécurisé
Expand Down
8 changes: 7 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# TODO

- champ affiché sur le tableau, si feature flag
- onglet dans le tiroir
- champ dans le tiroir
- je peux enregistrer la valeur depuis le tiroir
- tester en lecture seule le tiroir
- filtre sur la priorité

# DONE

- champ affiché sur le tableau, si feature flag
- je peux enregistrer la valeur depuis le tableau
- tester en lecture seule le tableau
2 changes: 1 addition & 1 deletion src/modeles/mesureGenerale.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class MesureGenerale extends Mesure {
constructor(donneesMesure, referentiel) {
super({
proprietesAtomiquesRequises: ['id', 'statut'],
proprietesAtomiquesFacultatives: ['modalites'],
proprietesAtomiquesFacultatives: ['modalites', 'priorite'],
});

MesureGenerale.valide(donneesMesure, referentiel);
Expand Down
2 changes: 1 addition & 1 deletion src/modeles/mesureSpecifique.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MesureSpecifique extends Mesure {
) {
super({
proprietesAtomiquesRequises: MesureSpecifique.proprietesObligatoires(),
proprietesAtomiquesFacultatives: ['modalites'],
proprietesAtomiquesFacultatives: ['modalites', 'priorite'],
});

MesureSpecifique.valide(donneesMesure, referentiel);
Expand Down
5 changes: 3 additions & 2 deletions src/routes/connecte/routesConnecteApiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ const routesConnecteApiService = ({
'*.description',
'*.categorie',
'*.statut',
'*.modalites'
'*.modalites',
'*.priorite'
),
async (requete, reponse, suite) => {
// il ne faut pas utiliser params.id qui est modifié par le middleware aseptise
Expand Down Expand Up @@ -254,7 +255,7 @@ const routesConnecteApiService = ({
'/:id/mesures/:idMesure',
middleware.verificationAcceptationCGU,
middleware.trouveService({ [SECURISER]: ECRITURE }),
middleware.aseptise('statut', 'modalites'),
middleware.aseptise('statut', 'modalites', 'priorite'),
async (requete, reponse, suite) => {
const { service, idUtilisateurCourant, body, params } = requete;
const mesureGenerale = {
Expand Down
4 changes: 4 additions & 0 deletions svelte/lib/featureFlags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const featureFlags = {
planAction: () =>
import.meta.env.VITE_FEATURE_FLAG_AVEC_PLAN_ACTION === 'true',
};
2 changes: 1 addition & 1 deletion svelte/lib/tableauDesMesures/BandeauActions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</script>

<tr>
<th colspan="2">
<th colspan="3">
<div class="actions">
<button
class="bouton-action-mesure"
Expand Down
81 changes: 48 additions & 33 deletions svelte/lib/tableauDesMesures/TableauDesMesures.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import TagStatutMesure from '../ui/TagStatutMesure.svelte';
import BandeauActions from './BandeauActions.svelte';
import { afficheTiroirDeMesure } from './actionsTiroir';
import { featureFlags } from '../featureFlags';

const { Jamais, EnCours, Fait } = EtatEnregistrement;

Expand All @@ -53,18 +54,26 @@

let etatEnregistrement: EtatEnregistrement = Jamais;

const metsAJourMesuresSpecifiques = async (indexReel: number) => {
const metsAJourMesuresSpecifiques = async (
indexReel: number,
affichetoast: boolean = false
) => {
etatEnregistrement = EnCours;
await enregistreMesuresSpecifiques(idService, $mesures.mesuresSpecifiques);
etatEnregistrement = Fait;
document.body.dispatchEvent(new CustomEvent('mesure-modifiee'));
toasterStore.afficheToastChangementStatutMesure(
$mesures.mesuresSpecifiques[indexReel],
statuts
);
if (affichetoast) {
toasterStore.afficheToastChangementStatutMesure(
$mesures.mesuresSpecifiques[indexReel],
statuts
);
}
};

const metsAJourMesureGenerale = async (idMesure: IdMesureGenerale) => {
const metsAJourMesureGenerale = async (
idMesure: IdMesureGenerale,
affichetoast: boolean = false
) => {
etatEnregistrement = EnCours;
await enregistreMesureGenerale(
idService,
Expand All @@ -73,10 +82,13 @@
);
etatEnregistrement = Fait;
document.body.dispatchEvent(new CustomEvent('mesure-modifiee'));
toasterStore.afficheToastChangementStatutMesure(
$mesures.mesuresGenerales[idMesure],
statuts
);

if (affichetoast) {
toasterStore.afficheToastChangementStatutMesure(
$mesures.mesuresGenerales[idMesure],
statuts
);
}
if (
$volumetrieMesures.totalSansStatut === 0 &&
$rechercheParAvancement === 'statutADefinir'
Expand All @@ -88,6 +100,9 @@
const marqueNouveauteLue = async () => {
await storeNotifications.marqueLue('nouveaute', 'ongletStatutsMesures');
};

$: affichePlanAction =
$rechercheParAvancement !== 'statutADefinir' && featureFlags.planAction();
</script>

<svelte:body on:mesure-modifiee={rafraichisMesures} />
Expand Down Expand Up @@ -120,34 +135,26 @@
</span>
<br />
<p>
Les mesures <TagStatutMesure
statut="aLancer"
actif
referentielStatuts={statuts}
/> et
Les mesures
<TagStatutMesure statut="aLancer" actif referentielStatuts={statuts} />
et
<TagStatutMesure statut="enCours" actif referentielStatuts={statuts} />
sont désormais dans l’onglet <b>“En action”</b>
</p>
<p>
Les mesures <TagStatutMesure
statut="fait"
actif
referentielStatuts={statuts}
/> et
Les mesures
<TagStatutMesure statut="fait" actif referentielStatuts={statuts} />
et
<TagStatutMesure statut="nonFait" actif referentielStatuts={statuts} />
sont dans l’onglet <b>“Traité”</b>
</p>
</div>
</Avertissement>
{/if}
<table class="tableau-des-mesures">
<colgroup>
<col class="infos-mesures" />
<col class="statut-mesure" />
</colgroup>
<thead>
<tr class="ligne-onglet">
<th colspan="2">
<th colspan="3">
<div class="conteneur-onglet">
{#if $volumetrieMesures.totalSansStatut}
<Onglet
Expand Down Expand Up @@ -184,6 +191,9 @@
{#if !$nombreResultats.aucunResultat}
<tr class="titres">
<th>Mesure</th>
{#if affichePlanAction}
<th>Priorité</th>
{/if}
<th>Statut</th>
</tr>
{/if}
Expand All @@ -203,6 +213,10 @@
bind:mesure={$mesures.mesuresGenerales[id]}
on:modificationStatut={(e) => {
mesures.metAJourStatutMesureGenerale(id, e.detail.statut);
metsAJourMesureGenerale(id, true);
}}
on:modificationPriorite={(e) => {
mesures.metAJourPrioriteMesureGenerale(id, e.detail.priorite);
metsAJourMesureGenerale(id);
}}
on:click={() =>
Expand All @@ -211,6 +225,7 @@
metadonnees: { typeMesure: 'GENERALE', idMesure: id },
})}
estLectureSeule={estLectureSeule || etatEnregistrement === EnCours}
{affichePlanAction}
/>
{/each}
{#each $resultatsDeRecherche.mesuresSpecifiques as mesure, index (index)}
Expand All @@ -224,6 +239,13 @@
bind:mesure={$mesures.mesuresSpecifiques[indexReel]}
on:modificationStatut={(e) => {
mesures.metAJourStatutMesureSpecifique(indexReel, e.detail.statut);
metsAJourMesuresSpecifiques(indexReel, true);
}}
on:modificationPriorite={(e) => {
mesures.metAJourPrioriteMesureSpecifique(
indexReel,
e.detail.priorite
);
metsAJourMesuresSpecifiques(indexReel);
}}
on:click={() =>
Expand All @@ -232,6 +254,7 @@
metadonnees: { typeMesure: 'SPECIFIQUE', idMesure: indexReel },
})}
estLectureSeule={estLectureSeule || etatEnregistrement === EnCours}
{affichePlanAction}
/>
{/each}
{/if}
Expand Down Expand Up @@ -267,14 +290,6 @@
border-collapse: collapse;
}

colgroup .infos-mesures {
width: 80%;
}

colgroup .statut-mesure {
width: 20%;
}

thead tr th {
padding: 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</script>

<tr class="ligne-aucun-resultat">
<td colspan="2">
<td>
<div class="aucun-resultat">
{#if $nombreResultats.aDesFiltresAppliques || $rechercheTextuelle}
<img
Expand Down
20 changes: 19 additions & 1 deletion svelte/lib/tableauDesMesures/ligne/LigneMesure.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
MesureSpecifique,
} from '../tableauDesMesures.d';
import CartoucheReferentiel from '../../ui/CartoucheReferentiel.svelte';
import { Referentiel, type ReferentielStatut } from '../../ui/types.d';
import {
type PrioriteMesure,
Referentiel,
type ReferentielStatut,
} from '../../ui/types.d';
import SelectionStatut from '../../ui/SelectionStatut.svelte';
import CartoucheIndispensable from '../../ui/CartoucheIndispensable.svelte';
import CartoucheIdentifiantMesure from '../../ui/CartoucheIdentifiantMesure.svelte';
import { rechercheTextuelle } from '../stores/rechercheTextuelle.store';
import SelectionPriorite from '../../ui/SelectionPriorite.svelte';

type IdDom = string;

Expand All @@ -21,9 +26,11 @@
export let categorie: string;
export let referentielStatuts: ReferentielStatut;
export let estLectureSeule: boolean;
export let affichePlanAction: boolean;

const dispatch = createEventDispatcher<{
modificationStatut: { statut: string };
modificationPriorite: { priorite: PrioriteMesure | undefined };
}>();

$: texteSurligne = nom.replace(
Expand All @@ -46,6 +53,17 @@
<CartoucheIdentifiantMesure identifiant={mesure.identifiantNumerique} />
</div>
</td>
{#if affichePlanAction}
<td>
<SelectionPriorite
bind:priorite={mesure.priorite}
{id}
{estLectureSeule}
on:input={(e) =>
dispatch('modificationPriorite', { priorite: e.detail.priorite })}
/>
</td>
{/if}
<td>
<SelectionStatut
bind:statut={mesure.statut}
Expand Down
19 changes: 19 additions & 0 deletions svelte/lib/tableauDesMesures/stores/mesures.store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Mesures } from '../tableauDesMesures.d';
import { writable } from 'svelte/store';
import type { PrioriteMesure } from '../../ui/types';

export const mesuresParDefaut = (): Mesures => ({
mesuresGenerales: {},
Expand All @@ -23,4 +24,22 @@ export const mesures = {
valeur.mesuresSpecifiques[idMesure].statut = statut;
return valeur;
}),
metAJourPrioriteMesureGenerale: (
idMesure: string,
priorite: PrioriteMesure | undefined
) => {
toutesLesMesures.update((valeur) => {
valeur.mesuresGenerales[idMesure].priorite = priorite;
return valeur;
});
},
metAJourPrioriteMesureSpecifique: (
idMesure: number,
priorite: PrioriteMesure | undefined
) => {
toutesLesMesures.update((valeur) => {
valeur.mesuresSpecifiques[idMesure].priorite = priorite;
return valeur;
});
},
};
1 change: 1 addition & 0 deletions svelte/lib/tableauDesMesures/tableauDesMesures.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const enregistreMesureGenerale = async (
) => {
await axios.put(`/api/service/${idService}/mesures/${idMesure}`, {
statut: donneesMesure.statut,
priorite: donneesMesure.priorite,
...(donneesMesure.modalites && { modalites: donneesMesure.modalites }),
});
};
4 changes: 3 additions & 1 deletion svelte/lib/tableauDesMesures/tableauDesMesures.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Referentiel } from '../ui/types.d';
import { type PrioriteMesure, Referentiel } from '../ui/types.d';

declare global {
interface HTMLElementEventMap {
Expand Down Expand Up @@ -27,6 +27,7 @@ export type MesureGenerale = {
modalites?: string;
referentiel: Referentiel;
identifiantNumerique: string;
priorite?: PrioriteMesure;
};

export type MesureSpecifique = {
Expand All @@ -35,6 +36,7 @@ export type MesureSpecifique = {
statut: string;
modalites: string;
identifiantNumerique: string;
priorite?: PrioriteMesure;
};

export type IdMesureGenerale = string;
Expand Down
Loading
Loading