feat(gui-v2): Storybook stories for the v2 shell components
This commit is contained in:
@@ -1,28 +1,41 @@
|
||||
import type { Preview } from '@storybook/vue3-vite'
|
||||
import { setup } from '@storybook/vue3-vite'
|
||||
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
import { installPrimeVue } from '../src/plugins/primevue'
|
||||
|
||||
// Side-effect: bootstrap the Tabler set so @iconify/vue <Icon> renders
|
||||
// real SVG in Storybook (mirrors main.ts; preview.ts is the SB entry).
|
||||
import '../src/plugins/iconify'
|
||||
|
||||
import '../src/assets/styles/tailwind.css'
|
||||
|
||||
const noop = { template: '<div />' }
|
||||
const routeNames = [
|
||||
'dashboard', 'events', 'organisation', 'members',
|
||||
'organisation-companies', 'organisation-form-failures',
|
||||
'organisation-settings', 'platform', 'platform-organisations',
|
||||
'platform-users', 'platform-form-failures', 'platform-activity-log',
|
||||
]
|
||||
|
||||
export const storyRouter = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{ path: '/', name: 'home', component: noop },
|
||||
...routeNames.map(name => ({ path: `/${name}`, name, component: noop })),
|
||||
{ path: '/:pathMatch(.*)*', name: 'catchall', component: noop },
|
||||
],
|
||||
})
|
||||
|
||||
setup((app) => {
|
||||
installPrimeVue(app)
|
||||
app.use(storyRouter)
|
||||
})
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
toc: true,
|
||||
},
|
||||
a11y: {
|
||||
test: 'todo',
|
||||
},
|
||||
controls: { matchers: { color: /(background|color)$/i, date: /Date$/i } },
|
||||
docs: { toc: true },
|
||||
a11y: { test: 'todo' },
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
119
apps/app/src/stories/v2/AppDialog.stories.ts
Normal file
119
apps/app/src/stories/v2/AppDialog.stories.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { ref } from 'vue'
|
||||
import Button from 'primevue/button'
|
||||
import AppDialog from '@/components-v2/shared/AppDialog.vue'
|
||||
|
||||
/**
|
||||
* AppDialog stories. PrimeVue Dialog is `modal` + teleports to <body>,
|
||||
* so each story binds `v-model:open` to a ref seeded from `args.open`
|
||||
* and renders the dialog open by default for autodocs visibility.
|
||||
*/
|
||||
const meta: Meta<typeof AppDialog> = {
|
||||
title: 'v2 Shell/AppDialog',
|
||||
component: AppDialog,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
open: { control: 'boolean' },
|
||||
title: { control: 'text' },
|
||||
sub: { control: 'text' },
|
||||
width: { control: 'text' },
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof AppDialog>
|
||||
|
||||
export const Default: Story = {
|
||||
args: { open: true, title: 'Edit shift' },
|
||||
render: args => ({
|
||||
components: { AppDialog },
|
||||
setup() {
|
||||
const open = ref(args.open)
|
||||
|
||||
return { args, open }
|
||||
},
|
||||
template: `
|
||||
<AppDialog v-model:open="open" :title="args.title" :sub="args.sub" :width="args.width">
|
||||
<p class="text-sm">Dialog body content goes here.</p>
|
||||
</AppDialog>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const WithSubtitle: Story = {
|
||||
args: { open: true, title: 'Edit shift', sub: 'Saturday — Main Stage' },
|
||||
render: args => ({
|
||||
components: { AppDialog },
|
||||
setup() {
|
||||
const open = ref(args.open)
|
||||
|
||||
return { args, open }
|
||||
},
|
||||
template: `
|
||||
<AppDialog v-model:open="open" :title="args.title" :sub="args.sub" :width="args.width">
|
||||
<p class="text-sm">Dialog body with a subtitle in the header.</p>
|
||||
</AppDialog>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const WithFooter: Story = {
|
||||
args: { open: true, title: 'Confirm action' },
|
||||
render: args => ({
|
||||
components: { AppDialog, Button },
|
||||
setup() {
|
||||
const open = ref(args.open)
|
||||
|
||||
return { args, open }
|
||||
},
|
||||
template: `
|
||||
<AppDialog v-model:open="open" :title="args.title" :sub="args.sub" :width="args.width">
|
||||
<p class="text-sm">Are you sure you want to continue?</p>
|
||||
<template #footer>
|
||||
<Button label="Cancel" severity="secondary" @click="open = false" />
|
||||
<Button label="Confirm" @click="open = false" />
|
||||
</template>
|
||||
</AppDialog>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const WithTabs: Story = {
|
||||
args: { open: true, title: 'Settings' },
|
||||
render: args => ({
|
||||
components: { AppDialog },
|
||||
setup() {
|
||||
const open = ref(args.open)
|
||||
|
||||
return { args, open }
|
||||
},
|
||||
template: `
|
||||
<AppDialog v-model:open="open" :title="args.title" :sub="args.sub" :width="args.width">
|
||||
<template #tabs>
|
||||
<div class="flex gap-4 px-6 py-2 border-b border-[var(--p-content-border-color)] text-[13px]">
|
||||
<span class="font-semibold text-[var(--p-primary-color)]">General</span>
|
||||
<span class="text-[var(--p-text-muted-color)]">Advanced</span>
|
||||
</div>
|
||||
</template>
|
||||
<p class="text-sm">Tab strip rendered between header and body.</p>
|
||||
</AppDialog>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const Wide: Story = {
|
||||
args: { open: true, title: 'Wide dialog', width: '960px' },
|
||||
render: args => ({
|
||||
components: { AppDialog },
|
||||
setup() {
|
||||
const open = ref(args.open)
|
||||
|
||||
return { args, open }
|
||||
},
|
||||
template: `
|
||||
<AppDialog v-model:open="open" :title="args.title" :sub="args.sub" :width="args.width">
|
||||
<p class="text-sm">This dialog uses an explicit width of 960px.</p>
|
||||
</AppDialog>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
75
apps/app/src/stories/v2/AppSidebar.stories.ts
Normal file
75
apps/app/src/stories/v2/AppSidebar.stories.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { navFixture, orgA, userFixture, withPinia } from './_helpers'
|
||||
import AppSidebar from '@/components-v2/layout/AppSidebar.vue'
|
||||
import { useAuthStore } from '@/stores/useAuthStore'
|
||||
import { useShellUiStore } from '@/stores/useShellUiStore'
|
||||
|
||||
/**
|
||||
* AppSidebar composes SidebarHeader + SidebarNav + WorkspaceSwitcher and
|
||||
* reads useShellUiStore (sidebarCollapsed / mobileOpen) plus, transitively
|
||||
* via WorkspaceSwitcher, useAuthStore. Each story seeds both stores on a
|
||||
* fresh Pinia. The desktop <aside> is `hidden lg:flex`, so view at a
|
||||
* viewport ≥ 1024px to see the permanent column.
|
||||
*/
|
||||
const meta: Meta<typeof AppSidebar> = {
|
||||
title: 'v2 Shell/AppSidebar',
|
||||
component: AppSidebar,
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof AppSidebar>
|
||||
|
||||
export const Expanded: Story = {
|
||||
args: { groups: navFixture },
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.sidebarCollapsed = false
|
||||
}),
|
||||
],
|
||||
render: args => ({
|
||||
components: { AppSidebar },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="flex h-[600px]">
|
||||
<AppSidebar :groups="args.groups" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const Collapsed: Story = {
|
||||
args: { groups: navFixture },
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.sidebarCollapsed = true
|
||||
}),
|
||||
],
|
||||
render: args => ({
|
||||
components: { AppSidebar },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="flex h-[600px]">
|
||||
<AppSidebar :groups="args.groups" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
91
apps/app/src/stories/v2/AppTopbar.stories.ts
Normal file
91
apps/app/src/stories/v2/AppTopbar.stories.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { onUnmounted } from 'vue'
|
||||
import { orgA, userFixture, withPinia } from './_helpers'
|
||||
import AppTopbar from '@/components-v2/layout/AppTopbar.vue'
|
||||
import { useAuthStore } from '@/stores/useAuthStore'
|
||||
import { useShellUiStore } from '@/stores/useShellUiStore'
|
||||
|
||||
/**
|
||||
* AppTopbar reads useShellUiStore (theme / density), useAuthStore (user +
|
||||
* currentOrganisation) and useBreadcrumb (route-driven — router is global
|
||||
* in preview.ts). Each story seeds both stores on a fresh Pinia.
|
||||
*/
|
||||
const meta: Meta<typeof AppTopbar> = {
|
||||
title: 'v2 Shell/AppTopbar',
|
||||
component: AppTopbar,
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof AppTopbar>
|
||||
|
||||
export const Default: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { AppTopbar },
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<AppTopbar />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const DarkTheme: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.setTheme('dark')
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { AppTopbar },
|
||||
setup() {
|
||||
document.documentElement.classList.add('dark')
|
||||
onUnmounted(() => {
|
||||
document.documentElement.classList.remove('dark')
|
||||
})
|
||||
},
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<AppTopbar />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const CompactDensity: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.setDensity('compact')
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { AppTopbar },
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<AppTopbar />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
84
apps/app/src/stories/v2/RightDrawer.stories.ts
Normal file
84
apps/app/src/stories/v2/RightDrawer.stories.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { defineComponent } from 'vue'
|
||||
import { withPinia } from './_helpers'
|
||||
import RightDrawer from '@/components-v2/layout/RightDrawer.vue'
|
||||
import { registerDrawerComponent } from '@/composables/drawerRegistry'
|
||||
import { useShellUiStore } from '@/stores/useShellUiStore'
|
||||
|
||||
/**
|
||||
* RightDrawer is fully store-driven via useShellUiStore().drawer +
|
||||
* the drawerRegistry singleton. Each seed registers a demo body under
|
||||
* "SbDemo" (idempotent overwrite — registry is a module singleton) and
|
||||
* optionally seeds openDrawer() so the teleported PrimeVue Drawer is
|
||||
* visible. Chrome keys title/flush are passed in the props object.
|
||||
*/
|
||||
const SbDemoBody = defineComponent({
|
||||
name: 'SbDemoBody',
|
||||
template: '<div class="p-2 text-sm">Demo drawer body</div>',
|
||||
})
|
||||
|
||||
const meta: Meta<typeof RightDrawer> = {
|
||||
title: 'v2 Shell/RightDrawer',
|
||||
component: RightDrawer,
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof RightDrawer>
|
||||
|
||||
export const Closed: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
registerDrawerComponent('SbDemo', SbDemoBody)
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { RightDrawer },
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<p class="text-sm text-[var(--p-text-muted-color)]">Drawer is closed (store seeded but openDrawer not called).</p>
|
||||
<RightDrawer />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const OpenWithBody: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
registerDrawerComponent('SbDemo', SbDemoBody)
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.openDrawer('SbDemo', { title: 'Details' })
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { RightDrawer },
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<RightDrawer />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const Flush: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
registerDrawerComponent('SbDemo', SbDemoBody)
|
||||
|
||||
const shellUi = useShellUiStore()
|
||||
|
||||
shellUi.openDrawer('SbDemo', { title: 'Flush', flush: true })
|
||||
}),
|
||||
],
|
||||
render: () => ({
|
||||
components: { RightDrawer },
|
||||
template: `
|
||||
<div class="min-h-[200px]">
|
||||
<RightDrawer />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
71
apps/app/src/stories/v2/SidebarNav.stories.ts
Normal file
71
apps/app/src/stories/v2/SidebarNav.stories.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { navFixture } from './_helpers'
|
||||
import SidebarNav from '@/components-v2/layout/SidebarNav.vue'
|
||||
|
||||
/**
|
||||
* SidebarNav needs no Pinia, but vue-router is installed app-wide in
|
||||
* preview.ts (the component uses useRoute + RouterLink). The
|
||||
* WithActiveItem story pushes the `events` route in setup so the
|
||||
* Evenementen item renders in its active state.
|
||||
*/
|
||||
const meta: Meta<typeof SidebarNav> = {
|
||||
title: 'v2 Shell/SidebarNav',
|
||||
component: SidebarNav,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
collapsed: { control: 'boolean' },
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof SidebarNav>
|
||||
|
||||
export const Expanded: Story = {
|
||||
args: { groups: navFixture, collapsed: false },
|
||||
render: args => ({
|
||||
components: { SidebarNav },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-64 bg-[var(--p-content-background)]">
|
||||
<SidebarNav :groups="args.groups" :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const Collapsed: Story = {
|
||||
args: { groups: navFixture, collapsed: true },
|
||||
render: args => ({
|
||||
components: { SidebarNav },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-16 bg-[var(--p-content-background)]">
|
||||
<SidebarNav :groups="args.groups" :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const WithActiveItem: Story = {
|
||||
args: { groups: navFixture, collapsed: false },
|
||||
render: args => ({
|
||||
components: { SidebarNav },
|
||||
setup() {
|
||||
const router = useRouter()
|
||||
|
||||
router.push({ name: 'events' })
|
||||
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-64 bg-[var(--p-content-background)]">
|
||||
<SidebarNav :groups="args.groups" :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
88
apps/app/src/stories/v2/WorkspaceSwitcher.stories.ts
Normal file
88
apps/app/src/stories/v2/WorkspaceSwitcher.stories.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
import { orgA, orgB, orgC, userFixture, withPinia } from './_helpers'
|
||||
import WorkspaceSwitcher from '@/components-v2/layout/WorkspaceSwitcher.vue'
|
||||
import { useAuthStore } from '@/stores/useAuthStore'
|
||||
|
||||
/**
|
||||
* WorkspaceSwitcher reads useAuthStore (organisations + computed
|
||||
* currentOrganisation). Each story gets a fresh Pinia via withPinia and
|
||||
* seeds the auth store by direct assignment after the store is created.
|
||||
*/
|
||||
const meta: Meta<typeof WorkspaceSwitcher> = {
|
||||
title: 'v2 Shell/WorkspaceSwitcher',
|
||||
component: WorkspaceSwitcher,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
collapsed: { control: 'boolean' },
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof WorkspaceSwitcher>
|
||||
|
||||
export const SingleOrg: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA]
|
||||
}),
|
||||
],
|
||||
render: args => ({
|
||||
components: { WorkspaceSwitcher },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-64 bg-[var(--p-content-background)]">
|
||||
<WorkspaceSwitcher :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const MultiOrg: Story = {
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA, orgB, orgC]
|
||||
}),
|
||||
],
|
||||
render: args => ({
|
||||
components: { WorkspaceSwitcher },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-64 bg-[var(--p-content-background)]">
|
||||
<WorkspaceSwitcher :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const Collapsed: Story = {
|
||||
args: { collapsed: true },
|
||||
decorators: [
|
||||
withPinia(() => {
|
||||
const auth = useAuthStore()
|
||||
|
||||
auth.user = userFixture
|
||||
auth.organisations = [orgA, orgB, orgC]
|
||||
}),
|
||||
],
|
||||
render: args => ({
|
||||
components: { WorkspaceSwitcher },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: `
|
||||
<div class="w-16 bg-[var(--p-content-background)]">
|
||||
<WorkspaceSwitcher :collapsed="args.collapsed" />
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
84
apps/app/src/stories/v2/_helpers.ts
Normal file
84
apps/app/src/stories/v2/_helpers.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import type { Decorator } from '@storybook/vue3-vite'
|
||||
import type { Organisation, User } from '@/types/auth'
|
||||
import type { V2NavGroup } from '@/types/v2/nav'
|
||||
|
||||
/**
|
||||
* Fresh Pinia per story + optional seeding. The seed fn runs AFTER
|
||||
* setActivePinia so `useXxxStore()` inside it (and inside the rendered
|
||||
* component) resolves to this story's isolated store instance.
|
||||
*/
|
||||
export function withPinia(seed?: () => void): Decorator {
|
||||
return story => {
|
||||
setActivePinia(createPinia())
|
||||
seed?.()
|
||||
|
||||
return { components: { story }, template: '<story />' }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal valid User fixture (every required key from `@/types/auth`
|
||||
* User present and typed — no `any`). Shared so AppTopbar / AppSidebar /
|
||||
* WorkspaceSwitcher seeds stay DRY.
|
||||
*/
|
||||
export const userFixture: User = {
|
||||
id: 'usr_01',
|
||||
first_name: 'Bert',
|
||||
last_name: 'Hausmans',
|
||||
full_name: 'Bert Hausmans',
|
||||
date_of_birth: null,
|
||||
email: 'bert@hausmans.nl',
|
||||
phone: null,
|
||||
timezone: 'Europe/Amsterdam',
|
||||
locale: 'nl',
|
||||
avatar: null,
|
||||
}
|
||||
|
||||
/**
|
||||
* Three Organisation fixtures (every required key from `@/types/auth`
|
||||
* Organisation present). `currentOrganisation` is a computed that returns
|
||||
* `organisations[0]` when no active id is set, so assigning
|
||||
* `auth.organisations = [orgA]` makes orgA the current workspace.
|
||||
*/
|
||||
export const orgA: Organisation = {
|
||||
id: 'org_a',
|
||||
name: 'Festival Crew NL',
|
||||
slug: 'festival-crew-nl',
|
||||
role: 'org_admin',
|
||||
}
|
||||
|
||||
export const orgB: Organisation = {
|
||||
id: 'org_b',
|
||||
name: 'Stadspark Events',
|
||||
slug: 'stadspark-events',
|
||||
role: 'org_member',
|
||||
}
|
||||
|
||||
export const orgC: Organisation = {
|
||||
id: 'org_c',
|
||||
name: 'Volunteer Collective',
|
||||
slug: 'volunteer-collective',
|
||||
role: 'event_manager',
|
||||
}
|
||||
|
||||
/** Convenience single-org list for store seeds. */
|
||||
export const orgFixture: Organisation[] = [orgA]
|
||||
|
||||
export const navFixture: V2NavGroup[] = [
|
||||
{
|
||||
label: '',
|
||||
items: [
|
||||
{ id: 'dashboard', label: 'Dashboard', icon: 'tabler-smart-home', to: { name: 'dashboard' } },
|
||||
{ id: 'events', label: 'Evenementen', icon: 'tabler-calendar-event', to: { name: 'events' }, count: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Beheer',
|
||||
items: [
|
||||
{ id: 'organisation', label: 'Mijn Organisatie', icon: 'tabler-building', to: { name: 'organisation' } },
|
||||
{ id: 'members', label: 'Leden', icon: 'tabler-users', to: { name: 'members' } },
|
||||
{ id: 'organisation-settings', label: 'Instellingen', icon: 'tabler-settings', to: { name: 'organisation-settings' } },
|
||||
],
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user