refactor(admin): split the secretary form from its permissions into two modals
Adding a secretary meant deciding all 17 permission resources in the same dialog. The full-height capture showed the form running past 1300px with the save button below 16 accordions, and the dynamic registry makes that worse: every page added in future lengthens this one modal. The add/edit modal now carries only doctors, profile and address, and fits on screen with its footer visible. Permissions move to SecretaryPermissionsModal, reachable from a row action and opened automatically right after a successful add, since a new secretary starts on the role defaults and the owner usually wants to set them. Neither create nor update sends permissions any more — the backend seeds the role defaults on create, and the permissions modal owns the writes, fanning out over every link row so a secretary shared across doctors stays consistent. PermissionAccordions moves to components/ui as a shared component. Sections now start collapsed with a granted/total badge on each header, so the panel opens at a fixed height and still says which sections are on. Two design-system slips caught by re-screenshotting rather than by the audit: - a text button as a third row action pushed the name column out of the table, so the desktop row uses an icon with a title and the mobile card keeps the label - .btn.secondary is not defined in styles.css (variants are primary/ghost/soft/ danger/accent), so it renders as a bare .btn. Used ghost here. 25 other files have the same dead class; left alone as a separate sweep. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,14 +113,28 @@ describe("MySecretariesPage", () => {
|
||||
expect(await screen.findByText("هنوز منشی فعالی اضافه نشده است")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("opens the add modal with permission sections from the catalog", async () => {
|
||||
// ── جداسازی فرمِ منشی از دسترسیها ──────────────────────────────────────
|
||||
// مودالِ افزودن دیگر مجوز ندارد؛ مجوزها مودالِ خودشان را دارند تا افزودنِ یک
|
||||
// منشی به تصمیمگیری دربارهٔ همهٔ منابع گره نخورد.
|
||||
|
||||
it("keeps permissions out of the add form", async () => {
|
||||
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
|
||||
await screen.findAllByText("سارا احمدی");
|
||||
|
||||
fireEvent.click(screen.getByText("اضافه کردن منشی"));
|
||||
|
||||
expect(await screen.findByText("اضافه کردن منشی جدید")).toBeInTheDocument();
|
||||
expect(screen.getByText("مجوزهای دسترسی")).toBeInTheDocument();
|
||||
expect(screen.queryByText("مدیریت نوبتها")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("پرونده بیماران")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("opens a separate permissions modal from the row action", async () => {
|
||||
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
|
||||
await screen.findAllByText("سارا احمدی");
|
||||
|
||||
fireEvent.click(screen.getAllByRole("button", { name: "دسترسیها" })[0]);
|
||||
|
||||
expect(await screen.findByText("دسترسیهای سارا احمدی")).toBeInTheDocument();
|
||||
expect(await screen.findByText("مدیریت نوبتها")).toBeInTheDocument();
|
||||
expect(screen.getByText("پرونده بیماران")).toBeInTheDocument();
|
||||
});
|
||||
@@ -137,7 +151,7 @@ describe("MySecretariesPage", () => {
|
||||
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
|
||||
await screen.findAllByText("سارا احمدی");
|
||||
|
||||
fireEvent.click(screen.getByText("اضافه کردن منشی"));
|
||||
fireEvent.click(screen.getAllByRole("button", { name: "دسترسیها" })[0]);
|
||||
|
||||
expect(await screen.findByText("صفحهٔ کاملاً تازه")).toBeInTheDocument();
|
||||
});
|
||||
@@ -147,9 +161,27 @@ describe("MySecretariesPage", () => {
|
||||
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
|
||||
await screen.findAllByText("سارا احمدی");
|
||||
|
||||
fireEvent.click(screen.getByText("اضافه کردن منشی"));
|
||||
fireEvent.click(screen.getAllByRole("button", { name: "دسترسیها" })[0]);
|
||||
|
||||
expect(await screen.findByText("مدیریت نوبتها")).toBeInTheDocument();
|
||||
expect(screen.queryByText("مدیریت پزشکان کلینیک")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
/** آکاردئونها بسته باز میشوند و شمارِ روشنها روی هدر دیده میشود. */
|
||||
it("starts every section collapsed with a granted counter", async () => {
|
||||
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
|
||||
await screen.findAllByText("سارا احمدی");
|
||||
|
||||
fireEvent.click(screen.getAllByRole("button", { name: "دسترسیها" })[0]);
|
||||
await screen.findByText("مدیریت نوبتها");
|
||||
|
||||
// appointments.view=true در fullPerms → «۱ از ۲» با ارقام فارسی
|
||||
expect(screen.getByText("۱ از ۲")).toBeInTheDocument();
|
||||
// بسته است، پس سوییچِ داخلش رندر نشده
|
||||
expect(screen.queryByLabelText("مدیریت نوبتها — مشاهده نوبتها")).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText("مدیریت نوبتها"));
|
||||
expect(await screen.findByLabelText("مدیریت نوبتها — مشاهده نوبتها")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user