@quazardous/qdadm 2.13.0 → 2.15.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/README.md +1 -0
- package/package.json +6 -4
- package/src/chain/index.ts +5 -0
- package/src/components/InfoBanner.vue +3 -3
- package/src/components/base/QdButton.vue +20 -0
- package/src/components/base/QdMessage.vue +17 -0
- package/src/components/dialogs/MultiStepDialog.vue +5 -5
- package/src/components/dialogs/SimpleDialog.vue +4 -4
- package/src/components/dialogs/UnsavedChangesDialog.vue +2 -2
- package/src/components/display/CopyableId.vue +2 -2
- package/src/components/edit/FormActions.vue +4 -4
- package/src/components/edit/FormPage.vue +7 -7
- package/src/components/edit/LookupPickerDialog.vue +3 -3
- package/src/components/editors/JsonEditorFoldable.vue +8 -8
- package/src/components/editors/JsonStructuredField.vue +3 -3
- package/src/components/editors/KeyValueEditor.vue +3 -3
- package/src/components/editors/LanguageEditor.vue +5 -5
- package/src/components/editors/ScopeEditor.vue +3 -3
- package/src/components/index.ts +4 -0
- package/src/components/layout/AppLayout.vue +2 -2
- package/src/components/layout/PageLayout.vue +2 -2
- package/src/components/layout/defaults/DefaultUserInfo.vue +2 -2
- package/src/components/lists/ActionButtons.vue +2 -2
- package/src/components/lists/ListPage.vue +4 -4
- package/src/components/pages/LoginPage.vue +2 -2
- package/src/components/show/ShowPage.vue +6 -6
- package/src/composables/useEntityItemShowPage.ts +8 -0
- package/src/composables/useListPage.ts +23 -0
- package/src/composables/useListPage.types.ts +3 -0
- package/src/composables/useLiveEntity.ts +115 -0
- package/src/deferred/index.ts +5 -0
- package/src/entity/EntityManager.cache.ts +20 -0
- package/src/entity/EntityManager.interface.ts +3 -0
- package/src/entity/EntityManager.ts +29 -1
- package/src/entity/EntityManager.types.ts +32 -0
- package/src/gen/vite-plugin.ts +4 -0
- package/src/index.ts +10 -0
- package/src/kernel/Kernel.registries.ts +31 -5
- package/src/kernel/Kernel.ts +3 -0
- package/src/kernel/Kernel.types.ts +31 -0
- package/src/kernel/LiveEntityRouter.ts +189 -0
- package/src/kernel/SSEBridge.ts +3 -0
- package/src/query/index.ts +7 -0
- package/src/security/pages/RoleList.vue +3 -3
- package/src/types/index.ts +2 -0
- package/src/utils/pluralize.ts +472 -0
- package/src/vite/qdadmDebugPlugin.ts +178 -2
- package/src/vite/qdadmPlugin.ts +5 -19
- package/src/vite-env.d.ts +0 -16
- package/src/types/pluralize.d.ts +0 -19
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quazardous/qdadm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"description": "Vue 3 framework for admin dashboards with PrimeVue",
|
|
5
5
|
"author": "quazardous",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,16 +51,15 @@
|
|
|
51
51
|
"LICENSE"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@quazardous/qdcore": "^1.
|
|
55
|
-
"@types/pluralize": "^0.0.33",
|
|
54
|
+
"@quazardous/qdcore": "^1.1.0",
|
|
56
55
|
"@quazardous/qddebug": "^1.0.0",
|
|
57
56
|
"@quazardous/quarkernel": "^2.1.0",
|
|
58
|
-
"pluralize": "^8.0.0",
|
|
59
57
|
"yaml": "^2.8.4"
|
|
60
58
|
},
|
|
61
59
|
"peerDependencies": {
|
|
62
60
|
"pinia": "^2.0.0 || ^3.0.0 || ^4.0.0",
|
|
63
61
|
"primevue": "^4.0.0",
|
|
62
|
+
"sass-embedded": "^1.0.0",
|
|
64
63
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
65
64
|
"vue": "^3.3.0",
|
|
66
65
|
"vue-router": "^4.0.0 || ^5.0.0"
|
|
@@ -74,6 +73,9 @@
|
|
|
74
73
|
},
|
|
75
74
|
"primevue": {
|
|
76
75
|
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"sass-embedded": {
|
|
78
|
+
"optional": "true"
|
|
77
79
|
}
|
|
78
80
|
},
|
|
79
81
|
"optionalDependencies": {
|
package/src/chain/index.ts
CHANGED
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* - useActiveStack: Composable to build and access the sync stack
|
|
8
8
|
* - useStackHydrator: Composable to access hydrated data
|
|
9
9
|
*
|
|
10
|
+
* @experimental Navigation-stack plumbing that happens to be exported: the
|
|
11
|
+
* level shape and the hydration payloads may change in a minor release. The
|
|
12
|
+
* parent/child routing built on top of it is stable — see
|
|
13
|
+
* docs/API_STABILITY.md.
|
|
14
|
+
*
|
|
10
15
|
* @module chain
|
|
11
16
|
*/
|
|
12
17
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* Just some information.
|
|
21
21
|
* </InfoBanner>
|
|
22
22
|
*/
|
|
23
|
-
import
|
|
23
|
+
import QdMessage from './base/QdMessage.vue'
|
|
24
24
|
import { computed } from 'vue'
|
|
25
25
|
|
|
26
26
|
type Severity = 'info' | 'success' | 'warn' | 'error' | 'secondary' | 'contrast'
|
|
@@ -58,7 +58,7 @@ const iconClass = computed(() => {
|
|
|
58
58
|
</script>
|
|
59
59
|
|
|
60
60
|
<template>
|
|
61
|
-
<
|
|
61
|
+
<QdMessage
|
|
62
62
|
:severity="severity"
|
|
63
63
|
:closable="closable"
|
|
64
64
|
class="info-banner"
|
|
@@ -69,5 +69,5 @@ const iconClass = computed(() => {
|
|
|
69
69
|
<slot />
|
|
70
70
|
</span>
|
|
71
71
|
</div>
|
|
72
|
-
</
|
|
72
|
+
</QdMessage>
|
|
73
73
|
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* QdButton — the single indirection point over the widget library's Button
|
|
4
|
+
* (#1391 exit-readiness). Generic pass-through: every attr/prop/listener and
|
|
5
|
+
* every slot is forwarded verbatim, so swapping or shimming the underlying
|
|
6
|
+
* widget is a one-file change. Imports `primevue/button`, which the
|
|
7
|
+
* qdadmVitePlugin flavor alias (#1393) traverses.
|
|
8
|
+
*/
|
|
9
|
+
import Button from 'primevue/button'
|
|
10
|
+
|
|
11
|
+
defineOptions({ inheritAttrs: false })
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<Button v-bind="$attrs">
|
|
16
|
+
<template v-for="(_, name) in $slots" #[name]="slotProps">
|
|
17
|
+
<slot :name="name" v-bind="slotProps ?? {}" />
|
|
18
|
+
</template>
|
|
19
|
+
</Button>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* QdMessage — the single indirection point over the widget library's Message
|
|
4
|
+
* (#1391 exit-readiness). Generic pass-through, same contract as QdButton.
|
|
5
|
+
*/
|
|
6
|
+
import Message from 'primevue/message'
|
|
7
|
+
|
|
8
|
+
defineOptions({ inheritAttrs: false })
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Message v-bind="$attrs">
|
|
13
|
+
<template v-for="(_, name) in $slots" #[name]="slotProps">
|
|
14
|
+
<slot :name="name" v-bind="slotProps ?? {}" />
|
|
15
|
+
</template>
|
|
16
|
+
</Message>
|
|
17
|
+
</template>
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
*/
|
|
59
59
|
import { computed, watch, type PropType } from 'vue'
|
|
60
60
|
import Dialog from 'primevue/dialog'
|
|
61
|
-
import
|
|
61
|
+
import QdButton from '../base/QdButton.vue'
|
|
62
62
|
import Stepper from 'primevue/stepper'
|
|
63
63
|
import StepList from 'primevue/steplist'
|
|
64
64
|
import Step from 'primevue/step'
|
|
@@ -284,7 +284,7 @@ const slotActions = computed<SlotActions>(() => ({
|
|
|
284
284
|
<div class="step-actions">
|
|
285
285
|
<slot name="actions" v-bind="slotActions">
|
|
286
286
|
<!-- Back button -->
|
|
287
|
-
<
|
|
287
|
+
<QdButton
|
|
288
288
|
v-if="!isFirstStep || showBackOnFirst"
|
|
289
289
|
:label="backLabel"
|
|
290
290
|
icon="pi pi-arrow-left"
|
|
@@ -294,7 +294,7 @@ const slotActions = computed<SlotActions>(() => ({
|
|
|
294
294
|
/>
|
|
295
295
|
|
|
296
296
|
<!-- Cancel button -->
|
|
297
|
-
<
|
|
297
|
+
<QdButton
|
|
298
298
|
:label="cancelLabel"
|
|
299
299
|
severity="secondary"
|
|
300
300
|
@click="cancel"
|
|
@@ -302,7 +302,7 @@ const slotActions = computed<SlotActions>(() => ({
|
|
|
302
302
|
/>
|
|
303
303
|
|
|
304
304
|
<!-- Next button (not on last step) -->
|
|
305
|
-
<
|
|
305
|
+
<QdButton
|
|
306
306
|
v-if="!isLastStep"
|
|
307
307
|
:label="nextLabel"
|
|
308
308
|
icon="pi pi-arrow-right"
|
|
@@ -312,7 +312,7 @@ const slotActions = computed<SlotActions>(() => ({
|
|
|
312
312
|
/>
|
|
313
313
|
|
|
314
314
|
<!-- Submit button (only on last step) -->
|
|
315
|
-
<
|
|
315
|
+
<QdButton
|
|
316
316
|
v-if="isLastStep"
|
|
317
317
|
:label="submitLabel"
|
|
318
318
|
icon="pi pi-check"
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
* <SimpleDialog v-model:visible="showDialog" title="View Key" :showConfirm="false">
|
|
27
27
|
* <p>{{ key }}</p>
|
|
28
28
|
* <template #actions>
|
|
29
|
-
* <
|
|
29
|
+
* <QdButton label="Copy" icon="pi pi-copy" @click="copyKey" />
|
|
30
30
|
* </template>
|
|
31
31
|
* </SimpleDialog>
|
|
32
32
|
*/
|
|
33
33
|
import { computed } from 'vue'
|
|
34
34
|
import Dialog from 'primevue/dialog'
|
|
35
|
-
import
|
|
35
|
+
import QdButton from '../base/QdButton.vue'
|
|
36
36
|
|
|
37
37
|
interface Props {
|
|
38
38
|
visible?: boolean
|
|
@@ -101,14 +101,14 @@ const canClose = computed((): boolean => props.closable && !props.loading)
|
|
|
101
101
|
|
|
102
102
|
<template #footer v-if="showCancel || showConfirm || $slots.actions">
|
|
103
103
|
<slot name="actions" />
|
|
104
|
-
<
|
|
104
|
+
<QdButton
|
|
105
105
|
v-if="showCancel"
|
|
106
106
|
:label="cancelLabel"
|
|
107
107
|
severity="secondary"
|
|
108
108
|
@click="onCancel"
|
|
109
109
|
:disabled="loading"
|
|
110
110
|
/>
|
|
111
|
-
<
|
|
111
|
+
<QdButton
|
|
112
112
|
v-if="showConfirm"
|
|
113
113
|
:label="confirmLabel"
|
|
114
114
|
:icon="confirmIcon"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Stay: cancels navigation
|
|
9
9
|
*/
|
|
10
10
|
import SimpleDialog from './SimpleDialog.vue'
|
|
11
|
-
import
|
|
11
|
+
import QdButton from '../base/QdButton.vue'
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
14
|
visible?: boolean
|
|
@@ -67,7 +67,7 @@ function onSaveAndLeave(): void {
|
|
|
67
67
|
</div>
|
|
68
68
|
|
|
69
69
|
<template #actions>
|
|
70
|
-
<
|
|
70
|
+
<QdButton
|
|
71
71
|
v-if="hasOnSave"
|
|
72
72
|
label="Save & Leave"
|
|
73
73
|
icon="pi pi-save"
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* <CopyableId :value="apiKey" label="API Key" />
|
|
8
8
|
*/
|
|
9
9
|
import { ref, inject } from 'vue'
|
|
10
|
-
import
|
|
10
|
+
import QdButton from '../base/QdButton.vue'
|
|
11
11
|
import type { Orchestrator } from '../../orchestrator/Orchestrator'
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
@@ -40,7 +40,7 @@ async function copyToClipboard(): Promise<void> {
|
|
|
40
40
|
<div class="form-field">
|
|
41
41
|
<label class="form-field-label">{{ label }}</label>
|
|
42
42
|
<div class="copyable-id">
|
|
43
|
-
<
|
|
43
|
+
<QdButton
|
|
44
44
|
type="button"
|
|
45
45
|
:icon="copied ? 'pi pi-check' : 'pi pi-copy'"
|
|
46
46
|
:severity="copied ? 'success' : 'secondary'"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - cancel: Cancel/close without saving
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import
|
|
16
|
+
import QdButton from '../base/QdButton.vue'
|
|
17
17
|
import { useI18n } from '../../i18n/useI18n'
|
|
18
18
|
|
|
19
19
|
const { t } = useI18n()
|
|
@@ -42,7 +42,7 @@ const emit = defineEmits<{
|
|
|
42
42
|
<template>
|
|
43
43
|
<div class="form-actions">
|
|
44
44
|
<div class="form-actions-left">
|
|
45
|
-
<
|
|
45
|
+
<QdButton
|
|
46
46
|
type="button"
|
|
47
47
|
:label="isEdit ? t('core.actions.update') : t('core.actions.create')"
|
|
48
48
|
:loading="saving"
|
|
@@ -51,7 +51,7 @@ const emit = defineEmits<{
|
|
|
51
51
|
@click="emit('save')"
|
|
52
52
|
v-tooltip.top="t('core.tooltips.saveAndContinue')"
|
|
53
53
|
/>
|
|
54
|
-
<
|
|
54
|
+
<QdButton
|
|
55
55
|
v-if="showSaveAndClose"
|
|
56
56
|
type="button"
|
|
57
57
|
:label="isEdit ? t('core.actions.updateAndClose') : t('core.actions.createAndClose')"
|
|
@@ -66,7 +66,7 @@ const emit = defineEmits<{
|
|
|
66
66
|
<i class="pi pi-circle-fill"></i>
|
|
67
67
|
</span>
|
|
68
68
|
</div>
|
|
69
|
-
<
|
|
69
|
+
<QdButton
|
|
70
70
|
type="button"
|
|
71
71
|
:label="t('core.actions.cancel')"
|
|
72
72
|
severity="secondary"
|
|
@@ -38,8 +38,8 @@ import FormActions from './FormActions.vue'
|
|
|
38
38
|
import UnsavedChangesDialog from '../dialogs/UnsavedChangesDialog.vue'
|
|
39
39
|
import CardShell from '../layout/CardShell.vue'
|
|
40
40
|
import { formatFetchError } from '../../utils/errors'
|
|
41
|
-
import
|
|
42
|
-
import
|
|
41
|
+
import QdButton from '../base/QdButton.vue'
|
|
42
|
+
import QdMessage from '../base/QdMessage.vue'
|
|
43
43
|
import type { ResolvedAction, ResolvedFieldConfig } from '../../composables/useEntityItemFormPage'
|
|
44
44
|
import type { GuardDialogState } from '../../composables/useUnsavedChangesGuard'
|
|
45
45
|
|
|
@@ -151,7 +151,7 @@ function onGuardStay(): void {
|
|
|
151
151
|
<template #actions>
|
|
152
152
|
<slot name="header-actions" />
|
|
153
153
|
<!-- Header actions from builder (excludes save/delete/cancel) -->
|
|
154
|
-
<
|
|
154
|
+
<QdButton
|
|
155
155
|
v-for="action in headerActions"
|
|
156
156
|
:key="action.name"
|
|
157
157
|
:label="action.label"
|
|
@@ -180,16 +180,16 @@ function onGuardStay(): void {
|
|
|
180
180
|
<!-- Error State (fetch error) -->
|
|
181
181
|
<template v-else-if="fetchError">
|
|
182
182
|
<slot name="error" :error="fetchError">
|
|
183
|
-
<
|
|
183
|
+
<QdMessage severity="error" :closable="false" class="form-error-message">
|
|
184
184
|
{{ fetchErrorMessage }}
|
|
185
|
-
</
|
|
185
|
+
</QdMessage>
|
|
186
186
|
</slot>
|
|
187
187
|
</template>
|
|
188
188
|
|
|
189
189
|
<!-- Form Content -->
|
|
190
190
|
<template v-else>
|
|
191
191
|
<!-- Validation Error Summary -->
|
|
192
|
-
<
|
|
192
|
+
<QdMessage
|
|
193
193
|
v-if="errorSummary && errorSummary.length > 0"
|
|
194
194
|
severity="warn"
|
|
195
195
|
:closable="false"
|
|
@@ -200,7 +200,7 @@ function onGuardStay(): void {
|
|
|
200
200
|
<strong>{{ error.label }}:</strong> {{ error.message }}
|
|
201
201
|
</li>
|
|
202
202
|
</ul>
|
|
203
|
-
</
|
|
203
|
+
</QdMessage>
|
|
204
204
|
|
|
205
205
|
<!-- Single content body; Card wrapper is conditional (#1193) -->
|
|
206
206
|
<CardShell :card="cardWrapper">
|
|
@@ -12,7 +12,7 @@ import Dialog from 'primevue/dialog'
|
|
|
12
12
|
import DataTable from 'primevue/datatable'
|
|
13
13
|
import Column from 'primevue/column'
|
|
14
14
|
import InputText from 'primevue/inputtext'
|
|
15
|
-
import
|
|
15
|
+
import QdButton from '../base/QdButton.vue'
|
|
16
16
|
import { useI18n } from '../../i18n/useI18n'
|
|
17
17
|
|
|
18
18
|
const { t } = useI18n()
|
|
@@ -208,12 +208,12 @@ const confirmLabel = computed(() => {
|
|
|
208
208
|
</DataTable>
|
|
209
209
|
|
|
210
210
|
<template #footer>
|
|
211
|
-
<
|
|
211
|
+
<QdButton
|
|
212
212
|
:label="t('core.actions.cancel')"
|
|
213
213
|
severity="secondary"
|
|
214
214
|
@click="onCancel"
|
|
215
215
|
/>
|
|
216
|
-
<
|
|
216
|
+
<QdButton
|
|
217
217
|
:label="confirmLabel"
|
|
218
218
|
icon="pi pi-check"
|
|
219
219
|
:disabled="confirmDisabled"
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { ref, computed, watch } from 'vue'
|
|
13
|
-
import
|
|
13
|
+
import QdButton from '../base/QdButton.vue'
|
|
14
14
|
import Textarea from 'primevue/textarea'
|
|
15
15
|
import InputText from 'primevue/inputtext'
|
|
16
|
-
import
|
|
16
|
+
import QdMessage from '../base/QdMessage.vue'
|
|
17
17
|
import { getJsonValueType, getJsonPreview } from '../../composables/useJsonSyntax'
|
|
18
18
|
|
|
19
19
|
interface Props {
|
|
@@ -165,7 +165,7 @@ function isMultiline(value: unknown): boolean {
|
|
|
165
165
|
<!-- Toolbar -->
|
|
166
166
|
<div class="editor-toolbar">
|
|
167
167
|
<div class="toolbar-left">
|
|
168
|
-
<
|
|
168
|
+
<QdButton
|
|
169
169
|
:icon="rawJsonMode ? 'pi pi-list' : 'pi pi-code'"
|
|
170
170
|
:label="rawJsonMode ? 'Structured' : 'Raw JSON'"
|
|
171
171
|
size="small"
|
|
@@ -175,7 +175,7 @@ function isMultiline(value: unknown): boolean {
|
|
|
175
175
|
/>
|
|
176
176
|
</div>
|
|
177
177
|
<div class="toolbar-right" v-if="!rawJsonMode">
|
|
178
|
-
<
|
|
178
|
+
<QdButton
|
|
179
179
|
icon="pi pi-plus"
|
|
180
180
|
label="Expand All"
|
|
181
181
|
size="small"
|
|
@@ -183,7 +183,7 @@ function isMultiline(value: unknown): boolean {
|
|
|
183
183
|
text
|
|
184
184
|
@click="expandAll"
|
|
185
185
|
/>
|
|
186
|
-
<
|
|
186
|
+
<QdButton
|
|
187
187
|
icon="pi pi-minus"
|
|
188
188
|
label="Collapse All"
|
|
189
189
|
size="small"
|
|
@@ -282,12 +282,12 @@ function isMultiline(value: unknown): boolean {
|
|
|
282
282
|
spellcheck="false"
|
|
283
283
|
></textarea>
|
|
284
284
|
<div v-if="parseError" class="raw-json-actions">
|
|
285
|
-
<
|
|
285
|
+
<QdMessage severity="error" :closable="false" class="parse-error">
|
|
286
286
|
{{ parseError }}
|
|
287
|
-
</
|
|
287
|
+
</QdMessage>
|
|
288
288
|
</div>
|
|
289
289
|
<div v-else class="raw-json-actions">
|
|
290
|
-
<
|
|
290
|
+
<QdButton
|
|
291
291
|
label="Apply Changes"
|
|
292
292
|
icon="pi pi-check"
|
|
293
293
|
size="small"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
import { ref, computed, watch } from 'vue'
|
|
44
44
|
import SelectButton from 'primevue/selectbutton'
|
|
45
|
-
import
|
|
45
|
+
import QdMessage from '../base/QdMessage.vue'
|
|
46
46
|
import VanillaJsonEditor from './VanillaJsonEditor.vue'
|
|
47
47
|
import type { Mode } from 'vanilla-jsoneditor'
|
|
48
48
|
|
|
@@ -179,14 +179,14 @@ watch(() => props.mode, (newMode: ViewMode | null | undefined) => {
|
|
|
179
179
|
|
|
180
180
|
<!-- JSON View -->
|
|
181
181
|
<div v-if="viewMode === 'json'" class="json-view">
|
|
182
|
-
<
|
|
182
|
+
<QdMessage
|
|
183
183
|
v-if="guardInvalidJson && hasJsonError"
|
|
184
184
|
severity="error"
|
|
185
185
|
:closable="false"
|
|
186
186
|
class="json-error"
|
|
187
187
|
>
|
|
188
188
|
{{ invalidJsonMessage }}
|
|
189
|
-
</
|
|
189
|
+
</QdMessage>
|
|
190
190
|
<VanillaJsonEditor
|
|
191
191
|
:modelValue="effectiveJsonValue"
|
|
192
192
|
:mode="jsonMode"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { ref, computed } from 'vue'
|
|
21
|
-
import
|
|
21
|
+
import QdButton from '../base/QdButton.vue'
|
|
22
22
|
import InputText from 'primevue/inputtext'
|
|
23
23
|
import AutoComplete from 'primevue/autocomplete'
|
|
24
24
|
import Slider from 'primevue/slider'
|
|
@@ -161,7 +161,7 @@ function updateItemValue(index: number, value: string | number): void {
|
|
|
161
161
|
/>
|
|
162
162
|
</template>
|
|
163
163
|
</div>
|
|
164
|
-
<
|
|
164
|
+
<QdButton
|
|
165
165
|
icon="pi pi-times"
|
|
166
166
|
severity="danger"
|
|
167
167
|
text
|
|
@@ -172,7 +172,7 @@ function updateItemValue(index: number, value: string | number): void {
|
|
|
172
172
|
</div>
|
|
173
173
|
</div>
|
|
174
174
|
<div class="kv-add">
|
|
175
|
-
<
|
|
175
|
+
<QdButton
|
|
176
176
|
icon="pi pi-plus"
|
|
177
177
|
@click="addItem"
|
|
178
178
|
:disabled="!newItem.key || (isTextMode && !newItem.value)"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { ref, computed } from 'vue'
|
|
12
|
-
import
|
|
12
|
+
import QdButton from '../base/QdButton.vue'
|
|
13
13
|
import InputText from 'primevue/inputtext'
|
|
14
14
|
import Slider from 'primevue/slider'
|
|
15
15
|
import Checkbox from 'primevue/checkbox'
|
|
@@ -113,7 +113,7 @@ function updateFluency(index: number, fluency: number | number[]): void {
|
|
|
113
113
|
style="width: 100px"
|
|
114
114
|
/>
|
|
115
115
|
</div>
|
|
116
|
-
<
|
|
116
|
+
<QdButton
|
|
117
117
|
v-if="lang.primary"
|
|
118
118
|
icon="pi pi-star-fill"
|
|
119
119
|
severity="warning"
|
|
@@ -122,7 +122,7 @@ function updateFluency(index: number, fluency: number | number[]): void {
|
|
|
122
122
|
size="small"
|
|
123
123
|
v-tooltip.top="'Primary language'"
|
|
124
124
|
/>
|
|
125
|
-
<
|
|
125
|
+
<QdButton
|
|
126
126
|
v-else
|
|
127
127
|
icon="pi pi-star"
|
|
128
128
|
severity="secondary"
|
|
@@ -132,7 +132,7 @@ function updateFluency(index: number, fluency: number | number[]): void {
|
|
|
132
132
|
@click="setPrimaryLanguage(index)"
|
|
133
133
|
v-tooltip.top="'Set as primary'"
|
|
134
134
|
/>
|
|
135
|
-
<
|
|
135
|
+
<QdButton
|
|
136
136
|
icon="pi pi-times"
|
|
137
137
|
severity="danger"
|
|
138
138
|
text
|
|
@@ -143,7 +143,7 @@ function updateFluency(index: number, fluency: number | number[]): void {
|
|
|
143
143
|
</div>
|
|
144
144
|
</div>
|
|
145
145
|
<div class="lang-add">
|
|
146
|
-
<
|
|
146
|
+
<QdButton
|
|
147
147
|
icon="pi pi-plus"
|
|
148
148
|
@click="addLanguage"
|
|
149
149
|
:disabled="!newLanguage.code"
|
|
@@ -3,7 +3,7 @@ import { ref, computed, onMounted, watch, inject } from 'vue'
|
|
|
3
3
|
import type { HttpClient } from '../../entity/storage/ApiStorage'
|
|
4
4
|
import AutoComplete from 'primevue/autocomplete'
|
|
5
5
|
import Select from 'primevue/select'
|
|
6
|
-
import
|
|
6
|
+
import QdButton from '../base/QdButton.vue'
|
|
7
7
|
|
|
8
8
|
interface ScopeRow {
|
|
9
9
|
resource: string
|
|
@@ -266,7 +266,7 @@ onMounted(async () => {
|
|
|
266
266
|
/>
|
|
267
267
|
<span v-if="isRowComplete(row)" class="scope-valid">✓</span>
|
|
268
268
|
<span v-else class="scope-incomplete">...</span>
|
|
269
|
-
<
|
|
269
|
+
<QdButton
|
|
270
270
|
icon="pi pi-trash"
|
|
271
271
|
severity="danger"
|
|
272
272
|
text
|
|
@@ -279,7 +279,7 @@ onMounted(async () => {
|
|
|
279
279
|
</div>
|
|
280
280
|
|
|
281
281
|
<div class="scope-add">
|
|
282
|
-
<
|
|
282
|
+
<QdButton
|
|
283
283
|
label="Add Scope"
|
|
284
284
|
icon="pi pi-plus"
|
|
285
285
|
severity="secondary"
|
package/src/components/index.ts
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
// Layout
|
|
6
|
+
// Base widget wrappers — the single indirection points over the widget
|
|
7
|
+
// library (#1391 exit-readiness)
|
|
8
|
+
export { default as QdButton } from './base/QdButton.vue'
|
|
9
|
+
export { default as QdMessage } from './base/QdMessage.vue'
|
|
6
10
|
export { default as AppLayout } from './layout/AppLayout.vue'
|
|
7
11
|
export { default as BaseLayout } from './layout/BaseLayout.vue'
|
|
8
12
|
export { default as PageLayout } from './layout/PageLayout.vue'
|
|
@@ -21,7 +21,7 @@ import { useApp } from '../../composables/useApp'
|
|
|
21
21
|
import { useAuth } from '../../composables/useAuth'
|
|
22
22
|
import { useGuardDialog } from '../../composables/useGuardStore'
|
|
23
23
|
import { useNavContext, type BreadcrumbItem, type NavLinkItem } from '../../composables/useNavContext'
|
|
24
|
-
import
|
|
24
|
+
import QdButton from '../base/QdButton.vue'
|
|
25
25
|
import Breadcrumb from 'primevue/breadcrumb'
|
|
26
26
|
import UnsavedChangesDialog from '../dialogs/UnsavedChangesDialog.vue'
|
|
27
27
|
import SidebarBox from './SidebarBox.vue'
|
|
@@ -366,7 +366,7 @@ const showBreadcrumb = computed<boolean>(() => {
|
|
|
366
366
|
<main class="main-content" :class="{ 'main-content--sidebar-collapsed': sidebarCollapsed }">
|
|
367
367
|
<!-- Mobile header bar -->
|
|
368
368
|
<div class="mobile-header">
|
|
369
|
-
<
|
|
369
|
+
<QdButton
|
|
370
370
|
icon="pi pi-bars"
|
|
371
371
|
severity="secondary"
|
|
372
372
|
text
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import PageHeader from './PageHeader.vue'
|
|
19
19
|
import CardsGrid from '../display/CardsGrid.vue'
|
|
20
|
-
import
|
|
20
|
+
import QdButton from '../base/QdButton.vue'
|
|
21
21
|
|
|
22
22
|
interface TitleParts {
|
|
23
23
|
action?: string
|
|
@@ -89,7 +89,7 @@ function resolveLabel(label: string | (() => string)): string {
|
|
|
89
89
|
</template>
|
|
90
90
|
<template #actions>
|
|
91
91
|
<slot name="header-actions" ></slot>
|
|
92
|
-
<
|
|
92
|
+
<QdButton
|
|
93
93
|
v-for="action in headerActions"
|
|
94
94
|
:key="action.name"
|
|
95
95
|
:label="resolveLabel(action.label)"
|
|
@@ -11,7 +11,7 @@ import { computed, type ComputedRef } from 'vue'
|
|
|
11
11
|
import { useRouter } from 'vue-router'
|
|
12
12
|
import { prettifyRole } from '../../../utils/formatters'
|
|
13
13
|
import { useAuth } from '../../../composables/useAuth'
|
|
14
|
-
import
|
|
14
|
+
import QdButton from '../../base/QdButton.vue'
|
|
15
15
|
|
|
16
16
|
interface UserData {
|
|
17
17
|
username?: string
|
|
@@ -56,7 +56,7 @@ function handleLogout(): void {
|
|
|
56
56
|
<div class="user-name">{{ userDisplayName }}</div>
|
|
57
57
|
<div class="user-role">{{ userSubtitle }}</div>
|
|
58
58
|
</div>
|
|
59
|
-
<
|
|
59
|
+
<QdButton
|
|
60
60
|
icon="pi pi-sign-out"
|
|
61
61
|
severity="secondary"
|
|
62
62
|
text
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - handler: Click handler function
|
|
13
13
|
* - isDisabled: Boolean disabled state
|
|
14
14
|
*/
|
|
15
|
-
import
|
|
15
|
+
import QdButton from '../base/QdButton.vue'
|
|
16
16
|
|
|
17
17
|
interface Action {
|
|
18
18
|
name: string
|
|
@@ -32,7 +32,7 @@ defineProps<Props>()
|
|
|
32
32
|
|
|
33
33
|
<template>
|
|
34
34
|
<div class="table-actions">
|
|
35
|
-
<
|
|
35
|
+
<QdButton
|
|
36
36
|
v-for="action in actions"
|
|
37
37
|
:key="action.name"
|
|
38
38
|
:icon="action.icon"
|
|
@@ -21,7 +21,7 @@ import FilterBar from './FilterBar.vue'
|
|
|
21
21
|
import ActionButtons from './ActionButtons.vue'
|
|
22
22
|
import DataTable from 'primevue/datatable'
|
|
23
23
|
import Column from 'primevue/column'
|
|
24
|
-
import
|
|
24
|
+
import QdButton from '../base/QdButton.vue'
|
|
25
25
|
import Select from 'primevue/select'
|
|
26
26
|
import AutoComplete from 'primevue/autocomplete'
|
|
27
27
|
import SplitButton from 'primevue/splitbutton'
|
|
@@ -333,7 +333,7 @@ function getFilterClass(filter: FilterConfig): Record<string, boolean> {
|
|
|
333
333
|
<!-- Mobile: split button (primary action + dropdown) -->
|
|
334
334
|
<template v-if="isMobile && headerActions.length > 0 && primaryHeaderAction">
|
|
335
335
|
<!-- Single action: just a button -->
|
|
336
|
-
<
|
|
336
|
+
<QdButton
|
|
337
337
|
v-if="headerActions.length === 1"
|
|
338
338
|
:label="resolveLabel(primaryHeaderAction.label)"
|
|
339
339
|
:icon="primaryHeaderAction.icon"
|
|
@@ -355,7 +355,7 @@ function getFilterClass(filter: FilterConfig): Record<string, boolean> {
|
|
|
355
355
|
</template>
|
|
356
356
|
<!-- Desktop: individual buttons -->
|
|
357
357
|
<template v-else>
|
|
358
|
-
<
|
|
358
|
+
<QdButton
|
|
359
359
|
v-for="action in headerActions"
|
|
360
360
|
:key="action.name"
|
|
361
361
|
:label="resolveLabel(action.label)"
|
|
@@ -417,7 +417,7 @@ function getFilterClass(filter: FilterConfig): Record<string, boolean> {
|
|
|
417
417
|
/>
|
|
418
418
|
</template>
|
|
419
419
|
<slot name="filters" ></slot>
|
|
420
|
-
<
|
|
420
|
+
<QdButton
|
|
421
421
|
v-if="hasActiveFilters"
|
|
422
422
|
icon="pi pi-filter-slash"
|
|
423
423
|
severity="secondary"
|