@cat-factory/app 0.132.0 → 0.133.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/layout/BoardToolbar.vue +18 -0
- package/app/components/layout/CommandBar.vue +95 -182
- package/app/components/layout/SideBar.vue +18 -266
- package/app/composables/useNavContributions.ts +75 -0
- package/app/modular/nav-contributions.spec.ts +182 -0
- package/app/modular/nav-contributions.ts +483 -0
- package/app/modular/nav-gates.ts +63 -0
- package/app/modular/registry.spec.ts +52 -7
- package/app/modular/registry.ts +32 -14
- package/app/plugins/modular.client.ts +14 -6
- package/package.json +3 -3
package/app/modular/registry.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { defineModule } from '@modular-vue/core'
|
|
2
1
|
import type { AnyModuleDescriptor } from '@modular-vue/core'
|
|
3
2
|
import { createRegistry } from '@modular-vue/runtime'
|
|
4
3
|
import type { ModuleRegistry } from '@modular-vue/runtime'
|
|
4
|
+
import { navigationModule } from '~/modular/nav-contributions'
|
|
5
|
+
import type { AppSlots, NavGates } from '~/modular/nav-contributions'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* modular-vue registry for the `@cat-factory/app` layer (slice 0 of the
|
|
@@ -13,21 +14,29 @@ import type { ModuleRegistry } from '@modular-vue/runtime'
|
|
|
13
14
|
* contributes its own, all through the same seam. The registry is resolved and
|
|
14
15
|
* installed by `app/plugins/modular.client.ts`.
|
|
15
16
|
*
|
|
16
|
-
* Slice
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Slice 1 registers the first real feature module: `cat-factory:navigation`
|
|
18
|
+
* contributes the whole nav/command catalog to the `nav` slot, gated reactively
|
|
19
|
+
* by a `gates` service + `navSlotFilter` and rendered by `SideBar`, `CommandBar`,
|
|
20
|
+
* and `BoardToolbar` via `useReactiveSlots`. Later slices add result views,
|
|
21
|
+
* wizards, and inspector panels as further modules registered here.
|
|
20
22
|
*/
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* The layer's shared-dependency shape (grows as later slices wire more deps).
|
|
26
|
+
* A `type` (not `interface`) so it satisfies the registry's
|
|
27
|
+
* `Record<string, any>` dependency constraint — an interface lacks the implicit
|
|
28
|
+
* index signature a type-literal has.
|
|
27
29
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
export type AppDeps = {
|
|
31
|
+
/** Reactive RBAC/availability gates the nav `slotFilter` reads. */
|
|
32
|
+
gates: NavGates
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* First-party modules the layer always registers. Real feature modules land
|
|
37
|
+
* here as each area is converted; slice 1 adds the navigation catalog.
|
|
38
|
+
*/
|
|
39
|
+
const FIRST_PARTY_MODULES: readonly AnyModuleDescriptor[] = [navigationModule]
|
|
31
40
|
|
|
32
41
|
/**
|
|
33
42
|
* Consumer-contributed modules, collected before the layer resolves its
|
|
@@ -65,9 +74,18 @@ export function __resetConsumerModulesForTest(): void {
|
|
|
65
74
|
* contributed via {@link registerAppModule}. A new registry per call because
|
|
66
75
|
* `resolve()` / `resolveManifest()` are single-commit; the install plugin calls
|
|
67
76
|
* this exactly once at client startup (`ssr: false`, so a singleton app).
|
|
77
|
+
*
|
|
78
|
+
* `deps.gates` is the reactive gate service the nav `slotFilter` reads; it's
|
|
79
|
+
* built in the install plugin (Vue context) and registered as a `service` so
|
|
80
|
+
* `useReactiveSlots` tracks it. The `nav` slot default is seeded empty so the
|
|
81
|
+
* key always exists even before any module (or with only consumer modules)
|
|
82
|
+
* contributes.
|
|
68
83
|
*/
|
|
69
|
-
export function createAppRegistry(): ModuleRegistry<
|
|
70
|
-
const registry = createRegistry<
|
|
84
|
+
export function createAppRegistry(deps: AppDeps): ModuleRegistry<AppDeps, AppSlots> {
|
|
85
|
+
const registry = createRegistry<AppDeps, AppSlots>({
|
|
86
|
+
services: { gates: deps.gates },
|
|
87
|
+
slots: { nav: [] },
|
|
88
|
+
})
|
|
71
89
|
for (const mod of [...FIRST_PARTY_MODULES, ...consumerModules]) {
|
|
72
90
|
registry.register(mod)
|
|
73
91
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { installModularApp } from '@modular-vue/nuxt/runtime'
|
|
2
2
|
import { createAppRegistry } from '~/modular/registry'
|
|
3
|
+
import { navSlotFilter } from '~/modular/nav-contributions'
|
|
4
|
+
import { createNavGates } from '~/modular/nav-gates'
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Wire the modular-vue registry into the Nuxt app (slice 0 of the modular-vue
|
|
@@ -16,17 +18,23 @@ import { createAppRegistry } from '~/modular/registry'
|
|
|
16
18
|
*
|
|
17
19
|
* `ssr: false`, so this runs once on the client and a singleton registry is
|
|
18
20
|
* fine. `installModularApp` is the router-owning path: it grafts each module's
|
|
19
|
-
* routes onto Nuxt's router (none yet —
|
|
20
|
-
* installs the modular contexts (shared deps, navigation, slots) app-wide.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* routes onto Nuxt's router (none yet — the nav modules are non-routed) and
|
|
22
|
+
* installs the modular contexts (shared deps, navigation, slots) app-wide.
|
|
23
|
+
*
|
|
24
|
+
* Slice 1 wires the reactive nav gating here: `createNavGates()` builds the
|
|
25
|
+
* reactive `gates` service (Pinia + composables are available in a `post`
|
|
26
|
+
* plugin), which the registry registers as a `service` and `navSlotFilter` reads
|
|
27
|
+
* per item. The shells consume the gated `nav` slot through `useReactiveSlots`,
|
|
28
|
+
* so a permission/connection flip re-gates them with no `recalculateSlots()`.
|
|
23
29
|
*/
|
|
24
30
|
export default defineNuxtPlugin({
|
|
25
31
|
name: 'cat-factory:modular',
|
|
26
32
|
enforce: 'post',
|
|
27
33
|
setup(nuxtApp) {
|
|
28
|
-
const registry = createAppRegistry()
|
|
29
|
-
const manifest = installModularApp({ vueApp: nuxtApp.vueApp, $router: useRouter() }, registry
|
|
34
|
+
const registry = createAppRegistry({ gates: createNavGates() })
|
|
35
|
+
const manifest = installModularApp({ vueApp: nuxtApp.vueApp, $router: useRouter() }, registry, {
|
|
36
|
+
slotFilter: navSlotFilter,
|
|
37
|
+
})
|
|
30
38
|
return { provide: { modular: manifest } }
|
|
31
39
|
},
|
|
32
40
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.133.0",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@modular-frontend/core": "^0.1.0",
|
|
22
22
|
"@modular-vue/core": "^1.0.1",
|
|
23
23
|
"@modular-vue/nuxt": "^0.1.1",
|
|
24
|
-
"@modular-vue/runtime": "^1.0
|
|
25
|
-
"@modular-vue/vue": "^1.
|
|
24
|
+
"@modular-vue/runtime": "^1.1.0",
|
|
25
|
+
"@modular-vue/vue": "^1.1.0",
|
|
26
26
|
"@nuxt/ui": "^4.9.0",
|
|
27
27
|
"@nuxtjs/i18n": "^10.4.1",
|
|
28
28
|
"@pinia/nuxt": "^0.11.3",
|