mgv-backoffice 1.30.0 → 1.32.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 +63 -0
- package/dist/components/BaseConfirmModal.vue.d.ts +3 -3
- package/dist/components/BaseCopyButton.vue.d.ts +1 -1
- package/dist/components/BaseFileDropzone.vue.d.ts +32 -0
- package/dist/components/BaseModalShell.vue.d.ts +23 -7
- package/dist/composables/useFieldClasses.d.ts +29 -0
- package/dist/index.d.ts +7 -2
- package/dist/ui-lib.css +1 -1
- package/dist/ui-lib.js +847 -699
- package/dist/ui-lib.umd.cjs +1 -1
- package/dist/utils/format.d.ts +23 -0
- package/dist/utils/httpColors.d.ts +13 -0
- package/dist/utils/kvRows.d.ts +21 -0
- package/package.json +1 -1
- package/src/components/BaseConfirmModal.vue +5 -17
- package/src/components/BaseEntityPickerModal.vue +7 -9
- package/src/components/BaseFileDropzone.vue +94 -0
- package/src/components/BaseModalShell.vue +45 -3
- package/src/components/BaseTextInputModal.vue +5 -9
- package/src/composables/useFieldClasses.test.ts +55 -0
- package/src/composables/useFieldClasses.ts +56 -0
- package/src/index.ts +11 -0
- package/src/utils/format.test.ts +55 -0
- package/src/utils/format.ts +57 -0
- package/src/utils/httpColors.test.ts +38 -0
- package/src/utils/httpColors.ts +31 -0
- package/src/utils/kvRows.test.ts +47 -0
- package/src/utils/kvRows.ts +34 -0
|
@@ -60,3 +60,41 @@ describe('statusBadgeTinted', () => {
|
|
|
60
60
|
expect(statusBadgeTinted(undefined, false)).toBe('bg-green-100 text-green-800')
|
|
61
61
|
})
|
|
62
62
|
})
|
|
63
|
+
|
|
64
|
+
import { methodBadgeTinted, statusBadgeSoft } from './httpColors'
|
|
65
|
+
|
|
66
|
+
describe('methodBadgeTinted', () => {
|
|
67
|
+
it('gives each method its own hue (dark)', () => {
|
|
68
|
+
expect(methodBadgeTinted('GET', true)).toBe('bg-blue-500/15 text-blue-400')
|
|
69
|
+
expect(methodBadgeTinted('POST', true)).toBe('bg-emerald-500/15 text-emerald-400')
|
|
70
|
+
expect(methodBadgeTinted('PUT', true)).toBe('bg-amber-500/15 text-amber-400')
|
|
71
|
+
expect(methodBadgeTinted('DELETE', true)).toBe('bg-red-500/15 text-red-400')
|
|
72
|
+
expect(methodBadgeTinted('PATCH', true)).toBe('bg-purple-500/15 text-purple-400')
|
|
73
|
+
expect(methodBadgeTinted('HEAD', true)).toBe('bg-sky-500/15 text-sky-400')
|
|
74
|
+
})
|
|
75
|
+
it('uses the light palette when isDark is false', () => {
|
|
76
|
+
expect(methodBadgeTinted('GET', false)).toBe('bg-blue-100 text-blue-700')
|
|
77
|
+
})
|
|
78
|
+
it('is case-insensitive and falls back to gray for unknown/ANY/missing', () => {
|
|
79
|
+
expect(methodBadgeTinted('get', true)).toBe('bg-blue-500/15 text-blue-400')
|
|
80
|
+
expect(methodBadgeTinted(undefined, false)).toBe('bg-gray-100 text-gray-600')
|
|
81
|
+
expect(methodBadgeTinted('OPTIONS', false)).toBe('bg-gray-100 text-gray-600')
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
describe('statusBadgeSoft', () => {
|
|
86
|
+
it('buckets by status class (light)', () => {
|
|
87
|
+
expect(statusBadgeSoft(201, false)).toBe('bg-emerald-100 text-emerald-700')
|
|
88
|
+
expect(statusBadgeSoft(302, false)).toBe('bg-sky-100 text-sky-700')
|
|
89
|
+
expect(statusBadgeSoft(404, false)).toBe('bg-amber-100 text-amber-700')
|
|
90
|
+
expect(statusBadgeSoft(503, false)).toBe('bg-red-100 text-red-700')
|
|
91
|
+
})
|
|
92
|
+
it('uses tinted surfaces in dark mode', () => {
|
|
93
|
+
expect(statusBadgeSoft(200, true)).toBe('bg-emerald-500/15 text-emerald-300')
|
|
94
|
+
})
|
|
95
|
+
it('defaults undefined to 200 and gray for out-of-range codes', () => {
|
|
96
|
+
expect(statusBadgeSoft(undefined, false)).toBe('bg-emerald-100 text-emerald-700')
|
|
97
|
+
expect(statusBadgeSoft(999, false)).toBe('bg-gray-100 text-gray-600')
|
|
98
|
+
expect(statusBadgeSoft(100, true)).toBe('bg-gray-800 text-gray-400')
|
|
99
|
+
})
|
|
100
|
+
})
|
package/src/utils/httpColors.ts
CHANGED
|
@@ -52,6 +52,37 @@ export function statusBadgeSolid(status?: number): string {
|
|
|
52
52
|
return 'bg-gray-600'
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Dark/light-aware tinted method badge — per-method hue on a soft
|
|
57
|
+
* `*-500/15` (dark) / `*-100` (light) surface, for card-surface chips.
|
|
58
|
+
* (Extracted from WireMate's mock/stub cards; GET is blue here, unlike
|
|
59
|
+
* the green-leaning bright family above.)
|
|
60
|
+
*/
|
|
61
|
+
export function methodBadgeTinted(method: string | undefined, isDark: boolean): string {
|
|
62
|
+
const m = (method || 'ANY').toUpperCase()
|
|
63
|
+
if (m === 'GET') return isDark ? 'bg-blue-500/15 text-blue-400' : 'bg-blue-100 text-blue-700'
|
|
64
|
+
if (m === 'POST') return isDark ? 'bg-emerald-500/15 text-emerald-400' : 'bg-emerald-100 text-emerald-700'
|
|
65
|
+
if (m === 'PUT') return isDark ? 'bg-amber-500/15 text-amber-400' : 'bg-amber-100 text-amber-700'
|
|
66
|
+
if (m === 'DELETE') return isDark ? 'bg-red-500/15 text-red-400' : 'bg-red-100 text-red-700'
|
|
67
|
+
if (m === 'PATCH') return isDark ? 'bg-purple-500/15 text-purple-400' : 'bg-purple-100 text-purple-700'
|
|
68
|
+
if (m === 'HEAD') return isDark ? 'bg-sky-500/15 text-sky-400' : 'bg-sky-100 text-sky-700'
|
|
69
|
+
return isDark ? 'bg-gray-500/15 text-gray-400' : 'bg-gray-100 text-gray-600'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Dark/light-aware soft status badge keyed by status class — emerald 2xx,
|
|
74
|
+
* sky 3xx, amber 4xx, red 5xx, gray otherwise. Softer companion to
|
|
75
|
+
* `statusBadgeTinted` (which uses the green/blue/yellow palette).
|
|
76
|
+
*/
|
|
77
|
+
export function statusBadgeSoft(status: number | undefined, isDark: boolean): string {
|
|
78
|
+
const code = status ?? 200
|
|
79
|
+
if (code >= 200 && code < 300) return isDark ? 'bg-emerald-500/15 text-emerald-300' : 'bg-emerald-100 text-emerald-700'
|
|
80
|
+
if (code >= 300 && code < 400) return isDark ? 'bg-sky-500/15 text-sky-300' : 'bg-sky-100 text-sky-700'
|
|
81
|
+
if (code >= 400 && code < 500) return isDark ? 'bg-amber-500/15 text-amber-300' : 'bg-amber-100 text-amber-700'
|
|
82
|
+
if (code >= 500 && code < 600) return isDark ? 'bg-red-500/15 text-red-300' : 'bg-red-100 text-red-700'
|
|
83
|
+
return isDark ? 'bg-gray-800 text-gray-400' : 'bg-gray-100 text-gray-600'
|
|
84
|
+
}
|
|
85
|
+
|
|
55
86
|
/** Dark/light-aware tinted status badge. */
|
|
56
87
|
export function statusBadgeTinted(status: number | undefined, isDark: boolean): string {
|
|
57
88
|
const code = status ?? 200
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { rowKeyMissing, rowValueMissing } from './kvRows'
|
|
3
|
+
|
|
4
|
+
describe('rowValueMissing', () => {
|
|
5
|
+
it('is false for a fully blank row', () => {
|
|
6
|
+
expect(rowValueMissing({ key: '', value: '' })).toBe(false)
|
|
7
|
+
expect(rowValueMissing({})).toBe(false)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('is true when the key is filled but the value is blank', () => {
|
|
11
|
+
expect(rowValueMissing({ key: 'X-Trace', value: '' })).toBe(true)
|
|
12
|
+
expect(rowValueMissing({ key: 'X-Trace', value: ' ' })).toBe(true)
|
|
13
|
+
expect(rowValueMissing({ key: 'X-Trace' })).toBe(true)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('is false when both sides are filled', () => {
|
|
17
|
+
expect(rowValueMissing({ key: 'X-Trace', value: 'abc' })).toBe(false)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('exempts absent matchers — they carry no value by design', () => {
|
|
21
|
+
expect(rowValueMissing({ key: 'X-Trace', value: '', matcherType: 'absent' })).toBe(false)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('treats whitespace-only keys as blank', () => {
|
|
25
|
+
expect(rowValueMissing({ key: ' ', value: '' })).toBe(false)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('rowKeyMissing', () => {
|
|
30
|
+
it('is false for a fully blank row', () => {
|
|
31
|
+
expect(rowKeyMissing({ key: '', value: '' })).toBe(false)
|
|
32
|
+
expect(rowKeyMissing({})).toBe(false)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('is true when the value is filled but the key is blank', () => {
|
|
36
|
+
expect(rowKeyMissing({ key: '', value: 'abc' })).toBe(true)
|
|
37
|
+
expect(rowKeyMissing({ key: ' ', value: 'abc' })).toBe(true)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('is false when both sides are filled', () => {
|
|
41
|
+
expect(rowKeyMissing({ key: 'X-Trace', value: 'abc' })).toBe(false)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('exempts absent matchers', () => {
|
|
45
|
+
expect(rowKeyMissing({ key: '', value: 'abc', matcherType: 'absent' })).toBe(false)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validators for dynamic key/value row grids (header lists, query-param
|
|
3
|
+
* lists, metadata grids, …). A row is inconsistent when one side is
|
|
4
|
+
* filled in and the other is blank:
|
|
5
|
+
*
|
|
6
|
+
* • key present, value blank → rowValueMissing
|
|
7
|
+
* • value present, key blank → rowKeyMissing
|
|
8
|
+
*
|
|
9
|
+
* Rows whose `matcherType` is `'absent'` are exempt — an absent matcher
|
|
10
|
+
* intentionally carries no value (it asserts the key is NOT present).
|
|
11
|
+
* Rows without a matcherType (plain key/value pairs) validate normally.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface KeyValueRowLike {
|
|
15
|
+
key?: string
|
|
16
|
+
value?: string
|
|
17
|
+
matcherType?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** True when the row has a (non-absent) key but no value. */
|
|
21
|
+
export function rowValueMissing(row: KeyValueRowLike): boolean {
|
|
22
|
+
const key = (row.key ?? '').trim()
|
|
23
|
+
if (!key) return false
|
|
24
|
+
if (row.matcherType === 'absent') return false
|
|
25
|
+
return !(row.value ?? '').trim()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** True when the row has a value but no key to bind it to. */
|
|
29
|
+
export function rowKeyMissing(row: KeyValueRowLike): boolean {
|
|
30
|
+
if (row.matcherType === 'absent') return false
|
|
31
|
+
const hasValue = !!(row.value ?? '').trim()
|
|
32
|
+
if (!hasValue) return false
|
|
33
|
+
return !(row.key ?? '').trim()
|
|
34
|
+
}
|