@anzusystems/common-admin 1.47.0-beta.dev-1782074999 → 1.47.0-beta.dev-1782077999

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/dist/labs.d.ts CHANGED
@@ -1006,6 +1006,29 @@ declare type ExecuteRequestParams<T> = {
1006
1006
  object?: T;
1007
1007
  };
1008
1008
 
1009
+ /**
1010
+ * The shape a CONSUMER sees when it reads a list-editor handle through a template/function ref.
1011
+ * Vue's `expose` proxy unwraps every exposed ref, so the reactive fields (`hasUnsaved`, `hasErrors`,
1012
+ * `unsavedCount`, …) arrive as plain VALUES here, not `Ref`s: read `handle.hasUnsaved` (a boolean),
1013
+ * never `handle.hasUnsaved.value` (that is `undefined`). Type your `useTemplateRef` / collected-ref
1014
+ * maps with this so a stray `.value` is a compile error instead of a silently-dead guard/save-gate.
1015
+ */
1016
+ export declare type ExposedListEditorHandle<TItem extends Record<string, any>> = ShallowUnwrapRef<ListEditorHandle<TItem>>;
1017
+
1018
+ /**
1019
+ * Consumer-facing shape of a nested-list-editor handle read through a template/function ref — Vue's
1020
+ * `expose` proxy unwraps the exposed refs, so read `handle.hasUnsaved` (a boolean), not
1021
+ * `handle.hasUnsaved.value`. See {@link ExposedListEditorHandle}.
1022
+ *
1023
+ * The `ANestedSortableListEditor` component also exposes `hasUnsavedChanges` (a legacy alias of
1024
+ * `hasUnsaved`, likewise a ComputedRef → unwrapped to a boolean here) — included so it can't be
1025
+ * `.value`-read by accident. Its imperative-only extras (addAfterId / resetDirtyBaseline / expand /
1026
+ * reorder / …) are not refs and carry no unwrap hazard; intersect them in the consumer if you call them.
1027
+ */
1028
+ export declare type ExposedNestedListEditorHandle<TItem extends Record<string, any>> = ShallowUnwrapRef<NestedListEditorHandle<TItem>> & {
1029
+ hasUnsavedChanges: boolean;
1030
+ };
1031
+
1009
1032
  declare type FetchByIdsParams = {
1010
1033
  urlTemplate?: string;
1011
1034
  urlParams?: UrlParams;
@@ -1187,7 +1210,7 @@ export declare interface ListEditorHandle<TItem extends Record<string, any>> {
1187
1210
  /** Amber: is this row added / edited / moved since the last commit? */
1188
1211
  isUnsaved: (key: ListEditorKey) => boolean;
1189
1212
  /** Red rail (gated): 'invalid' only once the row is unsaved or `validateAll()` ran. */
1190
- rowState: (item: TItem, key: ListEditorKey) => ListEditorValidationState;
1213
+ rowState: (item: TItem, key: ListEditorKey, editing?: boolean) => ListEditorValidationState;
1191
1214
  /** Force-show all invalid rows + return whether the list is valid. The save guard. */
1192
1215
  validateAll: () => boolean;
1193
1216
  /** Normalized ordered array for a full-DTO save. */
@@ -1198,7 +1221,7 @@ export declare interface ListEditorHandle<TItem extends Record<string, any>> {
1198
1221
  commit: (savedItems?: TItem[]) => void;
1199
1222
  /** Discard unsaved edits back to the last committed baseline (or given items). */
1200
1223
  reset: (items?: TItem[]) => void;
1201
- addItem: (item?: TItem, hint?: PositionHint) => void;
1224
+ addItem: (item?: TItem, hint?: PositionHint) => ListEditorKey | undefined;
1202
1225
  updateItem: (key: ListEditorKey, next: TItem | Partial<TItem> | ((current: TItem) => TItem)) => void;
1203
1226
  /** Remove a row. `trackDeleted: false` (immediate mode) skips the deferred-deletion tombstone. */
1204
1227
  deleteItem: (key: ListEditorKey, opts?: {
@@ -1207,19 +1230,14 @@ export declare interface ListEditorHandle<TItem extends Record<string, any>> {
1207
1230
  /** Clear a deferred-deletion tombstone (the caller re-inserts the row, e.g. reorder Cancel). */
1208
1231
  restoreDeleted: (key: ListEditorKey) => void;
1209
1232
  moveItem: (fromIndex: number, toIndex: number) => void;
1233
+ /** Drop the "moved" flag for the given keys (or all) without touching edits/adds — e.g. reorder Cancel. */
1234
+ clearMoved: (keys?: Iterable<ListEditorKey>) => void;
1210
1235
  /** Escape hatch: a row form (e.g. vuelidate) reports its own validity instead of `validate`. */
1211
1236
  registerValidity: (key: ListEditorKey, isValid: () => boolean) => () => void;
1212
1237
  }
1213
1238
 
1214
1239
  export declare type ListEditorKey = DocId | IntegerId | string;
1215
1240
 
1216
- export declare const ListEditorValidationKey: InjectionKey<ListEditorValidationRegistry>;
1217
-
1218
- export declare interface ListEditorValidationRegistry {
1219
- register: (key: ListEditorKey, state: Ref<ListEditorValidationState> | ComputedRef<ListEditorValidationState>) => void;
1220
- unregister: (key: ListEditorKey) => void;
1221
- }
1222
-
1223
1241
  /** Per-row validity. `true` (or `{ valid: true }`) = VALID. Only `valid: false` blocks save. */
1224
1242
  export declare type ListEditorValidationResult = boolean | {
1225
1243
  valid: boolean;
@@ -1322,7 +1340,7 @@ export declare interface NestedListEditorHandle<TItem extends Record<string, any
1322
1340
  /** Amber: is this row added / edited / moved / reparented since the last commit? */
1323
1341
  isUnsaved: (key: ListEditorKey) => boolean;
1324
1342
  /** Red rail (gated): 'invalid' only once the row is unsaved or `validateAll()` ran. */
1325
- rowState: (item: TItem, key: ListEditorKey) => ListEditorValidationState;
1343
+ rowState: (item: TItem, key: ListEditorKey, editing?: boolean) => ListEditorValidationState;
1326
1344
  /** Force-show all invalid rows + return whether the tree is valid. The save guard. */
1327
1345
  validateAll: () => boolean;
1328
1346
  /** Flattened ordered array (each row carrying its resolved position + parent key) for a full-DTO save. */
@@ -2097,6 +2115,25 @@ export declare function useFilterHelpers<F extends readonly MakeFilterOption<str
2097
2115
  } | null;
2098
2116
  };
2099
2117
 
2118
+ /**
2119
+ * Wrap an entity-delete handler so it bypasses the unsaved-changes leave guard.
2120
+ *
2121
+ * An entity delete destroys the record together with any unsaved edits, so the "you have unsaved
2122
+ * changes — really leave?" prompt that the delete's `router.push` would otherwise trigger is
2123
+ * meaningless: the user already confirmed the delete, and there is nothing left to keep. Without this
2124
+ * the delete runs, then the leave-guard fires on the post-delete navigation and choosing "stay" leaves
2125
+ * the view on an already-deleted entity (system error). This acknowledges the guard right before the
2126
+ * delete so the follow-up navigation proceeds without prompting. (QA 85050 batch 7 — BUG-08)
2127
+ *
2128
+ * If `onDelete` REJECTS (the delete failed and never navigated), the acknowledgement is undone
2129
+ * immediately (`unacknowledge()`) so a subsequently-dirtied navigation is still guarded (M1) — the
2130
+ * error is re-thrown so the caller's own handling runs. For this to catch failures, `onDelete` must
2131
+ * let its error propagate (don't swallow it in the action's try/catch).
2132
+ *
2133
+ * Usage: `@delete-record="guardedDelete(() => onDelete(id))"` or wrap the handler once.
2134
+ */
2135
+ export declare function useGuardedDelete<A extends unknown[], R>(guard: Pick<UseUnsavedChangesGuardApi, 'acknowledge' | 'unacknowledge'>, onDelete: (...args: A) => R): (...args: A) => R | Promise<Awaited<R>>;
2136
+
2100
2137
  export declare function useJobApi<JobType extends JobBase = JobBase>(client: () => AxiosInstance, system: string): {
2101
2138
  useFetchJobList: () => UseApiFetchListReturnType<JobType[]>;
2102
2139
  fetchJob: (id: number) => Promise<JobType>;
@@ -2154,39 +2191,6 @@ export declare interface UseListEditorControllerOptions<TItem extends Record<str
2154
2191
  normalizeSaved?: (savedItems: TItem[]) => TItem[];
2155
2192
  }
2156
2193
 
2157
- export declare function useListEditorItemValidation(options: UseListEditorItemValidationOptions): void;
2158
-
2159
- declare interface UseListEditorItemValidationOptions {
2160
- /**
2161
- * Stable identity of the row in the editor's v-model. Pass a getter so the
2162
- * composable can re-register if the key ever swaps.
2163
- */
2164
- key: () => ListEditorKey;
2165
- /**
2166
- * Reactive validation state. Common shape: a computed reading vuelidate's
2167
- * `v$.$dirty && v$.$invalid` and returning 'invalid' or null.
2168
- *
2169
- * Prefer `invalid` (+ optional `dirty`) below: it lets the editor surface the
2170
- * error once the row is unsaved without relying on mount-relative `$anyDirty`.
2171
- * `state` is kept for callers that report 'valid'/'warning' or custom logic.
2172
- */
2173
- state?: Ref<ListEditorValidationState> | ComputedRef<ListEditorValidationState> | (() => ListEditorValidationState);
2174
- /**
2175
- * Whether the row's data fails validation right now (e.g. `() => v$.value.$invalid`).
2176
- * When provided, the row is flagged 'invalid' as soon as it is invalid AND the
2177
- * user has had a chance to fix it — i.e. the row is unsaved (added / modified)
2178
- * or `dirty` below is true. Untouched rows on initial load stay clear so a
2179
- * persisted-but-invalid record does not light up red before any interaction.
2180
- */
2181
- invalid?: () => boolean;
2182
- /**
2183
- * Optional extra "has been interacted with" signal OR-ed with the editor's
2184
- * unsaved tracking (e.g. `() => v$.value.$anyDirty`). Useful when unsaved
2185
- * tracking is disabled on the editor.
2186
- */
2187
- dirty?: () => boolean;
2188
- }
2189
-
2190
2194
  export declare interface UseListEditorOptions {
2191
2195
  keyField?: string;
2192
2196
  positionField?: string;
@@ -2194,25 +2198,6 @@ export declare interface UseListEditorOptions {
2194
2198
  updatePosition?: boolean;
2195
2199
  }
2196
2200
 
2197
- /**
2198
- * Registers a row's vuelidate state with the surrounding list editor so the
2199
- * row shows the red invalid rail (invalid + unsaved/dirty) instead of amber.
2200
- *
2201
- * This is the one blessed shape for row validity sentinels — domain sentinels
2202
- * call their validation composable and delegate here:
2203
- *
2204
- * ```ts
2205
- * const item = computed(() => props.modelValue)
2206
- * const { v$ } = useReviewListItemValidation(item)
2207
- * useListEditorVuelidateSentinel(v$, () => item.value.id ?? item.value.position)
2208
- * ```
2209
- *
2210
- * `key` must return the same key the editor resolves for the row
2211
- * (its `key-field`) or the item's own id/position — the editor's validation
2212
- * registry accepts either.
2213
- */
2214
- export declare function useListEditorVuelidateSentinel(v$: Ref<VuelidateSentinelSource>, key: () => ListEditorKey): void;
2215
-
2216
2201
  /**
2217
2202
  * Nested list editor core. Pure data behavior shared by ANestedSortableListEditor.
2218
2203
  * Works on a tree of `{ data, children, meta }` nodes — shape-compatible with the
@@ -2415,8 +2400,19 @@ declare interface UseUnsavedChangesGuardApi {
2415
2400
  * route/dialog/unload attempt proceeds without prompting. Useful right
2416
2401
  * before a programmatic navigation that the consumer has already
2417
2402
  * confirmed.
2403
+ *
2404
+ * The acknowledgement AUTO-EXPIRES after a few seconds if nothing consumes it
2405
+ * (see `ACKNOWLEDGE_TTL_MS`): a delete that acknowledges up-front but then FAILS
2406
+ * (throws, never navigates) must not leave the guard silently disarmed for the
2407
+ * next unrelated navigation. Consuming it (a real leave) clears the timer.
2418
2408
  */
2419
2409
  acknowledge: () => void;
2410
+ /**
2411
+ * Cancel a pending `acknowledge()` (disarm). Call from a delete's failure path
2412
+ * so a failed/aborted delete restores the guard immediately instead of waiting
2413
+ * for the TTL. No-op if nothing is acknowledged.
2414
+ */
2415
+ unacknowledge: () => void;
2420
2416
  }
2421
2417
 
2422
2418
  declare interface UseUnsavedChangesGuardOptions {
@@ -2491,15 +2487,6 @@ declare interface ViewBodySlotProps<TItem extends Record<string, any>> {
2491
2487
  };
2492
2488
  }
2493
2489
 
2494
- /**
2495
- * Minimal surface of a vuelidate instance the sentinel reads — any
2496
- * `useVuelidate()` return value is structurally assignable.
2497
- */
2498
- export declare interface VuelidateSentinelSource {
2499
- $invalid: boolean;
2500
- $anyDirty: boolean;
2501
- }
2502
-
2503
2490
  export { }
2504
2491
 
2505
2492
  declare global {