@agile-team/mach-table-react 0.19.1 → 0.24.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.
@@ -0,0 +1,12 @@
1
+ import { MutableRefObject } from 'react';
2
+ import { GridApi } from '@agile-team/mach-table';
3
+
4
+ interface UseMachTableReturn<TData = any> {
5
+ apiRef: MutableRefObject<GridApi<TData> | null>;
6
+ api: GridApi<TData> | null;
7
+ ready: boolean;
8
+ }
9
+ /** Reactive access to the table lifecycle and command API. */
10
+ declare function useMachTable<TData = any>(): UseMachTableReturn<TData>;
11
+
12
+ export { type UseMachTableReturn as U, useMachTable as u };
package/dist/worker.cjs CHANGED
@@ -1,2 +1 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); }var _worker = require('@agile-team/mach-table/worker'); _createStarExport(_worker);
2
- //# sourceMappingURL=worker.cjs.map
package/dist/worker.js CHANGED
@@ -1,2 +1 @@
1
1
  export*from"@agile-team/mach-table/worker";
2
- //# sourceMappingURL=worker.js.map
@@ -1,2 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkTSVK66UXcjs = require('./chunk-TSVK66UX.cjs');exports.useMachTableController = _chunkTSVK66UXcjs.d; exports.useMachTableEditing = _chunkTSVK66UXcjs.b; exports.useMachTableQuery = _chunkTSVK66UXcjs.c;
2
- //# sourceMappingURL=workflows.cjs.map
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkII7TCYIUcjs = require('./chunk-II7TCYIU.cjs');var _react = require('react');var _machtable = require('@agile-team/mach-table');function ee(t,a={}){let[b,R]=_react.useState.call(void 0, []),[w,Q]=_react.useState.call(void 0, []),[D,l]=_react.useState.call(void 0, !1),[v,M]=_react.useState.call(void 0, null),[i,F]=_react.useState.call(void 0, null),S=_react.useRef.call(void 0, !1),g=_react.useCallback.call(void 0, ()=>{let r=t.apiRef.current;if(!r||r.isDestroyed()){Q([]),R([]);return}Q(r.editing.getDirtyRowIds()),R(r.editing.getChanges())},[t.apiRef]);_react.useEffect.call(void 0, ()=>{let r=t.api;return g(),r&&!r.isDestroyed()?r.on("dirtyStateChanged",g):void 0},[t.api,g]);let P=_react.useCallback.call(void 0, async(r,u)=>{let d=t.apiRef.current;if(!d||d.isDestroyed())throw new Error("[MachTable] Cannot save before the grid is ready.");if(S.current)throw new Error("[MachTable] A save operation is already in progress.");S.current=!0,l(!0),M(null),F(null);try{let o=await d.editing.save(r,u);return F(o),g(),_optionalChain([a, 'access', _2 => _2.onSaveSuccess, 'optionalCall', _3 => _3(o.saved)]),_optionalChain([a, 'access', _4 => _4.onSaveResult, 'optionalCall', _5 => _5(o)]),o}catch(o){throw M(o),_optionalChain([a, 'access', _6 => _6.onSaveError, 'optionalCall', _7 => _7(o)]),o}finally{S.current=!1,l(!1)}},[a,g,t.apiRef]),H=_react.useCallback.call(void 0, async(r,u)=>(await P(r,u)).saved,[P]),K=_react.useCallback.call(void 0, ()=>F(null),[]),N=_react.useCallback.call(void 0, (r,u)=>{let d=_optionalChain([i, 'optionalAccess', _8 => _8.conflicts, 'access', _9 => _9.find, 'call', _10 => _10(y=>y.rowId===r)]),o=t.apiRef.current;return!i||!d||!o||!_machtable.resolveSaveConflict.call(void 0, o,d,u)?!1:(F({...i,failures:i.failures,conflicts:i.conflicts.filter(y=>y.rowId!==r)}),g(),!0)},[i,g,t.apiRef]),U=_react.useCallback.call(void 0, r=>{let u=_nullishCoalesce(_optionalChain([t, 'access', _11 => _11.apiRef, 'access', _12 => _12.current, 'optionalAccess', _13 => _13.editing, 'access', _14 => _14.rollback, 'call', _15 => _15(r)]), () => (!1));return g(),u},[g,t.apiRef]),V=_react.useCallback.call(void 0, r=>{_optionalChain([t, 'access', _16 => _16.apiRef, 'access', _17 => _17.current, 'optionalAccess', _18 => _18.editing, 'access', _19 => _19.markSaved, 'call', _20 => _20(r)]),g()},[g,t.apiRef]),q=_react.useCallback.call(void 0, (r,u,d=!1)=>{let o=t.apiRef.current,y=_optionalChain([o, 'optionalAccess', _21 => _21.rows, 'access', _22 => _22.getById, 'call', _23 => _23(r)]);return!o||!y||y.rowIndex<0?!1:(o.view.scrollToRow(y.rowIndex,"middle"),u&&d?o.editing.startCell({rowIndex:y.rowIndex,colId:u}):!0)},[t.apiRef]);_react.useEffect.call(void 0, ()=>{if(!a.guardBeforeUnload||typeof window>"u")return;let r=u=>{if(w.length===0)return;let d=_nullishCoalesce(a.beforeUnloadMessage, () => ("\u5B58\u5728\u672A\u4FDD\u5B58\u7684\u8868\u683C\u4FEE\u6539\u3002"));return u.preventDefault(),u.returnValue=d,d};return window.addEventListener("beforeunload",r),()=>window.removeEventListener("beforeunload",r)},[w.length,a.beforeUnloadMessage,a.guardBeforeUnload]);let z=_react.useMemo.call(void 0, ()=>[..._nullishCoalesce(_optionalChain([i, 'optionalAccess', _24 => _24.failures]), () => ([])),..._nullishCoalesce(_optionalChain([i, 'optionalAccess', _25 => _25.conflicts]), () => ([]))],[i]),W=_react.useMemo.call(void 0, ()=>[...new Set(z.map(r=>r.rowId))],[z]);return _react.useMemo.call(void 0, ()=>({changes:b,dirtyRowIds:w,dirty:w.length>0,saving:D,saveError:v,lastSaveResult:i,saveIssues:z,failedRowIds:W,save:H,saveDetailed:P,clearSaveIssues:K,resolveConflict:N,rollback:U,markSaved:V,reveal:q,refresh:g}),[b,K,w,W,i,V,g,N,q,U,H,P,v,z,D])}function re(t,a){return typeof t=="number"&&Number.isFinite(t)&&t>0?Math.floor(t):a}function Ue(t){return(t instanceof DOMException||typeof t=="object"&&t!=null&&"name"in t)&&t.name==="AbortError"}function qe(t){return typeof t=="function"?t():t}function Oe(t){let a=_react.useRef.call(void 0, t);a.current=t;let[b,R]=_react.useState.call(void 0, []),[w,Q]=_react.useState.call(void 0, !1),[D,l]=_react.useState.call(void 0, null),[v,M]=_react.useState.call(void 0, re(t.initialPage,1)),[i,F]=_react.useState.call(void 0, re(t.pageSize,20)),[S,g]=_react.useState.call(void 0, 0),[P,H]=_react.useState.call(void 0, []),[K,N]=_react.useState.call(void 0, {}),[U,V]=_react.useState.call(void 0, null),[q,z]=_react.useState.call(void 0, _nullishCoalesce(t.initialQuickFilterText, () => (null))),[,W]=_react.useReducer.call(void 0, e=>e+1,0),r=_react.useRef.call(void 0, {page:v,pageSize:i,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,rows:b});r.current={page:v,pageSize:i,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,rows:b};let u=_react.useRef.call(void 0, null),d=_react.useRef.call(void 0, null),o=_react.useRef.call(void 0, null),y=_react.useRef.call(void 0, 0),C=_react.useRef.call(void 0, new Set),x=_react.useRef.call(void 0, new Set),T=_react.useRef.call(void 0, new Map),O=_react.useRef.call(void 0, !1),j=_react.useRef.call(void 0, !1),$=_react.useRef.call(void 0, !1),p=_react.useCallback.call(void 0, e=>{let n=a.current.rowKey,s=typeof n=="function"?n(e):_machtable.getByPath.call(void 0, e,n);if(s==null||String(s).length===0)throw new Error(`[MachTable] useMachTableQuery rowKey "${String(n)}" returned an empty value.`);return String(s)},[]),B=_react.useCallback.call(void 0, e=>O.current?!x.current.has(e):C.current.has(e),[]),E=_react.useCallback.call(void 0, ()=>W(),[]),I=_react.useCallback.call(void 0, ()=>{let e=u.current;if(!(!e||e.isDestroyed())){$.current=!0;try{e.selection.setRows(r.current.rows.filter(n=>B(p(n))),!0)}finally{$.current=!1}}},[p,B]),te=_react.useCallback.call(void 0, ()=>{y.current++,_optionalChain([d, 'access', _26 => _26.current, 'optionalAccess', _27 => _27.abort, 'call', _28 => _28()]),d.current=null,o.current&&clearTimeout(o.current),o.current=null,Q(!1)},[]),X=_react.useCallback.call(void 0, (e,n)=>e.signal.aborted||n!==y.current,[]),ne=_react.useCallback.call(void 0, (e,n,s)=>{if(X(n,s))return;if(!e||!Array.isArray(e.rows)||!Number.isFinite(e.total)||e.total<0)throw new TypeError("[MachTable] Remote request must resolve to { rows: TData[], total: non-negative number }.");let c=[...e.rows];for(let Y of c){let Z=p(Y);B(Z)?T.current.set(Z,Y):T.current.delete(Z)}r.current.rows=c,R(c),g(Math.floor(e.total)),E(),_optionalChain([a, 'access', _29 => _29.current, 'access', _30 => _30.onSuccess, 'optionalCall', _31 => _31(e)]),queueMicrotask(I)},[X,E,p,B,I]),ae=_react.useCallback.call(void 0, (e,n,s)=>{if(X(n,s)||Ue(e))return;let c=_nullishCoalesce(e, () => (new Error("Remote request failed")));l(c),_optionalChain([a, 'access', _32 => _32.current, 'access', _33 => _33.onError, 'optionalCall', _34 => _34(c)])},[X]),oe=_react.useCallback.call(void 0, (e,n)=>{n===y.current&&(Q(!1),d.current===e&&(d.current=null))},[]),h=_react.useCallback.call(void 0, async()=>{o.current&&clearTimeout(o.current),o.current=null,_optionalChain([d, 'access', _35 => _35.current, 'optionalAccess', _36 => _36.abort, 'call', _37 => _37()]);let e=new AbortController;d.current=e;let n=++y.current;Q(!0),l(null),a.current.keepPreviousData===!1&&R([]);let s=r.current;try{let c=await a.current.request({page:s.page,pageSize:s.pageSize,query:qe(a.current.query),sortModel:s.sortModel.map(Y=>({...Y})),filterModel:{...s.filterModel},advancedFilterModel:_machtable.normalizeAdvancedFilterModel.call(void 0, s.advancedFilterModel),quickFilterText:s.quickFilterText,signal:e.signal});ne(c,e,n)}catch(c){ae(c,e,n)}finally{oe(e,n)}},[ne,oe,ae]),L=_react.useCallback.call(void 0, e=>{e&&(r.current.page=1,M(1)),_optionalChain([d, 'access', _38 => _38.current, 'optionalAccess', _39 => _39.abort, 'call', _40 => _40()]),d.current=null;let n=Math.max(0,_nullishCoalesce(a.current.debounceMs, () => (0)));o.current&&clearTimeout(o.current),n===0?h():o.current=setTimeout(()=>{h()},n)},[h]),G=_react.useCallback.call(void 0, ()=>{let e=O.current||C.current.size>0||x.current.size>0||T.current.size>0;O.current=!1,C.current.clear(),x.current.clear(),T.current.clear(),e&&E(),$.current=!0;try{_optionalChain([u, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.selection, 'access', _43 => _43.clear, 'call', _44 => _44()])}finally{$.current=!1}},[E]),le=_react.useCallback.call(void 0, e=>{if(j.current)return;let n=r.current;e.page===n.page&&e.pageSize===n.pageSize||(n.page=e.page,n.pageSize=e.pageSize,M(e.page),F(e.pageSize),a.current.mode!=="manual"&&h())},[h]),ie=_react.useCallback.call(void 0, e=>{if(j.current)return;let n=e.sortModel.map(s=>({...s}));r.current.sortModel=n,H(n),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[L]),se=_react.useCallback.call(void 0, e=>{if(j.current)return;let n={...e.filterModel};r.current.filterModel=n;let s=_machtable.normalizeAdvancedFilterModel.call(void 0, e.advancedFilterModel);r.current.advancedFilterModel=s,r.current.quickFilterText=e.api.filtering.getQuickText(),N(n),V(s),z(r.current.quickFilterText),a.current.clearSelectionOnQueryChange!==!1&&G(),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[G,L]),ce=_react.useCallback.call(void 0, e=>{if($.current)return;let n=new Set(r.current.rows.map(p)),s=new Set(e.selectedRows.map(p));if(O.current)for(let c of n)s.has(c)?x.current.delete(c):(x.current.add(c),T.current.delete(c));else{if((_nullishCoalesce(a.current.selectionScope, () => ("preserve")))==="page")C.current.clear(),T.current.clear();else for(let c of n)C.current.delete(c),T.current.delete(c);for(let c of e.selectedRows)C.current.add(p(c))}for(let c of e.selectedRows)T.current.set(p(c),c);E()},[E,p]),Me=_react.useCallback.call(void 0, async(e={})=>{e.resetPage&&(r.current.page=1,M(1)),await h()},[h]),Se=_react.useCallback.call(void 0, async()=>{r.current.page=1,r.current.sortModel=[],r.current.filterModel={},r.current.advancedFilterModel=null,M(1),H([]),N({}),V(null),G(),j.current=!0;try{_optionalChain([u, 'access', _45 => _45.current, 'optionalAccess', _46 => _46.sorting, 'access', _47 => _47.setModel, 'call', _48 => _48(null)]),_optionalChain([u, 'access', _49 => _49.current, 'optionalAccess', _50 => _50.filtering, 'access', _51 => _51.setModel, 'call', _52 => _52(null)]),_optionalChain([u, 'access', _53 => _53.current, 'optionalAccess', _54 => _54.filtering, 'access', _55 => _55.setAdvancedModel, 'call', _56 => _56(null)])}finally{j.current=!1}await h()},[G,h]),we=_react.useCallback.call(void 0, ()=>{O.current=!0,C.current.clear(),x.current.clear(),T.current.clear();for(let e of r.current.rows)T.current.set(p(e),e);E(),I()},[E,p,I]),Re=_react.useCallback.call(void 0, e=>{C.current.clear(),x.current.clear(),T.current.clear(),O.current=e.mode==="allMatching";for(let n of(e.mode==="allMatching"?e.excludedKeys:e.selectedKeys).map(String))e.mode==="allMatching"?x.current.add(n):C.current.add(n);for(let n of r.current.rows)B(p(n))&&T.current.set(p(n),n);E(),I()},[E,p,B,I]),ue=_react.useRef.call(void 0, !0),De=t.queryKey===void 0?t.query:t.queryKey;_react.useEffect.call(void 0, ()=>{if(ue.current){ue.current=!1;return}a.current.clearSelectionOnQueryChange!==!1&&G(),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[De,G,L]),_react.useEffect.call(void 0, ()=>(t.mode!=="manual"&&t.immediate!==!1&&h(),te),[]);let de=_react.useMemo.call(void 0, ()=>{let e=[...new Set((_nullishCoalesce(t.pageSizeOptions, () => ([10,20,50,100]))).map(n=>re(n,0)).filter(Boolean))];return e.includes(i)||e.push(i),e.sort((n,s)=>n-s)},[t.pageSizeOptions,i]),Ce=_react.useMemo.call(void 0, ()=>({rowData:b,loading:w,error:D,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:U,quickFilterText:q,overlayErrorTemplate:D?()=>_nullishCoalesce(_optionalChain([a, 'access', _57 => _57.current, 'access', _58 => _58.errorOverlay, 'optionalCall', _59 => _59({error:D,retry:h})]), () => ("Remote request failed. Please retry.")):void 0,overlayNoRowsTemplate:t.emptyOverlay,pagination:{mode:"server",page:v,pageSize:i,pageSizeOptions:de,total:S,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{u.current=e,queueMicrotask(I)},onPaginationChanged:le,onSortChanged:ie,onFilterChanged:se,onSelectionChanged:ce}),[U,D,h,w,se,le,ce,ie,t.emptyOverlay,v,i,de,q,p,b,I,S]),fe=O.current?[]:[...C.current],xe=[...T.current.entries()].filter(([e])=>!x.current.has(e)).map(([,e])=>e),Ee=O.current?{mode:"allMatching",excludedKeys:[...x.current]}:{mode:"explicit",selectedKeys:fe};return{rows:b,loading:w,error:D,page:v,pageSize:i,total:S,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,setQuickFilterText(e){r.current.quickFilterText=e,z(e),_optionalChain([u, 'access', _60 => _60.current, 'optionalAccess', _61 => _61.filtering, 'access', _62 => _62.setQuickText, 'call', _63 => _63(e)])},selectedKeys:fe,selectedRows:xe,selectionState:Ee,bindings:Ce,reload:Me,retry:h,reset:Se,abort:te,clearSelection:G,selectAllMatching:we,applySelectionState:Re}}function Ae(t={}){let a=_chunkII7TCYIUcjs.a.call(void 0, ),b=ee(a,t.editing),[R,w]=_react.useState.call(void 0, _nullishCoalesce(t.initialSearch, () => (""))),[Q,D]=_react.useState.call(void 0, []),l=_nullishCoalesce(t.query, () => (null));_react.useEffect.call(void 0, ()=>{let S=a.api;if(!S||S.isDestroyed()||l)return;let g=()=>D(S.selection.getRows());return g(),S.on("selectionChanged",g)},[l,a.api]),_react.useEffect.call(void 0, ()=>{l?l.setQuickFilterText(R||null):_optionalChain([a, 'access', _64 => _64.apiRef, 'access', _65 => _65.current, 'optionalAccess', _66 => _66.filtering, 'access', _67 => _67.setQuickText, 'call', _68 => _68(R||null)])},[l,R,a.apiRef]);let v=_react.useMemo.call(void 0, ()=>async()=>{l?await l.reload():_optionalChain([a, 'access', _69 => _69.apiRef, 'access', _70 => _70.current, 'optionalAccess', _71 => _71.rows, 'access', _72 => _72.isRemote, 'call', _73 => _73()])?await a.apiRef.current.rows.reload():_optionalChain([a, 'access', _74 => _74.apiRef, 'access', _75 => _75.current, 'optionalAccess', _76 => _76.view, 'access', _77 => _77.refreshCells, 'call', _78 => _78()])},[l,a.apiRef]),M=_react.useMemo.call(void 0, ()=>_machtable.createMachTableCommands.call(void 0, {getApi:()=>a.apiRef.current,reload:v}),[v,a.apiRef]),i=_nullishCoalesce(_optionalChain([l, 'optionalAccess', _79 => _79.selectedRows]), () => (Q)),F=l?l.selectionState.mode==="allMatching"?Math.max(0,l.total-l.selectionState.excludedKeys.length):l.selectionState.selectedKeys.length:i.length;return{table:a,query:l,editing:b,bindings:_nullishCoalesce(_optionalChain([l, 'optionalAccess', _80 => _80.bindings]), () => ({})),search:R,setSearch:w,selectedRows:i,selectedCount:F,busy:_optionalChain([l, 'optionalAccess', _81 => _81.loading])===!0||b.saving,error:_nullishCoalesce(_nullishCoalesce(_optionalChain([l, 'optionalAccess', _82 => _82.error]), () => (b.saveError)), () => (null)),commands:M,reload:v}}exports.useMachTableController = Ae; exports.useMachTableEditing = ee; exports.useMachTableQuery = Oe;
@@ -1,3 +1,131 @@
1
- export { M as MachTablePageRequest, a as MachTablePageResult, b as MachTableQuerySource, c as MachTableRemoteSelectionState, d as UseMachTableControllerOptions, e as UseMachTableControllerReturn, f as UseMachTableEditingOptions, g as UseMachTableEditingReturn, h as UseMachTableQueryOptions, i as UseMachTableQueryReturn, j as useMachTableController, k as useMachTableEditing, l as useMachTableQuery } from './workflows-CoKf5zIV.cjs';
2
- import '@agile-team/mach-table';
1
+ import { GridChange, GridBatchSaveResult, SaveChangeIssue, SaveChangeConflict, SaveChangesHandler, SortModel, FilterModel, AdvancedFilterModel, GridOptions, OverlayContent, OverlayTemplate, MachTableCommands } from '@agile-team/mach-table';
2
+ import { U as UseMachTableReturn } from './useMachTable-lL575Wzq.cjs';
3
3
  import 'react';
4
+
5
+ interface UseMachTableEditingOptions<TData = any> {
6
+ guardBeforeUnload?: boolean;
7
+ beforeUnloadMessage?: string;
8
+ onSaveSuccess?(saved: readonly GridChange<TData>[]): void;
9
+ onSaveResult?(result: GridBatchSaveResult<TData>): void;
10
+ onSaveError?(error: unknown): void;
11
+ }
12
+ interface UseMachTableEditingReturn<TData = any> {
13
+ changes: GridChange<TData>[];
14
+ dirtyRowIds: string[];
15
+ dirty: boolean;
16
+ saving: boolean;
17
+ saveError: unknown | null;
18
+ lastSaveResult: GridBatchSaveResult<TData> | null;
19
+ saveIssues: Array<SaveChangeIssue | SaveChangeConflict<TData>>;
20
+ failedRowIds: string[];
21
+ save(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridChange<TData>[]>;
22
+ saveDetailed(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridBatchSaveResult<TData>>;
23
+ clearSaveIssues(): void;
24
+ resolveConflict(rowId: string, strategy: "acceptServer" | "keepLocal"): boolean;
25
+ rollback(rowIds?: readonly string[]): boolean;
26
+ markSaved(rowIds?: readonly string[]): void;
27
+ reveal(rowId: string, colId?: string, edit?: boolean): boolean;
28
+ refresh(): void;
29
+ }
30
+ /** Reactive dirty/save workflow layered over useMachTable(). */
31
+ declare function useMachTableEditing<TData = any>(table: UseMachTableReturn<TData>, options?: UseMachTableEditingOptions<TData>): UseMachTableEditingReturn<TData>;
32
+
33
+ type MachTableQuerySource<TQuery> = TQuery | (() => TQuery);
34
+ interface MachTablePageRequest<TQuery> {
35
+ page: number;
36
+ pageSize: number;
37
+ query: TQuery;
38
+ sortModel: SortModel;
39
+ filterModel: FilterModel;
40
+ advancedFilterModel: AdvancedFilterModel | null;
41
+ quickFilterText: string | null;
42
+ signal: AbortSignal;
43
+ }
44
+ interface MachTablePageResult<TData> {
45
+ rows: readonly TData[];
46
+ total: number;
47
+ }
48
+ type MachTableRemoteSelectionState = {
49
+ mode: "explicit";
50
+ selectedKeys: string[];
51
+ } | {
52
+ mode: "allMatching";
53
+ excludedKeys: string[];
54
+ };
55
+ interface UseMachTableQueryOptions<TData, TQuery = Record<string, unknown>> {
56
+ request(params: MachTablePageRequest<TQuery>): Promise<MachTablePageResult<TData>>;
57
+ query: MachTableQuerySource<TQuery>;
58
+ /** Memoize object queries in React; queryKey can explicitly control reload dependencies. */
59
+ queryKey?: unknown;
60
+ rowKey: string | ((row: TData) => string | number);
61
+ initialPage?: number;
62
+ pageSize?: number;
63
+ pageSizeOptions?: readonly number[];
64
+ immediate?: boolean;
65
+ mode?: "auto" | "manual";
66
+ debounceMs?: number;
67
+ keepPreviousData?: boolean;
68
+ selectionScope?: "page" | "preserve" | "query";
69
+ clearSelectionOnQueryChange?: boolean;
70
+ initialQuickFilterText?: string | null;
71
+ errorOverlay?(context: {
72
+ error: unknown;
73
+ retry(): Promise<void>;
74
+ }): OverlayContent;
75
+ emptyOverlay?: OverlayTemplate;
76
+ onSuccess?(result: MachTablePageResult<TData>): void;
77
+ onError?(error: unknown): void;
78
+ }
79
+ interface UseMachTableQueryReturn<TData> {
80
+ rows: TData[];
81
+ loading: boolean;
82
+ error: unknown | null;
83
+ page: number;
84
+ pageSize: number;
85
+ total: number;
86
+ sortModel: SortModel;
87
+ filterModel: FilterModel;
88
+ advancedFilterModel: AdvancedFilterModel | null;
89
+ quickFilterText: string | null;
90
+ setQuickFilterText(value: string | null): void;
91
+ selectedKeys: string[];
92
+ selectedRows: TData[];
93
+ selectionState: MachTableRemoteSelectionState;
94
+ bindings: GridOptions<TData>;
95
+ reload(options?: {
96
+ resetPage?: boolean;
97
+ }): Promise<void>;
98
+ retry(): Promise<void>;
99
+ reset(): Promise<void>;
100
+ abort(): void;
101
+ clearSelection(): void;
102
+ selectAllMatching(): void;
103
+ applySelectionState(state: MachTableRemoteSelectionState): void;
104
+ }
105
+ /** React remote-list controller with cancellation, stale guards and cross-page selection. */
106
+ declare function useMachTableQuery<TData, TQuery = Record<string, unknown>>(options: UseMachTableQueryOptions<TData, TQuery>): UseMachTableQueryReturn<TData>;
107
+
108
+ interface UseMachTableControllerOptions<TData> {
109
+ /** Pass the result of useMachTableQuery for remote workflows. */
110
+ query?: UseMachTableQueryReturn<TData>;
111
+ editing?: UseMachTableEditingOptions<TData>;
112
+ initialSearch?: string;
113
+ }
114
+ interface UseMachTableControllerReturn<TData> {
115
+ table: UseMachTableReturn<TData>;
116
+ query: UseMachTableQueryReturn<TData> | null;
117
+ editing: UseMachTableEditingReturn<TData>;
118
+ bindings: GridOptions<TData>;
119
+ search: string;
120
+ setSearch(value: string): void;
121
+ selectedRows: TData[];
122
+ selectedCount: number;
123
+ busy: boolean;
124
+ error: unknown | null;
125
+ commands: MachTableCommands;
126
+ reload(): Promise<void>;
127
+ }
128
+ /** Cohesive React controller for API readiness, selection, editing and toolbar commands. */
129
+ declare function useMachTableController<TData>(options?: UseMachTableControllerOptions<TData>): UseMachTableControllerReturn<TData>;
130
+
131
+ export { type MachTablePageRequest, type MachTablePageResult, type MachTableQuerySource, type MachTableRemoteSelectionState, type UseMachTableControllerOptions, type UseMachTableControllerReturn, type UseMachTableEditingOptions, type UseMachTableEditingReturn, type UseMachTableQueryOptions, type UseMachTableQueryReturn, useMachTableController, useMachTableEditing, useMachTableQuery };
@@ -1,3 +1,131 @@
1
- export { M as MachTablePageRequest, a as MachTablePageResult, b as MachTableQuerySource, c as MachTableRemoteSelectionState, d as UseMachTableControllerOptions, e as UseMachTableControllerReturn, f as UseMachTableEditingOptions, g as UseMachTableEditingReturn, h as UseMachTableQueryOptions, i as UseMachTableQueryReturn, j as useMachTableController, k as useMachTableEditing, l as useMachTableQuery } from './workflows-CoKf5zIV.js';
2
- import '@agile-team/mach-table';
1
+ import { GridChange, GridBatchSaveResult, SaveChangeIssue, SaveChangeConflict, SaveChangesHandler, SortModel, FilterModel, AdvancedFilterModel, GridOptions, OverlayContent, OverlayTemplate, MachTableCommands } from '@agile-team/mach-table';
2
+ import { U as UseMachTableReturn } from './useMachTable-lL575Wzq.js';
3
3
  import 'react';
4
+
5
+ interface UseMachTableEditingOptions<TData = any> {
6
+ guardBeforeUnload?: boolean;
7
+ beforeUnloadMessage?: string;
8
+ onSaveSuccess?(saved: readonly GridChange<TData>[]): void;
9
+ onSaveResult?(result: GridBatchSaveResult<TData>): void;
10
+ onSaveError?(error: unknown): void;
11
+ }
12
+ interface UseMachTableEditingReturn<TData = any> {
13
+ changes: GridChange<TData>[];
14
+ dirtyRowIds: string[];
15
+ dirty: boolean;
16
+ saving: boolean;
17
+ saveError: unknown | null;
18
+ lastSaveResult: GridBatchSaveResult<TData> | null;
19
+ saveIssues: Array<SaveChangeIssue | SaveChangeConflict<TData>>;
20
+ failedRowIds: string[];
21
+ save(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridChange<TData>[]>;
22
+ saveDetailed(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridBatchSaveResult<TData>>;
23
+ clearSaveIssues(): void;
24
+ resolveConflict(rowId: string, strategy: "acceptServer" | "keepLocal"): boolean;
25
+ rollback(rowIds?: readonly string[]): boolean;
26
+ markSaved(rowIds?: readonly string[]): void;
27
+ reveal(rowId: string, colId?: string, edit?: boolean): boolean;
28
+ refresh(): void;
29
+ }
30
+ /** Reactive dirty/save workflow layered over useMachTable(). */
31
+ declare function useMachTableEditing<TData = any>(table: UseMachTableReturn<TData>, options?: UseMachTableEditingOptions<TData>): UseMachTableEditingReturn<TData>;
32
+
33
+ type MachTableQuerySource<TQuery> = TQuery | (() => TQuery);
34
+ interface MachTablePageRequest<TQuery> {
35
+ page: number;
36
+ pageSize: number;
37
+ query: TQuery;
38
+ sortModel: SortModel;
39
+ filterModel: FilterModel;
40
+ advancedFilterModel: AdvancedFilterModel | null;
41
+ quickFilterText: string | null;
42
+ signal: AbortSignal;
43
+ }
44
+ interface MachTablePageResult<TData> {
45
+ rows: readonly TData[];
46
+ total: number;
47
+ }
48
+ type MachTableRemoteSelectionState = {
49
+ mode: "explicit";
50
+ selectedKeys: string[];
51
+ } | {
52
+ mode: "allMatching";
53
+ excludedKeys: string[];
54
+ };
55
+ interface UseMachTableQueryOptions<TData, TQuery = Record<string, unknown>> {
56
+ request(params: MachTablePageRequest<TQuery>): Promise<MachTablePageResult<TData>>;
57
+ query: MachTableQuerySource<TQuery>;
58
+ /** Memoize object queries in React; queryKey can explicitly control reload dependencies. */
59
+ queryKey?: unknown;
60
+ rowKey: string | ((row: TData) => string | number);
61
+ initialPage?: number;
62
+ pageSize?: number;
63
+ pageSizeOptions?: readonly number[];
64
+ immediate?: boolean;
65
+ mode?: "auto" | "manual";
66
+ debounceMs?: number;
67
+ keepPreviousData?: boolean;
68
+ selectionScope?: "page" | "preserve" | "query";
69
+ clearSelectionOnQueryChange?: boolean;
70
+ initialQuickFilterText?: string | null;
71
+ errorOverlay?(context: {
72
+ error: unknown;
73
+ retry(): Promise<void>;
74
+ }): OverlayContent;
75
+ emptyOverlay?: OverlayTemplate;
76
+ onSuccess?(result: MachTablePageResult<TData>): void;
77
+ onError?(error: unknown): void;
78
+ }
79
+ interface UseMachTableQueryReturn<TData> {
80
+ rows: TData[];
81
+ loading: boolean;
82
+ error: unknown | null;
83
+ page: number;
84
+ pageSize: number;
85
+ total: number;
86
+ sortModel: SortModel;
87
+ filterModel: FilterModel;
88
+ advancedFilterModel: AdvancedFilterModel | null;
89
+ quickFilterText: string | null;
90
+ setQuickFilterText(value: string | null): void;
91
+ selectedKeys: string[];
92
+ selectedRows: TData[];
93
+ selectionState: MachTableRemoteSelectionState;
94
+ bindings: GridOptions<TData>;
95
+ reload(options?: {
96
+ resetPage?: boolean;
97
+ }): Promise<void>;
98
+ retry(): Promise<void>;
99
+ reset(): Promise<void>;
100
+ abort(): void;
101
+ clearSelection(): void;
102
+ selectAllMatching(): void;
103
+ applySelectionState(state: MachTableRemoteSelectionState): void;
104
+ }
105
+ /** React remote-list controller with cancellation, stale guards and cross-page selection. */
106
+ declare function useMachTableQuery<TData, TQuery = Record<string, unknown>>(options: UseMachTableQueryOptions<TData, TQuery>): UseMachTableQueryReturn<TData>;
107
+
108
+ interface UseMachTableControllerOptions<TData> {
109
+ /** Pass the result of useMachTableQuery for remote workflows. */
110
+ query?: UseMachTableQueryReturn<TData>;
111
+ editing?: UseMachTableEditingOptions<TData>;
112
+ initialSearch?: string;
113
+ }
114
+ interface UseMachTableControllerReturn<TData> {
115
+ table: UseMachTableReturn<TData>;
116
+ query: UseMachTableQueryReturn<TData> | null;
117
+ editing: UseMachTableEditingReturn<TData>;
118
+ bindings: GridOptions<TData>;
119
+ search: string;
120
+ setSearch(value: string): void;
121
+ selectedRows: TData[];
122
+ selectedCount: number;
123
+ busy: boolean;
124
+ error: unknown | null;
125
+ commands: MachTableCommands;
126
+ reload(): Promise<void>;
127
+ }
128
+ /** Cohesive React controller for API readiness, selection, editing and toolbar commands. */
129
+ declare function useMachTableController<TData>(options?: UseMachTableControllerOptions<TData>): UseMachTableControllerReturn<TData>;
130
+
131
+ export { type MachTablePageRequest, type MachTablePageResult, type MachTableQuerySource, type MachTableRemoteSelectionState, type UseMachTableControllerOptions, type UseMachTableControllerReturn, type UseMachTableEditingOptions, type UseMachTableEditingReturn, type UseMachTableQueryOptions, type UseMachTableQueryReturn, useMachTableController, useMachTableEditing, useMachTableQuery };
package/dist/workflows.js CHANGED
@@ -1,2 +1 @@
1
- import{b as e,c as a,d as r}from"./chunk-MW23Z6MV.js";export{r as useMachTableController,e as useMachTableEditing,a as useMachTableQuery};
2
- //# sourceMappingURL=workflows.js.map
1
+ import{a as ge}from"./chunk-FN4LWAOL.js";import{useCallback as A,useEffect as pe,useMemo as _,useRef as ke,useState as J}from"react";import{resolveSaveConflict as Qe}from"@agile-team/mach-table";function ee(t,a={}){let[b,R]=J([]),[w,Q]=J([]),[D,l]=J(!1),[v,M]=J(null),[i,F]=J(null),S=ke(!1),g=A(()=>{let r=t.apiRef.current;if(!r||r.isDestroyed()){Q([]),R([]);return}Q(r.editing.getDirtyRowIds()),R(r.editing.getChanges())},[t.apiRef]);pe(()=>{let r=t.api;return g(),r&&!r.isDestroyed()?r.on("dirtyStateChanged",g):void 0},[t.api,g]);let P=A(async(r,u)=>{let d=t.apiRef.current;if(!d||d.isDestroyed())throw new Error("[MachTable] Cannot save before the grid is ready.");if(S.current)throw new Error("[MachTable] A save operation is already in progress.");S.current=!0,l(!0),M(null),F(null);try{let o=await d.editing.save(r,u);return F(o),g(),a.onSaveSuccess?.(o.saved),a.onSaveResult?.(o),o}catch(o){throw M(o),a.onSaveError?.(o),o}finally{S.current=!1,l(!1)}},[a,g,t.apiRef]),H=A(async(r,u)=>(await P(r,u)).saved,[P]),K=A(()=>F(null),[]),N=A((r,u)=>{let d=i?.conflicts.find(y=>y.rowId===r),o=t.apiRef.current;return!i||!d||!o||!Qe(o,d,u)?!1:(F({...i,failures:i.failures,conflicts:i.conflicts.filter(y=>y.rowId!==r)}),g(),!0)},[i,g,t.apiRef]),U=A(r=>{let u=t.apiRef.current?.editing.rollback(r)??!1;return g(),u},[g,t.apiRef]),V=A(r=>{t.apiRef.current?.editing.markSaved(r),g()},[g,t.apiRef]),q=A((r,u,d=!1)=>{let o=t.apiRef.current,y=o?.rows.getById(r);return!o||!y||y.rowIndex<0?!1:(o.view.scrollToRow(y.rowIndex,"middle"),u&&d?o.editing.startCell({rowIndex:y.rowIndex,colId:u}):!0)},[t.apiRef]);pe(()=>{if(!a.guardBeforeUnload||typeof window>"u")return;let r=u=>{if(w.length===0)return;let d=a.beforeUnloadMessage??"\u5B58\u5728\u672A\u4FDD\u5B58\u7684\u8868\u683C\u4FEE\u6539\u3002";return u.preventDefault(),u.returnValue=d,d};return window.addEventListener("beforeunload",r),()=>window.removeEventListener("beforeunload",r)},[w.length,a.beforeUnloadMessage,a.guardBeforeUnload]);let z=_(()=>[...i?.failures??[],...i?.conflicts??[]],[i]),W=_(()=>[...new Set(z.map(r=>r.rowId))],[z]);return _(()=>({changes:b,dirtyRowIds:w,dirty:w.length>0,saving:D,saveError:v,lastSaveResult:i,saveIssues:z,failedRowIds:W,save:H,saveDetailed:P,clearSaveIssues:K,resolveConflict:N,rollback:U,markSaved:V,reveal:q,refresh:g}),[b,K,w,W,i,V,g,N,q,U,H,P,v,z,D])}import{useCallback as f,useEffect as ye,useMemo as Te,useReducer as Fe,useRef as m,useState as k}from"react";import{getByPath as Pe,normalizeAdvancedFilterModel as he}from"@agile-team/mach-table";function re(t,a){return typeof t=="number"&&Number.isFinite(t)&&t>0?Math.floor(t):a}function Ue(t){return(t instanceof DOMException||typeof t=="object"&&t!=null&&"name"in t)&&t.name==="AbortError"}function qe(t){return typeof t=="function"?t():t}function Oe(t){let a=m(t);a.current=t;let[b,R]=k([]),[w,Q]=k(!1),[D,l]=k(null),[v,M]=k(re(t.initialPage,1)),[i,F]=k(re(t.pageSize,20)),[S,g]=k(0),[P,H]=k([]),[K,N]=k({}),[U,V]=k(null),[q,z]=k(t.initialQuickFilterText??null),[,W]=Fe(e=>e+1,0),r=m({page:v,pageSize:i,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,rows:b});r.current={page:v,pageSize:i,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,rows:b};let u=m(null),d=m(null),o=m(null),y=m(0),C=m(new Set),x=m(new Set),T=m(new Map),O=m(!1),j=m(!1),$=m(!1),p=f(e=>{let n=a.current.rowKey,s=typeof n=="function"?n(e):Pe(e,n);if(s==null||String(s).length===0)throw new Error(`[MachTable] useMachTableQuery rowKey "${String(n)}" returned an empty value.`);return String(s)},[]),B=f(e=>O.current?!x.current.has(e):C.current.has(e),[]),E=f(()=>W(),[]),I=f(()=>{let e=u.current;if(!(!e||e.isDestroyed())){$.current=!0;try{e.selection.setRows(r.current.rows.filter(n=>B(p(n))),!0)}finally{$.current=!1}}},[p,B]),te=f(()=>{y.current++,d.current?.abort(),d.current=null,o.current&&clearTimeout(o.current),o.current=null,Q(!1)},[]),X=f((e,n)=>e.signal.aborted||n!==y.current,[]),ne=f((e,n,s)=>{if(X(n,s))return;if(!e||!Array.isArray(e.rows)||!Number.isFinite(e.total)||e.total<0)throw new TypeError("[MachTable] Remote request must resolve to { rows: TData[], total: non-negative number }.");let c=[...e.rows];for(let Y of c){let Z=p(Y);B(Z)?T.current.set(Z,Y):T.current.delete(Z)}r.current.rows=c,R(c),g(Math.floor(e.total)),E(),a.current.onSuccess?.(e),queueMicrotask(I)},[X,E,p,B,I]),ae=f((e,n,s)=>{if(X(n,s)||Ue(e))return;let c=e??new Error("Remote request failed");l(c),a.current.onError?.(c)},[X]),oe=f((e,n)=>{n===y.current&&(Q(!1),d.current===e&&(d.current=null))},[]),h=f(async()=>{o.current&&clearTimeout(o.current),o.current=null,d.current?.abort();let e=new AbortController;d.current=e;let n=++y.current;Q(!0),l(null),a.current.keepPreviousData===!1&&R([]);let s=r.current;try{let c=await a.current.request({page:s.page,pageSize:s.pageSize,query:qe(a.current.query),sortModel:s.sortModel.map(Y=>({...Y})),filterModel:{...s.filterModel},advancedFilterModel:he(s.advancedFilterModel),quickFilterText:s.quickFilterText,signal:e.signal});ne(c,e,n)}catch(c){ae(c,e,n)}finally{oe(e,n)}},[ne,oe,ae]),L=f(e=>{e&&(r.current.page=1,M(1)),d.current?.abort(),d.current=null;let n=Math.max(0,a.current.debounceMs??0);o.current&&clearTimeout(o.current),n===0?h():o.current=setTimeout(()=>{h()},n)},[h]),G=f(()=>{let e=O.current||C.current.size>0||x.current.size>0||T.current.size>0;O.current=!1,C.current.clear(),x.current.clear(),T.current.clear(),e&&E(),$.current=!0;try{u.current?.selection.clear()}finally{$.current=!1}},[E]),le=f(e=>{if(j.current)return;let n=r.current;e.page===n.page&&e.pageSize===n.pageSize||(n.page=e.page,n.pageSize=e.pageSize,M(e.page),F(e.pageSize),a.current.mode!=="manual"&&h())},[h]),ie=f(e=>{if(j.current)return;let n=e.sortModel.map(s=>({...s}));r.current.sortModel=n,H(n),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[L]),se=f(e=>{if(j.current)return;let n={...e.filterModel};r.current.filterModel=n;let s=he(e.advancedFilterModel);r.current.advancedFilterModel=s,r.current.quickFilterText=e.api.filtering.getQuickText(),N(n),V(s),z(r.current.quickFilterText),a.current.clearSelectionOnQueryChange!==!1&&G(),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[G,L]),ce=f(e=>{if($.current)return;let n=new Set(r.current.rows.map(p)),s=new Set(e.selectedRows.map(p));if(O.current)for(let c of n)s.has(c)?x.current.delete(c):(x.current.add(c),T.current.delete(c));else{if((a.current.selectionScope??"preserve")==="page")C.current.clear(),T.current.clear();else for(let c of n)C.current.delete(c),T.current.delete(c);for(let c of e.selectedRows)C.current.add(p(c))}for(let c of e.selectedRows)T.current.set(p(c),c);E()},[E,p]),Me=f(async(e={})=>{e.resetPage&&(r.current.page=1,M(1)),await h()},[h]),Se=f(async()=>{r.current.page=1,r.current.sortModel=[],r.current.filterModel={},r.current.advancedFilterModel=null,M(1),H([]),N({}),V(null),G(),j.current=!0;try{u.current?.sorting.setModel(null),u.current?.filtering.setModel(null),u.current?.filtering.setAdvancedModel(null)}finally{j.current=!1}await h()},[G,h]),we=f(()=>{O.current=!0,C.current.clear(),x.current.clear(),T.current.clear();for(let e of r.current.rows)T.current.set(p(e),e);E(),I()},[E,p,I]),Re=f(e=>{C.current.clear(),x.current.clear(),T.current.clear(),O.current=e.mode==="allMatching";for(let n of(e.mode==="allMatching"?e.excludedKeys:e.selectedKeys).map(String))e.mode==="allMatching"?x.current.add(n):C.current.add(n);for(let n of r.current.rows)B(p(n))&&T.current.set(p(n),n);E(),I()},[E,p,B,I]),ue=m(!0),De=t.queryKey===void 0?t.query:t.queryKey;ye(()=>{if(ue.current){ue.current=!1;return}a.current.clearSelectionOnQueryChange!==!1&&G(),a.current.mode!=="manual"?L(!0):(r.current.page=1,M(1))},[De,G,L]),ye(()=>(t.mode!=="manual"&&t.immediate!==!1&&h(),te),[]);let de=Te(()=>{let e=[...new Set((t.pageSizeOptions??[10,20,50,100]).map(n=>re(n,0)).filter(Boolean))];return e.includes(i)||e.push(i),e.sort((n,s)=>n-s)},[t.pageSizeOptions,i]),Ce=Te(()=>({rowData:b,loading:w,error:D,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:U,quickFilterText:q,overlayErrorTemplate:D?()=>a.current.errorOverlay?.({error:D,retry:h})??"Remote request failed. Please retry.":void 0,overlayNoRowsTemplate:t.emptyOverlay,pagination:{mode:"server",page:v,pageSize:i,pageSizeOptions:de,total:S,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{u.current=e,queueMicrotask(I)},onPaginationChanged:le,onSortChanged:ie,onFilterChanged:se,onSelectionChanged:ce}),[U,D,h,w,se,le,ce,ie,t.emptyOverlay,v,i,de,q,p,b,I,S]),fe=O.current?[]:[...C.current],xe=[...T.current.entries()].filter(([e])=>!x.current.has(e)).map(([,e])=>e),Ee=O.current?{mode:"allMatching",excludedKeys:[...x.current]}:{mode:"explicit",selectedKeys:fe};return{rows:b,loading:w,error:D,page:v,pageSize:i,total:S,sortModel:P,filterModel:K,advancedFilterModel:U,quickFilterText:q,setQuickFilterText(e){r.current.quickFilterText=e,z(e),u.current?.filtering.setQuickText(e)},selectedKeys:fe,selectedRows:xe,selectionState:Ee,bindings:Ce,reload:Me,retry:h,reset:Se,abort:te,clearSelection:G,selectAllMatching:we,applySelectionState:Re}}import{useEffect as me,useMemo as be,useState as ve}from"react";import{createMachTableCommands as Ie}from"@agile-team/mach-table";function Ae(t={}){let a=ge(),b=ee(a,t.editing),[R,w]=ve(t.initialSearch??""),[Q,D]=ve([]),l=t.query??null;me(()=>{let S=a.api;if(!S||S.isDestroyed()||l)return;let g=()=>D(S.selection.getRows());return g(),S.on("selectionChanged",g)},[l,a.api]),me(()=>{l?l.setQuickFilterText(R||null):a.apiRef.current?.filtering.setQuickText(R||null)},[l,R,a.apiRef]);let v=be(()=>async()=>{l?await l.reload():a.apiRef.current?.rows.isRemote()?await a.apiRef.current.rows.reload():a.apiRef.current?.view.refreshCells()},[l,a.apiRef]),M=be(()=>Ie({getApi:()=>a.apiRef.current,reload:v}),[v,a.apiRef]),i=l?.selectedRows??Q,F=l?l.selectionState.mode==="allMatching"?Math.max(0,l.total-l.selectionState.excludedKeys.length):l.selectionState.selectedKeys.length:i.length;return{table:a,query:l,editing:b,bindings:l?.bindings??{},search:R,setSearch:w,selectedRows:i,selectedCount:F,busy:l?.loading===!0||b.saving,error:l?.error??b.saveError??null,commands:M,reload:v}}export{Ae as useMachTableController,ee as useMachTableEditing,Oe as useMachTableQuery};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/mach-table-react",
3
- "version": "0.19.1",
3
+ "version": "0.24.0",
4
4
  "description": "Official React 18+ adapter for the MachTable enterprise data grid",
5
5
  "keywords": [
6
6
  "react",
@@ -51,6 +51,26 @@
51
51
  "default": "./dist/workflows.cjs"
52
52
  }
53
53
  },
54
+ "./adapters": {
55
+ "import": {
56
+ "types": "./dist/adapters.d.ts",
57
+ "default": "./dist/adapters.js"
58
+ },
59
+ "require": {
60
+ "types": "./dist/adapters.d.cts",
61
+ "default": "./dist/adapters.cjs"
62
+ }
63
+ },
64
+ "./ui": {
65
+ "import": {
66
+ "types": "./dist/ui.d.ts",
67
+ "default": "./dist/ui.js"
68
+ },
69
+ "require": {
70
+ "types": "./dist/ui.d.cts",
71
+ "default": "./dist/ui.cjs"
72
+ }
73
+ },
54
74
  "./worker": {
55
75
  "import": {
56
76
  "types": "./dist/worker.d.ts",
@@ -77,7 +97,7 @@
77
97
  "**/*.css"
78
98
  ],
79
99
  "dependencies": {
80
- "@agile-team/mach-table": "0.19.1"
100
+ "@agile-team/mach-table": "0.24.0"
81
101
  },
82
102
  "peerDependencies": {
83
103
  "react": ">=18.0.0",
@@ -93,5 +113,5 @@
93
113
  "test": "vitest run",
94
114
  "test:coverage": "vitest run --coverage"
95
115
  },
96
- "readme": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/ChenyCHENYU/MachTable/main/assets/mach-table-logo.svg\" alt=\"MachTable\" width=\"760\" />\n</p>\n\n# @agile-team/mach-table-react\n\nOfficial React 18+ adapter for MachTable 0.19. It provides a generic `<MachTable>`, full app/route configuration, advanced-filter aware remote query, conflict-aware editing workflows, persistent named views, a cohesive controller, optional and persistent column resizing, random-access remote blocks, batched/domain APIs, optional Worker processing, a standard toolbar, in-place React cell refresh, latest-closure event handling and StrictMode-safe cleanup. `RobotGrid` remains a deprecated 0.x alias.\n\n## Install\n\n```bash\npnpm add @agile-team/mach-table-react\n```\n\nOptional large local-data Worker helpers use the same installed package but a separate chunk:\n\n```ts\nimport { createWorkerDataProcessor } from \"@agile-team/mach-table-react/worker\";\n```\n\nImport the stylesheet once from your application entry:\n\n```ts\nimport \"@agile-team/mach-table-react/styles.css\";\n```\n\n## Direct import\n\n```tsx\nimport { useMemo } from \"react\";\nimport { MachTable, useMachGrid, type ColDef } from \"@agile-team/mach-table-react\";\n\ninterface Row { id: string; name: string }\n\nexport function App({ rows }: { rows: Row[] }) {\n const grid = useMachGrid<Row>();\n const columns = useMemo<ColDef<Row>[]>(\n () => [{ field: \"name\", headerName: \"Name\", flex: 1 }],\n []\n );\n\n return (\n <div style={{ height: 520 }}>\n <MachTable<Row>\n apiRef={grid.apiRef}\n rowData={rows}\n columnDefs={columns}\n rowKey=\"id\"\n stateKey=\"customer-list\"\n enableColumnResize\n />\n </div>\n );\n}\n```\n\n## Route-level lazy loading\n\nReact intentionally has no global component registry. MachTable provides a default component export so the standard `React.lazy` API works without a mapping wrapper:\n\n```tsx\nimport { lazy, Suspense } from \"react\";\n\nconst MachTable = lazy(() => import(\"@agile-team/mach-table-react\"));\n\nexport function OrdersPage() {\n return (\n <Suspense fallback={<div>Loading table...</div>}>\n <MachTable columnDefs={columns} rowData={rows} />\n </Suspense>\n );\n}\n```\n\nWhen the page itself is route-lazy, a normal named import inside that page already produces the same route-level split. Use `React.lazy` when the grid should be split independently from the page.\n\n## Application and route defaults\n\nKeep table conventions in one file. Providers can be nested; the nearest configuration is merged, named presets are reusable, and explicit table props win:\n\n```tsx\n// mach-table.config.ts\nimport { defineMachTableConfig, defineMachTablePreset } from \"@agile-team/mach-table-react\";\nexport default defineMachTableConfig({\n defaults: {\n size: \"compact\",\n enableColumnResize: true,\n defaultColDef: { sortable: true, resizable: true, filter: true }\n },\n defaultPreset: \"list\",\n presets: {\n list: defineMachTablePreset({ pagination: false }),\n crud: defineMachTablePreset({ rowSelection: \"multiple\", editType: \"fullRow\" })\n }\n});\n\n// main.tsx\n<MachTableProvider config={machTableConfig}>\n <App />\n</MachTableProvider>\n```\n\nThe adapter installs the matching `@agile-team/mach-table` core automatically and re-exports its complete API and types. Only `react >= 18` and `react-dom >= 18` remain peer dependencies supplied by the host application.\n\n## Remote lists and standard workflows\n\nImport heavier page workflows from the tree-shakeable subpath:\n\n```tsx\nimport { useMachTableQuery, useMachTableController } from \"@agile-team/mach-table-react/workflows\";\nimport { MachTable, MachTableToolbar } from \"@agile-team/mach-table-react\";\n\nconst query = useMachTableQuery({\n query: filters,\n queryKey: filters,\n rowKey: \"id\",\n request: orderApi.page,\n mode: \"manual\"\n});\nconst controller = useMachTableController({ query });\n\n<MachTableToolbar\n api={controller.table.api}\n commands={controller.commands}\n search={controller.search}\n onSearchChange={controller.setSearch}\n loading={controller.busy}\n/>;\n<MachTable apiRef={controller.table.apiRef} {...controller.bindings} />;\n```\n\nThe query hook cancels superseded requests, ignores stale responses, forwards nested advanced filters, exposes an error overlay and supports cross-page or select-all-matching selection. `useMachTableEditing()` adds dirty state, detailed partial-save/conflict results, guarded saves, conflict resolution, rollback and reveal helpers.\n\n```tsx\nconst editing = useMachTableEditing(grid, { guardBeforeUnload: true });\nconst result = await editing.saveDetailed(orderApi.saveChanges);\nif (result.conflicts.length) editing.reveal(result.conflicts[0].rowId);\n\nasync function saveCurrentView() {\n const api = grid.apiRef.current;\n if (!api) return;\n const views = createGridViewManager(api, {\n scope: `${tenantId}:${userId}:orders`\n });\n await views.save(\"My pending orders\");\n}\n```\n\nSee the [advanced filter](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/recipes/advanced-filter.md), [named views](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/recipes/saved-views.md), and [batch save](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/recipes/batch-save.md) guides.\n\n## Cell and full-row editing\n\n```tsx\nimport { MachTable, rowActionsColumn } from \"@agile-team/mach-table-react\";\n\nconst columns = [\n { field: \"name\", editable: true },\n { field: \"age\", editable: true, cellEditor: \"number\" },\n rowActionsColumn({ onView, onDelete, overflow: \"drawer\" })\n];\n\n<MachTable editType=\"fullRow\" columnDefs={columns} rowData={rows} />;\n```\n\nCell mode is the default and provides a pencil plus inline confirm/cancel controls. Use `editableIndicator=\"always\" | \"hover\" | \"none\"` to match the page density.\n\nDocumentation: [React guide](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/react.md) · [Enterprise integration](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/enterprise-integration.md) · [Next.js / SSR](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/ssr.md)\n\nSource-available © ChenyCHENYU (Agile Team). Any use requires prior written authorization. See the [license](https://github.com/ChenyCHENYU/MachTable/blob/main/LICENSE) and [authorization process](https://github.com/ChenyCHENYU/MachTable/blob/main/LICENSING.md).\n"
116
+ "readme": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/ChenyCHENYU/MachTable/main/assets/mach-table-logo.svg\" alt=\"MachTable\" width=\"760\" />\n</p>\n\n# @agile-team/mach-table-react\n\nMachTable 0.24 的官方 React 18+ 适配包。一个依赖即可获得 Core、泛型 `<MachTable>`、应用/路由配置、按需工作流、StrictMode 安全清理和最新闭包事件处理。\n\n```bash\npnpm add @agile-team/mach-table-react\n```\n\n应用入口只引入一次样式:\n\n```ts\nimport \"@agile-team/mach-table-react/styles.css\";\n```\n\n## 基础接入\n\n```tsx\nimport { useMemo } from \"react\";\nimport { MachTable, useMachTable, type ColDef } from \"@agile-team/mach-table-react\";\n\ninterface Row { id: string; name: string }\n\nexport function Customers({ rows }: { rows: Row[] }) {\n const table = useMachTable<Row>();\n const columns = useMemo<ColDef<Row>[]>(\n () => [{ field: \"name\", flex: 1, editable: true }],\n []\n );\n\n return (\n <div style={{ height: 520 }}>\n <MachTable<Row>\n apiRef={table.apiRef}\n rowData={rows}\n columnDefs={columns}\n rowKey=\"id\"\n enableColumnResize\n persistence={{ key: \"customers:list\", sections: [\"columns\"] }}\n />\n </div>\n );\n}\n```\n\n对象型列和配置建议用 `useMemo` 保持引用稳定。`useMachTable()` 同时提供 `apiRef`、响应式 `api` 与 `ready`。\n\n## 应用配置\n\n```ts\n// src/config/mach-table.config.ts\nimport { defineMachTableConfig, defineMachTablePreset } from \"@agile-team/mach-table-react\";\n\nexport default defineMachTableConfig({\n defaults: {\n size: \"compact\",\n columnLayout: \"fit\",\n enableColumnResize: true,\n defaultColDef: { sortable: true, filter: true, resizable: true }\n },\n defaultPreset: \"list\",\n presets: {\n list: defineMachTablePreset({ stripedRows: true }),\n crud: defineMachTablePreset({ rowSelection: \"multiple\", editType: \"fullRow\" })\n }\n});\n```\n\n```tsx\n<MachTableProvider config={machTableConfig}>\n <App />\n</MachTableProvider>\n```\n\nProvider 可按路由/布局嵌套,最近一层覆盖外层,表格 props 优先级最高。\n\n## 按需加载\n\nReact 不模拟全局组件注册。路由本身懒加载时普通 import 已自然拆包;需要独立边界时:\n\n```tsx\nconst MachTable = lazy(() => import(\"@agile-team/mach-table-react\"));\n```\n\n可选能力使用子入口:\n\n```tsx\nimport { useMachTableQuery, useMachTableEditing } from \"@agile-team/mach-table-react/workflows\";\nimport { MachTableToolbar } from \"@agile-team/mach-table-react/ui\";\nimport { reactCellRenderer } from \"@agile-team/mach-table-react/adapters\";\nimport { createWorkerDataProcessor } from \"@agile-team/mach-table-react/worker\";\n```\n\n- `/workflows`:请求取消、防过期覆盖、服务端分页、跨页选择、脏数据和冲突保存。\n- `/ui`:可选标准工具栏。\n- `/adapters`:自定义 React cell/detail renderer 桥接。\n- `/worker`:大型本地过滤/排序的独立 Worker 能力。\n\n```tsx\nconst query = useMachTableQuery({\n query: filters,\n queryKey: filters,\n rowKey: \"id\",\n request: orderApi.page,\n mode: \"manual\"\n});\n\n<MachTable<Row> apiRef={table.apiRef} columnDefs={columns} {...query.bindings} />;\n```\n\n该包自动依赖 `@agile-team/mach-table` 并重导出 Core 类型;宿主只需提供 `react` 和 `react-dom >= 18`。\n\n文档:[React 指南](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/react.md) · [企业接入](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/enterprise-integration.md) · [SSR](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/guide/ssr.md)\n\nSource-available © ChenyCHENYU (Agile Team). 任何使用均须事先取得书面授权。详见 [LICENSE](https://github.com/ChenyCHENYU/MachTable/blob/main/LICENSE) 与[授权流程](https://github.com/ChenyCHENYU/MachTable/blob/main/LICENSING.md)。\n"
97
117
  }
@@ -1,2 +0,0 @@
1
- import{useMemo as xe,useState as ge}from"react";function pe(){let[r,a]=ge(null),[T,h]=ge(!1);return{apiRef:xe(()=>{let m=null;return Object.defineProperty({},"current",{enumerable:!0,get:()=>m,set:g=>{g!==m&&(m=g,a(g),h(!1),g&&g.whenReady().then(()=>{m===g&&!g.isDestroyed()&&h(!0)}))}})},[]),api:r,ready:T}}import{useCallback as I,useEffect as ye,useMemo as _,useRef as Pe,useState as J}from"react";import{resolveSaveConflict as Ge}from"@agile-team/mach-table";function Te(r,a={}){let[T,h]=J([]),[R,m]=J([]),[g,l]=J(!1),[w,D]=J(null),[i,P]=J(null),C=Pe(!1),p=I(()=>{let t=r.apiRef.current;if(!t||t.isDestroyed()){m([]),h([]);return}m(t.getDirtyRowIds()),h(t.getChanges())},[r.apiRef]);ye(()=>{let t=r.api;return p(),t&&!t.isDestroyed()?t.addEventListener("dirtyStateChanged",p):void 0},[r.api,p]);let G=I(async(t,u)=>{let d=r.apiRef.current;if(!d||d.isDestroyed())throw new Error("[MachTable] Cannot save before the grid is ready.");if(C.current)throw new Error("[MachTable] A save operation is already in progress.");C.current=!0,l(!0),D(null),P(null);try{let o=await d.saveChangesDetailed(t,u);return P(o),p(),a.onSaveSuccess?.(o.saved),a.onSaveResult?.(o),o}catch(o){throw D(o),a.onSaveError?.(o),o}finally{C.current=!1,l(!1)}},[a,p,r.apiRef]),j=I(async(t,u)=>(await G(t,u)).saved,[G]),K=I(()=>P(null),[]),H=I((t,u)=>{let d=i?.conflicts.find(v=>v.rowId===t),o=r.apiRef.current;return!i||!d||!o||!Ge(o,d,u)?!1:(P({...i,failures:i.failures,conflicts:i.conflicts.filter(v=>v.rowId!==t)}),p(),!0)},[i,p,r.apiRef]),Q=I(t=>{let u=r.apiRef.current?.rollbackChanges(t)??!1;return p(),u},[p,r.apiRef]),N=I(t=>{r.apiRef.current?.markChangesSaved(t),p()},[p,r.apiRef]),A=I((t,u,d=!1)=>{let o=r.apiRef.current,v=o?.getNodeById(t);return!o||!v||v.rowIndex<0?!1:(o.scrollToIndex(v.rowIndex,"middle"),u&&d?o.startEditingCell({rowIndex:v.rowIndex,colId:u}):!0)},[r.apiRef]);ye(()=>{if(!a.guardBeforeUnload||typeof window>"u")return;let t=u=>{if(R.length===0)return;let d=a.beforeUnloadMessage??"\u5B58\u5728\u672A\u4FDD\u5B58\u7684\u8868\u683C\u4FEE\u6539\u3002";return u.preventDefault(),u.returnValue=d,d};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[R.length,a.beforeUnloadMessage,a.guardBeforeUnload]);let U=_(()=>[...i?.failures??[],...i?.conflicts??[]],[i]),W=_(()=>[...new Set(U.map(t=>t.rowId))],[U]);return _(()=>({changes:T,dirtyRowIds:R,dirty:R.length>0,saving:g,saveError:w,lastSaveResult:i,saveIssues:U,failedRowIds:W,save:j,saveDetailed:G,clearSaveIssues:K,resolveConflict:H,rollback:Q,markSaved:N,reveal:A,refresh:p}),[T,K,R,W,i,N,p,H,A,Q,j,G,w,U,g])}import{useCallback as f,useEffect as he,useMemo as me,useReducer as Qe,useRef as S,useState as x}from"react";import{getByPath as Ae,normalizeAdvancedFilterModel as ve}from"@agile-team/mach-table";function ee(r,a){return typeof r=="number"&&Number.isFinite(r)&&r>0?Math.floor(r):a}function Oe(r){return(r instanceof DOMException||typeof r=="object"&&r!=null&&"name"in r)&&r.name==="AbortError"}function qe(r){return typeof r=="function"?r():r}function Ne(r){let a=S(r);a.current=r;let[T,h]=x([]),[R,m]=x(!1),[g,l]=x(null),[w,D]=x(ee(r.initialPage,1)),[i,P]=x(ee(r.pageSize,20)),[C,p]=x(0),[G,j]=x([]),[K,H]=x({}),[Q,N]=x(null),[A,U]=x(r.initialQuickFilterText??null),[,W]=Qe(e=>e+1,0),t=S({page:w,pageSize:i,sortModel:G,filterModel:K,advancedFilterModel:Q,quickFilterText:A,rows:T});t.current={page:w,pageSize:i,sortModel:G,filterModel:K,advancedFilterModel:Q,quickFilterText:A,rows:T};let u=S(null),d=S(null),o=S(null),v=S(0),E=S(new Set),k=S(new Set),b=S(new Map),O=S(!1),V=S(!1),$=S(!1),y=f(e=>{let n=a.current.rowKey,s=typeof n=="function"?n(e):Ae(e,n);if(s==null||String(s).length===0)throw new Error(`[MachTable] useMachTableQuery rowKey "${String(n)}" returned an empty value.`);return String(s)},[]),B=f(e=>O.current?!k.current.has(e):E.current.has(e),[]),F=f(()=>W(),[]),q=f(()=>{let e=u.current;if(!(!e||e.isDestroyed())){$.current=!0;try{e.setSelection(t.current.rows.filter(n=>B(y(n))),!0)}finally{$.current=!1}}},[y,B]),re=f(()=>{v.current++,d.current?.abort(),d.current=null,o.current&&clearTimeout(o.current),o.current=null,m(!1)},[]),X=f((e,n)=>e.signal.aborted||n!==v.current,[]),te=f((e,n,s)=>{if(X(n,s))return;if(!e||!Array.isArray(e.rows)||!Number.isFinite(e.total)||e.total<0)throw new TypeError("[MachTable] Remote request must resolve to { rows: TData[], total: non-negative number }.");let c=[...e.rows];for(let Y of c){let Z=y(Y);B(Z)?b.current.set(Z,Y):b.current.delete(Z)}t.current.rows=c,h(c),p(Math.floor(e.total)),F(),a.current.onSuccess?.(e),queueMicrotask(q)},[X,F,y,B,q]),ne=f((e,n,s)=>{if(X(n,s)||Oe(e))return;let c=e??new Error("Remote request failed");l(c),a.current.onError?.(c)},[X]),ae=f((e,n)=>{n===v.current&&(m(!1),d.current===e&&(d.current=null))},[]),M=f(async()=>{o.current&&clearTimeout(o.current),o.current=null,d.current?.abort();let e=new AbortController;d.current=e;let n=++v.current;m(!0),l(null),a.current.keepPreviousData===!1&&h([]);let s=t.current;try{let c=await a.current.request({page:s.page,pageSize:s.pageSize,query:qe(a.current.query),sortModel:s.sortModel.map(Y=>({...Y})),filterModel:{...s.filterModel},advancedFilterModel:ve(s.advancedFilterModel),quickFilterText:s.quickFilterText,signal:e.signal});te(c,e,n)}catch(c){ne(c,e,n)}finally{ae(e,n)}},[te,ae,ne]),L=f(e=>{e&&(t.current.page=1,D(1)),d.current?.abort(),d.current=null;let n=Math.max(0,a.current.debounceMs??0);o.current&&clearTimeout(o.current),n===0?M():o.current=setTimeout(()=>{M()},n)},[M]),z=f(()=>{let e=O.current||E.current.size>0||k.current.size>0||b.current.size>0;O.current=!1,E.current.clear(),k.current.clear(),b.current.clear(),e&&F(),$.current=!0;try{u.current?.deselectAll()}finally{$.current=!1}},[F]),oe=f(e=>{if(V.current)return;let n=t.current;e.page===n.page&&e.pageSize===n.pageSize||(n.page=e.page,n.pageSize=e.pageSize,D(e.page),P(e.pageSize),a.current.mode!=="manual"&&M())},[M]),le=f(e=>{if(V.current)return;let n=e.sortModel.map(s=>({...s}));t.current.sortModel=n,j(n),a.current.mode!=="manual"?L(!0):(t.current.page=1,D(1))},[L]),ie=f(e=>{if(V.current)return;let n={...e.filterModel};t.current.filterModel=n;let s=ve(e.advancedFilterModel);t.current.advancedFilterModel=s,t.current.quickFilterText=e.api.getQuickFilter(),H(n),N(s),U(t.current.quickFilterText),a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?L(!0):(t.current.page=1,D(1))},[z,L]),se=f(e=>{if($.current)return;let n=new Set(t.current.rows.map(y)),s=new Set(e.selectedRows.map(y));if(O.current)for(let c of n)s.has(c)?k.current.delete(c):(k.current.add(c),b.current.delete(c));else{if((a.current.selectionScope??"preserve")==="page")E.current.clear(),b.current.clear();else for(let c of n)E.current.delete(c),b.current.delete(c);for(let c of e.selectedRows)E.current.add(y(c))}for(let c of e.selectedRows)b.current.set(y(c),c);F()},[F,y]),Re=f(async(e={})=>{e.resetPage&&(t.current.page=1,D(1)),await M()},[M]),we=f(async()=>{t.current.page=1,t.current.sortModel=[],t.current.filterModel={},t.current.advancedFilterModel=null,D(1),j([]),H({}),N(null),z(),V.current=!0;try{u.current?.setSortModel(null),u.current?.setFilterModel(null),u.current?.setAdvancedFilterModel(null)}finally{V.current=!1}await M()},[z,M]),De=f(()=>{O.current=!0,E.current.clear(),k.current.clear(),b.current.clear();for(let e of t.current.rows)b.current.set(y(e),e);F(),q()},[F,y,q]),Ce=f(e=>{E.current.clear(),k.current.clear(),b.current.clear(),O.current=e.mode==="allMatching";for(let n of(e.mode==="allMatching"?e.excludedKeys:e.selectedKeys).map(String))e.mode==="allMatching"?k.current.add(n):E.current.add(n);for(let n of t.current.rows)B(y(n))&&b.current.set(y(n),n);F(),q()},[F,y,B,q]),ce=S(!0),Ee=r.queryKey===void 0?r.query:r.queryKey;he(()=>{if(ce.current){ce.current=!1;return}a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?L(!0):(t.current.page=1,D(1))},[Ee,z,L]),he(()=>(r.mode!=="manual"&&r.immediate!==!1&&M(),re),[]);let ue=me(()=>{let e=[...new Set((r.pageSizeOptions??[10,20,50,100]).map(n=>ee(n,0)).filter(Boolean))];return e.includes(i)||e.push(i),e.sort((n,s)=>n-s)},[r.pageSizeOptions,i]),de=me(()=>({rowData:T,loading:R,error:g,rowKey:y,manualSorting:!0,manualFiltering:!0,advancedFilterModel:Q,quickFilterText:A,overlayErrorTemplate:g?()=>a.current.errorOverlay?.({error:g,retry:M})??"Remote request failed. Please retry.":void 0,overlayNoRowsTemplate:r.emptyOverlay,pagination:{mode:"server",page:w,pageSize:i,pageSizeOptions:ue,total:C,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{u.current=e,queueMicrotask(q)},onPaginationChanged:oe,onSortChanged:le,onFilterChanged:ie,onSelectionChanged:se}),[Q,g,M,R,ie,oe,se,le,r.emptyOverlay,w,i,ue,A,y,T,q,C]),fe=O.current?[]:[...E.current],ke=[...b.current.entries()].filter(([e])=>!k.current.has(e)).map(([,e])=>e),Fe=O.current?{mode:"allMatching",excludedKeys:[...k.current]}:{mode:"explicit",selectedKeys:fe};return{rows:T,loading:R,error:g,page:w,pageSize:i,total:C,sortModel:G,filterModel:K,advancedFilterModel:Q,quickFilterText:A,setQuickFilterText(e){t.current.quickFilterText=e,U(e),u.current?.setQuickFilter(e)},selectedKeys:fe,selectedRows:ke,selectionState:Fe,gridProps:de,bindings:de,reload:Re,retry:M,reset:we,abort:re,clearSelection:z,selectAllMatching:De,applySelectionState:Ce}}import{useEffect as be,useMemo as Me,useState as Se}from"react";import{createMachTableCommands as Ie}from"@agile-team/mach-table";function Ye(r={}){let a=pe(),T=Te(a,r.editing),[h,R]=Se(r.initialSearch??""),[m,g]=Se([]),l=r.query??null;be(()=>{let C=a.api;if(!C||C.isDestroyed()||l)return;let p=()=>g(C.getSelectedRows());return p(),C.addEventListener("selectionChanged",p)},[l,a.api]),be(()=>{l?l.setQuickFilterText(h||null):a.apiRef.current?.setQuickFilter(h||null)},[l,h,a.apiRef]);let w=Me(()=>async()=>{l?await l.reload():a.apiRef.current?.isInfinite()?await a.apiRef.current.reload():a.apiRef.current?.refreshCells()},[l,a.apiRef]),D=Me(()=>Ie({getApi:()=>a.apiRef.current,reload:w}),[w,a.apiRef]),i=l?.selectedRows??m,P=l?l.selectionState.mode==="allMatching"?Math.max(0,l.total-l.selectionState.excludedKeys.length):l.selectionState.selectedKeys.length:i.length;return{table:a,query:l,editing:T,bindings:l?.bindings??{},search:h,setSearch:R,selectedRows:i,selectedCount:P,busy:l?.loading===!0||T.saving,error:l?.error??T.saveError??null,commands:D,reload:w}}export{pe as a,Te as b,Ne as c,Ye as d};
2
- //# sourceMappingURL=chunk-MW23Z6MV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/useMachGrid.ts","../src/useMachTableEditing.ts","../src/useMachTableQuery.ts","../src/useMachTableController.ts"],"sourcesContent":["import { useMemo, useState, type MutableRefObject } from \"react\";\nimport type { GridApi } from \"@agile-team/mach-table\";\n\nexport interface UseMachGridReturn<TData = any> {\n apiRef: MutableRefObject<GridApi<TData> | null>;\n api: GridApi<TData> | null;\n ready: boolean;\n}\n\nexport function useMachGrid<TData = any>(): UseMachGridReturn<TData> {\n const [api, setApi] = useState<GridApi<TData> | null>(null);\n const [ready, setReady] = useState(false);\n const apiRef = useMemo(() => {\n let current: GridApi<TData> | null = null;\n return Object.defineProperty({}, \"current\", {\n enumerable: true,\n get: () => current,\n set: (next: GridApi<TData> | null) => {\n if (next === current) return;\n current = next;\n setApi(next);\n setReady(false);\n if (next) {\n void next.whenReady().then(() => {\n if (current === next && !next.isDestroyed()) setReady(true);\n });\n }\n }\n }) as MutableRefObject<GridApi<TData> | null>;\n }, []);\n\n return { apiRef, api, ready };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n resolveSaveConflict as resolveCoreSaveConflict,\n type GridBatchSaveResult,\n type GridChange,\n type SaveChangeConflict,\n type SaveChangeIssue,\n type SaveChangesHandler\n} from \"@agile-team/mach-table\";\nimport type { UseMachGridReturn } from \"./useMachGrid\";\n\nexport interface UseMachTableEditingOptions<TData = any> {\n guardBeforeUnload?: boolean;\n beforeUnloadMessage?: string;\n onSaveSuccess?(saved: readonly GridChange<TData>[]): void;\n onSaveResult?(result: GridBatchSaveResult<TData>): void;\n onSaveError?(error: unknown): void;\n}\n\nexport interface UseMachTableEditingReturn<TData = any> {\n changes: GridChange<TData>[];\n dirtyRowIds: string[];\n dirty: boolean;\n saving: boolean;\n saveError: unknown | null;\n lastSaveResult: GridBatchSaveResult<TData> | null;\n saveIssues: Array<SaveChangeIssue | SaveChangeConflict<TData>>;\n failedRowIds: string[];\n save(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridChange<TData>[]>;\n saveDetailed(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridBatchSaveResult<TData>>;\n clearSaveIssues(): void;\n resolveConflict(rowId: string, strategy: \"acceptServer\" | \"keepLocal\"): boolean;\n rollback(rowIds?: readonly string[]): boolean;\n markSaved(rowIds?: readonly string[]): void;\n reveal(rowId: string, colId?: string, edit?: boolean): boolean;\n refresh(): void;\n}\n\n/** Reactive dirty/save workflow layered over useMachGrid(). */\nexport function useMachTableEditing<TData = any>(\n table: UseMachGridReturn<TData>,\n options: UseMachTableEditingOptions<TData> = {}\n): UseMachTableEditingReturn<TData> {\n const [changes, setChanges] = useState<GridChange<TData>[]>([]);\n const [dirtyRowIds, setDirtyRowIds] = useState<string[]>([]);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<unknown | null>(null);\n const [lastSaveResult, setLastSaveResult] = useState<GridBatchSaveResult<TData> | null>(null);\n const savingRef = useRef(false);\n\n const refresh = useCallback((): void => {\n const api = table.apiRef.current;\n if (!api || api.isDestroyed()) {\n setDirtyRowIds([]);\n setChanges([]);\n return;\n }\n setDirtyRowIds(api.getDirtyRowIds());\n setChanges(api.getChanges());\n }, [table.apiRef]);\n\n useEffect(() => {\n const api = table.api;\n refresh();\n return api && !api.isDestroyed() ? api.addEventListener(\"dirtyStateChanged\", refresh) : undefined;\n }, [table.api, refresh]);\n\n const saveDetailed = useCallback(async (\n handler: SaveChangesHandler<TData>,\n rowIds?: readonly string[]\n ): Promise<GridBatchSaveResult<TData>> => {\n const api = table.apiRef.current;\n if (!api || api.isDestroyed()) throw new Error(\"[MachTable] Cannot save before the grid is ready.\");\n if (savingRef.current) throw new Error(\"[MachTable] A save operation is already in progress.\");\n savingRef.current = true;\n setSaving(true);\n setSaveError(null);\n setLastSaveResult(null);\n try {\n const result = await api.saveChangesDetailed(handler, rowIds);\n setLastSaveResult(result);\n refresh();\n options.onSaveSuccess?.(result.saved);\n options.onSaveResult?.(result);\n return result;\n } catch (error) {\n setSaveError(error);\n options.onSaveError?.(error);\n throw error;\n } finally {\n savingRef.current = false;\n setSaving(false);\n }\n }, [options, refresh, table.apiRef]);\n const save = useCallback(async (\n handler: SaveChangesHandler<TData>,\n rowIds?: readonly string[]\n ): Promise<GridChange<TData>[]> => (await saveDetailed(handler, rowIds)).saved, [saveDetailed]);\n\n const clearSaveIssues = useCallback((): void => setLastSaveResult(null), []);\n const resolveConflict = useCallback((rowId: string, strategy: \"acceptServer\" | \"keepLocal\"): boolean => {\n const conflict = lastSaveResult?.conflicts.find((entry) => entry.rowId === rowId);\n const api = table.apiRef.current;\n if (!lastSaveResult || !conflict || !api || !resolveCoreSaveConflict(api, conflict, strategy)) return false;\n setLastSaveResult({\n ...lastSaveResult,\n failures: lastSaveResult.failures,\n conflicts: lastSaveResult.conflicts.filter((entry) => entry.rowId !== rowId)\n });\n refresh();\n return true;\n }, [lastSaveResult, refresh, table.apiRef]);\n\n const rollback = useCallback((rowIds?: readonly string[]): boolean => {\n const changed = table.apiRef.current?.rollbackChanges(rowIds) ?? false;\n refresh();\n return changed;\n }, [refresh, table.apiRef]);\n const markSaved = useCallback((rowIds?: readonly string[]): void => {\n table.apiRef.current?.markChangesSaved(rowIds);\n refresh();\n }, [refresh, table.apiRef]);\n const reveal = useCallback((rowId: string, colId?: string, edit = false): boolean => {\n const api = table.apiRef.current;\n const node = api?.getNodeById(rowId);\n if (!api || !node || node.rowIndex < 0) return false;\n api.scrollToIndex(node.rowIndex, \"middle\");\n return colId && edit ? api.startEditingCell({ rowIndex: node.rowIndex, colId }) : true;\n }, [table.apiRef]);\n\n useEffect(() => {\n if (!options.guardBeforeUnload || typeof window === \"undefined\") return;\n const handler = (event: BeforeUnloadEvent): string | undefined => {\n if (dirtyRowIds.length === 0) return undefined;\n const message = options.beforeUnloadMessage ?? \"存在未保存的表格修改。\";\n event.preventDefault();\n event.returnValue = message;\n return message;\n };\n window.addEventListener(\"beforeunload\", handler);\n return () => window.removeEventListener(\"beforeunload\", handler);\n }, [dirtyRowIds.length, options.beforeUnloadMessage, options.guardBeforeUnload]);\n\n const saveIssues = useMemo(() => [\n ...(lastSaveResult?.failures ?? []),\n ...(lastSaveResult?.conflicts ?? [])\n ], [lastSaveResult]);\n const failedRowIds = useMemo(() => [...new Set(saveIssues.map((issue) => issue.rowId))], [saveIssues]);\n\n return useMemo(() => ({\n changes, dirtyRowIds, dirty: dirtyRowIds.length > 0, saving, saveError,\n lastSaveResult, saveIssues, failedRowIds,\n save, saveDetailed, clearSaveIssues, resolveConflict, rollback, markSaved, reveal, refresh\n }), [changes, clearSaveIssues, dirtyRowIds, failedRowIds, lastSaveResult, markSaved, refresh, resolveConflict, reveal, rollback, save, saveDetailed, saveError, saveIssues, saving]);\n}\n","import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport {\n getByPath,\n normalizeAdvancedFilterModel,\n type AdvancedFilterModel,\n type FilterModel,\n type FilterChangedEvent,\n type GridApi,\n type GridOptions,\n type OverlayContent,\n type OverlayTemplate,\n type PaginationChangedEvent,\n type SelectionChangedEvent,\n type SortModel\n} from \"@agile-team/mach-table\";\n\nexport type MachTableQuerySource<TQuery> = TQuery | (() => TQuery);\n\nexport interface MachTablePageRequest<TQuery> {\n page: number;\n pageSize: number;\n query: TQuery;\n sortModel: SortModel;\n filterModel: FilterModel;\n advancedFilterModel: AdvancedFilterModel | null;\n quickFilterText: string | null;\n signal: AbortSignal;\n}\n\nexport interface MachTablePageResult<TData> {\n rows: readonly TData[];\n total: number;\n}\n\nexport type MachTableRemoteSelectionState =\n | { mode: \"explicit\"; selectedKeys: string[] }\n | { mode: \"allMatching\"; excludedKeys: string[] };\n\nexport interface UseMachTableQueryOptions<TData, TQuery = Record<string, unknown>> {\n request(params: MachTablePageRequest<TQuery>): Promise<MachTablePageResult<TData>>;\n query: MachTableQuerySource<TQuery>;\n /** Memoize object queries in React; queryKey can explicitly control reload dependencies. */\n queryKey?: unknown;\n rowKey: string | ((row: TData) => string | number);\n initialPage?: number;\n pageSize?: number;\n pageSizeOptions?: readonly number[];\n immediate?: boolean;\n mode?: \"auto\" | \"manual\";\n debounceMs?: number;\n keepPreviousData?: boolean;\n selectionScope?: \"page\" | \"preserve\" | \"query\";\n clearSelectionOnQueryChange?: boolean;\n initialQuickFilterText?: string | null;\n errorOverlay?(context: { error: unknown; retry(): Promise<void> }): OverlayContent;\n emptyOverlay?: OverlayTemplate;\n onSuccess?(result: MachTablePageResult<TData>): void;\n onError?(error: unknown): void;\n}\n\nexport interface UseMachTableQueryReturn<TData> {\n rows: TData[];\n loading: boolean;\n error: unknown | null;\n page: number;\n pageSize: number;\n total: number;\n sortModel: SortModel;\n filterModel: FilterModel;\n advancedFilterModel: AdvancedFilterModel | null;\n quickFilterText: string | null;\n setQuickFilterText(value: string | null): void;\n selectedKeys: string[];\n selectedRows: TData[];\n selectionState: MachTableRemoteSelectionState;\n gridProps: GridOptions<TData>;\n bindings: GridOptions<TData>;\n reload(options?: { resetPage?: boolean }): Promise<void>;\n retry(): Promise<void>;\n reset(): Promise<void>;\n abort(): void;\n clearSelection(): void;\n selectAllMatching(): void;\n applySelectionState(state: MachTableRemoteSelectionState): void;\n}\n\nfunction positive(value: number | undefined, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException\n ? error.name === \"AbortError\"\n : typeof error === \"object\" && error != null && \"name\" in error && (error as { name?: unknown }).name === \"AbortError\";\n}\n\nfunction readQuery<T>(source: MachTableQuerySource<T>): T {\n return typeof source === \"function\" ? (source as () => T)() : source;\n}\n\n/** React remote-list controller with cancellation, stale guards and cross-page selection. */\nexport function useMachTableQuery<TData, TQuery = Record<string, unknown>>(\n options: UseMachTableQueryOptions<TData, TQuery>\n): UseMachTableQueryReturn<TData> {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const [rows, setRows] = useState<TData[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<unknown | null>(null);\n const [page, setPage] = useState(positive(options.initialPage, 1));\n const [pageSize, setPageSize] = useState(positive(options.pageSize, 20));\n const [total, setTotal] = useState(0);\n const [sortModel, setSortModel] = useState<SortModel>([]);\n const [filterModel, setFilterModel] = useState<FilterModel>({});\n const [advancedFilterModel, setAdvancedFilterModel] = useState<AdvancedFilterModel | null>(null);\n const [quickFilterText, setQuickFilterText] = useState<string | null>(options.initialQuickFilterText ?? null);\n const [, refreshSelection] = useReducer((value: number) => value + 1, 0);\n const stateRef = useRef({ page, pageSize, sortModel, filterModel, advancedFilterModel, quickFilterText, rows });\n stateRef.current = { page, pageSize, sortModel, filterModel, advancedFilterModel, quickFilterText, rows };\n const apiRef = useRef<GridApi<TData> | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const generationRef = useRef(0);\n const selectedIds = useRef(new Set<string>());\n const excludedIds = useRef(new Set<string>());\n const selectedById = useRef(new Map<string, TData>());\n const allMatching = useRef(false);\n const suppressGrid = useRef(false);\n const suppressSelection = useRef(false);\n\n const rowId = useCallback((row: TData): string => {\n const rowKey = optionsRef.current.rowKey;\n const value = typeof rowKey === \"function\" ? rowKey(row) : getByPath(row, rowKey);\n if (value == null || String(value).length === 0) {\n throw new Error(`[MachTable] useMachTableQuery rowKey \"${String(rowKey)}\" returned an empty value.`);\n }\n return String(value);\n }, []);\n const selected = useCallback((id: string): boolean => allMatching.current ? !excludedIds.current.has(id) : selectedIds.current.has(id), []);\n const notifySelection = useCallback(() => refreshSelection(), []);\n const syncVisibleSelection = useCallback((): void => {\n const api = apiRef.current;\n if (!api || api.isDestroyed()) return;\n suppressSelection.current = true;\n try { api.setSelection(stateRef.current.rows.filter((row) => selected(rowId(row))), true); }\n finally { suppressSelection.current = false; }\n }, [rowId, selected]);\n\n const abort = useCallback((): void => {\n generationRef.current++;\n abortRef.current?.abort();\n abortRef.current = null;\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = null;\n setLoading(false);\n }, []);\n\n const isStale = useCallback((controller: AbortController, generation: number): boolean =>\n controller.signal.aborted || generation !== generationRef.current, []);\n\n const applyPageResult = useCallback((\n result: MachTablePageResult<TData>,\n controller: AbortController,\n generation: number\n ): void => {\n if (isStale(controller, generation)) return;\n if (!result || !Array.isArray(result.rows) || !Number.isFinite(result.total) || result.total < 0) {\n throw new TypeError(\"[MachTable] Remote request must resolve to { rows: TData[], total: non-negative number }.\");\n }\n const nextRows = [...result.rows];\n for (const row of nextRows) {\n const id = rowId(row);\n if (selected(id)) selectedById.current.set(id, row);\n else selectedById.current.delete(id);\n }\n stateRef.current.rows = nextRows;\n setRows(nextRows);\n setTotal(Math.floor(result.total));\n notifySelection();\n optionsRef.current.onSuccess?.(result);\n queueMicrotask(syncVisibleSelection);\n }, [isStale, notifySelection, rowId, selected, syncVisibleSelection]);\n\n const handleRequestError = useCallback((\n requestError: unknown,\n controller: AbortController,\n generation: number\n ): void => {\n if (isStale(controller, generation) || isAbortError(requestError)) return;\n const normalized = requestError ?? new Error(\"Remote request failed\");\n setError(normalized);\n optionsRef.current.onError?.(normalized);\n }, [isStale]);\n\n const finishRequest = useCallback((controller: AbortController, generation: number): void => {\n if (generation !== generationRef.current) return;\n setLoading(false);\n if (abortRef.current === controller) abortRef.current = null;\n }, []);\n\n const load = useCallback(async (): Promise<void> => {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = null;\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n const generation = ++generationRef.current;\n setLoading(true);\n setError(null);\n if (optionsRef.current.keepPreviousData === false) setRows([]);\n const current = stateRef.current;\n try {\n const result = await optionsRef.current.request({\n page: current.page,\n pageSize: current.pageSize,\n query: readQuery(optionsRef.current.query),\n sortModel: current.sortModel.map((item) => ({ ...item })),\n filterModel: { ...current.filterModel },\n advancedFilterModel: normalizeAdvancedFilterModel(current.advancedFilterModel),\n quickFilterText: current.quickFilterText,\n signal: controller.signal\n });\n applyPageResult(result, controller, generation);\n } catch (requestError) {\n handleRequestError(requestError, controller, generation);\n } finally {\n finishRequest(controller, generation);\n }\n }, [applyPageResult, finishRequest, handleRequestError]);\n\n const scheduleLoad = useCallback((resetPage: boolean): void => {\n if (resetPage) {\n stateRef.current.page = 1;\n setPage(1);\n }\n abortRef.current?.abort();\n abortRef.current = null;\n const delay = Math.max(0, optionsRef.current.debounceMs ?? 0);\n if (timerRef.current) clearTimeout(timerRef.current);\n if (delay === 0) void load();\n else timerRef.current = setTimeout(() => { void load(); }, delay);\n }, [load]);\n\n const clearSelection = useCallback((): void => {\n const changed = allMatching.current || selectedIds.current.size > 0 ||\n excludedIds.current.size > 0 || selectedById.current.size > 0;\n allMatching.current = false;\n selectedIds.current.clear();\n excludedIds.current.clear();\n selectedById.current.clear();\n if (changed) notifySelection();\n suppressSelection.current = true;\n try { apiRef.current?.deselectAll(); } finally { suppressSelection.current = false; }\n }, [notifySelection]);\n\n const onPaginationChanged = useCallback((event: PaginationChangedEvent<TData>): void => {\n if (suppressGrid.current) return;\n const current = stateRef.current;\n if (event.page === current.page && event.pageSize === current.pageSize) return;\n current.page = event.page;\n current.pageSize = event.pageSize;\n setPage(event.page);\n setPageSize(event.pageSize);\n if (optionsRef.current.mode !== \"manual\") void load();\n }, [load]);\n const onSortChanged = useCallback((event: { sortModel: SortModel }): void => {\n if (suppressGrid.current) return;\n const next = event.sortModel.map((item) => ({ ...item }));\n stateRef.current.sortModel = next;\n setSortModel(next);\n if (optionsRef.current.mode !== \"manual\") scheduleLoad(true);\n else { stateRef.current.page = 1; setPage(1); }\n }, [scheduleLoad]);\n const onFilterChanged = useCallback((event: FilterChangedEvent<TData>): void => {\n if (suppressGrid.current) return;\n const next = { ...event.filterModel };\n stateRef.current.filterModel = next;\n const advanced = normalizeAdvancedFilterModel(event.advancedFilterModel);\n stateRef.current.advancedFilterModel = advanced;\n stateRef.current.quickFilterText = event.api.getQuickFilter();\n setFilterModel(next);\n setAdvancedFilterModel(advanced);\n setQuickFilterText(stateRef.current.quickFilterText);\n if (optionsRef.current.clearSelectionOnQueryChange !== false) clearSelection();\n if (optionsRef.current.mode !== \"manual\") scheduleLoad(true);\n else { stateRef.current.page = 1; setPage(1); }\n }, [clearSelection, scheduleLoad]);\n const onSelectionChanged = useCallback((event: SelectionChangedEvent<TData>): void => {\n if (suppressSelection.current) return;\n const visibleIds = new Set(stateRef.current.rows.map(rowId));\n const nextVisible = new Set(event.selectedRows.map(rowId));\n if (allMatching.current) {\n for (const id of visibleIds) {\n if (nextVisible.has(id)) excludedIds.current.delete(id);\n else { excludedIds.current.add(id); selectedById.current.delete(id); }\n }\n } else {\n if ((optionsRef.current.selectionScope ?? \"preserve\") === \"page\") {\n selectedIds.current.clear(); selectedById.current.clear();\n } else {\n for (const id of visibleIds) { selectedIds.current.delete(id); selectedById.current.delete(id); }\n }\n for (const row of event.selectedRows) selectedIds.current.add(rowId(row));\n }\n for (const row of event.selectedRows) selectedById.current.set(rowId(row), row);\n notifySelection();\n }, [notifySelection, rowId]);\n\n const reload = useCallback(async (reloadOptions: { resetPage?: boolean } = {}): Promise<void> => {\n if (reloadOptions.resetPage) { stateRef.current.page = 1; setPage(1); }\n await load();\n }, [load]);\n const reset = useCallback(async (): Promise<void> => {\n stateRef.current.page = 1;\n stateRef.current.sortModel = [];\n stateRef.current.filterModel = {};\n stateRef.current.advancedFilterModel = null;\n setPage(1); setSortModel([]); setFilterModel({}); setAdvancedFilterModel(null); clearSelection();\n suppressGrid.current = true;\n try {\n apiRef.current?.setSortModel(null);\n apiRef.current?.setFilterModel(null);\n apiRef.current?.setAdvancedFilterModel(null);\n }\n finally { suppressGrid.current = false; }\n await load();\n }, [clearSelection, load]);\n const selectAllMatching = useCallback((): void => {\n allMatching.current = true; selectedIds.current.clear(); excludedIds.current.clear(); selectedById.current.clear();\n for (const row of stateRef.current.rows) selectedById.current.set(rowId(row), row);\n notifySelection(); syncVisibleSelection();\n }, [notifySelection, rowId, syncVisibleSelection]);\n const applySelectionState = useCallback((state: MachTableRemoteSelectionState): void => {\n selectedIds.current.clear(); excludedIds.current.clear(); selectedById.current.clear();\n allMatching.current = state.mode === \"allMatching\";\n for (const id of (state.mode === \"allMatching\" ? state.excludedKeys : state.selectedKeys).map(String)) {\n if (state.mode === \"allMatching\") excludedIds.current.add(id); else selectedIds.current.add(id);\n }\n for (const row of stateRef.current.rows) if (selected(rowId(row))) selectedById.current.set(rowId(row), row);\n notifySelection(); syncVisibleSelection();\n }, [notifySelection, rowId, selected, syncVisibleSelection]);\n\n const firstQueryEffect = useRef(true);\n const queryDependency = options.queryKey === undefined ? options.query : options.queryKey;\n useEffect(() => {\n if (firstQueryEffect.current) { firstQueryEffect.current = false; return; }\n if (optionsRef.current.clearSelectionOnQueryChange !== false) clearSelection();\n if (optionsRef.current.mode !== \"manual\") scheduleLoad(true);\n else { stateRef.current.page = 1; setPage(1); }\n }, [queryDependency, clearSelection, scheduleLoad]);\n useEffect(() => {\n if (options.mode !== \"manual\" && options.immediate !== false) void load();\n return abort;\n }, []);\n\n const pageSizes = useMemo(() => {\n const values = [...new Set((options.pageSizeOptions ?? [10, 20, 50, 100]).map((value) => positive(value, 0)).filter(Boolean))];\n if (!values.includes(pageSize)) values.push(pageSize);\n return values.sort((left, right) => left - right);\n }, [options.pageSizeOptions, pageSize]);\n const gridProps = useMemo<GridOptions<TData>>(() => ({\n rowData: rows,\n loading,\n error,\n rowKey: rowId,\n manualSorting: true,\n manualFiltering: true,\n advancedFilterModel,\n quickFilterText,\n overlayErrorTemplate: error\n ? () => optionsRef.current.errorOverlay?.({ error, retry: load }) ?? \"Remote request failed. Please retry.\"\n : undefined,\n overlayNoRowsTemplate: options.emptyOverlay,\n pagination: {\n mode: \"server\", page, pageSize, pageSizeOptions: pageSizes, total,\n showTotal: true, showPageSizeSelector: true\n },\n onGridReady: ({ api }) => { apiRef.current = api; queueMicrotask(syncVisibleSelection); },\n onPaginationChanged,\n onSortChanged,\n onFilterChanged,\n onSelectionChanged\n }), [advancedFilterModel, error, load, loading, onFilterChanged, onPaginationChanged, onSelectionChanged, onSortChanged, options.emptyOverlay, page, pageSize, pageSizes, quickFilterText, rowId, rows, syncVisibleSelection, total]);\n\n const selectedKeys = allMatching.current ? [] : [...selectedIds.current];\n const selectedRows = [...selectedById.current.entries()]\n .filter(([id]) => !excludedIds.current.has(id))\n .map(([, row]) => row);\n const selectionState: MachTableRemoteSelectionState = allMatching.current\n ? { mode: \"allMatching\", excludedKeys: [...excludedIds.current] }\n : { mode: \"explicit\", selectedKeys };\n\n return {\n rows, loading, error, page, pageSize, total, sortModel, filterModel, advancedFilterModel,\n quickFilterText,\n setQuickFilterText(value) {\n stateRef.current.quickFilterText = value;\n setQuickFilterText(value);\n apiRef.current?.setQuickFilter(value);\n },\n selectedKeys, selectedRows, selectionState, gridProps, bindings: gridProps,\n reload, retry: load, reset, abort, clearSelection, selectAllMatching, applySelectionState\n };\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { createMachTableCommands, type GridOptions, type MachTableCommands } from \"@agile-team/mach-table\";\nimport { useMachGrid, type UseMachGridReturn } from \"./useMachGrid\";\nimport { useMachTableEditing, type UseMachTableEditingOptions, type UseMachTableEditingReturn } from \"./useMachTableEditing\";\nimport type { UseMachTableQueryReturn } from \"./useMachTableQuery\";\n\nexport interface UseMachTableControllerOptions<TData> {\n /** Pass the result of useMachTableQuery for remote workflows. */\n query?: UseMachTableQueryReturn<TData>;\n editing?: UseMachTableEditingOptions<TData>;\n initialSearch?: string;\n}\n\nexport interface UseMachTableControllerReturn<TData> {\n table: UseMachGridReturn<TData>;\n query: UseMachTableQueryReturn<TData> | null;\n editing: UseMachTableEditingReturn<TData>;\n bindings: GridOptions<TData>;\n search: string;\n setSearch(value: string): void;\n selectedRows: TData[];\n selectedCount: number;\n busy: boolean;\n error: unknown | null;\n commands: MachTableCommands;\n reload(): Promise<void>;\n}\n\n/** Cohesive React controller for API readiness, selection, editing and toolbar commands. */\nexport function useMachTableController<TData>(\n options: UseMachTableControllerOptions<TData> = {}\n): UseMachTableControllerReturn<TData> {\n const table = useMachGrid<TData>();\n const editing = useMachTableEditing(table, options.editing);\n const [search, setSearch] = useState(options.initialSearch ?? \"\");\n const [localSelection, setLocalSelection] = useState<TData[]>([]);\n const query = options.query ?? null;\n\n useEffect(() => {\n const api = table.api;\n if (!api || api.isDestroyed() || query) return;\n const sync = () => setLocalSelection(api.getSelectedRows());\n sync();\n return api.addEventListener(\"selectionChanged\", sync);\n }, [query, table.api]);\n useEffect(() => {\n if (!query) table.apiRef.current?.setQuickFilter(search || null);\n else query.setQuickFilterText(search || null);\n }, [query, search, table.apiRef]);\n\n const reload = useMemo(() => async (): Promise<void> => {\n if (query) await query.reload();\n else if (table.apiRef.current?.isInfinite()) await table.apiRef.current.reload();\n else table.apiRef.current?.refreshCells();\n }, [query, table.apiRef]);\n const commands = useMemo(() => createMachTableCommands<TData>({\n getApi: () => table.apiRef.current,\n reload\n }), [reload, table.apiRef]);\n const selectedRows = query?.selectedRows ?? localSelection;\n const selectedCount = query\n ? query.selectionState.mode === \"allMatching\"\n ? Math.max(0, query.total - query.selectionState.excludedKeys.length)\n : query.selectionState.selectedKeys.length\n : selectedRows.length;\n\n return {\n table,\n query,\n editing,\n bindings: query?.bindings ?? {},\n search,\n setSearch,\n selectedRows,\n selectedCount,\n busy: query?.loading === true || editing.saving,\n error: query?.error ?? editing.saveError ?? null,\n commands,\n reload\n };\n}\n"],"mappings":"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","names":["useMemo","useState","useMachGrid","api","setApi","ready","setReady","current","next","useCallback","useEffect","useMemo","useRef","useState","resolveCoreSaveConflict","useMachTableEditing","table","options","changes","setChanges","dirtyRowIds","setDirtyRowIds","saving","setSaving","saveError","setSaveError","lastSaveResult","setLastSaveResult","savingRef","refresh","api","saveDetailed","handler","rowIds","result","error","save","clearSaveIssues","resolveConflict","rowId","strategy","conflict","entry","rollback","changed","markSaved","reveal","colId","edit","node","event","message","saveIssues","failedRowIds","issue","useCallback","useEffect","useMemo","useReducer","useRef","useState","getByPath","normalizeAdvancedFilterModel","positive","value","fallback","isAbortError","error","readQuery","source","useMachTableQuery","options","optionsRef","rows","setRows","loading","setLoading","setError","page","setPage","pageSize","setPageSize","total","setTotal","sortModel","setSortModel","filterModel","setFilterModel","advancedFilterModel","setAdvancedFilterModel","quickFilterText","setQuickFilterText","refreshSelection","stateRef","apiRef","abortRef","timerRef","generationRef","selectedIds","excludedIds","selectedById","allMatching","suppressGrid","suppressSelection","rowId","row","rowKey","selected","id","notifySelection","syncVisibleSelection","api","abort","isStale","controller","generation","applyPageResult","result","nextRows","handleRequestError","requestError","normalized","finishRequest","load","current","item","scheduleLoad","resetPage","delay","clearSelection","changed","onPaginationChanged","event","onSortChanged","next","onFilterChanged","advanced","onSelectionChanged","visibleIds","nextVisible","reload","reloadOptions","reset","selectAllMatching","applySelectionState","state","firstQueryEffect","queryDependency","pageSizes","values","left","right","gridProps","selectedKeys","selectedRows","selectionState","useEffect","useMemo","useState","createMachTableCommands","useMachTableController","options","table","useMachGrid","editing","useMachTableEditing","search","setSearch","useState","localSelection","setLocalSelection","query","useEffect","api","sync","reload","useMemo","commands","createMachTableCommands","selectedRows","selectedCount"]}