@quazardous/qdadm 1.19.3

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.
Files changed (291) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/package.json +101 -0
  4. package/src/assets/logo.svg +6 -0
  5. package/src/auth/SessionAuthAdapter.ts +459 -0
  6. package/src/auth/index.ts +15 -0
  7. package/src/chain/ActiveStack.ts +154 -0
  8. package/src/chain/StackHydrator.ts +292 -0
  9. package/src/chain/index.ts +25 -0
  10. package/src/chain/useActiveStack.ts +120 -0
  11. package/src/chain/useStackHydrator.ts +155 -0
  12. package/src/components/BoolCell.vue +34 -0
  13. package/src/components/InfoBanner.vue +73 -0
  14. package/src/components/QdadmRoot.vue +52 -0
  15. package/src/components/SeverityTag.vue +86 -0
  16. package/src/components/dialogs/BulkStatusDialog.vue +60 -0
  17. package/src/components/dialogs/MultiStepDialog.vue +331 -0
  18. package/src/components/dialogs/SimpleDialog.vue +122 -0
  19. package/src/components/dialogs/UnsavedChangesDialog.vue +80 -0
  20. package/src/components/display/BannerZone.vue +65 -0
  21. package/src/components/display/CardsGrid.vue +72 -0
  22. package/src/components/display/CopyableId.vue +84 -0
  23. package/src/components/display/EmptyState.vue +62 -0
  24. package/src/components/display/IntensityBar.vue +190 -0
  25. package/src/components/display/RichCardsGrid.vue +101 -0
  26. package/src/components/edit/FormActions.vue +78 -0
  27. package/src/components/edit/FormField.vue +82 -0
  28. package/src/components/edit/FormInput.vue +158 -0
  29. package/src/components/edit/FormPage.vue +260 -0
  30. package/src/components/edit/FormTab.vue +217 -0
  31. package/src/components/edit/FormTabs.vue +120 -0
  32. package/src/components/edit/LookupField.vue +406 -0
  33. package/src/components/edit/LookupPickerDialog.vue +230 -0
  34. package/src/components/editors/JsonEditorFoldable.vue +470 -0
  35. package/src/components/editors/JsonStructuredField.vue +264 -0
  36. package/src/components/editors/JsonViewer.vue +51 -0
  37. package/src/components/editors/KeyValueEditor.vue +314 -0
  38. package/src/components/editors/LanguageEditor.vue +259 -0
  39. package/src/components/editors/PermissionEditor.vue +558 -0
  40. package/src/components/editors/ScopeEditor.vue +372 -0
  41. package/src/components/editors/VanillaJsonEditor.vue +183 -0
  42. package/src/components/index.ts +83 -0
  43. package/src/components/item/FieldGroups.vue +392 -0
  44. package/src/components/layout/AppLayout.vue +1032 -0
  45. package/src/components/layout/BaseLayout.vue +190 -0
  46. package/src/components/layout/Breadcrumb.vue +55 -0
  47. package/src/components/layout/DashboardLayout.vue +104 -0
  48. package/src/components/layout/FormLayout.vue +256 -0
  49. package/src/components/layout/ListLayout.vue +278 -0
  50. package/src/components/layout/PageHeader.vue +156 -0
  51. package/src/components/layout/PageLayout.vue +126 -0
  52. package/src/components/layout/PageNav.vue +192 -0
  53. package/src/components/layout/SidebarBox.vue +87 -0
  54. package/src/components/layout/Zone.vue +182 -0
  55. package/src/components/layout/defaults/DefaultBreadcrumb.vue +149 -0
  56. package/src/components/layout/defaults/DefaultFooter.vue +89 -0
  57. package/src/components/layout/defaults/DefaultFormActions.vue +67 -0
  58. package/src/components/layout/defaults/DefaultHeader.vue +78 -0
  59. package/src/components/layout/defaults/DefaultMenu.vue +188 -0
  60. package/src/components/layout/defaults/DefaultPagination.vue +75 -0
  61. package/src/components/layout/defaults/DefaultTable.vue +137 -0
  62. package/src/components/layout/defaults/DefaultUserInfo.vue +111 -0
  63. package/src/components/layout/defaults/index.ts +16 -0
  64. package/src/components/lists/ActionButtons.vue +49 -0
  65. package/src/components/lists/ActionColumn.vue +40 -0
  66. package/src/components/lists/FilterBar.vue +54 -0
  67. package/src/components/lists/ListPage.vue +467 -0
  68. package/src/components/pages/LoginPage.vue +334 -0
  69. package/src/components/pages/NotFoundPage.vue +98 -0
  70. package/src/components/show/ShowDisplay.vue +343 -0
  71. package/src/components/show/ShowField.vue +67 -0
  72. package/src/components/show/ShowPage.vue +431 -0
  73. package/src/composables/index.ts +155 -0
  74. package/src/composables/useApp.ts +67 -0
  75. package/src/composables/useAuth.ts +98 -0
  76. package/src/composables/useBareForm.ts +319 -0
  77. package/src/composables/useBreadcrumb.ts +252 -0
  78. package/src/composables/useChildPage.ts +113 -0
  79. package/src/composables/useCurrentEntity.ts +60 -0
  80. package/src/composables/useDeferred.ts +94 -0
  81. package/src/composables/useDirtyState.ts +138 -0
  82. package/src/composables/useEntityItemFormPage.ts +942 -0
  83. package/src/composables/useEntityItemFormPage.types.ts +451 -0
  84. package/src/composables/useEntityItemPage.ts +438 -0
  85. package/src/composables/useEntityItemShowPage.ts +722 -0
  86. package/src/composables/useFieldManager.ts +692 -0
  87. package/src/composables/useForm.ts +544 -0
  88. package/src/composables/useGuardStore.ts +53 -0
  89. package/src/composables/useHooks.ts +56 -0
  90. package/src/composables/useInfoBanner.ts +217 -0
  91. package/src/composables/useJsonSyntax.ts +122 -0
  92. package/src/composables/useLayoutResolver.ts +329 -0
  93. package/src/composables/useListPage.ts +1535 -0
  94. package/src/composables/useListPage.types.ts +437 -0
  95. package/src/composables/useListPage.utils.ts +101 -0
  96. package/src/composables/useNavContext.ts +439 -0
  97. package/src/composables/useNavigation.ts +216 -0
  98. package/src/composables/useOptionsLookup.ts +323 -0
  99. package/src/composables/usePageTitle.ts +84 -0
  100. package/src/composables/useSSEBridge.ts +142 -0
  101. package/src/composables/useSemanticBreadcrumb.ts +222 -0
  102. package/src/composables/useSidebarState.ts +24 -0
  103. package/src/composables/useSignals.ts +52 -0
  104. package/src/composables/useUnsavedChangesGuard.ts +155 -0
  105. package/src/composables/useUserImpersonator.ts +317 -0
  106. package/src/composables/useZoneRegistry.ts +252 -0
  107. package/src/core/bundles.ts +558 -0
  108. package/src/core/decorator.ts +420 -0
  109. package/src/core/extension.ts +470 -0
  110. package/src/core/index.ts +59 -0
  111. package/src/deferred/DeferredRegistry.ts +353 -0
  112. package/src/deferred/index.ts +15 -0
  113. package/src/editors/index.ts +12 -0
  114. package/src/entity/EntityManager.cache.ts +530 -0
  115. package/src/entity/EntityManager.crud.ts +615 -0
  116. package/src/entity/EntityManager.interface.ts +78 -0
  117. package/src/entity/EntityManager.query.ts +221 -0
  118. package/src/entity/EntityManager.relations.ts +151 -0
  119. package/src/entity/EntityManager.ts +944 -0
  120. package/src/entity/EntityManager.types.ts +288 -0
  121. package/src/entity/auth/CompositeAuthAdapter.ts +194 -0
  122. package/src/entity/auth/EntityAuthAdapter.ts +119 -0
  123. package/src/entity/auth/PermissiveAdapter.ts +43 -0
  124. package/src/entity/auth/RoleHierarchy.ts +128 -0
  125. package/src/entity/auth/SecurityChecker.ts +202 -0
  126. package/src/entity/auth/factory.ts +203 -0
  127. package/src/entity/auth/index.ts +47 -0
  128. package/src/entity/factory.test.js +189 -0
  129. package/src/entity/factory.ts +146 -0
  130. package/src/entity/index.ts +49 -0
  131. package/src/entity/storage/ApiStorage.ts +228 -0
  132. package/src/entity/storage/IStorage.ts +100 -0
  133. package/src/entity/storage/LocalStorage.ts +200 -0
  134. package/src/entity/storage/MemoryStorage.ts +184 -0
  135. package/src/entity/storage/MockApiStorage.ts +318 -0
  136. package/src/entity/storage/SdkStorage.ts +377 -0
  137. package/src/entity/storage/factory.test.js +159 -0
  138. package/src/entity/storage/factory.ts +209 -0
  139. package/src/entity/storage/index.ts +75 -0
  140. package/src/gen/FieldMapper.ts +122 -0
  141. package/src/gen/StorageProfileFactory.ts +93 -0
  142. package/src/gen/connectors/BaseConnector.ts +150 -0
  143. package/src/gen/connectors/ManualConnector.test.js +499 -0
  144. package/src/gen/connectors/ManualConnector.ts +414 -0
  145. package/src/gen/connectors/OpenAPIConnector.test.js +836 -0
  146. package/src/gen/connectors/OpenAPIConnector.ts +693 -0
  147. package/src/gen/connectors/__fixtures__/sample-openapi.json +311 -0
  148. package/src/gen/connectors/index.ts +27 -0
  149. package/src/gen/createManagers.ts +245 -0
  150. package/src/gen/decorators.ts +134 -0
  151. package/src/gen/generateManagers.test.js +540 -0
  152. package/src/gen/generateManagers.ts +398 -0
  153. package/src/gen/index.ts +66 -0
  154. package/src/gen/schema.ts +248 -0
  155. package/src/gen/vite-plugin.ts +114 -0
  156. package/src/generated/managers/testManager.js +45 -0
  157. package/src/generated/managers/testManager.ts +46 -0
  158. package/src/hooks/HookRegistry.ts +16 -0
  159. package/src/hooks/index.ts +15 -0
  160. package/src/i18n/I18n.ts +344 -0
  161. package/src/i18n/IncrementalDomainProvider.ts +153 -0
  162. package/src/i18n/InlineTranslationProvider.ts +4 -0
  163. package/src/i18n/LazyTranslationProvider.ts +102 -0
  164. package/src/i18n/MessagesRegistry.ts +4 -0
  165. package/src/i18n/Resolver.ts +4 -0
  166. package/src/i18n/__tests__/I18n.test.ts +169 -0
  167. package/src/i18n/__tests__/IncrementalDomainProvider.test.ts +146 -0
  168. package/src/i18n/__tests__/LazyTranslationProvider.test.ts +100 -0
  169. package/src/i18n/__tests__/Resolver.test.ts +271 -0
  170. package/src/i18n/defaults/DefaultCoreProvider.ts +28 -0
  171. package/src/i18n/defaults/core.en.yml +55 -0
  172. package/src/i18n/defaults/core.fr.yml +55 -0
  173. package/src/i18n/index.ts +55 -0
  174. package/src/i18n/loaders/raw-modules.d.ts +15 -0
  175. package/src/i18n/loaders/yaml.ts +35 -0
  176. package/src/i18n/strategies.ts +4 -0
  177. package/src/i18n/types.ts +34 -0
  178. package/src/i18n/useI18n.ts +34 -0
  179. package/src/index.ts +453 -0
  180. package/src/kernel/EventRouter.ts +23 -0
  181. package/src/kernel/Kernel.api.ts +79 -0
  182. package/src/kernel/Kernel.auth.ts +120 -0
  183. package/src/kernel/Kernel.i18n.ts +29 -0
  184. package/src/kernel/Kernel.modules.ts +170 -0
  185. package/src/kernel/Kernel.registries.ts +237 -0
  186. package/src/kernel/Kernel.routing.ts +334 -0
  187. package/src/kernel/Kernel.ts +460 -0
  188. package/src/kernel/Kernel.types.ts +263 -0
  189. package/src/kernel/Kernel.vue.ts +304 -0
  190. package/src/kernel/KernelContext.entities.ts +80 -0
  191. package/src/kernel/KernelContext.events.ts +57 -0
  192. package/src/kernel/KernelContext.i18n.ts +37 -0
  193. package/src/kernel/KernelContext.permissions.ts +38 -0
  194. package/src/kernel/KernelContext.routing.ts +280 -0
  195. package/src/kernel/KernelContext.ts +252 -0
  196. package/src/kernel/KernelContext.types.ts +173 -0
  197. package/src/kernel/KernelContext.zones.ts +54 -0
  198. package/src/kernel/Module.ts +169 -0
  199. package/src/kernel/ModuleLoader.ts +645 -0
  200. package/src/kernel/SSEBridge.ts +11 -0
  201. package/src/kernel/SignalBus.ts +48 -0
  202. package/src/kernel/index.ts +56 -0
  203. package/src/module/index.ts +33 -0
  204. package/src/module/moduleRegistry.ts +492 -0
  205. package/src/modules/debug/AuthCollector.ts +501 -0
  206. package/src/modules/debug/Collector.ts +20 -0
  207. package/src/modules/debug/DebugBridge.ts +14 -0
  208. package/src/modules/debug/DebugModule.ts +220 -0
  209. package/src/modules/debug/EntitiesCollector.ts +839 -0
  210. package/src/modules/debug/ErrorCollector.ts +4 -0
  211. package/src/modules/debug/I18nCollector.ts +9 -0
  212. package/src/modules/debug/LocalStorageAdapter.ts +7 -0
  213. package/src/modules/debug/RouterCollector.ts +449 -0
  214. package/src/modules/debug/SignalCollector.ts +4 -0
  215. package/src/modules/debug/ToastCollector.ts +4 -0
  216. package/src/modules/debug/ZonesCollector.ts +447 -0
  217. package/src/modules/debug/components/DebugBar.vue +31 -0
  218. package/src/modules/debug/components/adminPanelsConfig.ts +42 -0
  219. package/src/modules/debug/components/index.ts +9 -0
  220. package/src/modules/debug/components/panels/AuthPanel.vue +267 -0
  221. package/src/modules/debug/components/panels/EntitiesPanel.vue +572 -0
  222. package/src/modules/debug/components/panels/I18nPanel.vue +738 -0
  223. package/src/modules/debug/components/panels/RouterPanel.vue +440 -0
  224. package/src/modules/debug/components/panels/ZonesPanel.vue +133 -0
  225. package/src/modules/debug/components/panels/index.ts +16 -0
  226. package/src/modules/debug/index.ts +58 -0
  227. package/src/modules/debug/styles.scss +2671 -0
  228. package/src/notifications/NotificationBadge.vue +35 -0
  229. package/src/notifications/NotificationListener.vue +71 -0
  230. package/src/notifications/NotificationModule.ts +76 -0
  231. package/src/notifications/NotificationPanel.vue +478 -0
  232. package/src/notifications/NotificationStore.ts +288 -0
  233. package/src/notifications/index.ts +42 -0
  234. package/src/notifications/styles.scss +32 -0
  235. package/src/orchestrator/Orchestrator.ts +427 -0
  236. package/src/orchestrator/index.ts +8 -0
  237. package/src/orchestrator/useOrchestrator.ts +80 -0
  238. package/src/plugin.ts +251 -0
  239. package/src/query/FilterQuery.ts +306 -0
  240. package/src/query/QueryExecutor.ts +341 -0
  241. package/src/query/index.ts +16 -0
  242. package/src/security/EntityRolesProvider.ts +385 -0
  243. package/src/security/PermissionMatcher.ts +152 -0
  244. package/src/security/PermissionRegistry.ts +273 -0
  245. package/src/security/PersistableRolesProvider.ts +584 -0
  246. package/src/security/RolesManager.ts +136 -0
  247. package/src/security/RolesProvider.ts +167 -0
  248. package/src/security/RolesProviderStorage.ts +211 -0
  249. package/src/security/SecurityModule.ts +94 -0
  250. package/src/security/StaticRolesProvider.ts +117 -0
  251. package/src/security/UsersManager.ts +163 -0
  252. package/src/security/index.ts +77 -0
  253. package/src/security/pages/RoleForm.vue +276 -0
  254. package/src/security/pages/RoleList.vue +123 -0
  255. package/src/styles/_alerts.scss +95 -0
  256. package/src/styles/_buttons.scss +391 -0
  257. package/src/styles/_cards.scss +241 -0
  258. package/src/styles/_code.scss +78 -0
  259. package/src/styles/_dialogs.scss +55 -0
  260. package/src/styles/_filter-bar.scss +70 -0
  261. package/src/styles/_forms.scss +434 -0
  262. package/src/styles/_helpers.scss +153 -0
  263. package/src/styles/_lists.scss +225 -0
  264. package/src/styles/_main.scss +356 -0
  265. package/src/styles/_markdown.scss +88 -0
  266. package/src/styles/_responsive.scss +255 -0
  267. package/src/styles/_show-pages.scss +186 -0
  268. package/src/styles/_sidebar.scss +380 -0
  269. package/src/styles/_states.scss +115 -0
  270. package/src/styles/_stats.scss +47 -0
  271. package/src/styles/_variables.scss +224 -0
  272. package/src/styles/index.scss +38 -0
  273. package/src/styles/theme/_components.scss +331 -0
  274. package/src/styles/theme/_index.scss +10 -0
  275. package/src/styles/theme/_tokens.scss +147 -0
  276. package/src/styles/theme/_utilities.scss +175 -0
  277. package/src/toast/ToastBridgeModule.ts +68 -0
  278. package/src/toast/ToastListener.vue +55 -0
  279. package/src/toast/index.ts +26 -0
  280. package/src/toast/useSignalToast.ts +154 -0
  281. package/src/types/index.ts +285 -0
  282. package/src/types/pluralize.d.ts +19 -0
  283. package/src/types/quarkernel.d.ts +50 -0
  284. package/src/utils/formatters.ts +174 -0
  285. package/src/utils/index.ts +35 -0
  286. package/src/utils/transformers.ts +131 -0
  287. package/src/vite/qdadmDebugPlugin.ts +401 -0
  288. package/src/vite-env.d.ts +50 -0
  289. package/src/zones/ZoneRegistry.ts +934 -0
  290. package/src/zones/index.ts +29 -0
  291. package/src/zones/zones.ts +191 -0
