From 7b35c9e785356e679fb6a0ec3d5df7b5d87adc01 Mon Sep 17 00:00:00 2001 From: BatLeDev Date: Mon, 11 May 2026 09:58:38 +0200 Subject: [PATCH 1/3] fix(types-builder): log compiledLayout options before attaching schemas The `compiledLayout {locale} options: ...` log was huge because it ran after `schemaVjsfOpts.ajvOptions = { schemas: otherSchemas }`, which serialized the entire schema collection. Move the log right after the `delete schemaVjsfOpts.compName` line, before any mutation of `schemaVjsfOpts`, matching the pattern used in the `vjsf` section. --- packages/types-builder/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types-builder/build.ts b/packages/types-builder/build.ts index ac17fea..df2f7d0 100755 --- a/packages/types-builder/build.ts +++ b/packages/types-builder/build.ts @@ -359,6 +359,7 @@ const emit = defineEmits(emits) for (const locale of vjsfLocales) { const schemaVjsfOpts = { ...schema['x-vjsf'] } delete schemaVjsfOpts.compName + console.log(` compiledLayout ${locale} options: ${JSON.stringify(schemaVjsfOpts)}`) const otherSchemas = { ...schemas } for (const [key, otherSchema] of Object.entries(schemas)) { if (key === schema.$id) continue @@ -375,7 +376,6 @@ const emit = defineEmits(emits) fullOptions.components[componentInfo.name] = componentInfo } - console.log(` compiledLayout ${locale} options: ${JSON.stringify(schemaVjsfOpts)}`) const compiledLayout = compileLayout(schema, fullOptions) let compiledLayoutCode = await serializeCompiledLayout(compiledLayout) // The serialized code declares `const compiledLayout = {...}`. From 46e1f71acb6d90ea7a1897f5c3fc88abd2e5ed6e Mon Sep 17 00:00:00 2001 From: BatLeDev Date: Fri, 22 May 2026 14:40:45 +0200 Subject: [PATCH 2/3] fix(lib-vuetify): capitalize i18n label and drop dead key in personal-menu - Admin mode toggle label (fr/en) now starts with a capital letter. - Drop the dead `darkMode` i18n key from personal-menu (never referenced via t()). --- packages/vuetify/personal-menu.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/vuetify/personal-menu.vue b/packages/vuetify/personal-menu.vue index 83e0410..508349c 100644 --- a/packages/vuetify/personal-menu.vue +++ b/packages/vuetify/personal-menu.vue @@ -182,9 +182,8 @@ fr: openPersonalMenu: Ouvrez le menu personnel personalAccount: Compte personnel switchAccount: Changer de compte - adminMode: mode admin + adminMode: Mode admin backToAdmin: Revenir à ma session administrateur - darkMode: mode nuit plannedDeletion: La suppression de l'utilisateur {name} et toutes ses informations est programmée le {plannedDeletion}. cancelDeletion: Annuler la suppression de l'utilisateur en: @@ -193,9 +192,8 @@ en: openPersonalMenu: Open personal menu personalAccount: Personal account switchAccount: Switch account - adminMode: admin mode + adminMode: Admin mode backToAdmin: Return to administrator session - darkMode: night mode plannedDeletion: The deletion of the user {name} and all its data is planned on the {plannedDeletion}. cancelDeletion: Cancel the deletion of the user From 3c2d92958dd5425aeee6bb98768eb82565b9aa15 Mon Sep 17 00:00:00 2001 From: BatLeDev Date: Mon, 11 May 2026 10:19:28 +0200 Subject: [PATCH 3/3] fix(lib-vuetify): offer root-of-org switch when department resource is forbidden The 403 "switch account" affordance in layout-fetch-error only matched user memberships when their department exactly equalled the resource's `x-owner.department`. A user who only had access at the root of the organization was therefore never offered a switch, even though root access generally grants visibility over department-scoped resources in simple-directory's authz model. - Match the exact department first, then fall back to a root membership of the same organization when the resource lives in a department. - Exclude the current account from candidates so the button is not offered when switching would be a no-op. --- packages/vuetify/layout-fetch-error.vue | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/vuetify/layout-fetch-error.vue b/packages/vuetify/layout-fetch-error.vue index f56e0bc..57d10fe 100644 --- a/packages/vuetify/layout-fetch-error.vue +++ b/packages/vuetify/layout-fetch-error.vue @@ -64,7 +64,7 @@ const { error, backTo = '/', backLabel } = defineProps<{ }>() const { t } = useI18n({ useScope: 'local' }) -const { switchOrganization, user } = useSession() +const { switchOrganization, user, account } = useSession() const statusCode = computed(() => error?.statusCode ?? error?.status ?? 500) @@ -99,9 +99,25 @@ const switchOrg = computed(() => { try { owner = JSON.parse(rawOwner) } catch { return null } if (!owner || owner.type !== 'organization' || !owner.id) return null - return user.value.organizations?.find(o => - o.id === owner!.id && (o.department ?? undefined) === (owner!.department ?? undefined) - ) ?? null + const orgs = user.value.organizations ?? [] + const ownerDept = owner.department ?? undefined + const isCurrentAccount = (o: { id: string, department?: string }) => + account.value?.type === 'organization' && + account.value.id === o.id && + (account.value.department ?? undefined) === (o.department ?? undefined) + + // Prefer a membership matching the resource's department exactly... + const exact = orgs.find(o => + o.id === owner!.id && (o.department ?? undefined) === ownerDept && !isCurrentAccount(o) + ) + if (exact) return exact + // ...otherwise fall back to a membership at the organization root: in + // simple-directory's authz model, root access generally grants visibility + // over department-scoped resources. + if (ownerDept) { + return orgs.find(o => o.id === owner!.id && !o.department && !isCurrentAccount(o)) ?? null + } + return null }) const doSwitch = () => {