Skip to content

Commit 0624bdb

Browse files
Merge branch 'alpha' into feat/issue-3242-admin-settings-refactor
2 parents 883734e + 8d94e73 commit 0624bdb

17 files changed

Lines changed: 273 additions & 88 deletions

packages/app/src/app/layout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import Script from "next/script";
44
import { MatomoAnalytics } from "~/modules/analytics";
55
import { SessionProviderWrapper } from "~/modules/auth";
66
import {
7-
Footer,
87
Header,
98
ImpersonateBanner,
10-
ResourceBanner,
9+
PublicChrome,
1110
SkipLinks,
1211
} from "~/modules/layout";
1312
import { ProfileModal } from "~/modules/profile";
@@ -59,8 +58,7 @@ export default function RootLayout({
5958
<ImpersonateBanner />
6059
<Header />
6160
{children}
62-
<ResourceBanner />
63-
<Footer />
61+
<PublicChrome />
6462
<ProfileModal />
6563
</TRPCReactProvider>
6664
</SessionProviderWrapper>

packages/app/src/e2e/admin.e2e.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ test("admin user can access /admin and sees backoffice page", async ({
1010
await expect(page.getByText("administrateur")).toBeVisible();
1111
});
1212

13+
test("admin routes hide the public footer and help banner", async ({
14+
page,
15+
}) => {
16+
// Runs in the authenticated `chromium` Playwright project (see
17+
// playwright.config.ts): `page.goto("/admin")` reaches the real backoffice
18+
// page, so the assertions below exercise the PublicChrome branch, not a
19+
// login-redirect fallback that would trivially pass.
20+
await page.goto("/admin");
21+
await expect(
22+
page.getByRole("heading", { name: "Backoffice", level: 1 }),
23+
).toBeVisible();
24+
await expect(page.locator("footer#footer")).toHaveCount(0);
25+
await expect(
26+
page.getByRole("region", { name: "Ressources et aide" }),
27+
).toHaveCount(0);
28+
});
29+
1330
test("admin user can access /admin/impersonate and sees impersonate page", async ({
1431
page,
1532
}) => {

packages/app/src/e2e/public-referents.e2e.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,35 @@ test.describe("public referents search", () => {
6868
}
6969
});
7070

71+
test("landing on /referents without a filter shows the empty-filter hint and no results", async ({
72+
browser,
73+
}) => {
74+
const anonCtx = await browser.newContext({ storageState: undefined });
75+
try {
76+
const page = await anonCtx.newPage();
77+
await page.goto("/referents");
78+
await expect(
79+
page.getByText(/remplissez au moins un filtre/i),
80+
).toBeVisible();
81+
await expect(page.getByText("E2E Référent Paris")).not.toBeVisible();
82+
} finally {
83+
await anonCtx.close();
84+
}
85+
});
86+
87+
test("/referents shows the public help banner", async ({ browser }) => {
88+
const anonCtx = await browser.newContext({ storageState: undefined });
89+
try {
90+
const page = await anonCtx.newPage();
91+
await page.goto("/referents");
92+
await expect(
93+
page.getByRole("region", { name: /ressources et aide/i }),
94+
).toBeVisible();
95+
} finally {
96+
await anonCtx.close();
97+
}
98+
});
99+
71100
test("search by region filters the results", async ({ browser }) => {
72101
const anonCtx = await browser.newContext({ storageState: undefined });
73102
try {
@@ -120,6 +149,8 @@ test.describe("public referents search", () => {
120149
try {
121150
const page = await anonCtx.newPage();
122151
await page.goto("/referents");
152+
await page.getByLabel("Région").selectOption("11");
153+
await page.getByRole("button", { name: /^rechercher$/i }).click();
123154
await expect(page.getByText("E2E Référent Paris")).toBeVisible();
124155
await expect(page.getByText("e2e-paris@dreets.test")).not.toBeVisible();
125156
await expect(
@@ -137,6 +168,8 @@ test.describe("public referents search", () => {
137168
try {
138169
const page = await anonCtx.newPage();
139170
await page.goto("/referents");
171+
await page.getByLabel("Région").selectOption("11");
172+
await page.getByRole("button", { name: /^rechercher$/i }).click();
140173

141174
const row = page.locator("li", { hasText: "E2E Référent Paris" });
142175
await row.getByRole("link", { name: /voir le contact/i }).click();

packages/app/src/modules/admin/AdminNavigation.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { usePathname } from "next/navigation";
55

66
const adminLinks = [
77
{ href: "/admin", label: "Accueil" },
8+
{ href: "/admin/declarations", label: "Déclarations" },
89
{ href: "/admin/impersonate", label: "Mimoquer un Siren" },
910
{ href: "/admin/liste-referents", label: "Référents" },
1011
{ href: "/admin/parametres", label: "Paramètres" },

packages/app/src/modules/admin/__tests__/AdminNavigation.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ describe("AdminNavigation", () => {
1919
it("renders all admin links", () => {
2020
render(<AdminNavigation />);
2121
expect(screen.getByRole("link", { name: "Accueil" })).toBeInTheDocument();
22+
expect(
23+
screen.getByRole("link", { name: "Déclarations" }),
24+
).toBeInTheDocument();
2225
expect(
2326
screen.getByRole("link", { name: "Mimoquer un Siren" }),
2427
).toBeInTheDocument();
@@ -61,4 +64,28 @@ describe("AdminNavigation", () => {
6164
"aria-current",
6265
);
6366
});
67+
68+
it("marks /admin/declarations as active — and not Accueil", () => {
69+
(usePathname as Mock).mockReturnValue("/admin/declarations");
70+
render(<AdminNavigation />);
71+
expect(screen.getByRole("link", { name: "Déclarations" })).toHaveAttribute(
72+
"aria-current",
73+
"page",
74+
);
75+
expect(screen.getByRole("link", { name: "Accueil" })).not.toHaveAttribute(
76+
"aria-current",
77+
);
78+
});
79+
80+
it("marks /admin/declarations/<id> as active on the Déclarations link", () => {
81+
(usePathname as Mock).mockReturnValue("/admin/declarations/abc123");
82+
render(<AdminNavigation />);
83+
expect(screen.getByRole("link", { name: "Déclarations" })).toHaveAttribute(
84+
"aria-current",
85+
"page",
86+
);
87+
expect(screen.getByRole("link", { name: "Accueil" })).not.toHaveAttribute(
88+
"aria-current",
89+
);
90+
});
6491
});

packages/app/src/modules/admin/declarations/AdminDeclarationsPage.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ function DeclarationsContent() {
2222
dateFrom: searchParams.get("dateFrom") ?? undefined,
2323
dateTo: searchParams.get("dateTo") ?? undefined,
2424
status: (searchParams.get("status") as "draft" | "submitted") || undefined,
25-
index: searchParams.get("index")
26-
? Number(searchParams.get("index"))
27-
: undefined,
28-
indexOperator:
29-
(searchParams.get("indexOperator") as "gt" | "lt" | "eq") || undefined,
3025
page: Number(searchParams.get("page") ?? "1"),
3126
pageSize: Number(searchParams.get("pageSize") ?? String(DEFAULT_PAGE_SIZE)),
3227
sortBy: (searchParams.get("sortBy") as SortColumn) ?? "createdAt",

packages/app/src/modules/admin/declarations/SearchForm.tsx

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ export function SearchForm() {
2323
dateTo: searchParams.get("dateTo") ?? "",
2424
status:
2525
(searchParams.get("status") as "" | "draft" | "submitted") ?? "",
26-
index: searchParams.get("index") ?? "",
27-
indexOperator:
28-
(searchParams.get("indexOperator") as "" | "gt" | "lt" | "eq") ?? "",
2926
},
3027
},
3128
);
@@ -52,8 +49,6 @@ export function SearchForm() {
5249
dateFrom: "",
5350
dateTo: "",
5451
status: "",
55-
index: "",
56-
indexOperator: "",
5752
});
5853
router.push("/admin/declarations");
5954
}, [reset, router]);
@@ -144,42 +139,6 @@ export function SearchForm() {
144139
</select>
145140
</div>
146141
</div>
147-
<div className="fr-col-12 fr-col-md-3">
148-
<div className="fr-grid-row fr-grid-row--gutters">
149-
<div className="fr-col-6">
150-
<div className="fr-select-group">
151-
<label className="fr-label" htmlFor="search-index-op">
152-
Index
153-
</label>
154-
<select
155-
className="fr-select"
156-
id="search-index-op"
157-
{...register("indexOperator")}
158-
>
159-
<option value=""></option>
160-
<option value="eq">=</option>
161-
<option value="gt">&ge;</option>
162-
<option value="lt">&le;</option>
163-
</select>
164-
</div>
165-
</div>
166-
<div className="fr-col-6">
167-
<div className="fr-input-group">
168-
<label className="fr-label" htmlFor="search-index">
169-
Valeur
170-
</label>
171-
<input
172-
className="fr-input"
173-
id="search-index"
174-
max={100}
175-
min={0}
176-
type="number"
177-
{...register("index")}
178-
/>
179-
</div>
180-
</div>
181-
</div>
182-
</div>
183142
</div>
184143
<div className="fr-grid-row fr-grid-row--right fr-mt-2w">
185144
<ul className="fr-btns-group fr-btns-group--inline">

packages/app/src/modules/admin/declarations/__tests__/SearchForm.test.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ vi.mock("next/navigation", async () => {
2020
import { SearchForm } from "../SearchForm";
2121

2222
describe("SearchForm", () => {
23-
it("renders all search fields", () => {
23+
it("renders all search fields and omits the removed Index / Valeur pair", () => {
2424
render(<SearchForm />);
2525

2626
expect(screen.getByLabelText("SIREN / Nom entreprise")).toBeInTheDocument();
@@ -29,8 +29,10 @@ describe("SearchForm", () => {
2929
expect(screen.getByLabelText("Date de dépôt (du)")).toBeInTheDocument();
3030
expect(screen.getByLabelText("Date de dépôt (au)")).toBeInTheDocument();
3131
expect(screen.getByLabelText("Statut")).toBeInTheDocument();
32-
expect(screen.getByLabelText("Index")).toBeInTheDocument();
33-
expect(screen.getByLabelText("Valeur")).toBeInTheDocument();
32+
// Regression guard for #3274 — keep these negative assertions next to
33+
// their positive counterparts so a future reintroduction is caught here.
34+
expect(screen.queryByLabelText("Index")).not.toBeInTheDocument();
35+
expect(screen.queryByLabelText("Valeur")).not.toBeInTheDocument();
3436
});
3537

3638
it("renders search and reset buttons", () => {

packages/app/src/modules/admin/declarations/__tests__/schemas.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ describe("searchDeclarationsSchema", () => {
2020
year: "2024",
2121
dateFrom: "2024-01-01",
2222
dateTo: "2024-12-31",
23-
index: "75",
24-
indexOperator: "gt",
2523
status: "submitted",
2624
page: "2",
2725
pageSize: "50",
@@ -35,8 +33,6 @@ describe("searchDeclarationsSchema", () => {
3533
year: 2024,
3634
dateFrom: "2024-01-01",
3735
dateTo: "2024-12-31",
38-
index: 75,
39-
indexOperator: "gt",
4036
status: "submitted",
4137
page: 2,
4238
pageSize: 50,

packages/app/src/modules/admin/declarations/schemas.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ export const SORT_COLUMNS = [
1111

1212
export type SortColumn = (typeof SORT_COLUMNS)[number];
1313

14-
export const INDEX_OPERATORS = ["gt", "lt", "eq"] as const;
15-
16-
export type IndexOperator = (typeof INDEX_OPERATORS)[number];
17-
1814
export const DEFAULT_PAGE_SIZE = 20;
1915

2016
export const searchDeclarationsSchema = z.object({
@@ -23,8 +19,6 @@ export const searchDeclarationsSchema = z.object({
2319
year: z.coerce.number().int().min(2018).max(2100).optional(),
2420
dateFrom: z.string().date().optional().or(z.literal("")),
2521
dateTo: z.string().date().optional().or(z.literal("")),
26-
index: z.coerce.number().int().min(0).max(100).optional(),
27-
indexOperator: z.enum(INDEX_OPERATORS).optional(),
2822
status: z.enum(["draft", "submitted"]).optional(),
2923
page: z.coerce.number().int().min(1).default(1),
3024
pageSize: z.coerce.number().int().min(10).max(100).default(DEFAULT_PAGE_SIZE),
@@ -43,8 +37,6 @@ export const searchDeclarationsFormSchema = z.object({
4337
year: z.string().optional(),
4438
dateFrom: z.string().optional(),
4539
dateTo: z.string().optional(),
46-
index: z.string().optional(),
47-
indexOperator: z.enum(["", ...INDEX_OPERATORS]).optional(),
4840
status: z.enum(["", "draft", "submitted"]).optional(),
4941
});
5042

0 commit comments

Comments
 (0)