qdadm 1.13.0 → 1.19.2
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/package.json +8 -4
- package/src/chain/ActiveStack.ts +79 -98
- package/src/chain/StackHydrator.ts +3 -2
- package/src/chain/index.ts +7 -1
- package/src/components/QdadmRoot.vue +52 -0
- package/src/components/edit/FormActions.vue +9 -6
- package/src/components/edit/LookupPickerDialog.vue +6 -3
- package/src/components/index.ts +6 -0
- package/src/composables/useEntityItemFormPage.ts +1 -0
- package/src/composables/useEntityItemShowPage.ts +1 -0
- package/src/composables/useFieldManager.ts +100 -3
- package/src/composables/useListPage.ts +50 -59
- package/src/composables/useListPage.utils.ts +101 -0
- package/src/composables/useNavigation.ts +26 -3
- package/src/composables/useOptionsLookup.ts +5 -1
- package/src/gen/generateManagers.test.js +27 -0
- package/src/gen/generateManagers.ts +12 -0
- package/src/hooks/HookRegistry.ts +14 -435
- 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 +37 -0
- package/src/kernel/EventRouter.ts +17 -300
- package/src/kernel/Kernel.i18n.ts +29 -0
- package/src/kernel/Kernel.modules.ts +6 -0
- package/src/kernel/Kernel.registries.ts +10 -2
- package/src/kernel/Kernel.routing.ts +43 -1
- package/src/kernel/Kernel.ts +43 -0
- package/src/kernel/Kernel.types.ts +52 -1
- package/src/kernel/Kernel.vue.ts +121 -15
- 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 +125 -834
- package/src/kernel/KernelContext.types.ts +173 -0
- package/src/kernel/KernelContext.zones.ts +54 -0
- package/src/kernel/SSEBridge.ts +7 -362
- package/src/kernel/SignalBus.ts +24 -148
- package/src/modules/debug/AuthCollector.ts +48 -1
- package/src/modules/debug/Collector.ts +16 -302
- package/src/modules/debug/DebugBridge.ts +10 -171
- package/src/modules/debug/DebugModule.ts +35 -5
- package/src/modules/debug/EntitiesCollector.ts +97 -1
- package/src/modules/debug/ErrorCollector.ts +2 -77
- package/src/modules/debug/I18nCollector.ts +9 -0
- package/src/modules/debug/LocalStorageAdapter.ts +3 -147
- package/src/modules/debug/RouterCollector.ts +101 -1
- package/src/modules/debug/SignalCollector.ts +2 -150
- package/src/modules/debug/ToastCollector.ts +2 -91
- package/src/modules/debug/ZonesCollector.ts +93 -1
- package/src/modules/debug/components/DebugBar.vue +19 -775
- package/src/modules/debug/components/adminPanelsConfig.ts +42 -0
- package/src/modules/debug/components/index.ts +4 -3
- package/src/modules/debug/components/panels/AuthPanel.vue +1 -1
- package/src/modules/debug/components/panels/EntitiesPanel.vue +5 -5
- package/src/modules/debug/components/panels/I18nPanel.vue +738 -0
- package/src/modules/debug/components/panels/RouterPanel.vue +1 -1
- package/src/modules/debug/components/panels/index.ts +10 -4
- package/src/modules/debug/index.ts +15 -0
- package/src/modules/debug/styles.scss +22 -18
- package/src/utils/index.ts +0 -3
- package/src/vite/qdadmDebugPlugin.ts +401 -0
- package/src/vite-env.d.ts +16 -0
- package/src/modules/debug/components/ObjectTree.vue +0 -123
- package/src/modules/debug/components/panels/EntriesPanel.vue +0 -100
- package/src/modules/debug/components/panels/SignalsPanel.vue +0 -188
- package/src/modules/debug/components/panels/ToastsPanel.vue +0 -45
- package/src/utils/debugInjector.ts +0 -306
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Debug Injector - Bypasses MCP/DevTools limitations
|
|
3
|
-
*
|
|
4
|
-
* Usage in browser console:
|
|
5
|
-
* window.__debug.listFilters()
|
|
6
|
-
* window.__debug.setFilter('queue_status', 'pending')
|
|
7
|
-
* window.__debug.getVueApp()
|
|
8
|
-
* window.__debug.triggerEvent('filterChange', { name: 'queue_status', value: 'pending' })
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
interface SelectInfo {
|
|
12
|
-
index: number
|
|
13
|
-
element: Element
|
|
14
|
-
component: VueComponentProxy | null
|
|
15
|
-
value: unknown
|
|
16
|
-
placeholder: string | null | undefined
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface VueComponentProxy {
|
|
20
|
-
modelValue?: unknown
|
|
21
|
-
localFilterValues?: Record<string, unknown>
|
|
22
|
-
onFilterChange?: (name: string) => void
|
|
23
|
-
$options?: { name?: string }
|
|
24
|
-
$parent?: VueComponentProxy
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface VNodeComponent {
|
|
28
|
-
proxy?: VueComponentProxy
|
|
29
|
-
parent?: VNodeComponent
|
|
30
|
-
type?: { name?: string; __name?: string }
|
|
31
|
-
subTree?: { children?: VNodeComponent[] }
|
|
32
|
-
component?: VNodeComponent
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface VueApp {
|
|
36
|
-
_instance?: VNodeComponent
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
declare global {
|
|
40
|
-
interface Window {
|
|
41
|
-
__debug: DebugInjector
|
|
42
|
-
}
|
|
43
|
-
interface HTMLElement {
|
|
44
|
-
__vue_app__?: VueApp
|
|
45
|
-
__vueParentComponent?: VNodeComponent
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
class DebugInjector {
|
|
50
|
-
vueApp: VueApp | null = null
|
|
51
|
-
components: Map<string, VueComponentProxy> = new Map()
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Initialize and expose to window
|
|
55
|
-
*/
|
|
56
|
-
init(): this {
|
|
57
|
-
window.__debug = this
|
|
58
|
-
console.log('🔧 Debug Injector initialized. Use window.__debug to access.')
|
|
59
|
-
this.findVueApp()
|
|
60
|
-
return this
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Find Vue app instance
|
|
65
|
-
*/
|
|
66
|
-
findVueApp(): VueApp | null {
|
|
67
|
-
const appEl = document.querySelector('#app') as HTMLElement | null
|
|
68
|
-
if (appEl && appEl.__vue_app__) {
|
|
69
|
-
this.vueApp = appEl.__vue_app__
|
|
70
|
-
console.log('✅ Vue app found:', this.vueApp)
|
|
71
|
-
return this.vueApp
|
|
72
|
-
}
|
|
73
|
-
console.warn('⚠️ Vue app not found on #app')
|
|
74
|
-
return null
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Get Vue component instance from DOM element
|
|
79
|
-
*/
|
|
80
|
-
getComponentFromElement(selector: string | Element): VueComponentProxy | null {
|
|
81
|
-
const el = (
|
|
82
|
-
typeof selector === 'string' ? document.querySelector(selector) : selector
|
|
83
|
-
) as HTMLElement | null
|
|
84
|
-
if (!el) return null
|
|
85
|
-
|
|
86
|
-
// Vue 3 stores component on __vueParentComponent
|
|
87
|
-
let vnode = el.__vueParentComponent
|
|
88
|
-
while (vnode && !vnode.proxy) {
|
|
89
|
-
vnode = vnode.parent
|
|
90
|
-
}
|
|
91
|
-
return vnode?.proxy || null
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Find all PrimeVue Select components
|
|
96
|
-
*/
|
|
97
|
-
findSelects(): SelectInfo[] {
|
|
98
|
-
const selects = document.querySelectorAll('[data-pc-name="select"]')
|
|
99
|
-
const results: SelectInfo[] = []
|
|
100
|
-
selects.forEach((el, i) => {
|
|
101
|
-
const component = this.getComponentFromElement(el)
|
|
102
|
-
results.push({
|
|
103
|
-
index: i,
|
|
104
|
-
element: el,
|
|
105
|
-
component,
|
|
106
|
-
value: component?.modelValue,
|
|
107
|
-
placeholder: el.querySelector('[data-pc-section="label"]')?.textContent,
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
console.table(
|
|
111
|
-
results.map((r) => ({
|
|
112
|
-
index: r.index,
|
|
113
|
-
placeholder: r.placeholder,
|
|
114
|
-
value: r.value,
|
|
115
|
-
}))
|
|
116
|
-
)
|
|
117
|
-
return results
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Simulate selecting a value in a PrimeVue Select
|
|
122
|
-
*/
|
|
123
|
-
selectValue(selectIndex: number, optionText: string): boolean {
|
|
124
|
-
const selects = this.findSelects()
|
|
125
|
-
const select = selects[selectIndex]
|
|
126
|
-
if (!select) {
|
|
127
|
-
console.error(`Select ${selectIndex} not found`)
|
|
128
|
-
return false
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Click to open dropdown
|
|
132
|
-
;(select.element as HTMLElement).click()
|
|
133
|
-
|
|
134
|
-
// Wait for dropdown to open and find option
|
|
135
|
-
setTimeout(() => {
|
|
136
|
-
const options = document.querySelectorAll('[data-pc-section="option"]')
|
|
137
|
-
for (const opt of options) {
|
|
138
|
-
if (opt.textContent?.includes(optionText)) {
|
|
139
|
-
console.log(`🎯 Clicking option: ${opt.textContent}`)
|
|
140
|
-
;(opt as HTMLElement).click()
|
|
141
|
-
return true
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
console.error(`Option "${optionText}" not found`)
|
|
145
|
-
// Close dropdown
|
|
146
|
-
document.body.click()
|
|
147
|
-
}, 100)
|
|
148
|
-
|
|
149
|
-
return true
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Direct Vue reactivity manipulation - find ListPage component
|
|
154
|
-
*/
|
|
155
|
-
findListPage(): VueComponentProxy | null {
|
|
156
|
-
// Find the main content area
|
|
157
|
-
const main = document.querySelector('main')
|
|
158
|
-
if (!main) return null
|
|
159
|
-
|
|
160
|
-
let component = this.getComponentFromElement(main)
|
|
161
|
-
|
|
162
|
-
// Walk up to find ListPage
|
|
163
|
-
while (component) {
|
|
164
|
-
if (component.$options?.name === 'ListPage' || component.localFilterValues) {
|
|
165
|
-
console.log('✅ Found ListPage component:', component)
|
|
166
|
-
return component
|
|
167
|
-
}
|
|
168
|
-
component = component.$parent || null
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Alternative: search in Vue app's component tree
|
|
172
|
-
console.warn('ListPage not found via DOM, searching component tree...')
|
|
173
|
-
return null
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Get current filter values from ListPage
|
|
178
|
-
*/
|
|
179
|
-
getFilterValues(): Record<string, unknown> | null {
|
|
180
|
-
const listPage = this.findListPage()
|
|
181
|
-
if (listPage) {
|
|
182
|
-
console.log('Filter values:', listPage.localFilterValues)
|
|
183
|
-
return listPage.localFilterValues || null
|
|
184
|
-
}
|
|
185
|
-
return null
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Directly set a filter value (bypasses UI)
|
|
190
|
-
*/
|
|
191
|
-
setFilterDirect(filterName: string, value: unknown): boolean {
|
|
192
|
-
const listPage = this.findListPage()
|
|
193
|
-
if (!listPage) {
|
|
194
|
-
console.error('ListPage not found')
|
|
195
|
-
return false
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
console.log(`Setting ${filterName} = ${value}`)
|
|
199
|
-
if (listPage.localFilterValues) {
|
|
200
|
-
listPage.localFilterValues[filterName] = value
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Trigger the change handler
|
|
204
|
-
if (listPage.onFilterChange) {
|
|
205
|
-
listPage.onFilterChange(filterName)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return true
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Dispatch a custom event that Vue components can listen to
|
|
213
|
-
*/
|
|
214
|
-
dispatchFilterChange(filterName: string, value: unknown): void {
|
|
215
|
-
const event = new CustomEvent('debug:filterChange', {
|
|
216
|
-
detail: { filterName, value },
|
|
217
|
-
bubbles: true,
|
|
218
|
-
})
|
|
219
|
-
document.dispatchEvent(event)
|
|
220
|
-
console.log(`📤 Dispatched debug:filterChange for ${filterName}=${value}`)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Log all Vue component instances in the tree
|
|
225
|
-
*/
|
|
226
|
-
logComponentTree(root: VNodeComponent | null = null, depth = 0): void {
|
|
227
|
-
if (!root) {
|
|
228
|
-
root = this.findVueApp()?._instance || null
|
|
229
|
-
if (!root) return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const indent = ' '.repeat(depth)
|
|
233
|
-
const name = root.type?.name || root.type?.__name || 'Anonymous'
|
|
234
|
-
console.log(`${indent}${name}`)
|
|
235
|
-
|
|
236
|
-
if (root.subTree?.children) {
|
|
237
|
-
for (const child of root.subTree.children) {
|
|
238
|
-
if (child?.component) {
|
|
239
|
-
this.logComponentTree(child.component, depth + 1)
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Execute code in Vue component context
|
|
247
|
-
*/
|
|
248
|
-
execInComponent(selector: string, code: string): unknown {
|
|
249
|
-
const component = this.getComponentFromElement(selector)
|
|
250
|
-
if (!component) {
|
|
251
|
-
console.error('Component not found')
|
|
252
|
-
return null
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
const fn = new Function('component', `with(component) { return ${code} }`)
|
|
257
|
-
return fn(component)
|
|
258
|
-
} catch (e) {
|
|
259
|
-
console.error('Exec failed:', e)
|
|
260
|
-
return null
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Monitor all events on an element
|
|
266
|
-
*/
|
|
267
|
-
monitorEvents(selector: string): void {
|
|
268
|
-
const el = document.querySelector(selector)
|
|
269
|
-
if (!el) return
|
|
270
|
-
|
|
271
|
-
const events = ['click', 'change', 'input', 'focus', 'blur', 'mousedown', 'mouseup']
|
|
272
|
-
events.forEach((evt) => {
|
|
273
|
-
el.addEventListener(
|
|
274
|
-
evt,
|
|
275
|
-
(e) => {
|
|
276
|
-
console.log(`📡 ${evt}:`, e.target, e)
|
|
277
|
-
},
|
|
278
|
-
true
|
|
279
|
-
)
|
|
280
|
-
})
|
|
281
|
-
console.log(`Monitoring events on ${selector}`)
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Quick help
|
|
286
|
-
*/
|
|
287
|
-
help(): void {
|
|
288
|
-
console.log(`
|
|
289
|
-
🔧 Debug Injector Commands:
|
|
290
|
-
__debug.findSelects() - List all Select components
|
|
291
|
-
__debug.selectValue(0, 'text') - Select option by text in Select #0
|
|
292
|
-
__debug.findListPage() - Find ListPage component
|
|
293
|
-
__debug.getFilterValues() - Get current filter values
|
|
294
|
-
__debug.setFilterDirect('name', 'value') - Directly set filter
|
|
295
|
-
__debug.monitorEvents('selector') - Monitor all events
|
|
296
|
-
__debug.logComponentTree() - Log Vue component tree
|
|
297
|
-
__debug.help() - Show this help
|
|
298
|
-
`)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Auto-initialize in development
|
|
303
|
-
const debugInjector = new DebugInjector()
|
|
304
|
-
|
|
305
|
-
export default debugInjector
|
|
306
|
-
export { DebugInjector }
|