@atscript/vue-table 0.1.139 → 0.1.141
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/as-action-form-dialog.cjs +1 -1
- package/dist/as-action-form-dialog.mjs +1 -1
- package/dist/{as-action-menu-content-D7NIwc9X.mjs → as-action-menu-content-6dR5q8bs.mjs} +1 -1
- package/dist/{as-action-menu-content-DXuyDZ_X.cjs → as-action-menu-content-AKbIp4Ni.cjs} +1 -1
- package/dist/as-cell-array.d.mts +1 -1
- package/dist/as-cell-date.d.mts +1 -1
- package/dist/as-cell-json.d.mts +1 -1
- package/dist/as-cell-number.d.mts +1 -1
- package/dist/as-cell-union.d.mts +1 -1
- package/dist/as-column-menu.d.cts +1 -1
- package/dist/as-column-menu.d.mts +1 -1
- package/dist/{as-column-menu.vue-Cul3eIz_.d.cts → as-column-menu.vue-DapdB_qF.d.cts} +1 -1
- package/dist/{as-column-menu.vue-Dw2m8ZqD.d.mts → as-column-menu.vue-Ys_sx0VE.d.mts} +1 -1
- package/dist/{as-config-dialog-j_-oUmN7.cjs → as-config-dialog-Chpw_2tu.cjs} +2 -2
- package/dist/{as-config-dialog-DrcYlrOh.mjs → as-config-dialog-UeMU7jTP.mjs} +2 -2
- package/dist/as-config-dialog.cjs +1 -1
- package/dist/as-config-dialog.d.mts +1 -1
- package/dist/as-config-dialog.mjs +1 -1
- package/dist/{as-confirm-dialog-Pnt60ALy.mjs → as-confirm-dialog-SIqCOw2p.mjs} +1 -1
- package/dist/{as-confirm-dialog-CStjIWN0.cjs → as-confirm-dialog-hHYVEX9E.cjs} +1 -1
- package/dist/as-confirm-dialog.cjs +1 -1
- package/dist/as-confirm-dialog.d.mts +1 -1
- package/dist/as-confirm-dialog.mjs +1 -1
- package/dist/{as-filter-dialog-CUzahpd_.mjs → as-filter-dialog-DVRhCx6O.mjs} +8 -8
- package/dist/{as-filter-dialog-B6_NvvlM.cjs → as-filter-dialog-Xvj5q09A.cjs} +8 -8
- package/dist/as-filter-dialog.cjs +1 -1
- package/dist/as-filter-dialog.d.mts +1 -1
- package/dist/as-filter-dialog.mjs +1 -1
- package/dist/{as-filter-field-DCUMuu0M.cjs → as-filter-field-B7b2sEG0.cjs} +3 -3
- package/dist/{as-filter-field-3DJh_ICs.mjs → as-filter-field-D4vQCOEU.mjs} +3 -3
- package/dist/as-filter-field.cjs +1 -1
- package/dist/as-filter-field.d.mts +1 -1
- package/dist/as-filter-field.mjs +1 -1
- package/dist/as-filter-input.d.mts +1 -1
- package/dist/{as-filters-CHLPYHNP.cjs → as-filters-CWQgQBCH.cjs} +19 -4
- package/dist/{as-filters-D0DWDyiv.mjs → as-filters-CudeInPr.mjs} +19 -4
- package/dist/as-filters.cjs +1 -1
- package/dist/as-filters.d.cts +1 -1
- package/dist/as-filters.d.mts +1 -1
- package/dist/as-filters.mjs +1 -1
- package/dist/{as-filters.vue-BG_ysCkC.d.mts → as-filters.vue-BSgUEh4D.d.mts} +23 -1
- package/dist/{as-filters.vue-DcxDnWAU.d.cts → as-filters.vue-DMXZhQW3.d.cts} +23 -1
- package/dist/{as-preset-dialog-H98DeOMM.mjs → as-preset-dialog-BsWSuY9N.mjs} +2 -2
- package/dist/{as-preset-dialog-RLW0gZDj.cjs → as-preset-dialog-l81WXBmf.cjs} +2 -2
- package/dist/as-preset-dialog.cjs +1 -1
- package/dist/as-preset-dialog.d.mts +1 -1
- package/dist/as-preset-dialog.mjs +1 -1
- package/dist/{as-preset-picker-Cw7LB7o1.mjs → as-preset-picker-BTkMqSxH.mjs} +31 -20
- package/dist/{as-preset-picker-yWXEhWEq.cjs → as-preset-picker-Bp4xMTua.cjs} +31 -20
- package/dist/as-preset-picker.cjs +1 -1
- package/dist/as-preset-picker.d.mts +1 -1
- package/dist/as-preset-picker.mjs +1 -1
- package/dist/as-residual-filter-BJ4cwFP4.cjs +54 -0
- package/dist/as-residual-filter-D1SGFQ1p.mjs +49 -0
- package/dist/as-residual-filter.cjs +2 -0
- package/dist/as-residual-filter.d.cts +2 -0
- package/dist/as-residual-filter.d.mts +2 -0
- package/dist/as-residual-filter.mjs +2 -0
- package/dist/as-residual-filter.vue-Dfw1l2wS.d.cts +21 -0
- package/dist/as-residual-filter.vue-N89YqlCz.d.mts +21 -0
- package/dist/{as-row-actions-D_TqnP3S.cjs → as-row-actions-9p_BJPga.cjs} +2 -2
- package/dist/{as-row-actions-BvJWHf3j.mjs → as-row-actions-CH8WZ5kN.mjs} +2 -2
- package/dist/as-row-actions.cjs +1 -1
- package/dist/as-row-actions.d.cts +1 -1
- package/dist/as-row-actions.d.mts +1 -1
- package/dist/as-row-actions.mjs +1 -1
- package/dist/{as-row-actions.vue-DxXodLGq.d.mts → as-row-actions.vue-BOURuyjv.d.mts} +1 -1
- package/dist/{as-row-actions.vue-WRrzvdbJ.d.cts → as-row-actions.vue-BezMFOr6.d.cts} +1 -1
- package/dist/{as-table-D5mMZKKg.mjs → as-table-DmmXWq94.mjs} +3 -3
- package/dist/{as-table-actions-C6moFlxt.mjs → as-table-actions-CFBAxKIS.mjs} +2 -2
- package/dist/{as-table-actions-D91sNgel.cjs → as-table-actions-oxVqSH-G.cjs} +2 -2
- package/dist/as-table-actions.cjs +1 -1
- package/dist/as-table-actions.d.cts +1 -1
- package/dist/as-table-actions.d.mts +1 -1
- package/dist/as-table-actions.mjs +1 -1
- package/dist/{as-table-actions.vue-CPVhj2ZC.d.mts → as-table-actions.vue-CrZtcxAY.d.mts} +2 -2
- package/dist/{as-table-actions.vue-DB3LW-eI.d.cts → as-table-actions.vue-Dls_1Vze.d.cts} +2 -2
- package/dist/{as-table-base-CyBOmUK9.cjs → as-table-base--MfU8LVN.cjs} +2 -2
- package/dist/{as-table-base-CEpvNFBd.mjs → as-table-base-Cl1XJu4H.mjs} +2 -2
- package/dist/as-table-cell-value.cjs +1 -1
- package/dist/as-table-cell-value.d.cts +1 -1
- package/dist/as-table-cell-value.d.mts +1 -1
- package/dist/as-table-cell-value.mjs +1 -1
- package/dist/{as-table-CVD1zLva.cjs → as-table-fOBpTDrI.cjs} +3 -3
- package/dist/{as-table-header-cell-D7pW2sV3.cjs → as-table-header-cell-10DQEs00.cjs} +1 -1
- package/dist/{as-table-header-cell-CUs-sSBm.mjs → as-table-header-cell-M8g9X9dR.mjs} +1 -1
- package/dist/as-table-header-cell.cjs +1 -1
- package/dist/as-table-header-cell.d.cts +1 -1
- package/dist/as-table-header-cell.d.mts +1 -1
- package/dist/as-table-header-cell.mjs +1 -1
- package/dist/{as-table-header-cell.vue-DFaRLZZA.d.cts → as-table-header-cell.vue-D-iI_EJY.d.cts} +1 -1
- package/dist/{as-table-header-cell.vue-BDhs3PNi.d.mts → as-table-header-cell.vue-SMBpzqU2.d.mts} +1 -1
- package/dist/{as-table-root-C61wrFd9.mjs → as-table-root-Bl423S7X.mjs} +11 -5
- package/dist/{as-table-root-C7Tr_9W-.cjs → as-table-root-CGXKfCIk.cjs} +11 -5
- package/dist/as-table-root.cjs +1 -1
- package/dist/as-table-root.d.cts +1 -1
- package/dist/as-table-root.d.mts +1 -1
- package/dist/as-table-root.mjs +1 -1
- package/dist/{as-table-root.vue-Bza3D5F1.d.mts → as-table-root.vue-BROdsTqv.d.mts} +41 -8
- package/dist/{as-table-root.vue-D5Xyux8I.d.cts → as-table-root.vue-D5H8uXFK.d.cts} +41 -8
- package/dist/{as-table-status-D08b0cqn.mjs → as-table-status-Bl9XmWqc.mjs} +5 -5
- package/dist/{as-table-status-B-MjDXNZ.cjs → as-table-status-bbuFDaaK.cjs} +5 -5
- package/dist/as-table.cjs +1 -1
- package/dist/as-table.d.cts +1 -1
- package/dist/as-table.d.mts +1 -1
- package/dist/as-table.mjs +1 -1
- package/dist/{as-table.vue-BuZGgKuM.d.cts → as-table.vue-B533pYs6.d.cts} +5 -5
- package/dist/{as-table.vue-CPfERNtx.d.mts → as-table.vue-B_7Y82yW.d.mts} +5 -5
- package/dist/{as-window-table-CjYMF0aX.mjs → as-window-table-CkTJOvu9.mjs} +3 -3
- package/dist/{as-window-table-BfSud7yB.cjs → as-window-table-Dpbezh9D.cjs} +3 -3
- package/dist/as-window-table.cjs +1 -1
- package/dist/as-window-table.d.cts +1 -1
- package/dist/as-window-table.d.mts +1 -1
- package/dist/as-window-table.mjs +1 -1
- package/dist/{as-window-table.vue-BIjQuSie.d.cts → as-window-table.vue-Bar8mWRL.d.cts} +5 -5
- package/dist/{as-window-table.vue-3egLvwAy.d.mts → as-window-table.vue-OL4KC7Y-.d.mts} +5 -5
- package/dist/index.cjs +23 -48
- package/dist/index.d.cts +11 -11
- package/dist/index.d.mts +23 -23
- package/dist/index.mjs +23 -48
- package/dist/{types-B6N5NDx_.d.cts → types-Cdk5OH1-.d.cts} +61 -5
- package/dist/{types-CgdpcJdd.d.mts → types-Ev-A5h_D.d.mts} +61 -5
- package/dist/{use-table-DUwUfjSZ.mjs → use-table-BG3IZyCO.mjs} +3 -2
- package/dist/{use-table-column-handlers-Do0Z-R9D.cjs → use-table-column-handlers-CWHRcQbE.cjs} +1 -1
- package/dist/{use-table-column-handlers-eKHCfUm_.mjs → use-table-column-handlers-CaT7dYnI.mjs} +1 -1
- package/dist/{use-table-component-wfU13P3L.mjs → use-table-component-OTdgA202.mjs} +1 -1
- package/dist/{use-table-component-DbQDINoa.cjs → use-table-component-Tc_ZvZua.cjs} +1 -1
- package/dist/{use-table-nav-bridge-DRrvQxXq.mjs → use-table-nav-bridge-BNjwR3qy.mjs} +1 -1
- package/dist/{use-table-nav-bridge-BLLVGR1r.cjs → use-table-nav-bridge-ByQo00IH.cjs} +1 -1
- package/dist/{use-table-c4ku22Mx.cjs → use-table-rc6_sYU6.cjs} +3 -2
- package/dist/{use-table-state-BEwXQayO.mjs → use-table-state-BgLIOO31.mjs} +208 -25
- package/dist/{use-table-state-Cnxv0w_E.cjs → use-table-state-CgXY-ruN.cjs} +212 -23
- package/package.json +14 -7
- /package/dist/{as-cell-array.vue-D4vS7C_D.d.mts → as-cell-array.vue-ow34clSF.d.mts} +0 -0
- /package/dist/{as-cell-date.vue-Chs7WTZ9.d.mts → as-cell-date.vue-B4JCr1qP.d.mts} +0 -0
- /package/dist/{as-cell-json.vue-C0_LDvQw.d.mts → as-cell-json.vue-B-T3TuFj.d.mts} +0 -0
- /package/dist/{as-cell-number.vue-BBF0OuU8.d.mts → as-cell-number.vue-CNH2fbCB.d.mts} +0 -0
- /package/dist/{as-cell-union.vue-CL-Lf-Rm.d.mts → as-cell-union.vue-CZwN81H4.d.mts} +0 -0
- /package/dist/{as-config-dialog.vue-BvFZZRuY.d.mts → as-config-dialog.vue-BKo2GpzN.d.mts} +0 -0
- /package/dist/{as-confirm-dialog.vue-Cz52-v6c.d.mts → as-confirm-dialog.vue-BN_yzu3h.d.mts} +0 -0
- /package/dist/{as-filter-dialog.vue-likNLqzF.d.mts → as-filter-dialog.vue-Bl8OIKOf.d.mts} +0 -0
- /package/dist/{as-filter-field.vue-BbXLhd6O.d.mts → as-filter-field.vue-DD0IZXS1.d.mts} +0 -0
- /package/dist/{as-filter-input.vue-B9ma2l9j.d.mts → as-filter-input.vue-CFZ33B--.d.mts} +0 -0
- /package/dist/{as-preset-dialog.vue-BRjjfPty.d.mts → as-preset-dialog.vue-ChM7H7B4.d.mts} +0 -0
- /package/dist/{as-preset-picker.vue-BPjsiaVt.d.mts → as-preset-picker.vue-OaAV2v9z.d.mts} +0 -0
- /package/dist/{as-table-cell-value-Ct0KnyKc.cjs → as-table-cell-value-COyZnwUj.cjs} +0 -0
- /package/dist/{as-table-cell-value-D1eLiQKJ.mjs → as-table-cell-value-DoH8Mieo.mjs} +0 -0
- /package/dist/{as-table-cell-value.vue-BgFDv2JQ.d.cts → as-table-cell-value.vue-C0VR9GRK.d.cts} +0 -0
- /package/dist/{as-table-cell-value.vue-kfNgVhzn.d.mts → as-table-cell-value.vue-DphckGq-.d.mts} +0 -0
- /package/dist/{error-message-CglODWl4.cjs → error-message-CfKpn_5w.cjs} +0 -0
- /package/dist/{error-message-hPSAu8Ug.mjs → error-message-gNEXnnbb.mjs} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ColumnDef, PaginationControl, SortControl, TableDef } from "@atscript/ui";
|
|
2
2
|
import { Component, ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
|
|
3
|
-
import { AsPresetEntryRow, AspectMask, ColumnWidthsMap, ConfigTab, FieldFilters, PresetAspect, PresetCapabilities, PresetSnapshot, SelectionMode, SystemPreset, SystemPresetInput, TableStateMethods } from "@atscript/ui-table";
|
|
3
|
+
import { AsPresetEntryRow, AspectMask, ColumnWidthsMap, ConfigTab, DroppedFields, FieldFilters, PresetAspect, PresetCapabilities, PresetSnapshot, SelectionMode, SystemPreset, SystemPresetInput, TableStateMethods } from "@atscript/ui-table";
|
|
4
4
|
import { ClientError, PageResult, TDbActionInfo, TDbActionProcessor, TDbDeleteResult } from "@atscript/db-client";
|
|
5
|
-
import { Uniquery } from "@uniqu/core";
|
|
5
|
+
import { FilterExpr, Uniquery } from "@uniqu/core";
|
|
6
6
|
|
|
7
7
|
//#region src/composables/state/intent-scope.d.ts
|
|
8
8
|
interface ActionBuckets {
|
|
@@ -369,6 +369,11 @@ interface TAsTableControls {
|
|
|
369
369
|
filterDialog?: Component;
|
|
370
370
|
filterField?: Component;
|
|
371
371
|
filterValueHelp?: Component;
|
|
372
|
+
/**
|
|
373
|
+
* One residual filter condition's chip in `<AsFilters>` — receives
|
|
374
|
+
* `expr` and `index`. Default `AsResidualFilter`. Since 0.1.140.
|
|
375
|
+
*/
|
|
376
|
+
residualFilter?: Component;
|
|
372
377
|
configDialog?: Component;
|
|
373
378
|
fieldsSelector?: Component;
|
|
374
379
|
sortersConfig?: Component;
|
|
@@ -408,6 +413,28 @@ type TAsCellTypeComponents = {
|
|
|
408
413
|
ref: Component; /** Synthesised row-actions pseudo-column (`:rowActionsColumn` opt-in). */
|
|
409
414
|
__actions?: Component;
|
|
410
415
|
} & Record<string, Component>;
|
|
416
|
+
/**
|
|
417
|
+
* What the table left out because it names a field outside the columns this
|
|
418
|
+
* caller can use — a field hidden from their role, or gone from the schema.
|
|
419
|
+
* Sent to `onFieldsDropped` / `@fields-dropped` once per apply, only when
|
|
420
|
+
* something was dropped. `fields` lists the unavailable paths; the other
|
|
421
|
+
* lists hold the dropped entries themselves.
|
|
422
|
+
*
|
|
423
|
+
* - `"preset"` — a preset applied (picker switch, reset, raw snapshot, and
|
|
424
|
+
* the bootstrap default with the local draft laid over it).
|
|
425
|
+
* - `"url"` — a restored URL (deep link, shared link, Back/Forward). Its
|
|
426
|
+
* dropped filter pieces are listed in `residual`, as whole expressions.
|
|
427
|
+
*
|
|
428
|
+
* State written straight to the model is not reported: the query leaves such
|
|
429
|
+
* fields out (a dev-mode warning names them once).
|
|
430
|
+
*
|
|
431
|
+
* @since 0.1.141
|
|
432
|
+
*/
|
|
433
|
+
interface DroppedFieldsReport extends DroppedFields {
|
|
434
|
+
source: "preset" | "url";
|
|
435
|
+
/** The preset whose apply dropped the entries (`"preset"`). */
|
|
436
|
+
presetId?: string;
|
|
437
|
+
}
|
|
411
438
|
/**
|
|
412
439
|
* How `applyUrlQuery` treats filters and sorters the URL does not mention.
|
|
413
440
|
* @since 0.1.137
|
|
@@ -442,6 +469,15 @@ interface ReactiveTableState extends TableStateMethods {
|
|
|
442
469
|
columnWidths: Ref<ColumnWidthsMap>;
|
|
443
470
|
filterFields: ShallowRef<string[]>;
|
|
444
471
|
filters: ShallowRef<FieldFilters>;
|
|
472
|
+
/**
|
|
473
|
+
* Residual filter conditions — AND-ed Uniquery conjuncts the field-filter
|
|
474
|
+
* model cannot hold (a cross-field `$or`, a second range on one field, …).
|
|
475
|
+
* AND'd after `filters` into every query, carried through the URL, shown
|
|
476
|
+
* as "custom filter" chips by `<AsFilters>`. Replace wholesale (or use
|
|
477
|
+
* `setResidualFilters` / `removeResidualFilter`); `resetFilters()`
|
|
478
|
+
* clears them. Not saved in presets. Since 0.1.140.
|
|
479
|
+
*/
|
|
480
|
+
residualFilters: ShallowRef<FilterExpr[]>;
|
|
445
481
|
sorters: ShallowRef<SortControl[]>;
|
|
446
482
|
results: ShallowRef<Record<string, unknown>[]>;
|
|
447
483
|
/** Absolute index where `results[0]` sits. */
|
|
@@ -686,6 +722,11 @@ interface ReactiveTableState extends TableStateMethods {
|
|
|
686
722
|
* the baseline.
|
|
687
723
|
*
|
|
688
724
|
* `opts.mode` overrides the marker either way. Since 0.1.139.
|
|
725
|
+
*
|
|
726
|
+
* Filter pieces the field-filter model cannot hold are restored as
|
|
727
|
+
* `residualFilters` (since 0.1.140). A URL owns every path it mentions —
|
|
728
|
+
* in a field filter or inside such a condition — so on merge the
|
|
729
|
+
* baseline's filters and residual conditions on those paths give way.
|
|
689
730
|
*/
|
|
690
731
|
applyUrlQuery: (urlString: string, opts?: ApplyUrlQueryOptions) => void;
|
|
691
732
|
/**
|
|
@@ -784,8 +825,19 @@ interface PresetSurface {
|
|
|
784
825
|
available: ComputedRef<boolean>;
|
|
785
826
|
/** Currently active preset id (system `'sys:*'` or stored). null = no active. */
|
|
786
827
|
activeId: Ref<string | null>;
|
|
787
|
-
/**
|
|
828
|
+
/**
|
|
829
|
+
* Active preset's snapshot (system presets are aspect-expanded), pruned of
|
|
830
|
+
* fields this caller cannot use — what applying it wrote. The stored row
|
|
831
|
+
* is never rewritten.
|
|
832
|
+
*/
|
|
788
833
|
activeSnapshot: ComputedRef<PresetSnapshot>;
|
|
834
|
+
/**
|
|
835
|
+
* What the active preset names that this caller cannot use — left out
|
|
836
|
+
* when it was applied — or `null`. Derived from the stored preset, so it
|
|
837
|
+
* follows the active id. `<AsPresetPicker>` shows a quiet note while set.
|
|
838
|
+
* Since 0.1.141.
|
|
839
|
+
*/
|
|
840
|
+
droppedFields: ComputedRef<DroppedFieldsReport | null>;
|
|
789
841
|
/** True when the current snapshot ≠ active preset's claimed aspects. */
|
|
790
842
|
isDirty: ComputedRef<boolean>;
|
|
791
843
|
/** True iff the active preset is owned by the current user (gates Save). */
|
|
@@ -811,7 +863,11 @@ interface PresetSurface {
|
|
|
811
863
|
* if it still references a known preset, else `STANDARD_PRESET_ID`.
|
|
812
864
|
*/
|
|
813
865
|
resolveDefaultId: () => string;
|
|
814
|
-
/**
|
|
866
|
+
/**
|
|
867
|
+
* Re-capture the active preset's existing aspect mask. Never widens.
|
|
868
|
+
* Entries on fields this caller cannot use (`droppedFields`) are appended
|
|
869
|
+
* back after the visible ones, so they survive the overwrite.
|
|
870
|
+
*/
|
|
815
871
|
saveActive: () => Promise<void>;
|
|
816
872
|
/** Create a new preset and switch the active id to it. */
|
|
817
873
|
saveAs: (label: string, opts?: {
|
|
@@ -849,4 +905,4 @@ interface PresetSurface {
|
|
|
849
905
|
lastError: Ref<Error | null>;
|
|
850
906
|
}
|
|
851
907
|
//#endregion
|
|
852
|
-
export {
|
|
908
|
+
export { TAsCellTypeComponents as C, TableNavBridge as D, TableActionsState as E, extractIdentifier as O, RowSelectableVerdict as S, TVueTableActionInfo as T, RowAttrsHook as _, ConfirmOptions as a, RowHookContext as b, InvokeOpts as c, NavKeyOptions as d, PresetConfig as f, RowActionsConfig as g, RowActionsColumnPlacement as h, ConfigTab as i, LocalRowAction as l, ReactiveTableState as m, ApplyUrlQueryOptions as n, DroppedFieldsReport as o, QueryErrorKind as p, ColumnMenuConfig as r, EnterAction as s, ActionResult as t, MainActionRequest as u, RowClassHook as v, TAsTableControls as w, RowSelectableHook as x, RowDeleteOpt as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as DEFAULT_AVAILABLE_ASPECTS, n as createTableState, r as provideTableContext } from "./use-table-state-BgLIOO31.mjs";
|
|
2
2
|
import { n as useTableSelection } from "./use-table-selection-ULbKT2xW.mjs";
|
|
3
3
|
import { createTableDef, getMetaEntry, resetMetaCache } from "@atscript/ui";
|
|
4
4
|
import { computed, inject, isRef, ref, shallowRef, toValue, watch } from "vue";
|
|
@@ -435,7 +435,8 @@ function useTable(url, opts) {
|
|
|
435
435
|
urlQueryReady: opts?.urlQueryReady,
|
|
436
436
|
onUrlQueryChange: opts?.onUrlQueryChange,
|
|
437
437
|
urlQuerySync: opts?.urlQuerySync,
|
|
438
|
-
onUnsupportedFilter: opts?.onUnsupportedFilter
|
|
438
|
+
onUnsupportedFilter: opts?.onUnsupportedFilter,
|
|
439
|
+
onFieldsDropped: opts?.onFieldsDropped
|
|
439
440
|
},
|
|
440
441
|
window: {
|
|
441
442
|
blockSize: opts?.blockSize,
|
package/dist/{use-table-column-handlers-Do0Z-R9D.cjs → use-table-column-handlers-CWHRcQbE.cjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_use_table_state = require("./use-table-state-
|
|
1
|
+
const require_use_table_state = require("./use-table-state-CgXY-ruN.cjs");
|
|
2
2
|
let vue = require("vue");
|
|
3
3
|
let _atscript_ui_table = require("@atscript/ui-table");
|
|
4
4
|
//#region src/composables/use-row-actions-column.ts
|
package/dist/{use-table-column-handlers-eKHCfUm_.mjs → use-table-column-handlers-CaT7dYnI.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as ROW_ACTIONS_PATH, k as ROW_ACTIONS_TYPE } from "./use-table-state-BgLIOO31.mjs";
|
|
2
2
|
import { computed, watch } from "vue";
|
|
3
3
|
import { reorderColumnNames } from "@atscript/ui-table";
|
|
4
4
|
//#region src/composables/use-row-actions-column.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as useTableContextOptional } from "./use-table-state-
|
|
1
|
+
import { o as useTableContextOptional } from "./use-table-state-BgLIOO31.mjs";
|
|
2
2
|
//#region src/composables/use-table-component.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolve a single skin-slot component from the injected `controls` map,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_use_table_state = require("./use-table-state-
|
|
1
|
+
const require_use_table_state = require("./use-table-state-CgXY-ruN.cjs");
|
|
2
2
|
//#region src/composables/use-table-component.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolve a single skin-slot component from the injected `controls` map,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as useTableContextOptional } from "./use-table-state-
|
|
1
|
+
import { o as useTableContextOptional } from "./use-table-state-BgLIOO31.mjs";
|
|
2
2
|
//#region src/composables/use-table-nav-bridge.ts
|
|
3
3
|
function isPassthroughKey(event) {
|
|
4
4
|
const key = event.key;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_use_table_state = require("./use-table-state-
|
|
1
|
+
const require_use_table_state = require("./use-table-state-CgXY-ruN.cjs");
|
|
2
2
|
const require_use_table_selection = require("./use-table-selection-DtCV3rhu.cjs");
|
|
3
3
|
let _atscript_ui = require("@atscript/ui");
|
|
4
4
|
let vue = require("vue");
|
|
@@ -435,7 +435,8 @@ function useTable(url, opts) {
|
|
|
435
435
|
urlQueryReady: opts?.urlQueryReady,
|
|
436
436
|
onUrlQueryChange: opts?.onUrlQueryChange,
|
|
437
437
|
urlQuerySync: opts?.urlQuerySync,
|
|
438
|
-
onUnsupportedFilter: opts?.onUnsupportedFilter
|
|
438
|
+
onUnsupportedFilter: opts?.onUnsupportedFilter,
|
|
439
|
+
onFieldsDropped: opts?.onFieldsDropped
|
|
439
440
|
},
|
|
440
441
|
window: {
|
|
441
442
|
blockSize: opts?.blockSize,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as getCellValue } from "./get-cell-value-Cb3X8nUn.mjs";
|
|
2
2
|
import { navigateHrefFor } from "@atscript/ui";
|
|
3
3
|
import { computed, inject, nextTick, onBeforeUnmount, onScopeDispose, provide, ref, shallowRef, toValue, watch } from "vue";
|
|
4
|
-
import { DEV, STANDARD_PRESET_ID, blockStartFor, buildTableQuery, cellAsString, debounce, derivePresetAspects, fromWireSnapshot, gateOwns, isDirtyAgainst, isFilled, isSystemPresetId, mergeDisplayColumns, mergeSorters, pageAlignedBlocksFor, planFetch, reconcileColumnWidthDefaults, resolveAspectGate, resolveSystemPresets, rowsToPks, sameColumnSet, sortRowsLocally, sortersEqual, stateToUrlQueryString, togglePk, urlQueryStringToState, walkBackwardAbsorb, walkForwardAbsorb } from "@atscript/ui-table";
|
|
4
|
+
import { DEV, STANDARD_PRESET_ID, arraysEqual, blockStartFor, buildTableQuery, cellAsString, debounce, derivePresetAspects, filterExprFields, filterExprKey, fromWireSnapshot, gateOwns, isDirtyAgainst, isFilled, isSystemPresetId, mergeDisplayColumns, mergeSorters, normalizeResidualFilters, pageAlignedBlocksFor, planFetch, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, residualGateOwns, resolveAspectGate, resolveSystemPresets, restoreDroppedEntries, rowsToPks, sameColumnSet, sortRowsLocally, sortersEqual, stateToUrlQueryString, togglePk, urlQueryStringToState, walkBackwardAbsorb, walkForwardAbsorb } from "@atscript/ui-table";
|
|
5
5
|
import { formatIdentifier } from "@atscript/db-client";
|
|
6
6
|
//#region src/types.ts
|
|
7
7
|
/** UI-side sentinel for the synthesised row-delete processor. */
|
|
@@ -1023,6 +1023,7 @@ function createPresetState(opts) {
|
|
|
1023
1023
|
apply(o, value, isSystem) {
|
|
1024
1024
|
if (!value && !isSystem) return;
|
|
1025
1025
|
o.filters.value = value ? { ...value } : {};
|
|
1026
|
+
if (o.residualFilters?.value.length) o.residualFilters.value = [];
|
|
1026
1027
|
},
|
|
1027
1028
|
expandDefault: () => ({})
|
|
1028
1029
|
},
|
|
@@ -1100,8 +1101,25 @@ function createPresetState(opts) {
|
|
|
1100
1101
|
nextActiveId: id
|
|
1101
1102
|
};
|
|
1102
1103
|
}
|
|
1104
|
+
/**
|
|
1105
|
+
* The one write-side prune: drop what names a field this table cannot use,
|
|
1106
|
+
* and report it. A no-op before the table definition loads — bootstrap
|
|
1107
|
+
* waits for it, and the query gate covers any other early writer.
|
|
1108
|
+
*/
|
|
1109
|
+
function pruneForApply(snapshot, presetId) {
|
|
1110
|
+
const known = opts.knownFields?.value;
|
|
1111
|
+
if (!known) return snapshot;
|
|
1112
|
+
const { snapshot: pruned, dropped } = prunePresetSnapshot(snapshot, known);
|
|
1113
|
+
if (dropped) opts.onFieldsDropped?.({
|
|
1114
|
+
...dropped,
|
|
1115
|
+
source: "preset",
|
|
1116
|
+
presetId: presetId ?? void 0
|
|
1117
|
+
});
|
|
1118
|
+
return pruned;
|
|
1119
|
+
}
|
|
1103
1120
|
function apply(idOrSnapshot) {
|
|
1104
|
-
const { snapshot, nextActiveId } = resolveSnapshot(idOrSnapshot);
|
|
1121
|
+
const { snapshot: resolved, nextActiveId } = resolveSnapshot(idOrSnapshot);
|
|
1122
|
+
const snapshot = pruneForApply(resolved, nextActiveId);
|
|
1105
1123
|
const isSystem = typeof idOrSnapshot === "string" && nextActiveId !== null && isSystemPresetId(nextActiveId);
|
|
1106
1124
|
for (const aspect of ownedAspects(nextActiveId)) {
|
|
1107
1125
|
const value = snapshot[aspect];
|
|
@@ -1142,7 +1160,8 @@ function createPresetState(opts) {
|
|
|
1142
1160
|
}
|
|
1143
1161
|
return out;
|
|
1144
1162
|
}
|
|
1145
|
-
|
|
1163
|
+
/** The active preset's snapshot as stored — the base `saveActive` merges back into. */
|
|
1164
|
+
const storedActiveSnapshot = computed(() => {
|
|
1146
1165
|
const id = activeId.value;
|
|
1147
1166
|
if (!id) return {};
|
|
1148
1167
|
if (isSystemPresetId(id)) return expandSystemSnapshot(systemPresetsById.value.get(id)?.content ?? {}, id);
|
|
@@ -1151,7 +1170,25 @@ function createPresetState(opts) {
|
|
|
1151
1170
|
const wire = row.data?.content;
|
|
1152
1171
|
return wire ? fromWireSnapshot(wire) : {};
|
|
1153
1172
|
});
|
|
1154
|
-
const
|
|
1173
|
+
const prunedActive = computed(() => {
|
|
1174
|
+
const known = opts.knownFields?.value;
|
|
1175
|
+
const stored = storedActiveSnapshot.value;
|
|
1176
|
+
return known ? prunePresetSnapshot(stored, known) : {
|
|
1177
|
+
snapshot: stored,
|
|
1178
|
+
dropped: null
|
|
1179
|
+
};
|
|
1180
|
+
});
|
|
1181
|
+
const activeSnapshot = computed(() => prunedActive.value.snapshot);
|
|
1182
|
+
const droppedFields = computed(() => {
|
|
1183
|
+
const dropped = prunedActive.value.dropped;
|
|
1184
|
+
const presetId = activeId.value;
|
|
1185
|
+
return dropped && presetId ? {
|
|
1186
|
+
...dropped,
|
|
1187
|
+
source: "preset",
|
|
1188
|
+
presetId
|
|
1189
|
+
} : null;
|
|
1190
|
+
});
|
|
1191
|
+
const isDirty = computed(() => isDirtyAgainst(activeSnapshot.value, captureSnapshot()) || activeSnapshot.value.filterOps !== void 0 && !!opts.residualFilters?.value.length);
|
|
1155
1192
|
function requirePresets() {
|
|
1156
1193
|
if (!opts.presetsHandle) throw new Error("[vue-table] presets feature not configured (preset.url missing)");
|
|
1157
1194
|
return opts.presetsHandle;
|
|
@@ -1162,10 +1199,12 @@ function createPresetState(opts) {
|
|
|
1162
1199
|
const id = activeId.value;
|
|
1163
1200
|
if (!id) throw new Error("[vue-table] saveActive: no active preset");
|
|
1164
1201
|
if (isSystemPresetId(id)) throw new Error("[vue-table] saveActive: system presets cannot be overwritten");
|
|
1165
|
-
const existing =
|
|
1202
|
+
const existing = storedActiveSnapshot.value;
|
|
1166
1203
|
const mask = {};
|
|
1167
1204
|
for (const aspect of availableAspects) if (existing[aspect] !== void 0) mask[aspect] = true;
|
|
1168
|
-
|
|
1205
|
+
const captured = captureSnapshot(mask);
|
|
1206
|
+
const dropped = prunedActive.value.dropped;
|
|
1207
|
+
await handle.savePreset(dropped ? restoreDroppedEntries(captured, dropped) : captured);
|
|
1169
1208
|
clearLocalDraft();
|
|
1170
1209
|
});
|
|
1171
1210
|
}
|
|
@@ -1224,20 +1263,25 @@ function createPresetState(opts) {
|
|
|
1224
1263
|
function bootstrap() {
|
|
1225
1264
|
if (!opts.presetsHandle) return;
|
|
1226
1265
|
const handle = opts.presetsHandle;
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1266
|
+
const knownReady = () => !opts.knownFields || opts.knownFields.value !== null;
|
|
1267
|
+
let done = false;
|
|
1268
|
+
let stop;
|
|
1269
|
+
stop = watch(() => !handle.loading.value && knownReady(), (ready) => {
|
|
1270
|
+
if (!ready || done) return;
|
|
1271
|
+
done = true;
|
|
1272
|
+
stop?.();
|
|
1230
1273
|
const id = resolveDefaultId();
|
|
1231
1274
|
const { snapshot, nextActiveId } = resolveSnapshot(id);
|
|
1232
1275
|
const base = isSystemPresetId(id) ? expandSystemSnapshot(snapshot, id) : snapshot;
|
|
1233
1276
|
const draftEnabled = !!(opts.draftHandle && opts.persistDrafts);
|
|
1234
|
-
apply(draftEnabled ? opts.draftHandle.hydrate(base) : base);
|
|
1277
|
+
apply(pruneForApply(draftEnabled ? opts.draftHandle.hydrate(base) : base, nextActiveId));
|
|
1235
1278
|
activeId.value = nextActiveId;
|
|
1236
1279
|
if (draftEnabled) opts.draftHandle.watchAndPersist(() => captureSnapshot(), () => activeSnapshot.value);
|
|
1237
1280
|
nextTick(() => {
|
|
1238
1281
|
gate.value = true;
|
|
1239
1282
|
});
|
|
1240
1283
|
}, { immediate: true });
|
|
1284
|
+
if (done) stop();
|
|
1241
1285
|
}
|
|
1242
1286
|
return {
|
|
1243
1287
|
slice: {
|
|
@@ -1253,6 +1297,7 @@ function createPresetState(opts) {
|
|
|
1253
1297
|
available,
|
|
1254
1298
|
activeId,
|
|
1255
1299
|
activeSnapshot,
|
|
1300
|
+
droppedFields,
|
|
1256
1301
|
isDirty,
|
|
1257
1302
|
canSaveActive,
|
|
1258
1303
|
currentUser,
|
|
@@ -1594,6 +1639,10 @@ const cloneSorter = (s) => ({
|
|
|
1594
1639
|
field: s.field,
|
|
1595
1640
|
direction: s.direction
|
|
1596
1641
|
});
|
|
1642
|
+
/** Same residual conditions, in the same (canonical) order. */
|
|
1643
|
+
function sameResidualFilters(a, b) {
|
|
1644
|
+
return arraysEqual(a.map(filterExprKey), b.map(filterExprKey));
|
|
1645
|
+
}
|
|
1597
1646
|
/**
|
|
1598
1647
|
* The report for a restored URL's filter piece when nobody handles it
|
|
1599
1648
|
* (`onUnsupportedFilter` / `@unsupported-filter`): a dev-mode warning.
|
|
@@ -1602,6 +1651,15 @@ function warnUnsupportedFilter(issue) {
|
|
|
1602
1651
|
if (!DEV) return;
|
|
1603
1652
|
console.warn(`[vue-table] URL filter left out (${issue.reason}): ${JSON.stringify(issue.expr)}. Field filters cannot express it, so the table shows more rows than the URL described.`);
|
|
1604
1653
|
}
|
|
1654
|
+
/**
|
|
1655
|
+
* The report for fields the table left out when nobody handles it
|
|
1656
|
+
* (`onFieldsDropped` / `@fields-dropped`): a dev-mode warning.
|
|
1657
|
+
*/
|
|
1658
|
+
function warnFieldsDropped(report) {
|
|
1659
|
+
if (!DEV) return;
|
|
1660
|
+
const from = report.presetId ? `${report.source} "${report.presetId}"` : report.source;
|
|
1661
|
+
console.warn(`[vue-table] Left out fields this table cannot use (${from}): ${report.fields.join(", ")}.`);
|
|
1662
|
+
}
|
|
1605
1663
|
function createTableState(opts) {
|
|
1606
1664
|
const client = opts.client;
|
|
1607
1665
|
const modelOpts = opts.model;
|
|
@@ -1638,6 +1696,7 @@ function createTableState(opts) {
|
|
|
1638
1696
|
*/
|
|
1639
1697
|
const rowActionsPolicy = computed(() => compileRowActionsConfig(rowActions.value));
|
|
1640
1698
|
const filters = shallowRef({});
|
|
1699
|
+
const residualFilters = shallowRef([]);
|
|
1641
1700
|
const results = shallowRef([]);
|
|
1642
1701
|
const resultsStart = ref(0);
|
|
1643
1702
|
const querying = ref(false);
|
|
@@ -1675,11 +1734,34 @@ function createTableState(opts) {
|
|
|
1675
1734
|
const configDialogOpen = ref(false);
|
|
1676
1735
|
const configTab = ref("columns");
|
|
1677
1736
|
const filterDialogColumn = ref(null);
|
|
1737
|
+
/**
|
|
1738
|
+
* The paths the table can use, from its column list: every column, and the
|
|
1739
|
+
* server-backed ones. `null` until the table definition loads. Presets,
|
|
1740
|
+
* drafts, URLs and the query itself are all pruned against it.
|
|
1741
|
+
*/
|
|
1742
|
+
const knownFields = computed(() => {
|
|
1743
|
+
const all = allColumns.value;
|
|
1744
|
+
if (all.length === 0) return null;
|
|
1745
|
+
const columns = /* @__PURE__ */ new Set();
|
|
1746
|
+
const server = /* @__PURE__ */ new Set();
|
|
1747
|
+
for (const c of all) {
|
|
1748
|
+
columns.add(c.path);
|
|
1749
|
+
if (!c.local) server.add(c.path);
|
|
1750
|
+
}
|
|
1751
|
+
return {
|
|
1752
|
+
columns,
|
|
1753
|
+
server
|
|
1754
|
+
};
|
|
1755
|
+
});
|
|
1756
|
+
function reportFieldsDropped(report) {
|
|
1757
|
+
(queryOpts?.onFieldsDropped ?? warnFieldsDropped)(report);
|
|
1758
|
+
}
|
|
1678
1759
|
const { slice: presetSlice, internals: presetInternals } = createPresetState({
|
|
1679
1760
|
columnNames,
|
|
1680
1761
|
columnWidths,
|
|
1681
1762
|
filterFields,
|
|
1682
1763
|
filters,
|
|
1764
|
+
residualFilters,
|
|
1683
1765
|
sorters,
|
|
1684
1766
|
pagination,
|
|
1685
1767
|
allColumns,
|
|
@@ -1688,7 +1770,9 @@ function createTableState(opts) {
|
|
|
1688
1770
|
availableAspects: opts.preset?.availableAspects,
|
|
1689
1771
|
systemAspects: opts.preset?.systemAspects,
|
|
1690
1772
|
persistDrafts: opts.preset?.persistDrafts,
|
|
1691
|
-
fallbackSystemPresets: opts.preset?.fallbackSystemPresets
|
|
1773
|
+
fallbackSystemPresets: opts.preset?.fallbackSystemPresets,
|
|
1774
|
+
knownFields,
|
|
1775
|
+
onFieldsDropped: reportFieldsDropped
|
|
1692
1776
|
});
|
|
1693
1777
|
presetInternals.bootstrap();
|
|
1694
1778
|
const promptSlot = createRequestSlot(false);
|
|
@@ -1730,7 +1814,10 @@ function createTableState(opts) {
|
|
|
1730
1814
|
*/
|
|
1731
1815
|
const localColumnPaths = computed(() => {
|
|
1732
1816
|
const out = /* @__PURE__ */ new Set();
|
|
1733
|
-
|
|
1817
|
+
const known = knownFields.value;
|
|
1818
|
+
if (known) {
|
|
1819
|
+
for (const p of known.columns) if (!known.server.has(p)) out.add(p);
|
|
1820
|
+
}
|
|
1734
1821
|
return out;
|
|
1735
1822
|
});
|
|
1736
1823
|
/**
|
|
@@ -1763,21 +1850,67 @@ function createTableState(opts) {
|
|
|
1763
1850
|
if (splitSorters.value.local.length === 0 || sortersIgnored()) return rows;
|
|
1764
1851
|
return sortRowsLocally(rows, queryOpts?.forceSorters?.length ? mergeSorters(queryOpts.forceSorters, sorters.value) : sorters.value, sortValueOf);
|
|
1765
1852
|
}
|
|
1853
|
+
/**
|
|
1854
|
+
* The query's view of the model, gated to the fields this caller can use.
|
|
1855
|
+
* This is the guarantee that no table state sends a field the server does
|
|
1856
|
+
* not expose: presets and URLs are pruned on apply, but `setFieldFilter`,
|
|
1857
|
+
* `addFilterField`, `v-model` writes, `setResidualFilters` and the like
|
|
1858
|
+
* write straight to the model. `$select` is gated by the column list
|
|
1859
|
+
* (`knownFields.columns`, then client-owned columns are stripped); filters
|
|
1860
|
+
* and residual conditions by the server-backed columns. `forceFilters` /
|
|
1861
|
+
* `forceSorters` are app-authored and never gated. Memoized: pages,
|
|
1862
|
+
* window blocks and exports reuse it.
|
|
1863
|
+
*/
|
|
1864
|
+
const queryModel = computed(() => {
|
|
1865
|
+
const model = {
|
|
1866
|
+
columnNames: columnNames.value,
|
|
1867
|
+
filters: filters.value,
|
|
1868
|
+
sorters: splitSorters.value.server,
|
|
1869
|
+
residual: residualFilters.value,
|
|
1870
|
+
stripped: []
|
|
1871
|
+
};
|
|
1872
|
+
const known = knownFields.value;
|
|
1873
|
+
if (!known) return model;
|
|
1874
|
+
const { snapshot, dropped } = prunePresetSnapshot({
|
|
1875
|
+
columns: { columnNames: model.columnNames },
|
|
1876
|
+
filterOps: model.filters,
|
|
1877
|
+
sorters: model.sorters
|
|
1878
|
+
}, known);
|
|
1879
|
+
const residual = pruneResidualFilters(model.residual, known.server);
|
|
1880
|
+
return {
|
|
1881
|
+
columnNames: model.columnNames,
|
|
1882
|
+
filters: snapshot.filterOps,
|
|
1883
|
+
sorters: snapshot.sorters,
|
|
1884
|
+
residual: residual.kept,
|
|
1885
|
+
stripped: [...new Set([...dropped?.fields ?? [], ...residual.dropped?.fields ?? []])]
|
|
1886
|
+
};
|
|
1887
|
+
});
|
|
1888
|
+
/** Stripped path sets already warned about — one dev warning per set. */
|
|
1889
|
+
const warnedStripped = /* @__PURE__ */ new Set();
|
|
1766
1890
|
function buildCurrentQuery(buildOpts) {
|
|
1767
|
-
const available = tableDef.value?.fetchableFields ?? new Set(
|
|
1891
|
+
const available = tableDef.value?.fetchableFields ?? knownFields.value?.columns ?? /* @__PURE__ */ new Set();
|
|
1768
1892
|
const extra = /* @__PURE__ */ new Set();
|
|
1769
1893
|
for (const c of columns.value) for (const p of c.selectWith ?? []) if (available.has(p)) extra.add(p);
|
|
1770
1894
|
if (queryOpts?.alwaysSelected) {
|
|
1771
1895
|
for (const p of queryOpts.alwaysSelected) if (available.has(p)) extra.add(p);
|
|
1772
1896
|
}
|
|
1897
|
+
const model = queryModel.value;
|
|
1898
|
+
if (DEV && model.stripped.length > 0) {
|
|
1899
|
+
const key = model.stripped.join(",");
|
|
1900
|
+
if (!warnedStripped.has(key)) {
|
|
1901
|
+
warnedStripped.add(key);
|
|
1902
|
+
console.warn(`[vue-table] Query leaves out fields this table cannot use: ${model.stripped.join(", ")}.`);
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
const known = knownFields.value;
|
|
1773
1906
|
const localPaths = localColumnPaths.value;
|
|
1774
|
-
const requested = buildOpts?.columnPaths ?? columnNames.value;
|
|
1775
1907
|
return buildTableQuery({
|
|
1776
|
-
visibleColumnPaths:
|
|
1908
|
+
visibleColumnPaths: (buildOpts?.columnPaths ?? model.columnNames).filter((p) => !localPaths.has(p) && (!known || known.columns.has(p))),
|
|
1777
1909
|
extraSelect: extra.size ? [...extra] : void 0,
|
|
1778
|
-
sorters:
|
|
1910
|
+
sorters: model.sorters,
|
|
1779
1911
|
forceSorters: queryOpts?.forceSorters,
|
|
1780
|
-
filters: filters
|
|
1912
|
+
filters: model.filters,
|
|
1913
|
+
residualFilters: model.residual,
|
|
1781
1914
|
forceFilters: queryOpts?.forceFilters,
|
|
1782
1915
|
search: searchTerm.value || void 0,
|
|
1783
1916
|
ignoreSorters: sortersIgnored(),
|
|
@@ -1964,6 +2097,10 @@ function createTableState(opts) {
|
|
|
1964
2097
|
}
|
|
1965
2098
|
};
|
|
1966
2099
|
}
|
|
2100
|
+
function setResidualFilters(exprs) {
|
|
2101
|
+
const next = normalizeResidualFilters(exprs);
|
|
2102
|
+
if (!sameResidualFilters(next, residualFilters.value)) residualFilters.value = next;
|
|
2103
|
+
}
|
|
1967
2104
|
const state = {
|
|
1968
2105
|
tableDef,
|
|
1969
2106
|
loadingMetadata,
|
|
@@ -1973,6 +2110,7 @@ function createTableState(opts) {
|
|
|
1973
2110
|
columnWidths,
|
|
1974
2111
|
filterFields,
|
|
1975
2112
|
filters,
|
|
2113
|
+
residualFilters,
|
|
1976
2114
|
sorters,
|
|
1977
2115
|
results,
|
|
1978
2116
|
resultsStart,
|
|
@@ -2047,8 +2185,14 @@ function createTableState(opts) {
|
|
|
2047
2185
|
loadingAt,
|
|
2048
2186
|
errorAt,
|
|
2049
2187
|
resetFilters() {
|
|
2050
|
-
if (Object.keys(filters.value).length
|
|
2051
|
-
|
|
2188
|
+
if (Object.keys(filters.value).length > 0) filters.value = {};
|
|
2189
|
+
if (residualFilters.value.length > 0) residualFilters.value = [];
|
|
2190
|
+
},
|
|
2191
|
+
setResidualFilters,
|
|
2192
|
+
removeResidualFilter(index) {
|
|
2193
|
+
const list = residualFilters.value;
|
|
2194
|
+
if (index < 0 || index >= list.length) return;
|
|
2195
|
+
residualFilters.value = list.filter((_, i) => i !== index);
|
|
2052
2196
|
},
|
|
2053
2197
|
showConfigDialog(tab) {
|
|
2054
2198
|
configTab.value = tab ?? "columns";
|
|
@@ -2099,6 +2243,7 @@ function createTableState(opts) {
|
|
|
2099
2243
|
function serializeStateForUrl() {
|
|
2100
2244
|
return stateToUrlQueryString({
|
|
2101
2245
|
filters: filters.value,
|
|
2246
|
+
residualFilters: residualFilters.value,
|
|
2102
2247
|
sorters: sorters.value,
|
|
2103
2248
|
page: pagination.value.page,
|
|
2104
2249
|
itemsPerPage: pagination.value.itemsPerPage,
|
|
@@ -2129,6 +2274,8 @@ function createTableState(opts) {
|
|
|
2129
2274
|
}
|
|
2130
2275
|
const filtersGate = resolveAspectGate(urlQuerySync?.filters);
|
|
2131
2276
|
const sortersGate = resolveAspectGate(urlQuerySync?.sorters);
|
|
2277
|
+
const residualSync = urlQuerySync?.residual !== false;
|
|
2278
|
+
const urlOwnsResidual = (expr) => residualSync && residualGateOwns(filtersGate, expr);
|
|
2132
2279
|
let urlBaseline = null;
|
|
2133
2280
|
function captureUrlBaseline() {
|
|
2134
2281
|
if (urlBaseline) return;
|
|
@@ -2139,6 +2286,7 @@ function createTableState(opts) {
|
|
|
2139
2286
|
}
|
|
2140
2287
|
urlBaseline = {
|
|
2141
2288
|
filters: owned,
|
|
2289
|
+
residual: residualFilters.value.filter(urlOwnsResidual),
|
|
2142
2290
|
sorters: sorters.value.filter((s) => gateOwns(sortersGate, s.field)).map(cloneSorter)
|
|
2143
2291
|
};
|
|
2144
2292
|
}
|
|
@@ -2156,12 +2304,30 @@ function createTableState(opts) {
|
|
|
2156
2304
|
function applyUrlQuery(urlString, opts) {
|
|
2157
2305
|
captureUrlBaseline();
|
|
2158
2306
|
if (urlsEquivalent(urlString, lastEmittedUrl)) return;
|
|
2159
|
-
const
|
|
2307
|
+
const known = knownFields.value;
|
|
2160
2308
|
const parsed = urlQueryStringToState(urlString, {
|
|
2161
|
-
knownFields:
|
|
2309
|
+
knownFields: known?.server,
|
|
2310
|
+
localFields: known ? localColumnPaths.value : void 0,
|
|
2162
2311
|
sync: urlQuerySync
|
|
2163
2312
|
});
|
|
2164
2313
|
for (const issue of parsed.unsupported ?? []) (queryOpts?.onUnsupportedFilter ?? warnUnsupportedFilter)(issue);
|
|
2314
|
+
if (parsed.unknown || parsed.unknownSorters) {
|
|
2315
|
+
const residual = parsed.unknown?.map((u) => u.expr) ?? [];
|
|
2316
|
+
const sorters = parsed.unknownSorters ?? [];
|
|
2317
|
+
const fields = new Set(parsed.unknown?.flatMap((u) => u.fields));
|
|
2318
|
+
for (const s of sorters) fields.add(s.field);
|
|
2319
|
+
reportFieldsDropped({
|
|
2320
|
+
source: "url",
|
|
2321
|
+
fields: [...fields],
|
|
2322
|
+
columns: [],
|
|
2323
|
+
filterFields: [],
|
|
2324
|
+
filters: {},
|
|
2325
|
+
residual,
|
|
2326
|
+
sorters
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
const urlResidual = parsed.residual ?? [];
|
|
2330
|
+
const residualPaths = new Set(urlResidual.flatMap((expr) => filterExprFields(expr)));
|
|
2165
2331
|
const base = (opts?.mode ? opts.mode === "replace" : parsed.snapshot === true) ? null : urlBaseline;
|
|
2166
2332
|
const currentItemsPerPage = pagination.value.itemsPerPage;
|
|
2167
2333
|
const skip = parsed.skip ?? 0;
|
|
@@ -2170,12 +2336,24 @@ function createTableState(opts) {
|
|
|
2170
2336
|
hydratingFromUrl = true;
|
|
2171
2337
|
if (filtersGate !== "none") {
|
|
2172
2338
|
const next = {};
|
|
2339
|
+
const fromBase = (path) => !!base?.filters[path] && !residualPaths.has(path);
|
|
2173
2340
|
for (const path in filters.value) if (!gateOwns(filtersGate, path)) next[path] = filters.value[path];
|
|
2174
|
-
else if (
|
|
2175
|
-
if (base)
|
|
2341
|
+
else if (fromBase(path)) next[path] = cloneConditions(base.filters[path]);
|
|
2342
|
+
if (base) {
|
|
2343
|
+
for (const path in base.filters) if (fromBase(path)) next[path] ??= cloneConditions(base.filters[path]);
|
|
2344
|
+
}
|
|
2176
2345
|
for (const path in parsed.filters) next[path] = parsed.filters[path];
|
|
2177
2346
|
filters.value = next;
|
|
2178
2347
|
}
|
|
2348
|
+
if (residualSync) {
|
|
2349
|
+
const mentioned = new Set([...Object.keys(parsed.filters), ...residualPaths]);
|
|
2350
|
+
const next = residualFilters.value.filter((expr) => !urlOwnsResidual(expr));
|
|
2351
|
+
if (base) {
|
|
2352
|
+
for (const expr of base.residual) if (!filterExprFields(expr).some((f) => mentioned.has(f))) next.push(expr);
|
|
2353
|
+
}
|
|
2354
|
+
next.push(...urlResidual);
|
|
2355
|
+
setResidualFilters(next);
|
|
2356
|
+
}
|
|
2179
2357
|
let urlSortersChanged = false;
|
|
2180
2358
|
if (sortersGate !== "none") {
|
|
2181
2359
|
const urlSortFields = new Set(parsed.sorters.map((s) => s.field));
|
|
@@ -2220,7 +2398,11 @@ function createTableState(opts) {
|
|
|
2220
2398
|
const debouncedFilterQuery = debounce(() => {
|
|
2221
2399
|
if (queryDetected) scheduleQuery();
|
|
2222
2400
|
}, FILTER_DEBOUNCE_MS);
|
|
2223
|
-
watch([
|
|
2401
|
+
watch([
|
|
2402
|
+
() => filters.value,
|
|
2403
|
+
() => residualFilters.value,
|
|
2404
|
+
() => searchTerm.value
|
|
2405
|
+
], () => {
|
|
2224
2406
|
if (hydratingFromUrl) return;
|
|
2225
2407
|
if (!queryDetected) return;
|
|
2226
2408
|
mustRefresh.value = true;
|
|
@@ -2267,6 +2449,7 @@ function createTableState(opts) {
|
|
|
2267
2449
|
});
|
|
2268
2450
|
watch([
|
|
2269
2451
|
() => filters.value,
|
|
2452
|
+
() => residualFilters.value,
|
|
2270
2453
|
() => sorters.value,
|
|
2271
2454
|
() => searchTerm.value,
|
|
2272
2455
|
() => pagination.value,
|
|
@@ -2451,4 +2634,4 @@ function useRegisterMainActionListener(state, listener, enabled) {
|
|
|
2451
2634
|
});
|
|
2452
2635
|
}
|
|
2453
2636
|
//#endregion
|
|
2454
|
-
export {
|
|
2637
|
+
export { intentClass as C, triggerAction as D, isPlainLeftClick as E, ROW_ACTIONS_PATH as O, extractIdentifier as S, isModClick as T, applyRowGate as _, useTableContext as a, collectIdentifiers as b, warnUnsupportedFilter as c, ASPECT_LABELS as d, ownerNameOf as f, rowActionHref as g, onSelectControlKeydown as h, useRegisterMainActionListener as i, ROW_ACTIONS_TYPE as k, DEFAULT_AVAILABLE_ASPECTS as l, INTERACTIVE_SELECTOR as m, createTableState as n, useTableContextOptional as o, readPresetLabel as p, provideTableContext as r, warnFieldsDropped as s, createStaticTableState as t, ASPECT_ICONS as u, applyRowsGate as v, intentToScope as w, createNavigateGestures as x, ariaLabelFor as y };
|