mgv-backoffice 1.45.0 → 1.46.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 +32 -0
- package/dist/components/BaseGroupedChecklist.vue.d.ts +26 -0
- package/dist/composables/useDirtyState.d.ts +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/types/checklist.d.ts +6 -0
- package/dist/ui-lib.css +1 -1
- package/dist/ui-lib.js +208 -117
- package/dist/ui-lib.umd.cjs +1 -1
- package/package.json +1 -1
- package/src/components/BaseGroupedChecklist.test.ts +73 -0
- package/src/components/BaseGroupedChecklist.vue +122 -0
- package/src/composables/useDirtyState.test.ts +38 -0
- package/src/composables/useDirtyState.ts +44 -0
- package/src/index.ts +3 -0
- package/src/types/checklist.ts +6 -0
package/README.md
CHANGED
|
@@ -1782,6 +1782,35 @@ Extracted from TradeAutomation's variant-stats modal.
|
|
|
1782
1782
|
|
|
1783
1783
|
---
|
|
1784
1784
|
|
|
1785
|
+
### BaseGroupedChecklist
|
|
1786
|
+
|
|
1787
|
+
Grouped multi-select checklist (since 1.46.0): a master "Select all (N)"
|
|
1788
|
+
checkbox, a per-group select-all, and one checkbox per item. Built for
|
|
1789
|
+
"pick which records this action applies to" confirmation modals. Empty groups
|
|
1790
|
+
are not rendered; items are plain strings, unique across groups.
|
|
1791
|
+
|
|
1792
|
+
| Prop | Type | Default | Description |
|
|
1793
|
+
| ---------------- | -------------------------- | ------------------ | ----------- |
|
|
1794
|
+
| `groups` | `ChecklistGroup[]` | **required** | `{ key, label, items: string[] }` per group, in display order. |
|
|
1795
|
+
| `modelValue` | `string[]` | **required** | Selected items (`v-model`); emitted in group order. |
|
|
1796
|
+
| `allLabel` | `string` | `'Select all'` | Master checkbox text; group checkboxes are labelled `"<allLabel> <group label>"`. |
|
|
1797
|
+
| `allAriaLabel` | `string` | `'Select all items'` | Accessible name of the master checkbox. |
|
|
1798
|
+
| `itemAriaLabel` | `(item: string) => string` | the item itself | Accessible name per item checkbox. |
|
|
1799
|
+
| `mono` | `boolean` | `false` | Monospace item labels (tickers, ids). |
|
|
1800
|
+
| `maxHeightClass` | `string` | `'max-h-72'` | Scroll cap of the group list. |
|
|
1801
|
+
|
|
1802
|
+
```vue
|
|
1803
|
+
<BaseGroupedChecklist
|
|
1804
|
+
v-model="selected"
|
|
1805
|
+
:groups="[{ key: 'STOCK', label: 'Stocks', items: ['AMD', 'NVDA'] }]"
|
|
1806
|
+
all-aria-label="Select all symbols"
|
|
1807
|
+
:item-aria-label="(s) => `Apply to ${s}`"
|
|
1808
|
+
mono
|
|
1809
|
+
/>
|
|
1810
|
+
```
|
|
1811
|
+
|
|
1812
|
+
---
|
|
1813
|
+
|
|
1785
1814
|
### BaseSearchSelect
|
|
1786
1815
|
|
|
1787
1816
|
Searchable select (combobox): type to filter, pick with the mouse or
|
|
@@ -1952,6 +1981,8 @@ import {
|
|
|
1952
1981
|
usePolling,
|
|
1953
1982
|
useLatestRequest,
|
|
1954
1983
|
isAbortError,
|
|
1984
|
+
useDirtyState,
|
|
1985
|
+
stableStringify,
|
|
1955
1986
|
} from 'mgv-backoffice'
|
|
1956
1987
|
import type {
|
|
1957
1988
|
UseThemeOptions,
|
|
@@ -1976,6 +2007,7 @@ import type {
|
|
|
1976
2007
|
| `useFieldClasses()` | Shared form-field class strings for the gray/emerald form skin: `{ label, input, requiredInput(value) }`. `requiredInput` returns a red border+ring skin while the value is empty and the standard skin otherwise. |
|
|
1977
2008
|
| `usePolling(fn, intervalMs, { immediate?, pauseWhenHidden? })` | Visibility-gated polling loop bound to the component lifecycle: starts on mount, stops on unmount, pauses while the tab is hidden and refreshes + resumes on return to visible (both default on). Pass `intervalMs: null` for refresh-only mode (run on mount + each return-to-visible, no timer). Returns `{ start, stop, active }`. A loop stopped via `stop()` stays stopped across hide/show cycles (since 1.36.0) — only a visibility-paused loop auto-resumes. Catch errors inside `fn` — the loop never swallows rejections. |
|
|
1978
2009
|
| `useLatestRequest()` | "Latest request wins" guard for views that refetch on filter changes / polls / Refresh (since 1.45.0). `begin()` aborts the previous in-flight request and returns `{ signal, isLatest() }` — pass `signal` to `fetch`, and check `isLatest()` after every `await` before writing state (and before clearing a loading flag in `finally`). `cancel()` aborts + invalidates without starting a new request. Auto-cancels on unmount when called in setup. Pair with `isAbortError(e)` to swallow superseded requests silently. |
|
|
2010
|
+
| `useDirtyState(snapshot)` | Unsaved-changes tracking for edit forms (since 1.46.0): `snapshot()` returns the form state (read reactively); `dirty` is true while it differs from the last baseline, `markClean()` makes the current state the baseline (call after load / save). Structural, key-order-insensitive comparison via `stableStringify` (also exported), so a server echo that reorders keys never reads as an edit. |
|
|
1979
2011
|
|
|
1980
2012
|
---
|
|
1981
2013
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ChecklistGroup } from '../types/checklist';
|
|
2
|
+
interface Props {
|
|
3
|
+
groups: ChecklistGroup[];
|
|
4
|
+
modelValue: string[];
|
|
5
|
+
/** Text of the master checkbox; group checkboxes read "<allLabel> <group>". */
|
|
6
|
+
allLabel?: string;
|
|
7
|
+
allAriaLabel?: string;
|
|
8
|
+
/** Accessible name per item checkbox (defaults to the item itself). */
|
|
9
|
+
itemAriaLabel?: (item: string) => string;
|
|
10
|
+
/** Render item labels in a monospace font (tickers, ids). */
|
|
11
|
+
mono?: boolean;
|
|
12
|
+
maxHeightClass?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const __VLS_export: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
15
|
+
"update:modelValue": (value: string[]) => any;
|
|
16
|
+
}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
|
|
17
|
+
"onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
|
|
18
|
+
}>, {
|
|
19
|
+
maxHeightClass: string;
|
|
20
|
+
mono: boolean;
|
|
21
|
+
allLabel: string;
|
|
22
|
+
allAriaLabel: string;
|
|
23
|
+
itemAriaLabel: (item: string) => string;
|
|
24
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* JSON-serialise a value with object keys sorted at every depth, so two
|
|
4
|
+
* structurally equal values always produce the same string regardless of
|
|
5
|
+
* key insertion order (arrays keep their order).
|
|
6
|
+
*/
|
|
7
|
+
export declare function stableStringify(value: unknown): string;
|
|
8
|
+
/**
|
|
9
|
+
* Unsaved-changes tracking for an edit form. `snapshot` returns the form's
|
|
10
|
+
* current state (read reactively); `dirty` is true whenever it differs from
|
|
11
|
+
* the last clean baseline. Call `markClean()` after loading or saving to make
|
|
12
|
+
* the current state the new baseline. Comparison is structural (key order is
|
|
13
|
+
* ignored), so a server echo that reorders keys never reads as an edit.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const form = reactive({ name: '', params: {} })
|
|
17
|
+
* const { dirty, markClean } = useDirtyState(() => form)
|
|
18
|
+
* // …load → assign form → markClean(); Save enabled while dirty.value
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function useDirtyState(snapshot: () => unknown): {
|
|
22
|
+
dirty: ComputedRef<boolean>;
|
|
23
|
+
markClean: () => void;
|
|
24
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export { default as BaseFilterChip } from './components/BaseFilterChip.vue';
|
|
|
44
44
|
export { default as BaseCredentialsForm } from './components/BaseCredentialsForm.vue';
|
|
45
45
|
export { default as BasePillPickerModal } from './components/BasePillPickerModal.vue';
|
|
46
46
|
export { default as BaseBarDistribution } from './components/BaseBarDistribution.vue';
|
|
47
|
+
export { default as BaseGroupedChecklist } from './components/BaseGroupedChecklist.vue';
|
|
47
48
|
export type { CredentialsView, CredentialsUpdate } from './components/BaseCredentialsForm.vue';
|
|
48
49
|
export { default as BaseDateTimePicker } from './components/BaseDateTimePicker.vue';
|
|
49
50
|
export type { DateTimePickerMode } from './components/BaseDateTimePicker.vue';
|
|
@@ -75,6 +76,7 @@ export type { FieldClasses } from './composables/useFieldClasses';
|
|
|
75
76
|
export { usePolling } from './composables/usePolling';
|
|
76
77
|
export type { UsePollingOptions } from './composables/usePolling';
|
|
77
78
|
export { useLatestRequest, isAbortError } from './composables/useLatestRequest';
|
|
79
|
+
export { useDirtyState, stableStringify } from './composables/useDirtyState';
|
|
78
80
|
export type { LatestRequestToken } from './composables/useLatestRequest';
|
|
79
81
|
export { AlertEnum } from './enums/AlertEnum';
|
|
80
82
|
export { BaseBadgeEnum } from './enums/BaseBadgeEnum';
|
|
@@ -98,6 +100,7 @@ export type { SpecField, SpecFieldType, SpecFieldValue } from './types/specField
|
|
|
98
100
|
export type { StatBreakdownItem } from './types/statBreakdown';
|
|
99
101
|
export type { PillPickerItem } from './types/pillPicker';
|
|
100
102
|
export type { DistributionBar } from './types/distribution';
|
|
103
|
+
export type { ChecklistGroup } from './types/checklist';
|
|
101
104
|
export { getBaseColor, getBaseColorOf } from './utils/util';
|
|
102
105
|
export { methodBadgeSolid, methodBadgeBright, methodBadgeTinted, statusBadgeSolid, statusBadgeTinted, statusBadgeSoft, } from './utils/httpColors';
|
|
103
106
|
export { rowKeyMissing, rowValueMissing } from './utils/kvRows';
|