Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
cc8d378
chore(git): ignore top-level .worktrees/ directory
PierreBrisorgueil May 21, 2026
6836f22
feat(core): add coreConfirmDialog shared destructive-confirm component
PierreBrisorgueil May 21, 2026
e4179e4
feat(core): add coreAvatarUploader (v-badge camera overlay, no inline…
PierreBrisorgueil May 21, 2026
3f37e9b
test(core): use flushPromises in coreAvatarUploader test (cleaner tha…
PierreBrisorgueil May 21, 2026
6e89b87
feat(admin): currentBreadcrumb state so sub-views push titles to the …
PierreBrisorgueil May 21, 2026
7c4e72d
test(admin): split currentBreadcrumb test for clearer failure messages
PierreBrisorgueil May 21, 2026
1b08897
refactor(admin): banners on top, tabs in PageHeader, breadcrumb suppo…
PierreBrisorgueil May 21, 2026
b394082
refactor(admin): resolveActiveTab uses allTabs (single source of truth)
PierreBrisorgueil May 21, 2026
1533b71
refactor(admin): drop v-container on list sub-views; users.view uses …
PierreBrisorgueil May 21, 2026
71efb3d
refactor(admin): drop gratuitous div wrapper in admin.users.view (Vue…
PierreBrisorgueil May 21, 2026
89e13be
refactor(admin): activity view — drop chrome + inline styles, use v-r…
PierreBrisorgueil May 21, 2026
94b0a88
refactor(admin): user detail — drop nested PageHeader, push breadcrum…
PierreBrisorgueil May 21, 2026
e9075ac
refactor(users): profile component — coreAvatarUploader + native Vuet…
PierreBrisorgueil May 21, 2026
140657b
refactor(users): drop dead isActiveOrg method from profile component
PierreBrisorgueil May 21, 2026
d50cfcc
refactor(admin): migrate layout to CoreSurfaceTabBar — chrome converg…
PierreBrisorgueil May 21, 2026
2265422
refactor(users): account dialogs — Delete Account + Leave Org use cor…
PierreBrisorgueil May 21, 2026
ab2bae4
refactor(organizations): detail — Delete Organization uses coreConfir…
PierreBrisorgueil May 21, 2026
e36392e
fix(admin): remove unused beforeEach import in admin.user.view tests
PierreBrisorgueil May 21, 2026
4380784
fix(admin): clear stale breadcrumb on blank user; fix org delete JSDoc
PierreBrisorgueil May 21, 2026
9f545c7
fix(review): address CodeRabbit + Copilot findings
PierreBrisorgueil May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ mongod
.github/*local.*
.claude/worktrees/
playwright.local.config.js

# Top-level git worktrees (per superpowers convention)
.worktrees/
20 changes: 20 additions & 0 deletions src/modules/admin/stores/admin.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const useAdminStore = defineStore('admin', {
users: [],
organizations: [],
error: null,
currentBreadcrumb: null,
readiness: [],
auditLogs: [],
auditTotal: 0,
Expand Down Expand Up @@ -124,6 +125,25 @@ export const useAdminStore = defineStore('admin', {
this.user = defaultUser();
},

/**
* @desc Set (or clear) the current breadcrumb published by an admin sub-view.
* A shallow copy is stored so callers cannot mutate the store state directly.
* Pass `null` to clear (identical effect to `clearBreadcrumb()`).
* @param {{ title: string, titleClass?: string } | null} payload - Breadcrumb data, or null to clear.
* @returns {void}
*/
setBreadcrumb(payload) {
this.currentBreadcrumb = payload ? { ...payload } : null;
},

/**
* @desc Clear the current breadcrumb (reset to null). Called by admin sub-views on unmount.
* @returns {void}
*/
clearBreadcrumb() {
this.currentBreadcrumb = null;
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* @desc Fetch SaaS readiness checklist from the admin API.
* @returns {Promise<void>}
Expand Down
41 changes: 41 additions & 0 deletions src/modules/admin/tests/admin.activity.view.unit.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,44 @@ describe('admin.activity.view', () => {
expect(getAuditLogs).not.toHaveBeenCalled();
});
});

import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';

describe('admin.activity.view — template chrome', () => {
it('does NOT wrap its template in <v-container> (admin layout owns chrome)', () => {
const here = dirname(fileURLToPath(import.meta.url));
const sfc = readFileSync(resolve(here, '../views/admin.activity.view.vue'), 'utf8');
const tmpl = sfc.split('<script>')[0];
expect(tmpl).not.toMatch(/<v-container/);
});

it('has zero inline style="…" attributes in its template', () => {
const here = dirname(fileURLToPath(import.meta.url));
const sfc = readFileSync(resolve(here, '../views/admin.activity.view.vue'), 'utf8');
const tmpl = sfc.split('<script>')[0];
// Allow :style="…" (dynamic bindings, none expected here) and reject plain style="…".
// But neither should appear in this view after the refactor.
expect(tmpl).not.toMatch(/\bstyle\s*=\s*"/);
expect(tmpl).not.toMatch(/:style\s*=\s*"/);
});

it('uses v-table with the hover prop for row affordance', () => {
const here = dirname(fileURLToPath(import.meta.url));
const sfc = readFileSync(resolve(here, '../views/admin.activity.view.vue'), 'utf8');
const tmpl = sfc.split('<script>')[0];
expect(tmpl).toMatch(/<v-table[^>]*\bhover\b/);
});

it('expandable rows have keyboard semantics (tabindex, role, aria-expanded, keydown handlers)', () => {
const here = dirname(fileURLToPath(import.meta.url));
const sfc = readFileSync(resolve(here, '../views/admin.activity.view.vue'), 'utf8');
const tmpl = sfc.split('<script>')[0];
expect(tmpl).toMatch(/tabindex="0"/);
expect(tmpl).toMatch(/role="button"/);
expect(tmpl).toMatch(/aria-expanded/);
expect(tmpl).toMatch(/@keydown\.enter/);
expect(tmpl).toMatch(/@keydown\.space/);
});
});
Loading
Loading