@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.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/package.json +101 -0
- package/src/assets/logo.svg +6 -0
- package/src/auth/SessionAuthAdapter.ts +459 -0
- package/src/auth/index.ts +15 -0
- package/src/chain/ActiveStack.ts +154 -0
- package/src/chain/StackHydrator.ts +292 -0
- package/src/chain/index.ts +25 -0
- package/src/chain/useActiveStack.ts +120 -0
- package/src/chain/useStackHydrator.ts +155 -0
- package/src/components/BoolCell.vue +34 -0
- package/src/components/InfoBanner.vue +73 -0
- package/src/components/QdadmRoot.vue +52 -0
- package/src/components/SeverityTag.vue +86 -0
- package/src/components/dialogs/BulkStatusDialog.vue +60 -0
- package/src/components/dialogs/MultiStepDialog.vue +331 -0
- package/src/components/dialogs/SimpleDialog.vue +122 -0
- package/src/components/dialogs/UnsavedChangesDialog.vue +80 -0
- package/src/components/display/BannerZone.vue +65 -0
- package/src/components/display/CardsGrid.vue +72 -0
- package/src/components/display/CopyableId.vue +84 -0
- package/src/components/display/EmptyState.vue +62 -0
- package/src/components/display/IntensityBar.vue +190 -0
- package/src/components/display/RichCardsGrid.vue +101 -0
- package/src/components/edit/FormActions.vue +78 -0
- package/src/components/edit/FormField.vue +82 -0
- package/src/components/edit/FormInput.vue +158 -0
- package/src/components/edit/FormPage.vue +260 -0
- package/src/components/edit/FormTab.vue +217 -0
- package/src/components/edit/FormTabs.vue +120 -0
- package/src/components/edit/LookupField.vue +406 -0
- package/src/components/edit/LookupPickerDialog.vue +230 -0
- package/src/components/editors/JsonEditorFoldable.vue +470 -0
- package/src/components/editors/JsonStructuredField.vue +264 -0
- package/src/components/editors/JsonViewer.vue +51 -0
- package/src/components/editors/KeyValueEditor.vue +314 -0
- package/src/components/editors/LanguageEditor.vue +259 -0
- package/src/components/editors/PermissionEditor.vue +558 -0
- package/src/components/editors/ScopeEditor.vue +372 -0
- package/src/components/editors/VanillaJsonEditor.vue +183 -0
- package/src/components/index.ts +83 -0
- package/src/components/item/FieldGroups.vue +392 -0
- package/src/components/layout/AppLayout.vue +1032 -0
- package/src/components/layout/BaseLayout.vue +190 -0
- package/src/components/layout/Breadcrumb.vue +55 -0
- package/src/components/layout/DashboardLayout.vue +104 -0
- package/src/components/layout/FormLayout.vue +256 -0
- package/src/components/layout/ListLayout.vue +278 -0
- package/src/components/layout/PageHeader.vue +156 -0
- package/src/components/layout/PageLayout.vue +126 -0
- package/src/components/layout/PageNav.vue +192 -0
- package/src/components/layout/SidebarBox.vue +87 -0
- package/src/components/layout/Zone.vue +182 -0
- package/src/components/layout/defaults/DefaultBreadcrumb.vue +149 -0
- package/src/components/layout/defaults/DefaultFooter.vue +89 -0
- package/src/components/layout/defaults/DefaultFormActions.vue +67 -0
- package/src/components/layout/defaults/DefaultHeader.vue +78 -0
- package/src/components/layout/defaults/DefaultMenu.vue +188 -0
- package/src/components/layout/defaults/DefaultPagination.vue +75 -0
- package/src/components/layout/defaults/DefaultTable.vue +137 -0
- package/src/components/layout/defaults/DefaultUserInfo.vue +111 -0
- package/src/components/layout/defaults/index.ts +16 -0
- package/src/components/lists/ActionButtons.vue +49 -0
- package/src/components/lists/ActionColumn.vue +40 -0
- package/src/components/lists/FilterBar.vue +54 -0
- package/src/components/lists/ListPage.vue +467 -0
- package/src/components/pages/LoginPage.vue +334 -0
- package/src/components/pages/NotFoundPage.vue +98 -0
- package/src/components/show/ShowDisplay.vue +343 -0
- package/src/components/show/ShowField.vue +67 -0
- package/src/components/show/ShowPage.vue +431 -0
- package/src/composables/index.ts +155 -0
- package/src/composables/useApp.ts +67 -0
- package/src/composables/useAuth.ts +98 -0
- package/src/composables/useBareForm.ts +319 -0
- package/src/composables/useBreadcrumb.ts +252 -0
- package/src/composables/useChildPage.ts +113 -0
- package/src/composables/useCurrentEntity.ts +60 -0
- package/src/composables/useDeferred.ts +94 -0
- package/src/composables/useDirtyState.ts +138 -0
- package/src/composables/useEntityItemFormPage.ts +942 -0
- package/src/composables/useEntityItemFormPage.types.ts +451 -0
- package/src/composables/useEntityItemPage.ts +438 -0
- package/src/composables/useEntityItemShowPage.ts +722 -0
- package/src/composables/useFieldManager.ts +692 -0
- package/src/composables/useForm.ts +544 -0
- package/src/composables/useGuardStore.ts +53 -0
- package/src/composables/useHooks.ts +56 -0
- package/src/composables/useInfoBanner.ts +217 -0
- package/src/composables/useJsonSyntax.ts +122 -0
- package/src/composables/useLayoutResolver.ts +329 -0
- package/src/composables/useListPage.ts +1535 -0
- package/src/composables/useListPage.types.ts +437 -0
- package/src/composables/useListPage.utils.ts +101 -0
- package/src/composables/useNavContext.ts +439 -0
- package/src/composables/useNavigation.ts +216 -0
- package/src/composables/useOptionsLookup.ts +323 -0
- package/src/composables/usePageTitle.ts +84 -0
- package/src/composables/useSSEBridge.ts +142 -0
- package/src/composables/useSemanticBreadcrumb.ts +222 -0
- package/src/composables/useSidebarState.ts +24 -0
- package/src/composables/useSignals.ts +52 -0
- package/src/composables/useUnsavedChangesGuard.ts +155 -0
- package/src/composables/useUserImpersonator.ts +317 -0
- package/src/composables/useZoneRegistry.ts +252 -0
- package/src/core/bundles.ts +558 -0
- package/src/core/decorator.ts +420 -0
- package/src/core/extension.ts +470 -0
- package/src/core/index.ts +59 -0
- package/src/deferred/DeferredRegistry.ts +353 -0
- package/src/deferred/index.ts +15 -0
- package/src/editors/index.ts +12 -0
- package/src/entity/EntityManager.cache.ts +530 -0
- package/src/entity/EntityManager.crud.ts +615 -0
- package/src/entity/EntityManager.interface.ts +78 -0
- package/src/entity/EntityManager.query.ts +221 -0
- package/src/entity/EntityManager.relations.ts +151 -0
- package/src/entity/EntityManager.ts +944 -0
- package/src/entity/EntityManager.types.ts +288 -0
- package/src/entity/auth/CompositeAuthAdapter.ts +194 -0
- package/src/entity/auth/EntityAuthAdapter.ts +119 -0
- package/src/entity/auth/PermissiveAdapter.ts +43 -0
- package/src/entity/auth/RoleHierarchy.ts +128 -0
- package/src/entity/auth/SecurityChecker.ts +202 -0
- package/src/entity/auth/factory.ts +203 -0
- package/src/entity/auth/index.ts +47 -0
- package/src/entity/factory.test.js +189 -0
- package/src/entity/factory.ts +146 -0
- package/src/entity/index.ts +49 -0
- package/src/entity/storage/ApiStorage.ts +228 -0
- package/src/entity/storage/IStorage.ts +100 -0
- package/src/entity/storage/LocalStorage.ts +200 -0
- package/src/entity/storage/MemoryStorage.ts +184 -0
- package/src/entity/storage/MockApiStorage.ts +318 -0
- package/src/entity/storage/SdkStorage.ts +377 -0
- package/src/entity/storage/factory.test.js +159 -0
- package/src/entity/storage/factory.ts +209 -0
- package/src/entity/storage/index.ts +75 -0
- package/src/gen/FieldMapper.ts +122 -0
- package/src/gen/StorageProfileFactory.ts +93 -0
- package/src/gen/connectors/BaseConnector.ts +150 -0
- package/src/gen/connectors/ManualConnector.test.js +499 -0
- package/src/gen/connectors/ManualConnector.ts +414 -0
- package/src/gen/connectors/OpenAPIConnector.test.js +836 -0
- package/src/gen/connectors/OpenAPIConnector.ts +693 -0
- package/src/gen/connectors/__fixtures__/sample-openapi.json +311 -0
- package/src/gen/connectors/index.ts +27 -0
- package/src/gen/createManagers.ts +245 -0
- package/src/gen/decorators.ts +134 -0
- package/src/gen/generateManagers.test.js +540 -0
- package/src/gen/generateManagers.ts +398 -0
- package/src/gen/index.ts +66 -0
- package/src/gen/schema.ts +248 -0
- package/src/gen/vite-plugin.ts +114 -0
- package/src/generated/managers/testManager.js +45 -0
- package/src/generated/managers/testManager.ts +46 -0
- package/src/hooks/HookRegistry.ts +16 -0
- package/src/hooks/index.ts +15 -0
- package/src/i18n/I18n.ts +344 -0
- package/src/i18n/IncrementalDomainProvider.ts +153 -0
- package/src/i18n/InlineTranslationProvider.ts +4 -0
- package/src/i18n/LazyTranslationProvider.ts +102 -0
- package/src/i18n/MessagesRegistry.ts +4 -0
- package/src/i18n/Resolver.ts +4 -0
- package/src/i18n/__tests__/I18n.test.ts +169 -0
- package/src/i18n/__tests__/IncrementalDomainProvider.test.ts +146 -0
- package/src/i18n/__tests__/LazyTranslationProvider.test.ts +100 -0
- package/src/i18n/__tests__/Resolver.test.ts +271 -0
- package/src/i18n/defaults/DefaultCoreProvider.ts +28 -0
- package/src/i18n/defaults/core.en.yml +55 -0
- package/src/i18n/defaults/core.fr.yml +55 -0
- package/src/i18n/index.ts +55 -0
- package/src/i18n/loaders/raw-modules.d.ts +15 -0
- package/src/i18n/loaders/yaml.ts +35 -0
- package/src/i18n/strategies.ts +4 -0
- package/src/i18n/types.ts +34 -0
- package/src/i18n/useI18n.ts +34 -0
- package/src/index.ts +453 -0
- package/src/kernel/EventRouter.ts +23 -0
- package/src/kernel/Kernel.api.ts +79 -0
- package/src/kernel/Kernel.auth.ts +120 -0
- package/src/kernel/Kernel.i18n.ts +29 -0
- package/src/kernel/Kernel.modules.ts +170 -0
- package/src/kernel/Kernel.registries.ts +237 -0
- package/src/kernel/Kernel.routing.ts +334 -0
- package/src/kernel/Kernel.ts +460 -0
- package/src/kernel/Kernel.types.ts +263 -0
- package/src/kernel/Kernel.vue.ts +304 -0
- package/src/kernel/KernelContext.entities.ts +80 -0
- package/src/kernel/KernelContext.events.ts +57 -0
- package/src/kernel/KernelContext.i18n.ts +37 -0
- package/src/kernel/KernelContext.permissions.ts +38 -0
- package/src/kernel/KernelContext.routing.ts +280 -0
- package/src/kernel/KernelContext.ts +252 -0
- package/src/kernel/KernelContext.types.ts +173 -0
- package/src/kernel/KernelContext.zones.ts +54 -0
- package/src/kernel/Module.ts +169 -0
- package/src/kernel/ModuleLoader.ts +645 -0
- package/src/kernel/SSEBridge.ts +11 -0
- package/src/kernel/SignalBus.ts +48 -0
- package/src/kernel/index.ts +56 -0
- package/src/module/index.ts +33 -0
- package/src/module/moduleRegistry.ts +492 -0
- package/src/modules/debug/AuthCollector.ts +501 -0
- package/src/modules/debug/Collector.ts +20 -0
- package/src/modules/debug/DebugBridge.ts +14 -0
- package/src/modules/debug/DebugModule.ts +220 -0
- package/src/modules/debug/EntitiesCollector.ts +839 -0
- package/src/modules/debug/ErrorCollector.ts +4 -0
- package/src/modules/debug/I18nCollector.ts +9 -0
- package/src/modules/debug/LocalStorageAdapter.ts +7 -0
- package/src/modules/debug/RouterCollector.ts +449 -0
- package/src/modules/debug/SignalCollector.ts +4 -0
- package/src/modules/debug/ToastCollector.ts +4 -0
- package/src/modules/debug/ZonesCollector.ts +447 -0
- package/src/modules/debug/components/DebugBar.vue +31 -0
- package/src/modules/debug/components/adminPanelsConfig.ts +42 -0
- package/src/modules/debug/components/index.ts +9 -0
- package/src/modules/debug/components/panels/AuthPanel.vue +267 -0
- package/src/modules/debug/components/panels/EntitiesPanel.vue +572 -0
- package/src/modules/debug/components/panels/I18nPanel.vue +738 -0
- package/src/modules/debug/components/panels/RouterPanel.vue +440 -0
- package/src/modules/debug/components/panels/ZonesPanel.vue +133 -0
- package/src/modules/debug/components/panels/index.ts +16 -0
- package/src/modules/debug/index.ts +58 -0
- package/src/modules/debug/styles.scss +2671 -0
- package/src/notifications/NotificationBadge.vue +35 -0
- package/src/notifications/NotificationListener.vue +71 -0
- package/src/notifications/NotificationModule.ts +76 -0
- package/src/notifications/NotificationPanel.vue +478 -0
- package/src/notifications/NotificationStore.ts +288 -0
- package/src/notifications/index.ts +42 -0
- package/src/notifications/styles.scss +32 -0
- package/src/orchestrator/Orchestrator.ts +427 -0
- package/src/orchestrator/index.ts +8 -0
- package/src/orchestrator/useOrchestrator.ts +80 -0
- package/src/plugin.ts +251 -0
- package/src/query/FilterQuery.ts +306 -0
- package/src/query/QueryExecutor.ts +341 -0
- package/src/query/index.ts +16 -0
- package/src/security/EntityRolesProvider.ts +385 -0
- package/src/security/PermissionMatcher.ts +152 -0
- package/src/security/PermissionRegistry.ts +273 -0
- package/src/security/PersistableRolesProvider.ts +584 -0
- package/src/security/RolesManager.ts +136 -0
- package/src/security/RolesProvider.ts +167 -0
- package/src/security/RolesProviderStorage.ts +211 -0
- package/src/security/SecurityModule.ts +94 -0
- package/src/security/StaticRolesProvider.ts +117 -0
- package/src/security/UsersManager.ts +163 -0
- package/src/security/index.ts +77 -0
- package/src/security/pages/RoleForm.vue +276 -0
- package/src/security/pages/RoleList.vue +123 -0
- package/src/styles/_alerts.scss +95 -0
- package/src/styles/_buttons.scss +391 -0
- package/src/styles/_cards.scss +241 -0
- package/src/styles/_code.scss +78 -0
- package/src/styles/_dialogs.scss +55 -0
- package/src/styles/_filter-bar.scss +70 -0
- package/src/styles/_forms.scss +434 -0
- package/src/styles/_helpers.scss +153 -0
- package/src/styles/_lists.scss +225 -0
- package/src/styles/_main.scss +356 -0
- package/src/styles/_markdown.scss +88 -0
- package/src/styles/_responsive.scss +255 -0
- package/src/styles/_show-pages.scss +186 -0
- package/src/styles/_sidebar.scss +380 -0
- package/src/styles/_states.scss +115 -0
- package/src/styles/_stats.scss +47 -0
- package/src/styles/_variables.scss +224 -0
- package/src/styles/index.scss +38 -0
- package/src/styles/theme/_components.scss +331 -0
- package/src/styles/theme/_index.scss +10 -0
- package/src/styles/theme/_tokens.scss +147 -0
- package/src/styles/theme/_utilities.scss +175 -0
- package/src/toast/ToastBridgeModule.ts +68 -0
- package/src/toast/ToastListener.vue +55 -0
- package/src/toast/index.ts +26 -0
- package/src/toast/useSignalToast.ts +154 -0
- package/src/types/index.ts +285 -0
- package/src/types/pluralize.d.ts +19 -0
- package/src/types/quarkernel.d.ts +50 -0
- package/src/utils/formatters.ts +174 -0
- package/src/utils/index.ts +35 -0
- package/src/utils/transformers.ts +131 -0
- package/src/vite/qdadmDebugPlugin.ts +401 -0
- package/src/vite-env.d.ts +50 -0
- package/src/zones/ZoneRegistry.ts +934 -0
- package/src/zones/index.ts +29 -0
- 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
|
+
}
|