@agile-team/mach-table-react 0.23.0 → 0.25.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 };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkMFRKW34Vcjs = require('./chunk-MFRKW34V.cjs');exports.useMachTableController = _chunkMFRKW34Vcjs.d; exports.useMachTableEditing = _chunkMFRKW34Vcjs.b; exports.useMachTableQuery = _chunkMFRKW34Vcjs.c;
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[v,R]=_react.useState.call(void 0, []),[w,Q]=_react.useState.call(void 0, []),[D,l]=_react.useState.call(void 0, !1),[M,y]=_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),y(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 y(o),_optionalChain([a, 'access', _6 => _6.onSaveError, 'optionalCall', _7 => _7(o)]),o}finally{S.current=!1,l(!1)}},[a,g,t.apiRef]),N=_react.useCallback.call(void 0, async(r,u)=>(await P(r,u)).saved,[P]),L=_react.useCallback.call(void 0, ()=>F(null),[]),V=_react.useCallback.call(void 0, (r,u)=>{let d=_optionalChain([i, 'optionalAccess', _8 => _8.conflicts, 'access', _9 => _9.find, 'call', _10 => _10(T=>T.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(T=>T.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]),j=_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,T=_optionalChain([o, 'optionalAccess', _21 => _21.rows, 'access', _22 => _22.getById, 'call', _23 => _23(r)]);return!o||!T||T.rowIndex<0?!1:(o.view.scrollToRow(T.rowIndex,"middle"),u&&d?o.editing.startCell({rowIndex:T.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 O=_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(O.map(r=>r.rowId))],[O]);return _react.useMemo.call(void 0, ()=>({changes:v,dirtyRowIds:w,dirty:w.length>0,saving:D,saveError:M,lastSaveResult:i,saveIssues:O,failedRowIds:W,save:N,saveDetailed:P,clearSaveIssues:L,resolveConflict:V,rollback:U,markSaved:j,reveal:q,refresh:g}),[v,L,w,W,i,j,g,V,q,U,N,P,M,O,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[v,R]=_react.useState.call(void 0, []),[w,Q]=_react.useState.call(void 0, !1),[D,l]=_react.useState.call(void 0, null),[M,y]=_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,N]=_react.useState.call(void 0, []),[L,V]=_react.useState.call(void 0, {}),[U,j]=_react.useState.call(void 0, null),[q,O]=_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:M,pageSize:i,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,rows:v});r.current={page:M,pageSize:i,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,rows:v};let u=_react.useRef.call(void 0, null),d=_react.useRef.call(void 0, null),o=_react.useRef.call(void 0, null),T=_react.useRef.call(void 0, 0),C=_react.useRef.call(void 0, new Set),x=_react.useRef.call(void 0, new Set),h=_react.useRef.call(void 0, new Map),I=_react.useRef.call(void 0, !1),K=_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)},[]),H=_react.useCallback.call(void 0, e=>I.current?!x.current.has(e):C.current.has(e),[]),k=_react.useCallback.call(void 0, ()=>W(),[]),A=_react.useCallback.call(void 0, ()=>{let e=u.current;if(!(!e||e.isDestroyed())){$.current=!0;try{e.selection.setRows(r.current.rows.filter(n=>H(p(n))),!0)}finally{$.current=!1}}},[p,H]),te=_react.useCallback.call(void 0, ()=>{T.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!==T.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);H(Z)?h.current.set(Z,Y):h.current.delete(Z)}r.current.rows=c,R(c),g(Math.floor(e.total)),k(),_optionalChain([a, 'access', _29 => _29.current, 'access', _30 => _30.onSuccess, 'optionalCall', _31 => _31(e)]),queueMicrotask(A)},[X,k,p,H,A]),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===T.current&&(Q(!1),d.current===e&&(d.current=null))},[]),m=_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=++T.current;Q(!0),l(null),a.current.keepPreviousData===!1&&(r.current.rows=[],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]),B=_react.useCallback.call(void 0, e=>{e&&(r.current.page=1,y(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?m():o.current=setTimeout(()=>{m()},n)},[m]),z=_react.useCallback.call(void 0, ()=>{let e=I.current||C.current.size>0||x.current.size>0||h.current.size>0;I.current=!1,C.current.clear(),x.current.clear(),h.current.clear(),e&&k(),$.current=!0;try{_optionalChain([u, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.selection, 'access', _43 => _43.clear, 'call', _44 => _44()])}finally{$.current=!1}},[k]),le=_react.useCallback.call(void 0, e=>{if(K.current)return;let n=r.current;e.page===n.page&&e.pageSize===n.pageSize||(n.page=e.page,n.pageSize=e.pageSize,y(e.page),F(e.pageSize),a.current.mode!=="manual"&&m())},[m]),ie=_react.useCallback.call(void 0, e=>{if(K.current)return;let n=e.sortModel.map(s=>({...s}));r.current.sortModel=n,N(n),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[B]),se=_react.useCallback.call(void 0, e=>{if(K.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(),V(n),j(s),O(r.current.quickFilterText),a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[z,B]),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(I.current)for(let c of n)s.has(c)?x.current.delete(c):(x.current.add(c),h.current.delete(c));else{if((_nullishCoalesce(a.current.selectionScope, () => ("preserve")))==="page")C.current.clear(),h.current.clear();else for(let c of n)C.current.delete(c),h.current.delete(c);for(let c of e.selectedRows)C.current.add(p(c))}for(let c of e.selectedRows)h.current.set(p(c),c);k()},[k,p]),Me=_react.useCallback.call(void 0, async(e={})=>{e.resetPage&&(r.current.page=1,y(1)),await m()},[m]),Se=_react.useCallback.call(void 0, async()=>{r.current.page=1,r.current.sortModel=[],r.current.filterModel={},r.current.advancedFilterModel=null,r.current.quickFilterText=null,y(1),N([]),V({}),j(null),O(null),z(),K.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)]),_optionalChain([u, 'access', _57 => _57.current, 'optionalAccess', _58 => _58.filtering, 'access', _59 => _59.setQuickText, 'call', _60 => _60(null)])}finally{K.current=!1}await m()},[z,m]),we=_react.useCallback.call(void 0, ()=>{I.current=!0,C.current.clear(),x.current.clear(),h.current.clear();for(let e of r.current.rows)h.current.set(p(e),e);k(),A()},[k,p,A]),Re=_react.useCallback.call(void 0, e=>{C.current.clear(),x.current.clear(),h.current.clear(),I.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)H(p(n))&&h.current.set(p(n),n);k(),A()},[k,p,H,A]),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&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[De,z,B]),_react.useEffect.call(void 0, ()=>(t.mode!=="manual"&&t.immediate!==!1&&m(),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:v,loading:w,error:D,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:U,quickFilterText:q,overlayErrorTemplate:D?()=>_nullishCoalesce(_optionalChain([a, 'access', _61 => _61.current, 'access', _62 => _62.errorOverlay, 'optionalCall', _63 => _63({error:D,retry:m})]), () => ("Remote request failed. Please retry.")):void 0,overlayNoRowsTemplate:t.emptyOverlay,pagination:{mode:"server",page:M,pageSize:i,pageSizeOptions:de,total:S,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{u.current=e,queueMicrotask(A)},onPaginationChanged:le,onSortChanged:ie,onFilterChanged:se,onSelectionChanged:ce}),[U,D,m,w,se,le,ce,ie,t.emptyOverlay,M,i,de,q,p,v,A,S]),fe=I.current?[]:[...C.current],xe=[...h.current.entries()].filter(([e])=>!x.current.has(e)).map(([,e])=>e),ke=I.current?{mode:"allMatching",excludedKeys:[...x.current]}:{mode:"explicit",selectedKeys:fe};return{rows:v,loading:w,error:D,page:M,pageSize:i,total:S,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,setQuickFilterText(e){r.current.quickFilterText=e,O(e),K.current=!0;try{_optionalChain([u, 'access', _64 => _64.current, 'optionalAccess', _65 => _65.filtering, 'access', _66 => _66.setQuickText, 'call', _67 => _67(e)])}finally{K.current=!1}a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},selectedKeys:fe,selectedRows:xe,selectionState:ke,bindings:Ce,reload:Me,retry:m,reset:Se,abort:te,clearSelection:z,selectAllMatching:we,applySelectionState:Re}}function Ae(t={}){let a=_chunkII7TCYIUcjs.a.call(void 0, ),v=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', _68 => _68.apiRef, 'access', _69 => _69.current, 'optionalAccess', _70 => _70.filtering, 'access', _71 => _71.setQuickText, 'call', _72 => _72(R||null)])},[l,R,a.apiRef]);let M=_react.useMemo.call(void 0, ()=>async()=>{l?await l.reload():_optionalChain([a, 'access', _73 => _73.apiRef, 'access', _74 => _74.current, 'optionalAccess', _75 => _75.rows, 'access', _76 => _76.isRemote, 'call', _77 => _77()])?await a.apiRef.current.rows.reload():_optionalChain([a, 'access', _78 => _78.apiRef, 'access', _79 => _79.current, 'optionalAccess', _80 => _80.view, 'access', _81 => _81.refreshCells, 'call', _82 => _82()])},[l,a.apiRef]),y=_react.useMemo.call(void 0, ()=>_machtable.createMachTableCommands.call(void 0, {getApi:()=>a.apiRef.current,reload:M}),[M,a.apiRef]),i=_nullishCoalesce(_optionalChain([l, 'optionalAccess', _83 => _83.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:v,bindings:_nullishCoalesce(_optionalChain([l, 'optionalAccess', _84 => _84.bindings]), () => ({})),search:R,setSearch:w,selectedRows:i,selectedCount:F,busy:_optionalChain([l, 'optionalAccess', _85 => _85.loading])===!0||v.saving,error:_nullishCoalesce(_nullishCoalesce(_optionalChain([l, 'optionalAccess', _86 => _86.error]), () => (v.saveError)), () => (null)),commands:y,reload:M}}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 +1 @@
1
- import{b as e,c as a,d as r}from"./chunk-WF435LXF.js";export{r as useMachTableController,e as useMachTableEditing,a as useMachTableQuery};
1
+ import{a as ge}from"./chunk-FN4LWAOL.js";import{useCallback as G,useEffect as pe,useMemo as _,useRef as Ee,useState as J}from"react";import{resolveSaveConflict as Qe}from"@agile-team/mach-table";function ee(t,a={}){let[v,R]=J([]),[w,Q]=J([]),[D,l]=J(!1),[M,y]=J(null),[i,F]=J(null),S=Ee(!1),g=G(()=>{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=G(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),y(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 y(o),a.onSaveError?.(o),o}finally{S.current=!1,l(!1)}},[a,g,t.apiRef]),N=G(async(r,u)=>(await P(r,u)).saved,[P]),L=G(()=>F(null),[]),V=G((r,u)=>{let d=i?.conflicts.find(T=>T.rowId===r),o=t.apiRef.current;return!i||!d||!o||!Qe(o,d,u)?!1:(F({...i,failures:i.failures,conflicts:i.conflicts.filter(T=>T.rowId!==r)}),g(),!0)},[i,g,t.apiRef]),U=G(r=>{let u=t.apiRef.current?.editing.rollback(r)??!1;return g(),u},[g,t.apiRef]),j=G(r=>{t.apiRef.current?.editing.markSaved(r),g()},[g,t.apiRef]),q=G((r,u,d=!1)=>{let o=t.apiRef.current,T=o?.rows.getById(r);return!o||!T||T.rowIndex<0?!1:(o.view.scrollToRow(T.rowIndex,"middle"),u&&d?o.editing.startCell({rowIndex:T.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 O=_(()=>[...i?.failures??[],...i?.conflicts??[]],[i]),W=_(()=>[...new Set(O.map(r=>r.rowId))],[O]);return _(()=>({changes:v,dirtyRowIds:w,dirty:w.length>0,saving:D,saveError:M,lastSaveResult:i,saveIssues:O,failedRowIds:W,save:N,saveDetailed:P,clearSaveIssues:L,resolveConflict:V,rollback:U,markSaved:j,reveal:q,refresh:g}),[v,L,w,W,i,j,g,V,q,U,N,P,M,O,D])}import{useCallback as f,useEffect as ye,useMemo as Te,useReducer as Fe,useRef as b,useState as E}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=b(t);a.current=t;let[v,R]=E([]),[w,Q]=E(!1),[D,l]=E(null),[M,y]=E(re(t.initialPage,1)),[i,F]=E(re(t.pageSize,20)),[S,g]=E(0),[P,N]=E([]),[L,V]=E({}),[U,j]=E(null),[q,O]=E(t.initialQuickFilterText??null),[,W]=Fe(e=>e+1,0),r=b({page:M,pageSize:i,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,rows:v});r.current={page:M,pageSize:i,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,rows:v};let u=b(null),d=b(null),o=b(null),T=b(0),C=b(new Set),x=b(new Set),h=b(new Map),I=b(!1),K=b(!1),$=b(!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)},[]),H=f(e=>I.current?!x.current.has(e):C.current.has(e),[]),k=f(()=>W(),[]),A=f(()=>{let e=u.current;if(!(!e||e.isDestroyed())){$.current=!0;try{e.selection.setRows(r.current.rows.filter(n=>H(p(n))),!0)}finally{$.current=!1}}},[p,H]),te=f(()=>{T.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!==T.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);H(Z)?h.current.set(Z,Y):h.current.delete(Z)}r.current.rows=c,R(c),g(Math.floor(e.total)),k(),a.current.onSuccess?.(e),queueMicrotask(A)},[X,k,p,H,A]),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===T.current&&(Q(!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=++T.current;Q(!0),l(null),a.current.keepPreviousData===!1&&(r.current.rows=[],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]),B=f(e=>{e&&(r.current.page=1,y(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=I.current||C.current.size>0||x.current.size>0||h.current.size>0;I.current=!1,C.current.clear(),x.current.clear(),h.current.clear(),e&&k(),$.current=!0;try{u.current?.selection.clear()}finally{$.current=!1}},[k]),le=f(e=>{if(K.current)return;let n=r.current;e.page===n.page&&e.pageSize===n.pageSize||(n.page=e.page,n.pageSize=e.pageSize,y(e.page),F(e.pageSize),a.current.mode!=="manual"&&m())},[m]),ie=f(e=>{if(K.current)return;let n=e.sortModel.map(s=>({...s}));r.current.sortModel=n,N(n),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[B]),se=f(e=>{if(K.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(),V(n),j(s),O(r.current.quickFilterText),a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[z,B]),ce=f(e=>{if($.current)return;let n=new Set(r.current.rows.map(p)),s=new Set(e.selectedRows.map(p));if(I.current)for(let c of n)s.has(c)?x.current.delete(c):(x.current.add(c),h.current.delete(c));else{if((a.current.selectionScope??"preserve")==="page")C.current.clear(),h.current.clear();else for(let c of n)C.current.delete(c),h.current.delete(c);for(let c of e.selectedRows)C.current.add(p(c))}for(let c of e.selectedRows)h.current.set(p(c),c);k()},[k,p]),Me=f(async(e={})=>{e.resetPage&&(r.current.page=1,y(1)),await m()},[m]),Se=f(async()=>{r.current.page=1,r.current.sortModel=[],r.current.filterModel={},r.current.advancedFilterModel=null,r.current.quickFilterText=null,y(1),N([]),V({}),j(null),O(null),z(),K.current=!0;try{u.current?.sorting.setModel(null),u.current?.filtering.setModel(null),u.current?.filtering.setAdvancedModel(null),u.current?.filtering.setQuickText(null)}finally{K.current=!1}await m()},[z,m]),we=f(()=>{I.current=!0,C.current.clear(),x.current.clear(),h.current.clear();for(let e of r.current.rows)h.current.set(p(e),e);k(),A()},[k,p,A]),Re=f(e=>{C.current.clear(),x.current.clear(),h.current.clear(),I.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)H(p(n))&&h.current.set(p(n),n);k(),A()},[k,p,H,A]),ue=b(!0),De=t.queryKey===void 0?t.query:t.queryKey;ye(()=>{if(ue.current){ue.current=!1;return}a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},[De,z,B]),ye(()=>(t.mode!=="manual"&&t.immediate!==!1&&m(),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:v,loading:w,error:D,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:U,quickFilterText:q,overlayErrorTemplate:D?()=>a.current.errorOverlay?.({error:D,retry:m})??"Remote request failed. Please retry.":void 0,overlayNoRowsTemplate:t.emptyOverlay,pagination:{mode:"server",page:M,pageSize:i,pageSizeOptions:de,total:S,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{u.current=e,queueMicrotask(A)},onPaginationChanged:le,onSortChanged:ie,onFilterChanged:se,onSelectionChanged:ce}),[U,D,m,w,se,le,ce,ie,t.emptyOverlay,M,i,de,q,p,v,A,S]),fe=I.current?[]:[...C.current],xe=[...h.current.entries()].filter(([e])=>!x.current.has(e)).map(([,e])=>e),ke=I.current?{mode:"allMatching",excludedKeys:[...x.current]}:{mode:"explicit",selectedKeys:fe};return{rows:v,loading:w,error:D,page:M,pageSize:i,total:S,sortModel:P,filterModel:L,advancedFilterModel:U,quickFilterText:q,setQuickFilterText(e){r.current.quickFilterText=e,O(e),K.current=!0;try{u.current?.filtering.setQuickText(e)}finally{K.current=!1}a.current.clearSelectionOnQueryChange!==!1&&z(),a.current.mode!=="manual"?B(!0):(r.current.page=1,y(1))},selectedKeys:fe,selectedRows:xe,selectionState:ke,bindings:Ce,reload:Me,retry:m,reset:Se,abort:te,clearSelection:z,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(),v=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 M=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]),y=be(()=>Ie({getApi:()=>a.apiRef.current,reload:M}),[M,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:v,bindings:l?.bindings??{},search:R,setSearch:w,selectedRows:i,selectedCount:F,busy:l?.loading===!0||v.saving,error:l?.error??v.saveError??null,commands:y,reload:M}}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.23.0",
3
+ "version": "0.25.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.23.0"
100
+ "@agile-team/mach-table": "0.25.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.23. 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, bounded random-access remote blocks, governed 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.25 的官方 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`:请求取消、防过期覆盖、服务端分页、跨页选择、脏数据和冲突保存;`reset()` 清空全部表格过滤且只请求一次。\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 +0,0 @@
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 _react = require('react');function pe(){let[r,a]=_react.useState.call(void 0, null),[T,h]=_react.useState.call(void 0, !1);return{apiRef:_react.useMemo.call(void 0, ()=>{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}}var _machtable = require('@agile-team/mach-table');function Te(r,a={}){let[T,h]=_react.useState.call(void 0, []),[R,m]=_react.useState.call(void 0, []),[g,l]=_react.useState.call(void 0, !1),[w,D]=_react.useState.call(void 0, null),[i,P]=_react.useState.call(void 0, null),C=_react.useRef.call(void 0, !1),p=_react.useCallback.call(void 0, ()=>{let t=r.apiRef.current;if(!t||t.isDestroyed()){m([]),h([]);return}m(t.getDirtyRowIds()),h(t.getChanges())},[r.apiRef]);_react.useEffect.call(void 0, ()=>{let t=r.api;return p(),t&&!t.isDestroyed()?t.addEventListener("dirtyStateChanged",p):void 0},[r.api,p]);let G=_react.useCallback.call(void 0, 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(),_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 D(o),_optionalChain([a, 'access', _6 => _6.onSaveError, 'optionalCall', _7 => _7(o)]),o}finally{C.current=!1,l(!1)}},[a,p,r.apiRef]),j=_react.useCallback.call(void 0, async(t,u)=>(await G(t,u)).saved,[G]),K=_react.useCallback.call(void 0, ()=>P(null),[]),H=_react.useCallback.call(void 0, (t,u)=>{let d=_optionalChain([i, 'optionalAccess', _8 => _8.conflicts, 'access', _9 => _9.find, 'call', _10 => _10(v=>v.rowId===t)]),o=r.apiRef.current;return!i||!d||!o||!_machtable.resolveSaveConflict.call(void 0, o,d,u)?!1:(P({...i,failures:i.failures,conflicts:i.conflicts.filter(v=>v.rowId!==t)}),p(),!0)},[i,p,r.apiRef]),Q=_react.useCallback.call(void 0, t=>{let u=_nullishCoalesce(_optionalChain([r, 'access', _11 => _11.apiRef, 'access', _12 => _12.current, 'optionalAccess', _13 => _13.rollbackChanges, 'call', _14 => _14(t)]), () => (!1));return p(),u},[p,r.apiRef]),N=_react.useCallback.call(void 0, t=>{_optionalChain([r, 'access', _15 => _15.apiRef, 'access', _16 => _16.current, 'optionalAccess', _17 => _17.markChangesSaved, 'call', _18 => _18(t)]),p()},[p,r.apiRef]),A=_react.useCallback.call(void 0, (t,u,d=!1)=>{let o=r.apiRef.current,v=_optionalChain([o, 'optionalAccess', _19 => _19.getNodeById, 'call', _20 => _20(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]);_react.useEffect.call(void 0, ()=>{if(!a.guardBeforeUnload||typeof window>"u")return;let t=u=>{if(R.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",t),()=>window.removeEventListener("beforeunload",t)},[R.length,a.beforeUnloadMessage,a.guardBeforeUnload]);let U=_react.useMemo.call(void 0, ()=>[..._nullishCoalesce(_optionalChain([i, 'optionalAccess', _21 => _21.failures]), () => ([])),..._nullishCoalesce(_optionalChain([i, 'optionalAccess', _22 => _22.conflicts]), () => ([]))],[i]),W=_react.useMemo.call(void 0, ()=>[...new Set(U.map(t=>t.rowId))],[U]);return _react.useMemo.call(void 0, ()=>({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])}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=_react.useRef.call(void 0, r);a.current=r;let[T,h]=_react.useState.call(void 0, []),[R,m]=_react.useState.call(void 0, !1),[g,l]=_react.useState.call(void 0, null),[w,D]=_react.useState.call(void 0, ee(r.initialPage,1)),[i,P]=_react.useState.call(void 0, ee(r.pageSize,20)),[C,p]=_react.useState.call(void 0, 0),[G,j]=_react.useState.call(void 0, []),[K,H]=_react.useState.call(void 0, {}),[Q,N]=_react.useState.call(void 0, null),[A,U]=_react.useState.call(void 0, _nullishCoalesce(r.initialQuickFilterText, () => (null))),[,W]=_react.useReducer.call(void 0, e=>e+1,0),t=_react.useRef.call(void 0, {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=_react.useRef.call(void 0, null),d=_react.useRef.call(void 0, null),o=_react.useRef.call(void 0, null),v=_react.useRef.call(void 0, 0),E=_react.useRef.call(void 0, new Set),k=_react.useRef.call(void 0, new Set),b=_react.useRef.call(void 0, new Map),O=_react.useRef.call(void 0, !1),V=_react.useRef.call(void 0, !1),$=_react.useRef.call(void 0, !1),y=_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?!k.current.has(e):E.current.has(e),[]),F=_react.useCallback.call(void 0, ()=>W(),[]),q=_react.useCallback.call(void 0, ()=>{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=_react.useCallback.call(void 0, ()=>{v.current++,_optionalChain([d, 'access', _23 => _23.current, 'optionalAccess', _24 => _24.abort, 'call', _25 => _25()]),d.current=null,o.current&&clearTimeout(o.current),o.current=null,m(!1)},[]),X=_react.useCallback.call(void 0, (e,n)=>e.signal.aborted||n!==v.current,[]),te=_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=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(),_optionalChain([a, 'access', _26 => _26.current, 'access', _27 => _27.onSuccess, 'optionalCall', _28 => _28(e)]),queueMicrotask(q)},[X,F,y,B,q]),ne=_react.useCallback.call(void 0, (e,n,s)=>{if(X(n,s)||Oe(e))return;let c=_nullishCoalesce(e, () => (new Error("Remote request failed")));l(c),_optionalChain([a, 'access', _29 => _29.current, 'access', _30 => _30.onError, 'optionalCall', _31 => _31(c)])},[X]),ae=_react.useCallback.call(void 0, (e,n)=>{n===v.current&&(m(!1),d.current===e&&(d.current=null))},[]),M=_react.useCallback.call(void 0, async()=>{o.current&&clearTimeout(o.current),o.current=null,_optionalChain([d, 'access', _32 => _32.current, 'optionalAccess', _33 => _33.abort, 'call', _34 => _34()]);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:_machtable.normalizeAdvancedFilterModel.call(void 0, 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=_react.useCallback.call(void 0, e=>{e&&(t.current.page=1,D(1)),_optionalChain([d, 'access', _35 => _35.current, 'optionalAccess', _36 => _36.abort, 'call', _37 => _37()]),d.current=null;let n=Math.max(0,_nullishCoalesce(a.current.debounceMs, () => (0)));o.current&&clearTimeout(o.current),n===0?M():o.current=setTimeout(()=>{M()},n)},[M]),z=_react.useCallback.call(void 0, ()=>{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{_optionalChain([u, 'access', _38 => _38.current, 'optionalAccess', _39 => _39.deselectAll, 'call', _40 => _40()])}finally{$.current=!1}},[F]),oe=_react.useCallback.call(void 0, 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=_react.useCallback.call(void 0, 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=_react.useCallback.call(void 0, e=>{if(V.current)return;let n={...e.filterModel};t.current.filterModel=n;let s=_machtable.normalizeAdvancedFilterModel.call(void 0, 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=_react.useCallback.call(void 0, 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((_nullishCoalesce(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=_react.useCallback.call(void 0, async(e={})=>{e.resetPage&&(t.current.page=1,D(1)),await M()},[M]),we=_react.useCallback.call(void 0, 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{_optionalChain([u, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.setSortModel, 'call', _43 => _43(null)]),_optionalChain([u, 'access', _44 => _44.current, 'optionalAccess', _45 => _45.setFilterModel, 'call', _46 => _46(null)]),_optionalChain([u, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.setAdvancedFilterModel, 'call', _49 => _49(null)])}finally{V.current=!1}await M()},[z,M]),De=_react.useCallback.call(void 0, ()=>{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=_react.useCallback.call(void 0, 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=_react.useRef.call(void 0, !0),Ee=r.queryKey===void 0?r.query:r.queryKey;_react.useEffect.call(void 0, ()=>{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]),_react.useEffect.call(void 0, ()=>(r.mode!=="manual"&&r.immediate!==!1&&M(),re),[]);let ue=_react.useMemo.call(void 0, ()=>{let e=[...new Set((_nullishCoalesce(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=_react.useMemo.call(void 0, ()=>({rowData:T,loading:R,error:g,rowKey:y,manualSorting:!0,manualFiltering:!0,advancedFilterModel:Q,quickFilterText:A,overlayErrorTemplate:g?()=>_nullishCoalesce(_optionalChain([a, 'access', _50 => _50.current, 'access', _51 => _51.errorOverlay, 'optionalCall', _52 => _52({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),_optionalChain([u, 'access', _53 => _53.current, 'optionalAccess', _54 => _54.setQuickFilter, 'call', _55 => _55(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}}function Ye(r={}){let a=pe(),T=Te(a,r.editing),[h,R]=_react.useState.call(void 0, _nullishCoalesce(r.initialSearch, () => (""))),[m,g]=_react.useState.call(void 0, []),l=_nullishCoalesce(r.query, () => (null));_react.useEffect.call(void 0, ()=>{let C=a.api;if(!C||C.isDestroyed()||l)return;let p=()=>g(C.getSelectedRows());return p(),C.addEventListener("selectionChanged",p)},[l,a.api]),_react.useEffect.call(void 0, ()=>{l?l.setQuickFilterText(h||null):_optionalChain([a, 'access', _56 => _56.apiRef, 'access', _57 => _57.current, 'optionalAccess', _58 => _58.setQuickFilter, 'call', _59 => _59(h||null)])},[l,h,a.apiRef]);let w=_react.useMemo.call(void 0, ()=>async()=>{l?await l.reload():_optionalChain([a, 'access', _60 => _60.apiRef, 'access', _61 => _61.current, 'optionalAccess', _62 => _62.isInfinite, 'call', _63 => _63()])?await a.apiRef.current.reload():_optionalChain([a, 'access', _64 => _64.apiRef, 'access', _65 => _65.current, 'optionalAccess', _66 => _66.refreshCells, 'call', _67 => _67()])},[l,a.apiRef]),D=_react.useMemo.call(void 0, ()=>_machtable.createMachTableCommands.call(void 0, {getApi:()=>a.apiRef.current,reload:w}),[w,a.apiRef]),i=_nullishCoalesce(_optionalChain([l, 'optionalAccess', _68 => _68.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:_nullishCoalesce(_optionalChain([l, 'optionalAccess', _69 => _69.bindings]), () => ({})),search:h,setSearch:R,selectedRows:i,selectedCount:P,busy:_optionalChain([l, 'optionalAccess', _70 => _70.loading])===!0||T.saving,error:_nullishCoalesce(_nullishCoalesce(_optionalChain([l, 'optionalAccess', _71 => _71.error]), () => (T.saveError)), () => (null)),commands:D,reload:w}}exports.a = pe; exports.b = Te; exports.c = Ne; exports.d = Ye;
@@ -1 +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};
@@ -1,138 +0,0 @@
1
- import { GridApi, GridChange, GridBatchSaveResult, SaveChangeIssue, SaveChangeConflict, SaveChangesHandler, SortModel, FilterModel, AdvancedFilterModel, GridOptions, OverlayContent, OverlayTemplate, MachTableCommands } from '@agile-team/mach-table';
2
- import { MutableRefObject } from 'react';
3
-
4
- interface UseMachGridReturn<TData = any> {
5
- apiRef: MutableRefObject<GridApi<TData> | null>;
6
- api: GridApi<TData> | null;
7
- ready: boolean;
8
- }
9
- declare function useMachGrid<TData = any>(): UseMachGridReturn<TData>;
10
-
11
- interface UseMachTableEditingOptions<TData = any> {
12
- guardBeforeUnload?: boolean;
13
- beforeUnloadMessage?: string;
14
- onSaveSuccess?(saved: readonly GridChange<TData>[]): void;
15
- onSaveResult?(result: GridBatchSaveResult<TData>): void;
16
- onSaveError?(error: unknown): void;
17
- }
18
- interface UseMachTableEditingReturn<TData = any> {
19
- changes: GridChange<TData>[];
20
- dirtyRowIds: string[];
21
- dirty: boolean;
22
- saving: boolean;
23
- saveError: unknown | null;
24
- lastSaveResult: GridBatchSaveResult<TData> | null;
25
- saveIssues: Array<SaveChangeIssue | SaveChangeConflict<TData>>;
26
- failedRowIds: string[];
27
- save(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridChange<TData>[]>;
28
- saveDetailed(handler: SaveChangesHandler<TData>, rowIds?: readonly string[]): Promise<GridBatchSaveResult<TData>>;
29
- clearSaveIssues(): void;
30
- resolveConflict(rowId: string, strategy: "acceptServer" | "keepLocal"): boolean;
31
- rollback(rowIds?: readonly string[]): boolean;
32
- markSaved(rowIds?: readonly string[]): void;
33
- reveal(rowId: string, colId?: string, edit?: boolean): boolean;
34
- refresh(): void;
35
- }
36
- /** Reactive dirty/save workflow layered over useMachGrid(). */
37
- declare function useMachTableEditing<TData = any>(table: UseMachGridReturn<TData>, options?: UseMachTableEditingOptions<TData>): UseMachTableEditingReturn<TData>;
38
-
39
- type MachTableQuerySource<TQuery> = TQuery | (() => TQuery);
40
- interface MachTablePageRequest<TQuery> {
41
- page: number;
42
- pageSize: number;
43
- query: TQuery;
44
- sortModel: SortModel;
45
- filterModel: FilterModel;
46
- advancedFilterModel: AdvancedFilterModel | null;
47
- quickFilterText: string | null;
48
- signal: AbortSignal;
49
- }
50
- interface MachTablePageResult<TData> {
51
- rows: readonly TData[];
52
- total: number;
53
- }
54
- type MachTableRemoteSelectionState = {
55
- mode: "explicit";
56
- selectedKeys: string[];
57
- } | {
58
- mode: "allMatching";
59
- excludedKeys: string[];
60
- };
61
- interface UseMachTableQueryOptions<TData, TQuery = Record<string, unknown>> {
62
- request(params: MachTablePageRequest<TQuery>): Promise<MachTablePageResult<TData>>;
63
- query: MachTableQuerySource<TQuery>;
64
- /** Memoize object queries in React; queryKey can explicitly control reload dependencies. */
65
- queryKey?: unknown;
66
- rowKey: string | ((row: TData) => string | number);
67
- initialPage?: number;
68
- pageSize?: number;
69
- pageSizeOptions?: readonly number[];
70
- immediate?: boolean;
71
- mode?: "auto" | "manual";
72
- debounceMs?: number;
73
- keepPreviousData?: boolean;
74
- selectionScope?: "page" | "preserve" | "query";
75
- clearSelectionOnQueryChange?: boolean;
76
- initialQuickFilterText?: string | null;
77
- errorOverlay?(context: {
78
- error: unknown;
79
- retry(): Promise<void>;
80
- }): OverlayContent;
81
- emptyOverlay?: OverlayTemplate;
82
- onSuccess?(result: MachTablePageResult<TData>): void;
83
- onError?(error: unknown): void;
84
- }
85
- interface UseMachTableQueryReturn<TData> {
86
- rows: TData[];
87
- loading: boolean;
88
- error: unknown | null;
89
- page: number;
90
- pageSize: number;
91
- total: number;
92
- sortModel: SortModel;
93
- filterModel: FilterModel;
94
- advancedFilterModel: AdvancedFilterModel | null;
95
- quickFilterText: string | null;
96
- setQuickFilterText(value: string | null): void;
97
- selectedKeys: string[];
98
- selectedRows: TData[];
99
- selectionState: MachTableRemoteSelectionState;
100
- gridProps: GridOptions<TData>;
101
- bindings: GridOptions<TData>;
102
- reload(options?: {
103
- resetPage?: boolean;
104
- }): Promise<void>;
105
- retry(): Promise<void>;
106
- reset(): Promise<void>;
107
- abort(): void;
108
- clearSelection(): void;
109
- selectAllMatching(): void;
110
- applySelectionState(state: MachTableRemoteSelectionState): void;
111
- }
112
- /** React remote-list controller with cancellation, stale guards and cross-page selection. */
113
- declare function useMachTableQuery<TData, TQuery = Record<string, unknown>>(options: UseMachTableQueryOptions<TData, TQuery>): UseMachTableQueryReturn<TData>;
114
-
115
- interface UseMachTableControllerOptions<TData> {
116
- /** Pass the result of useMachTableQuery for remote workflows. */
117
- query?: UseMachTableQueryReturn<TData>;
118
- editing?: UseMachTableEditingOptions<TData>;
119
- initialSearch?: string;
120
- }
121
- interface UseMachTableControllerReturn<TData> {
122
- table: UseMachGridReturn<TData>;
123
- query: UseMachTableQueryReturn<TData> | null;
124
- editing: UseMachTableEditingReturn<TData>;
125
- bindings: GridOptions<TData>;
126
- search: string;
127
- setSearch(value: string): void;
128
- selectedRows: TData[];
129
- selectedCount: number;
130
- busy: boolean;
131
- error: unknown | null;
132
- commands: MachTableCommands;
133
- reload(): Promise<void>;
134
- }
135
- /** Cohesive React controller for API readiness, selection, editing and toolbar commands. */
136
- declare function useMachTableController<TData>(options?: UseMachTableControllerOptions<TData>): UseMachTableControllerReturn<TData>;
137
-
138
- export { type MachTablePageRequest as M, type UseMachGridReturn as U, type MachTablePageResult as a, type MachTableQuerySource as b, type MachTableRemoteSelectionState as c, type UseMachTableControllerOptions as d, type UseMachTableControllerReturn as e, type UseMachTableEditingOptions as f, type UseMachTableEditingReturn as g, type UseMachTableQueryOptions as h, type UseMachTableQueryReturn as i, useMachTableController as j, useMachTableEditing as k, useMachTableQuery as l, useMachGrid as u };