@@ -0,0 +1,447 @@
1
+ /**
2
+ * ZonesCollector - Debug collector for Zone Registry visualization
3
+ *
4
+ * This collector provides real-time visibility into the zone system:
5
+ * - All defined zones
6
+ * - Blocks registered in each zone
7
+ * - Wrapper chains
8
+ * - Visual highlighting of zones on the page
9
+ *
10
+ * Unlike event collectors, this shows current state rather than historical events.
11
+ *
12
+ * @example
13
+ * const collector = new ZonesCollector()
14
+ * collector.install(ctx)
15
+ * collector.getZoneInfo() // { zones: [...], totalBlocks: n }
16
+ */
17
+
18
+ import {
19
+ Collector,
20
+ type CollectorContext,
21
+ type CollectorEntry,
22
+ type CollectorManifest,
23
+ type CollectorOptions,
24
+ type CollectorSnapshot,
25
+ } from './Collector'
26
+ import type { ZoneRegistry } from '../../zones/ZoneRegistry'
27
+ import type { Router } from 'vue-router'
28
+
29
+ /**
30
+ * Zone entry type (state-based, not event-based)
31
+ */
32
+ export interface ZoneEntry extends CollectorEntry {
33
+ name: string
34
+ isOnPage: boolean
35
+ hasDefault: boolean
36
+ defaultName: string | null
37
+ blocksCount: number
38
+ blocks: ZoneBlock[]
39
+ }
40
+
41
+ /**
42
+ * Zone block info
43
+ */
44
+ export interface ZoneBlock {
45
+ id: string
46
+ weight: number
47
+ component: string
48
+ hasWrappers: boolean
49
+ wrappersCount: number
50
+ wrappers: ZoneWrapper[]
51
+ }
52
+
53
+ /**
54
+ * Zone wrapper info
55
+ */
56
+ export interface ZoneWrapper {
57
+ component: string
58
+ weight: number
59
+ }
60
+
61
+ /**
62
+ * ZonesCollector options
63
+ */
64
+ export interface ZonesCollectorOptions extends CollectorOptions {
65
+ showCurrentPageOnly?: boolean
66
+ showInternalZones?: boolean
67
+ }
68
+
69
+ /**
70
+ * Extended context for zones collector
71
+ */
72
+ interface ZonesCollectorContext extends CollectorContext {
73
+ zones?: ZoneRegistry
74
+ router?: Router
75
+ }
76
+
77
+ /**
78
+ * Collector for Zone Registry state visualization
79
+ */
80
+ export class ZonesCollector extends Collector<ZoneEntry> {
81
+ /**
82
+ * Collector name identifier
83
+ */
84
+ static override collectorName = 'zones'
85
+
86
+ /**
87
+ * This collector shows state, not events
88
+ */
89
+ static override records = false
90
+
91
+ private _registry: ZoneRegistry | null = null
92
+ private _highlightedZone: string | null = null
93
+ private _overlays: Map<string, HTMLDivElement> = new Map()
94
+ private _showCurrentPageOnly: boolean
95
+ private _showInternalZones: boolean
96
+ private _routerCleanup: (() => void) | null = null
97
+
98
+ constructor(options: ZonesCollectorOptions = {}) {
99
+ super(options)
100
+ this._showCurrentPageOnly = options.showCurrentPageOnly ?? true
101
+ this._showInternalZones = options.showInternalZones ?? false
102
+ }
103
+
104
+ /**
105
+ * Internal install - get zone registry reference and subscribe to navigation
106
+ * @protected
107
+ */
108
+ protected override _doInstall(ctx: CollectorContext): void {
109
+ this._ctx = ctx
110
+ this._registry = (ctx as ZonesCollectorContext).zones ?? null
111
+ if (!this._registry) {
112
+ console.warn('[ZonesCollector] No zone registry found in context')
113
+ }
114
+ this._setupRouterListener()
115
+ }
116
+
117
+ /**
118
+ * Setup router listener for navigation changes
119
+ * @private
120
+ */
121
+ private _setupRouterListener(): void {
122
+ const router = (this._ctx as ZonesCollectorContext)?.router
123
+ if (!router) {
124
+ setTimeout(() => this._setupRouterListener(), 100)
125
+ return
126
+ }
127
+
128
+ // Listen to route changes - zones on page may differ
129
+ this._routerCleanup = router.afterEach(() => {
130
+ // Small delay to let DOM update
131
+ setTimeout(() => this.notifyChange(), 50)
132
+ })
133
+ }
134
+
135
+ /**
136
+ * Internal uninstall - cleanup highlights and router listener
137
+ * @protected
138
+ */
139
+ protected override _doUninstall(): void {
140
+ this.clearHighlights()
141
+ if (this._routerCleanup) {
142
+ this._routerCleanup()
143
+ this._routerCleanup = null
144
+ }
145
+ this._registry = null
146
+ this._ctx = null
147
+ }
148
+
149
+ /**
150
+ * Check if a zone is rendered on the current page
151
+ * @param zoneName - Zone name to check
152
+ *
153
+ * Note: Internal zones (prefixed with _) are currently considered always on page
154
+ * since they're typically global (app:debug, app:toasts).
155
+ */
156
+ isZoneOnPage(zoneName: string): boolean {
157
+ // Internal zones are global, always considered "on page"
158
+ if (zoneName.startsWith('_')) {
159
+ return true
160
+ }
161
+ const escapedName = CSS.escape(zoneName)
162
+ return document.querySelector(`[data-zone="${zoneName}"], .zone-${escapedName}`) !== null
163
+ }
164
+
165
+ /**
166
+ * Get/set filter for current page zones only
167
+ */
168
+ get showCurrentPageOnly(): boolean {
169
+ return this._showCurrentPageOnly
170
+ }
171
+
172
+ set showCurrentPageOnly(value: boolean) {
173
+ this._showCurrentPageOnly = value
174
+ }
175
+
176
+ /**
177
+ * Toggle current page filter
178
+ * @returns New filter state
179
+ */
180
+ toggleFilter(): boolean {
181
+ this._showCurrentPageOnly = !this._showCurrentPageOnly
182
+ return this._showCurrentPageOnly
183
+ }
184
+
185
+ /**
186
+ * Get/set filter for internal zones (prefixed with _)
187
+ */
188
+ get showInternalZones(): boolean {
189
+ return this._showInternalZones
190
+ }
191
+
192
+ set showInternalZones(value: boolean) {
193
+ this._showInternalZones = value
194
+ }
195
+
196
+ /**
197
+ * Toggle internal zones filter
198
+ * @returns New filter state
199
+ */
200
+ toggleInternalFilter(): boolean {
201
+ this._showInternalZones = !this._showInternalZones
202
+ return this._showInternalZones
203
+ }
204
+
205
+ /**
206
+ * Get badge - show number of zones (filtered if filter active)
207
+ */
208
+ override getBadge(): number {
209
+ if (!this._registry) return 0
210
+ const registry = this._registry as unknown as { _zones: Map<string, unknown> }
211
+ let count = 0
212
+ for (const [name] of registry._zones) {
213
+ // Skip internal zones (prefixed with _) unless showing them
214
+ if (name.startsWith('_') && !this._showInternalZones) continue
215
+ // Apply page filter if enabled
216
+ if (this._showCurrentPageOnly && !this.isZoneOnPage(name)) continue
217
+ count++
218
+ }
219
+ return count
220
+ }
221
+
222
+ /**
223
+ * Get all zone information for display
224
+ * @param forceAll - If true, ignore filter and return all zones
225
+ * @returns Zone info array
226
+ */
227
+ override getEntries(forceAll = false): ZoneEntry[] {
228
+ if (!this._registry) return []
229
+
230
+ const registry = this._registry as unknown as {
231
+ _zones: Map<string, { default?: { name?: string; __name?: string } }>
232
+ getBlocks: (name: string) => Array<{
233
+ id?: string
234
+ weight: number
235
+ component?: { name?: string; __name?: string }
236
+ wrappers?: Array<{
237
+ component?: { name?: string; __name?: string }
238
+ weight: number
239
+ }>
240
+ }>
241
+ }
242
+
243
+ const zones: ZoneEntry[] = []
244
+ for (const [name, config] of registry._zones) {
245
+ // Skip internal zones (prefixed with _) unless showing them
246
+ if (name.startsWith('_') && !this._showInternalZones) {
247
+ continue
248
+ }
249
+
250
+ // Apply filter if enabled
251
+ const isOnPage = this.isZoneOnPage(name)
252
+ if (!forceAll && this._showCurrentPageOnly && !isOnPage) {
253
+ continue
254
+ }
255
+
256
+ const blocks = registry.getBlocks(name)
257
+ zones.push({
258
+ timestamp: Date.now(),
259
+ name,
260
+ isOnPage,
261
+ hasDefault: !!config.default,
262
+ defaultName: config.default?.name || config.default?.__name || null,
263
+ blocksCount: blocks.length,
264
+ blocks: blocks.map(b => ({
265
+ id: b.id || '(anonymous)',
266
+ weight: b.weight,
267
+ component: b.component?.name || b.component?.__name || 'Component',
268
+ hasWrappers: !!(b.wrappers && b.wrappers.length),
269
+ wrappersCount: b.wrappers?.length || 0,
270
+ wrappers: b.wrappers?.map(w => ({
271
+ component: w.component?.name || w.component?.__name || 'Wrapper',
272
+ weight: w.weight
273
+ })) || []
274
+ }))
275
+ })
276
+ }
277
+ return zones.sort((a, b) => a.name.localeCompare(b.name))
278
+ }
279
+
280
+ /**
281
+ * Highlight a zone on the page
282
+ * Creates a visual overlay around zone elements
283
+ * @param zoneName - Zone name to highlight
284
+ */
285
+ highlightZone(zoneName: string): void {
286
+ this.clearHighlights()
287
+ this._highlightedZone = zoneName
288
+
289
+ // Find zone elements by data attribute
290
+ const escapedName = CSS.escape(zoneName)
291
+ const elements = document.querySelectorAll(`[data-zone="${zoneName}"], .zone-${escapedName}`)
292
+
293
+ elements.forEach((el, idx) => {
294
+ const rect = el.getBoundingClientRect()
295
+ const overlay = document.createElement('div')
296
+ overlay.className = 'qdadm-zone-overlay'
297
+ overlay.style.cssText = `
298
+ position: fixed;
299
+ top: ${rect.top}px;
300
+ left: ${rect.left}px;
301
+ width: ${rect.width}px;
302
+ height: ${rect.height}px;
303
+ border: 2px dashed #8b5cf6;
304
+ background: rgba(139, 92, 246, 0.1);
305
+ pointer-events: none;
306
+ z-index: 99998;
307
+ transition: all 0.2s;
308
+ `
309
+
310
+ // Label
311
+ const label = document.createElement('div')
312
+ label.style.cssText = `
313
+ position: absolute;
314
+ top: -20px;
315
+ left: 0;
316
+ background: #8b5cf6;
317
+ color: white;
318
+ padding: 2px 6px;
319
+ font-size: 10px;
320
+ font-family: system-ui, sans-serif;
321
+ border-radius: 2px;
322
+ white-space: nowrap;
323
+ `
324
+ label.textContent = zoneName
325
+ overlay.appendChild(label)
326
+
327
+ document.body.appendChild(overlay)
328
+ this._overlays.set(`${zoneName}-${idx}`, overlay)
329
+ })
330
+ }
331
+
332
+ /**
333
+ * Clear all zone highlights
334
+ */
335
+ clearHighlights(): void {
336
+ this._overlays.forEach(overlay => overlay.remove())
337
+ this._overlays.clear()
338
+ this._highlightedZone = null
339
+ }
340
+
341
+ /**
342
+ * Get currently highlighted zone
343
+ */
344
+ getHighlightedZone(): string | null {
345
+ return this._highlightedZone
346
+ }
347
+
348
+ /**
349
+ * Toggle zone highlight
350
+ * @param zoneName - Zone name
351
+ * @returns Whether zone is now highlighted
352
+ */
353
+ toggleHighlight(zoneName: string): boolean {
354
+ if (this._highlightedZone === zoneName) {
355
+ this.clearHighlights()
356
+ return false
357
+ } else {
358
+ this.highlightZone(zoneName)
359
+ return true
360
+ }
361
+ }
362
+
363
+ override describe(): CollectorManifest {
364
+ return {
365
+ name: this.name,
366
+ records: false,
367
+ summary:
368
+ 'Lists every zone defined in the running app and the blocks/wrappers registered in each. Reflects current page (filterable).',
369
+ entryShape: {
370
+ name: 'string',
371
+ isOnPage: 'boolean',
372
+ hasDefault: 'boolean',
373
+ defaultName: 'string?',
374
+ blocksCount: 'number',
375
+ blocks: 'ZoneBlock[]',
376
+ },
377
+ stateShape: {
378
+ showCurrentPageOnly: 'boolean',
379
+ showInternalZones: 'boolean',
380
+ highlightedZone: 'string?',
381
+ },
382
+ actions: [
383
+ ...this._builtinActionManifests(),
384
+ {
385
+ name: 'highlight',
386
+ summary: 'Draw an overlay on the page around a zone (browser-only).',
387
+ args: { name: 'string' },
388
+ mutates: true,
389
+ },
390
+ {
391
+ name: 'clearHighlights',
392
+ summary: 'Remove every zone overlay.',
393
+ mutates: true,
394
+ },
395
+ {
396
+ name: 'setShowCurrentPageOnly',
397
+ summary: 'Filter zones to those rendered on the current page.',
398
+ args: { value: 'boolean' },
399
+ mutates: true,
400
+ },
401
+ {
402
+ name: 'setShowInternalZones',
403
+ summary: 'Show internal zones (prefixed with _).',
404
+ args: { value: 'boolean' },
405
+ mutates: true,
406
+ },
407
+ ],
408
+ }
409
+ }
410
+
411
+ override snapshot(): CollectorSnapshot {
412
+ const entries = this.getEntries(true)
413
+ return {
414
+ name: this.name,
415
+ entries,
416
+ count: entries.length,
417
+ unseen: 0,
418
+ state: {
419
+ showCurrentPageOnly: this._showCurrentPageOnly,
420
+ showInternalZones: this._showInternalZones,
421
+ highlightedZone: this._highlightedZone,
422
+ },
423
+ }
424
+ }
425
+
426
+ override async call(actionName: string, args: Record<string, unknown> = {}): Promise<unknown> {
427
+ if (actionName === 'highlight') {
428
+ this.highlightZone(String(args.name ?? ''))
429
+ return { ok: true }
430
+ }
431
+ if (actionName === 'clearHighlights') {
432
+ this.clearHighlights()
433
+ return { ok: true }
434
+ }
435
+ if (actionName === 'setShowCurrentPageOnly') {
436
+ this._showCurrentPageOnly = Boolean(args.value)
437
+ this.notifyChange()
438
+ return { ok: true, value: this._showCurrentPageOnly }
439
+ }
440
+ if (actionName === 'setShowInternalZones') {
441
+ this._showInternalZones = Boolean(args.value)
442
+ this.notifyChange()
443
+ return { ok: true, value: this._showInternalZones }
444
+ }
445
+ return super.call(actionName, args)
446
+ }
447
+ }
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * qdadm DebugBar wrapper.
4
+ *
5
+ * Wraps the panel-pluggable `@quazardous/qddebug` `DebugBar` with qdadm's
6
+ * admin-specific panels (auth, entities, router, zones, i18n) and the
7
+ * matching tab metadata (icons / labels / colors). Existing call sites that
8
+ * imported this file continue to work unchanged.
9
+ */
10
+ import { DebugBar as QddebugBar } from '@quazardous/qddebug'
11
+ import { adminPanels, adminPanelsMeta } from './adminPanelsConfig'
12
+
13
+ defineProps<{
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ bridge: any
16
+ zIndex?: number
17
+ }>()
18
+
19
+ // Preserve the legacy localStorage key so existing users keep their saved layout.
20
+ const STORAGE_KEY = 'qdadm-debug-bar'
21
+ </script>
22
+
23
+ <template>
24
+ <QddebugBar
25
+ :bridge="bridge"
26
+ :z-index="zIndex"
27
+ :storage-key="STORAGE_KEY"
28
+ :panels="adminPanels"
29
+ :collector-meta="adminPanelsMeta"
30
+ />
31
+ </template>
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Admin panel registry — extracted from `DebugBar.vue` so host shells
3
+ * that own a shared bridge (qdcms demo) can merge these panels with
4
+ * their own and feed them to a single `<DebugBar />` instead of two.
5
+ *
6
+ * The keys MUST match what `bridge.collectors` keys into — both the
7
+ * lowercase short names (`zones`, `auth`, …) and the legacy
8
+ * collectorName strings (`ZonesCollector`, …) are aliased here so
9
+ * the bar resolves them under either form.
10
+ */
11
+
12
+ import type { Component } from 'vue'
13
+ import type { CollectorMeta } from '@quazardous/qddebug'
14
+ import ZonesPanel from './panels/ZonesPanel.vue'
15
+ import AuthPanel from './panels/AuthPanel.vue'
16
+ import EntitiesPanel from './panels/EntitiesPanel.vue'
17
+ import RouterPanel from './panels/RouterPanel.vue'
18
+ import I18nPanel from './panels/I18nPanel.vue'
19
+
20
+ export const adminPanels: Record<string, Component> = {
21
+ zones: ZonesPanel,
22
+ ZonesCollector: ZonesPanel,
23
+ auth: AuthPanel,
24
+ AuthCollector: AuthPanel,
25
+ entities: EntitiesPanel,
26
+ EntitiesCollector: EntitiesPanel,
27
+ router: RouterPanel,
28
+ RouterCollector: RouterPanel,
29
+ i18n: I18nPanel,
30
+ I18nCollector: I18nPanel,
31
+ }
32
+
33
+ export const adminPanelsMeta: Record<string, CollectorMeta> = {
34
+ zones: { icon: 'pi-th-large', label: 'Zones', color: '#06b6d4' },
35
+ ZonesCollector: { icon: 'pi-th-large', label: 'Zones', color: '#06b6d4' },
36
+ auth: { icon: 'pi-user', label: 'Auth', color: '#10b981' },
37
+ AuthCollector: { icon: 'pi-user', label: 'Auth', color: '#10b981' },
38
+ entities: { icon: 'pi-database', label: 'Entities', color: '#3b82f6' },
39
+ EntitiesCollector: { icon: 'pi-database', label: 'Entities', color: '#3b82f6' },
40
+ router: { icon: 'pi-directions', label: 'Router', color: '#ec4899' },
41
+ RouterCollector: { icon: 'pi-directions', label: 'Router', color: '#ec4899' },
42
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Debug Components — qdadm.
3
+ *
4
+ * Re-exports the qdadm DebugBar wrapper and the qddebug ObjectTree to
5
+ * preserve qdadm's public API.
6
+ */
7
+
8
+ export { default as DebugBar } from './DebugBar.vue'
9
+ export { ObjectTree } from '@quazardous/qddebug'