Skip to content

Commit 049c8b0

Browse files
bellangerqhissalht
andauthored
Permet de réordonner les pages de l'échantillon (#613)
* add select to change pages order * update order or pages when updating select * focus endIndex select after order change * fix select label index * delete old css class * sort report pages in the correct order * add order property to audit pages * order pages in report statement and report errors * Update confiture-rest-api/src/audits/audit.service.ts Co-authored-by: Adrien Boutigny <adrien@slash-tmp.dev> * Update confiture-rest-api/src/audits/audit.service.ts Co-authored-by: Adrien Boutigny <adrien@slash-tmp.dev> * Update confiture-rest-api/src/audits/audit.service.ts Co-authored-by: Adrien Boutigny <adrien@slash-tmp.dev> * remove order from dto * merge migrations * vocally announce page position changes * order tabs by pages order * fix page type * fix page type * simplfiy swapping pages * trigger heroku deployment * update changelog --------- Co-authored-by: Adrien Boutigny <adrien@slash-tmp.dev>
1 parent 2e69e23 commit 049c8b0

11 files changed

Lines changed: 161 additions & 61 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Tous les changements notables de Ara sont documentés ici avec leur date, leur c
44

55
## 25/01/2024
66

7+
### Nouvelles fonctionnalités 🚀
8+
9+
- Ajoute la possibilité de changer l’ordre des pages de l’échantilloon depuis les paramètres de l’audit ([#613](https://github.com/DISIC/Ara/pull/613))
10+
711
### Corrections 🐛
812

913
- Corrige la navigation au clavier des onglets des pages de l’audit ([#625](https://github.com/DISIC/Ara/pull/625))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "AuditedPage" ADD COLUMN "order" INTEGER NOT NULL DEFAULT 0;

confiture-rest-api/prisma/schema.prisma

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ model TestEnvironment {
103103
}
104104

105105
model AuditedPage {
106-
id Int @id @default(autoincrement())
107-
name String
108-
url String
106+
id Int @id @default(autoincrement())
107+
order Int @default(0)
108+
name String
109+
url String
109110
110111
audit Audit? @relation(fields: [auditUniqueId], references: [editUniqueId], onDelete: Cascade)
111112
auditUniqueId String?
@@ -220,11 +221,11 @@ model User {
220221
orgName String?
221222
222223
/// @DtoEntityHidden
223-
newEmail String?
224+
newEmail String?
224225
/// @DtoEntityHidden
225226
newEmailVerificationJti String?
226227
}
227228

228229
model ActiveFeedbackToken {
229230
uid String @id
230-
}
231+
}

confiture-rest-api/src/audits/audit.service.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ export class AuditService {
6161

6262
pages: {
6363
createMany: {
64-
data: data.pages
64+
data: data.pages.map((p, i) => {
65+
return { ...p, order: i };
66+
})
6567
}
6668
},
6769

@@ -183,8 +185,9 @@ export class AuditService {
183185
data: UpdateAuditDto
184186
): Promise<Audit | undefined> {
185187
try {
186-
const updatedPages = data.pages.filter((p) => p.id);
187-
const newPages = data.pages.filter((p) => !p.id);
188+
const orderedPages = data.pages.map((p, i) => ({ ...p, order: i }));
189+
const updatedPages = orderedPages.filter((p) => p.id);
190+
const newPages = orderedPages.filter((p) => !p.id);
188191

189192
const [audit] = await this.prisma.$transaction([
190193
this.prisma.audit.update({
@@ -302,12 +305,14 @@ export class AuditService {
302305
update: updatedPages.map((p) => ({
303306
where: { id: p.id },
304307
data: {
308+
order: p.order,
305309
name: p.name,
306310
url: p.url
307311
}
308312
})),
309313
createMany: {
310314
data: newPages.map((p) => ({
315+
order: p.order,
311316
name: p.name,
312317
url: p.url
313318
}))
@@ -784,12 +789,15 @@ export class AuditService {
784789
browserVersion: e.browserVersion
785790
})),
786791
referencial: "RGAA Version 4.1",
787-
samples: audit.pages.map((p, i) => ({
788-
name: p.name,
789-
number: i + 1,
790-
url: p.url,
791-
id: p.id
792-
})),
792+
samples: audit.pages
793+
.map((p, i) => ({
794+
name: p.name,
795+
order: p.order,
796+
number: i + 1,
797+
url: p.url,
798+
id: p.id
799+
}))
800+
.sort((p) => p.order),
793801
tools: audit.tools,
794802
technologies: audit.technologies
795803
},

confiture-rest-api/src/audits/dto/audit-report.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class ReportContext {
133133
class PageSample {
134134
id: number;
135135
number: number;
136+
order: number;
136137
name: string;
137138
url: string;
138139
}

confiture-rest-api/src/audits/dto/create-audit.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class CreateAuditPage {
1818
@IsNumber()
1919
@IsOptional()
2020
id?: number;
21+
2122
/**
2223
* @example "Page de contact"
2324
*/

confiture-web-app/src/components/audit/AuditGeneralInformationsForm.vue

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,56 @@ async function deletePage(i: number) {
137137
}
138138
}
139139
140+
const pageOrderSelectRefs = ref<HTMLSelectElement[]>();
141+
142+
const positionSuccessMessage = ref("");
143+
144+
/**
145+
* Change the order of pages. Swap pages if it is adjacent.
146+
* Otherwise, insert `startIndex` page at `endIndex` position.
147+
* @param {number} startIndex
148+
* @param {number} endIndex
149+
* @example
150+
* Given [1, 2, 3, 4] and if updatePageOrder(1, 3), new order will be [1, 4, 2, 3].
151+
*/
152+
function updatePageOrder(startIndex: number, endIndex: number) {
153+
positionSuccessMessage.value = "";
154+
pagesArePristine.value = false;
155+
156+
const defaultState = [...pages.value];
157+
const startEl = defaultState[startIndex];
158+
159+
if (startIndex === endIndex + 1 || startIndex === endIndex - 1) {
160+
// Swap 2 adjacent pages
161+
const temp = pages.value[startIndex];
162+
pages.value[startIndex] = pages.value[endIndex];
163+
pages.value[endIndex] = temp;
164+
} else {
165+
// Insert startIndex and endIndex
166+
pages.value =
167+
startIndex < endIndex
168+
? [
169+
...defaultState.slice(0, startIndex),
170+
...defaultState.slice(startIndex + 1, endIndex + 1),
171+
startEl,
172+
...defaultState.slice(endIndex + 1)
173+
]
174+
: [
175+
...defaultState.slice(0, endIndex),
176+
startEl,
177+
...defaultState.slice(endIndex, startIndex),
178+
...defaultState.slice(startIndex + 1)
179+
];
180+
}
181+
182+
// Focus `endIndex` select
183+
pageOrderSelectRefs.value?.at(endIndex)?.focus();
184+
185+
positionSuccessMessage.value = `Page déplacée en position ${
186+
endIndex + 1
187+
} sur ${pages.value.length}`;
188+
}
189+
140190
/**
141191
* Dev function to avoid filling all fields manually
142192
*/
@@ -159,7 +209,7 @@ function onSubmit() {
159209
emit("submit", {
160210
auditType: auditType.value!,
161211
procedureName: procedureName.value,
162-
// remove leading/trailing whitespaces from urls, the browser valifation might accept those our backend won't !
212+
// remove leading/trailing whitespaces from urls, the browser validation might accept those our backend won't!
163213
pages: pages.value.map((p) => ({ ...p, url: p.url.trim() })),
164214
auditorName: procedureAuditorName.value,
165215
auditorEmail: formatEmail(procedureAuditorEmail.value)
@@ -255,16 +305,44 @@ const previousRoute = usePreviousRoute();
255305
<h3 class="fr-h6 fr-mb-0">Page {{ i + 1 }}</h3>
256306
</legend>
257307

258-
<button
259-
class="fr-btn fr-btn--tertiary-no-outline page-delete-button"
260-
type="button"
261-
:disabled="pages.length === 1"
262-
data-cy="delete"
263-
@click="deletePage(i)"
264-
>
265-
Supprimer
266-
<span class="sr-only">la page {{ i + 1 }}</span>
267-
</button>
308+
<div class="page-right-actions">
309+
<button
310+
class="fr-btn fr-btn--icon-left fr-icon-delete-line fr-btn--tertiary-no-outline"
311+
type="button"
312+
:disabled="pages.length === 1"
313+
data-cy="delete"
314+
@click="deletePage(i)"
315+
>
316+
Supprimer
317+
<span class="sr-only">la page {{ i + 1 }}</span>
318+
</button>
319+
320+
<div class="fr-select-group fr-mb-0">
321+
<label class="fr-label sr-only" :for="`page-order-${i}`">
322+
Position de la page {{ i + 1 }}
323+
</label>
324+
<select
325+
:id="`page-order-${i}`"
326+
ref="pageOrderSelectRefs"
327+
class="fr-select fr-mt-0"
328+
:value="i"
329+
@change="
330+
updatePageOrder(
331+
i,
332+
Number(($event.target as HTMLSelectElement).value)
333+
)
334+
"
335+
>
336+
<option v-for="(_, j) in pages" :key="j" :value="j">
337+
Position {{ j + 1 }} sur {{ pages.length }}
338+
</option>
339+
</select>
340+
341+
<div class="sr-only" aria-live="polite" role="alert">
342+
<p v-if="positionSuccessMessage">{{ positionSuccessMessage }}</p>
343+
</div>
344+
</div>
345+
</div>
268346

269347
<DsfrField
270348
:id="`page-name-${i + 1}`"
@@ -289,7 +367,7 @@ const previousRoute = usePreviousRoute();
289367
</DsfrField>
290368
</fieldset>
291369
<button
292-
class="fr-btn fr-btn--tertiary-no-outline fr-mt-2w fr-mb-6w"
370+
class="fr-btn fr-btn--icon-left fr-icon-add-line fr-btn--secondary fr-mt-4w fr-mb-6w"
293371
type="button"
294372
@click="addPage"
295373
>
@@ -356,12 +434,6 @@ const previousRoute = usePreviousRoute();
356434
color: var(--text-mention-grey);
357435
}
358436
359-
.audit-types {
360-
display: flex;
361-
gap: 1rem;
362-
flex-wrap: wrap;
363-
}
364-
365437
.partial-audit-radios {
366438
display: flex;
367439
flex-wrap: wrap;
@@ -382,7 +454,10 @@ const previousRoute = usePreviousRoute();
382454
margin-top: 0.375rem;
383455
}
384456
385-
.page-delete-button {
457+
.page-right-actions {
458+
display: flex;
459+
align-items: center;
460+
gap: 1rem;
386461
float: right;
387462
}
388463

confiture-web-app/src/components/report/ReportErrors.vue

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,33 @@ const errors = computed(() => {
6161
} as Record<number, AuditReport["results"]>;
6262
6363
// TODO: make more legible
64-
const data = Object.values(
65-
mapValues(resultsGroupedByPage, (results, pageId) => {
66-
return {
67-
pageId: Number(pageId),
68-
pageName: getPage(Number(pageId)).name,
69-
pageUrl: getPage(Number(pageId)).url,
70-
topics: sortBy(
71-
Object.values(
72-
mapValues(groupBy(results, "topic"), (results, topicNumber) => {
73-
return {
74-
topic: Number(topicNumber),
75-
name: getTopicName(Number(topicNumber)),
76-
errors: sortBy(
77-
results.filter((r) => !r.transverse),
78-
"criterium"
79-
)
80-
};
81-
})
82-
),
83-
"topic"
84-
)
85-
};
86-
})
64+
const data = sortBy(
65+
Object.values(
66+
mapValues(resultsGroupedByPage, (results, pageId) => {
67+
return {
68+
pageId: Number(pageId),
69+
pageOrder: getPage(Number(pageId)).order,
70+
pageName: getPage(Number(pageId)).name,
71+
pageUrl: getPage(Number(pageId)).url,
72+
topics: sortBy(
73+
Object.values(
74+
mapValues(groupBy(results, "topic"), (results, topicNumber) => {
75+
return {
76+
topic: Number(topicNumber),
77+
name: getTopicName(Number(topicNumber)),
78+
errors: sortBy(
79+
results.filter((r) => !r.transverse),
80+
"criterium"
81+
)
82+
};
83+
})
84+
),
85+
"topic"
86+
)
87+
};
88+
})
89+
),
90+
(el) => el.pageOrder
8791
);
8892
8993
return data;

confiture-web-app/src/pages/audit/AuditGenerationPage.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import { sortBy } from "lodash-es";
23
import { computed, ref, watch } from "vue";
34
import { onBeforeRouteLeave, useRoute } from "vue-router";
45
@@ -212,11 +213,12 @@ const pageTitle = computed(() => {
212213
type TabData = { label: string; data: AuditPage };
213214
214215
const tabsData = computed((): TabData[] => {
215-
return (
216+
return sortBy(
216217
auditStore.currentAudit?.pages.map((p) => ({
217218
label: p.name,
218219
data: p
219-
})) ?? []
220+
})) ?? [],
221+
(p) => p.data.order
220222
);
221223
});
222224

confiture-web-app/src/types/report.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ interface AuditReportContext {
9696
interface PageSample {
9797
// number: number;
9898
id: number;
99+
order: number;
99100
name: string;
100101
url: string;
101102
}

0 commit comments

Comments
 (0)