@quazardous/qdadm 1.19.3 → 1.19.5

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/README.md CHANGED
@@ -106,6 +106,27 @@ Options: `transformRequest`, `transformResponse`, `responseFormat`, `clientSideP
106
106
  - primevue ^4.0.0
107
107
  - pinia ^2.0.0
108
108
 
109
+ ## Consuming via `file:` link from a sibling monorepo
110
+
111
+ If you install qdadm with a `file:../path/to/qdadm` link instead of from npm — typically during local development on qdadm itself, or before a release lands — pnpm/npm resolves the symlink into the qdadm-monorepo's hoisted `node_modules`. That can pull a *second* copy of `primevue` (and `vue`, `vue-router`, `@primeuix/themes`) into your host bundle even though qdadm itself only declares them as peers.
112
+
113
+ Symptom: PrimeVue components render without their Aura preset tokens — component-level CSS variables (`--p-paginator-nav-button-width`, etc.) end up undefined, so paginator buttons collapse to 16×16, datatables lose padding, rounded corners disappear. Plugin singletons rely on a shared runtime registry; two instances split the registry in half.
114
+
115
+ Fix in the host's bundler config — `dedupe` collapses duplicates back to a single resolved copy:
116
+
117
+ ```ts
118
+ // vite.config.ts
119
+ export default defineConfig({
120
+ resolve: {
121
+ dedupe: ['vue', 'vue-router', 'primevue', '@primeuix/themes'],
122
+ },
123
+ })
124
+ ```
125
+
126
+ This is the canonical Vite/Webpack pattern for Vue plugin singletons. The `file:` link can stay in place — useful for hot-reload during qdadm development — and the dedupe ensures only one instance of each peer ends up in the bundle.
127
+
128
+ Installing qdadm from npm (`@quazardous/qdadm@^1.19.3`) doesn't have this issue: the published tarball ships no `node_modules/`, so peers always resolve from the host. The trap is specific to `file:` / `workspace:` links onto a package that lives inside another monorepo.
129
+
109
130
  ## License
110
131
 
111
132
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quazardous/qdadm",
3
- "version": "1.19.3",
3
+ "version": "1.19.5",
4
4
  "description": "Vue 3 framework for admin dashboards with PrimeVue",
5
5
  "author": "quazardous",
6
6
  "license": "MIT",
@@ -81,6 +81,7 @@
81
81
  ],
82
82
  "devDependencies": {
83
83
  "@eslint/js": "^9.39.2",
84
+ "@primeuix/themes": "^1.0.0",
84
85
  "@types/node": "^25.0.6",
85
86
  "@vitejs/plugin-vue": "^6.0.0",
86
87
  "@vue/test-utils": "^2.4.6",
@@ -92,6 +93,7 @@
92
93
  "globals": "^17.0.0",
93
94
  "jsdom": "^25.0.1",
94
95
  "prettier": "^3.7.4",
96
+ "primevue": "^4.0.0",
95
97
  "sass": "^1.97.1",
96
98
  "typescript": "^5.9.3",
97
99
  "typescript-eslint": "^8.52.0",
@@ -160,6 +160,7 @@ function onGuardStay(): void {
160
160
  :label="action.label"
161
161
  :icon="action.icon"
162
162
  :severity="action.severity"
163
+ :size="action.size || 'small'"
163
164
  :loading="action.isLoading"
164
165
  :disabled="action.isDisabled"
165
166
  @click="action.onClick"
@@ -25,7 +25,7 @@ import Button from 'primevue/button'
25
25
  import Select from 'primevue/select'
26
26
  import AutoComplete from 'primevue/autocomplete'
27
27
  import SplitButton from 'primevue/splitbutton'
28
- import type { FilterConfig, CardConfig, ResolvedAction, ResolvedHeaderAction as BaseResolvedHeaderAction } from '../../composables/useListPage'
28
+ import type { FilterConfig, CardConfig, ResolvedAction, ResolvedHeaderAction } from '../../composables/useListPage'
29
29
 
30
30
  /**
31
31
  * Header action state for label function (matches useListPage)
@@ -41,13 +41,6 @@ interface HeaderActionState {
41
41
  */
42
42
  type LabelType = string | ((state: HeaderActionState) => string)
43
43
 
44
- /**
45
- * Extended header action with optional size property used in template
46
- */
47
- interface ResolvedHeaderAction extends BaseResolvedHeaderAction {
48
- size?: string
49
- }
50
-
51
44
  /**
52
45
  * Autocomplete event interface
53
46
  */
@@ -79,6 +79,7 @@ export interface ActionConfig {
79
79
  label: string
80
80
  icon?: string
81
81
  severity?: string
82
+ size?: string
82
83
  onClick: () => void | Promise<void>
83
84
  visible?: (ctx: { isEdit: boolean; dirty: boolean }) => boolean
84
85
  disabled?: (ctx: { dirty: boolean; saving: boolean }) => boolean
@@ -146,6 +146,7 @@ export interface HeaderActionConfig {
146
146
  label: string | ((state: HeaderActionState) => string)
147
147
  icon?: string
148
148
  severity?: string
149
+ size?: string
149
150
  onClick: () => void | Promise<void>
150
151
  visible?: (state: HeaderActionState) => boolean
151
152
  loading?: (state: HeaderActionState) => boolean
@@ -427,9 +427,12 @@ describe('generateManagers', () => {
427
427
  // Storage must be parameterized in class mode too — same TS2322
428
428
  // assignability problem as instance mode if we drop the generic.
429
429
  expect(content).toContain('new ApiStorage<UsersEntity>(')
430
- // Constructor signature should accept a typed storage override, not `unknown`
431
- expect(content).toContain("import type { EntityRecord, IStorage } from '@quazardous/qdadm'")
432
- expect(content).toContain('storage: IStorage<UsersEntity>')
430
+ // Constructor signature delegates to the parent's options type so
431
+ // `fields: Record<string, FieldConfig>` doesn't widen on spread (TS2345).
432
+ expect(content).toContain("import type { EntityRecord, EntityManagerOptions } from '@quazardous/qdadm'")
433
+ expect(content).toContain('options: Partial<EntityManagerOptions<UsersEntity>>')
434
+ expect(content).not.toContain('Record<string, unknown>')
435
+ expect(content).not.toContain('[key: string]: unknown')
433
436
  })
434
437
  })
435
438
 
@@ -241,7 +241,7 @@ function generateManagerSource(
241
241
  */
242
242
 
243
243
  import { EntityManager } from '@quazardous/qdadm'
244
- import type { EntityRecord, IStorage } from '@quazardous/qdadm'
244
+ import type { EntityRecord, EntityManagerOptions } from '@quazardous/qdadm'
245
245
  import { ${storageClass} } from '${storageImport}'
246
246
 
247
247
  ${entityInterface}
@@ -252,7 +252,7 @@ ${entityInterface}
252
252
  * @extends EntityManager
253
253
  */
254
254
  export class Generated${className}Manager extends EntityManager<${className}Entity> {
255
- constructor(options: Partial<{ name: string; idField: string; fields: Record<string, unknown>; storage: IStorage<${className}Entity>; [key: string]: unknown }> = {}) {
255
+ constructor(options: Partial<EntityManagerOptions<${className}Entity>> = {}) {
256
256
  super({
257
257
  ...${serializeValue(managerOptions, 2)},
258
258
  storage: new ${storageClass}<${className}Entity>(${serializeValue(fullStorageOptions, 2)}),
@@ -1,45 +0,0 @@
1
- /**
2
- * TestManager - Auto-generated EntityManager
3
- *
4
- * Generated by qdadm/gen/generateManagers
5
- * DO NOT EDIT MANUALLY - Changes will be overwritten
6
- *
7
- * Entity: test
8
- * Endpoint: /test
9
- */
10
-
11
- import { EntityManager } from '@quazardous/qdadm'
12
- import { ApiStorage } from '@quazardous/qdadm'
13
-
14
- /**
15
- * Schema definition for test
16
- * @type {import('qdadm/gen').UnifiedEntitySchema}
17
- */
18
- export const testSchema = {
19
- name: "test",
20
- endpoint: "/test",
21
- fields: {}
22
- }
23
-
24
- /**
25
- * Storage options for test
26
- */
27
- const storageOptions = {
28
- endpoint: "/test"
29
- }
30
-
31
- /**
32
- * TestManager instance
33
- *
34
- * Provides CRUD operations for test entity.
35
- *
36
- * @type {EntityManager}
37
- */
38
- export const testManager = new EntityManager({
39
- ...{
40
- name: "test",
41
- idField: "id",
42
- fields: {}
43
- },
44
- storage: new ApiStorage(storageOptions)
45
- })