@agile-team/mach-table-react 0.31.1 → 0.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # @agile-team/mach-table-react
6
6
 
7
- MachTable 0.31.1 的官方 React 18+ 适配包。一个依赖即可获得 Core、泛型 `<MachTable>`、应用/路由配置、按需工作流、StrictMode 安全清理和最新闭包事件处理。
7
+ MachTable 0.31.2 的官方 React 18+ 适配包。一个依赖即可获得 Core、泛型 `<MachTable>`、应用/路由配置、按需工作流、StrictMode 安全清理和最新闭包事件处理。
8
8
 
9
9
  ```bash
10
10
  pnpm add @agile-team/mach-table-react
@@ -77,6 +77,8 @@ export default defineMachTableConfig({
77
77
 
78
78
  Provider 可按路由/布局嵌套,最近一层覆盖外层,表格 props 优先级最高。
79
79
 
80
+ 编辑、粘贴、清空和填充复用已有列与整行校验。`useMachTableEditing()` 隔离重挂载或数据替换前的保存结果、错误和冲突;查询工作流在 StrictMode 下保留 `immediate: false`,重复设置相同搜索值不会重新请求。
81
+
80
82
  ## 按需加载
81
83
 
82
84
  React 不模拟全局组件注册。路由本身懒加载时普通 import 已自然拆包;需要独立边界时:
@@ -1 +1 @@
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
+ "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 te(r,n={}){let[R,F]=_react.useState.call(void 0, []),[k,A]=_react.useState.call(void 0, []),[E,i]=_react.useState.call(void 0, !1),[w,b]=_react.useState.call(void 0, null),[g,U]=_react.useState.call(void 0, null),v=_react.useRef.call(void 0, !1),O=_react.useRef.call(void 0, 0),D=_react.useRef.call(void 0, null),m=_react.useCallback.call(void 0, ()=>{let a=r.apiRef.current;if(!a||a.isDestroyed()){A([]),F([]);return}A(a.editing.getDirtyRowIds()),F(a.editing.getChanges())},[r.apiRef]);_react.useEffect.call(void 0, ()=>{let a=r.api;O.current++,v.current=!1,i(!1),b(null),U(null),D.current=null,m();let l=a&&!a.isDestroyed()?a.on("dirtyStateChanged",m):void 0;return()=>{O.current++,_optionalChain([l, 'optionalCall', _2 => _2()])}},[r.api,m]);let z=_react.useCallback.call(void 0, async(a,l)=>{let f=r.apiRef.current;if(!f||f.isDestroyed())throw new Error("[MachTable] Cannot save before the grid is ready.");if(v.current)throw new Error("[MachTable] A save operation is already in progress.");v.current=!0,i(!0),b(null),U(null),D.current=null;let y=O.current,c=()=>y===O.current&&r.apiRef.current===f&&!f.isDestroyed(),h=f.editing.getDirtyRowIds().filter(s=>!l||l.includes(s)).map(s=>{let P=f.rows.getById(s);return{rowId:s,node:P,data:_optionalChain([P, 'optionalAccess', _3 => _3.data])}}),C=s=>{let P=s===void 0?h:h.filter(p=>p.rowId===s);return c()&&P.every(({rowId:p,node:I,data:x})=>f.rows.getById(p)===I&&_optionalChain([I, 'optionalAccess', _4 => _4.data])===x)};try{let s=await f.editing.save(a,l);return C()&&(D.current=C,U(s),m(),_optionalChain([n, 'access', _5 => _5.onSaveSuccess, 'optionalCall', _6 => _6(s.saved)]),_optionalChain([n, 'access', _7 => _7.onSaveResult, 'optionalCall', _8 => _8(s)])),s}catch(s){throw C()&&(b(s),_optionalChain([n, 'access', _9 => _9.onSaveError, 'optionalCall', _10 => _10(s)])),s}finally{c()&&(v.current=!1,i(!1))}},[n,m,r.apiRef]),j=_react.useCallback.call(void 0, async(a,l)=>(await z(a,l)).saved,[z]),G=_react.useCallback.call(void 0, ()=>{D.current=null,U(null)},[]),$=_react.useCallback.call(void 0, (a,l)=>{let f=_optionalChain([g, 'optionalAccess', _11 => _11.conflicts, 'access', _12 => _12.find, 'call', _13 => _13(c=>c.rowId===a)]),y=r.apiRef.current;return!g||!f||!y||!_optionalChain([D, 'access', _14 => _14.current, 'optionalCall', _15 => _15(a)])||!_machtable.resolveSaveConflict.call(void 0, y,f,l)?!1:(U(c=>c&&{...c,conflicts:c.conflicts.filter(h=>h.rowId!==a)}),m(),!0)},[g,m,r.apiRef]),K=_react.useCallback.call(void 0, a=>{let l=_nullishCoalesce(_optionalChain([r, 'access', _16 => _16.apiRef, 'access', _17 => _17.current, 'optionalAccess', _18 => _18.editing, 'access', _19 => _19.rollback, 'call', _20 => _20(a)]), () => (!1));return m(),l},[m,r.apiRef]),V=_react.useCallback.call(void 0, a=>{_optionalChain([r, 'access', _21 => _21.apiRef, 'access', _22 => _22.current, 'optionalAccess', _23 => _23.editing, 'access', _24 => _24.markSaved, 'call', _25 => _25(a)]),m()},[m,r.apiRef]),W=_react.useCallback.call(void 0, (a,l,f=!1)=>{let y=r.apiRef.current,c=_optionalChain([y, 'optionalAccess', _26 => _26.rows, 'access', _27 => _27.getById, 'call', _28 => _28(a)]);return!y||!c||c.rowIndex<0?!1:(y.view.scrollToRow(c.rowIndex,"middle"),l&&f?y.editing.startCell({rowIndex:c.rowIndex,colId:l}):!0)},[r.apiRef]);_react.useEffect.call(void 0, ()=>{if(!n.guardBeforeUnload||typeof window>"u")return;let a=l=>{if(k.length===0)return;let f=_nullishCoalesce(n.beforeUnloadMessage, () => ("\u5B58\u5728\u672A\u4FDD\u5B58\u7684\u8868\u683C\u4FEE\u6539\u3002"));return l.preventDefault(),l.returnValue=f,f};return window.addEventListener("beforeunload",a),()=>window.removeEventListener("beforeunload",a)},[k.length,n.beforeUnloadMessage,n.guardBeforeUnload]);let o=_react.useMemo.call(void 0, ()=>[..._nullishCoalesce(_optionalChain([g, 'optionalAccess', _29 => _29.failures]), () => ([])),..._nullishCoalesce(_optionalChain([g, 'optionalAccess', _30 => _30.conflicts]), () => ([]))],[g]),Q=_react.useMemo.call(void 0, ()=>[...new Set(o.map(a=>a.rowId))],[o]);return _react.useMemo.call(void 0, ()=>({changes:R,dirtyRowIds:k,dirty:k.length>0,saving:E,saveError:w,lastSaveResult:g,saveIssues:o,failedRowIds:Q,save:j,saveDetailed:z,clearSaveIssues:G,resolveConflict:$,rollback:K,markSaved:V,reveal:W,refresh:m}),[R,G,k,Q,g,V,m,$,W,K,j,z,w,o,E])}function ne(r,n){return typeof r=="number"&&Number.isFinite(r)&&r>0?Math.floor(r):n}function qe(r){return(r instanceof DOMException||typeof r=="object"&&r!=null&&"name"in r)&&r.name==="AbortError"}function Ue(r){return typeof r=="function"?r():r}function Oe(r){let n=_react.useRef.call(void 0, r);n.current=r;let[R,F]=_react.useState.call(void 0, []),[k,A]=_react.useState.call(void 0, !1),[E,i]=_react.useState.call(void 0, null),[w,b]=_react.useState.call(void 0, ne(r.initialPage,1)),[g,U]=_react.useState.call(void 0, ne(r.pageSize,20)),[v,O]=_react.useState.call(void 0, 0),[D,m]=_react.useState.call(void 0, []),[z,j]=_react.useState.call(void 0, {}),[G,$]=_react.useState.call(void 0, null),[K,V]=_react.useState.call(void 0, _nullishCoalesce(r.initialQuickFilterText, () => (null))),[,W]=_react.useReducer.call(void 0, e=>e+1,0),o=_react.useRef.call(void 0, {page:w,pageSize:g,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,rows:R});o.current={page:w,pageSize:g,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,rows:R};let Q=_react.useRef.call(void 0, null),a=_react.useRef.call(void 0, null),l=_react.useRef.call(void 0, null),f=_react.useRef.call(void 0, 0),y=_react.useRef.call(void 0, new Set),c=_react.useRef.call(void 0, new Set),h=_react.useRef.call(void 0, new Map),C=_react.useRef.call(void 0, !1),s=_react.useRef.call(void 0, !1),P=_react.useRef.call(void 0, !1),p=_react.useCallback.call(void 0, e=>{let t=n.current.rowKey,u=typeof t=="function"?t(e):_machtable.getByPath.call(void 0, e,t);if(u==null||String(u).length===0)throw new Error(`[MachTable] useMachTableQuery rowKey "${String(t)}" returned an empty value.`);return String(u)},[]),I=_react.useCallback.call(void 0, e=>C.current?!c.current.has(e):y.current.has(e),[]),x=_react.useCallback.call(void 0, ()=>W(),[]),B=_react.useCallback.call(void 0, ()=>{let e=Q.current;if(!(!e||e.isDestroyed())){P.current=!0;try{e.selection.setRows(o.current.rows.filter(t=>I(p(t))),!0)}finally{P.current=!1}}},[p,I]),ae=_react.useCallback.call(void 0, ()=>{f.current++,_optionalChain([a, 'access', _31 => _31.current, 'optionalAccess', _32 => _32.abort, 'call', _33 => _33()]),a.current=null,l.current&&clearTimeout(l.current),l.current=null,A(!1)},[]),X=_react.useCallback.call(void 0, (e,t)=>e.signal.aborted||t!==f.current,[]),oe=_react.useCallback.call(void 0, (e,t,u)=>{if(X(t,u))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 d=[...e.rows];for(let Z of d){let _=p(Z);I(_)?h.current.set(_,Z):h.current.delete(_)}o.current.rows=d,F(d),O(Math.floor(e.total)),x(),_optionalChain([n, 'access', _34 => _34.current, 'access', _35 => _35.onSuccess, 'optionalCall', _36 => _36(e)]),queueMicrotask(B)},[X,x,p,I,B]),le=_react.useCallback.call(void 0, (e,t,u)=>{if(X(t,u)||qe(e))return;let d=_nullishCoalesce(e, () => (new Error("Remote request failed")));i(d),_optionalChain([n, 'access', _37 => _37.current, 'access', _38 => _38.onError, 'optionalCall', _39 => _39(d)])},[X]),ie=_react.useCallback.call(void 0, (e,t)=>{t===f.current&&(A(!1),a.current===e&&(a.current=null))},[]),M=_react.useCallback.call(void 0, async()=>{l.current&&clearTimeout(l.current),l.current=null,_optionalChain([a, 'access', _40 => _40.current, 'optionalAccess', _41 => _41.abort, 'call', _42 => _42()]);let e=new AbortController;a.current=e;let t=++f.current;A(!0),i(null),n.current.keepPreviousData===!1&&(o.current.rows=[],F([]));let u=o.current;try{let d=await n.current.request({page:u.page,pageSize:u.pageSize,query:Ue(n.current.query),sortModel:u.sortModel.map(Z=>({...Z})),filterModel:{...u.filterModel},advancedFilterModel:_machtable.normalizeAdvancedFilterModel.call(void 0, u.advancedFilterModel),quickFilterText:u.quickFilterText,signal:e.signal});oe(d,e,t)}catch(d){le(d,e,t)}finally{ie(e,t)}},[oe,ie,le]),N=_react.useCallback.call(void 0, e=>{e&&(o.current.page=1,b(1)),_optionalChain([a, 'access', _43 => _43.current, 'optionalAccess', _44 => _44.abort, 'call', _45 => _45()]),a.current=null;let t=Math.max(0,_nullishCoalesce(n.current.debounceMs, () => (0)));l.current&&clearTimeout(l.current),t===0?M():l.current=setTimeout(()=>{M()},t)},[M]),L=_react.useCallback.call(void 0, ()=>{let e=C.current||y.current.size>0||c.current.size>0||h.current.size>0;C.current=!1,y.current.clear(),c.current.clear(),h.current.clear(),e&&x(),P.current=!0;try{_optionalChain([Q, 'access', _46 => _46.current, 'optionalAccess', _47 => _47.selection, 'access', _48 => _48.clear, 'call', _49 => _49()])}finally{P.current=!1}},[x]),se=_react.useCallback.call(void 0, e=>{if(s.current)return;let t=o.current;e.page===t.page&&e.pageSize===t.pageSize||(t.page=e.page,t.pageSize=e.pageSize,b(e.page),U(e.pageSize),n.current.mode!=="manual"&&M())},[M]),ce=_react.useCallback.call(void 0, e=>{if(s.current)return;let t=e.sortModel.map(u=>({...u}));o.current.sortModel=t,m(t),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))},[N]),ue=_react.useCallback.call(void 0, e=>{if(s.current)return;let t={...e.filterModel};o.current.filterModel=t;let u=_machtable.normalizeAdvancedFilterModel.call(void 0, e.advancedFilterModel);o.current.advancedFilterModel=u,o.current.quickFilterText=e.api.filtering.getQuickText(),j(t),$(u),V(o.current.quickFilterText),n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))},[L,N]),de=_react.useCallback.call(void 0, e=>{if(P.current)return;let t=new Set(o.current.rows.map(p)),u=new Set(e.selectedRows.map(p));if(C.current)for(let d of t)u.has(d)?c.current.delete(d):(c.current.add(d),h.current.delete(d));else{if((_nullishCoalesce(n.current.selectionScope, () => ("preserve")))==="page")y.current.clear(),h.current.clear();else for(let d of t)y.current.delete(d),h.current.delete(d);for(let d of e.selectedRows)y.current.add(p(d))}for(let d of e.selectedRows)h.current.set(p(d),d);x()},[x,p]),Re=_react.useCallback.call(void 0, async(e={})=>{e.resetPage&&(o.current.page=1,b(1)),await M()},[M]),we=_react.useCallback.call(void 0, async()=>{o.current.page=1,o.current.sortModel=[],o.current.filterModel={},o.current.advancedFilterModel=null,o.current.quickFilterText=null,b(1),m([]),j({}),$(null),V(null),L(),s.current=!0;try{_optionalChain([Q, 'access', _50 => _50.current, 'optionalAccess', _51 => _51.sorting, 'access', _52 => _52.setModel, 'call', _53 => _53(null)]),_optionalChain([Q, 'access', _54 => _54.current, 'optionalAccess', _55 => _55.filtering, 'access', _56 => _56.setModel, 'call', _57 => _57(null)]),_optionalChain([Q, 'access', _58 => _58.current, 'optionalAccess', _59 => _59.filtering, 'access', _60 => _60.setAdvancedModel, 'call', _61 => _61(null)]),_optionalChain([Q, 'access', _62 => _62.current, 'optionalAccess', _63 => _63.filtering, 'access', _64 => _64.setQuickText, 'call', _65 => _65(null)])}finally{s.current=!1}await M()},[L,M]),De=_react.useCallback.call(void 0, ()=>{C.current=!0,y.current.clear(),c.current.clear(),h.current.clear();for(let e of o.current.rows)h.current.set(p(e),e);x(),B()},[x,p,B]),Ce=_react.useCallback.call(void 0, e=>{y.current.clear(),c.current.clear(),h.current.clear(),C.current=e.mode==="allMatching";for(let t of(e.mode==="allMatching"?e.excludedKeys:e.selectedKeys).map(String))e.mode==="allMatching"?c.current.add(t):y.current.add(t);for(let t of o.current.rows)I(p(t))&&h.current.set(p(t),t);x(),B()},[x,p,I,B]),Y=r.queryKey===void 0?r.query:r.queryKey,fe=_react.useRef.call(void 0, Y);_react.useEffect.call(void 0, ()=>{Object.is(fe.current,Y)||(fe.current=Y,n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1)))},[Y,L,N]),_react.useEffect.call(void 0, ()=>(r.mode!=="manual"&&r.immediate!==!1&&M(),ae),[]);let ge=_react.useMemo.call(void 0, ()=>{let e=[...new Set((_nullishCoalesce(r.pageSizeOptions, () => ([10,20,50,100]))).map(t=>ne(t,0)).filter(Boolean))];return e.includes(g)||e.push(g),e.sort((t,u)=>t-u)},[r.pageSizeOptions,g]),xe=_react.useMemo.call(void 0, ()=>({rowData:R,loading:k,error:E,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:G,quickFilterText:K,overlayErrorTemplate:E?()=>_nullishCoalesce(_optionalChain([n, 'access', _66 => _66.current, 'access', _67 => _67.errorOverlay, 'optionalCall', _68 => _68({error:E,retry:M})]), () => ("Remote request failed. Please retry.")):void 0,overlayNoRowsTemplate:r.emptyOverlay,pagination:{mode:"server",page:w,pageSize:g,pageSizeOptions:ge,total:v,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{Q.current=e,queueMicrotask(B)},onPaginationChanged:se,onSortChanged:ce,onFilterChanged:ue,onSelectionChanged:de}),[G,E,M,k,ue,se,de,ce,r.emptyOverlay,w,g,ge,K,p,R,B,v]),ye=C.current?[]:[...y.current],ke=[...h.current.entries()].filter(([e])=>!c.current.has(e)).map(([,e])=>e),Ee=C.current?{mode:"allMatching",excludedKeys:[...c.current]}:{mode:"explicit",selectedKeys:ye};return{rows:R,loading:k,error:E,page:w,pageSize:g,total:v,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,setQuickFilterText(e){if(o.current.quickFilterText!==e){o.current.quickFilterText=e,V(e),s.current=!0;try{_optionalChain([Q, 'access', _69 => _69.current, 'optionalAccess', _70 => _70.filtering, 'access', _71 => _71.setQuickText, 'call', _72 => _72(e)])}finally{s.current=!1}n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))}},selectedKeys:ye,selectedRows:ke,selectionState:Ee,bindings:xe,reload:Re,retry:M,reset:we,abort:ae,clearSelection:L,selectAllMatching:De,applySelectionState:Ce}}function Ae(r={}){let n=_chunkII7TCYIUcjs.a.call(void 0, ),R=te(n,r.editing),[F,k]=_react.useState.call(void 0, _nullishCoalesce(r.initialSearch, () => (""))),[A,E]=_react.useState.call(void 0, []),i=_nullishCoalesce(r.query, () => (null));_react.useEffect.call(void 0, ()=>{let v=n.api;if(i)return;if(!v||v.isDestroyed()){E(D=>D.length?[]:D);return}let O=()=>E(v.selection.getRows());return O(),v.on("selectionChanged",O)},[i,n.api]),_react.useEffect.call(void 0, ()=>{i?i.setQuickFilterText(F||null):_optionalChain([n, 'access', _73 => _73.apiRef, 'access', _74 => _74.current, 'optionalAccess', _75 => _75.filtering, 'access', _76 => _76.setQuickText, 'call', _77 => _77(F||null)])},[i,F,n.api,n.apiRef]);let w=_react.useMemo.call(void 0, ()=>async()=>{i?await i.reload():_optionalChain([n, 'access', _78 => _78.apiRef, 'access', _79 => _79.current, 'optionalAccess', _80 => _80.rows, 'access', _81 => _81.isRemote, 'call', _82 => _82()])?await n.apiRef.current.rows.reload():_optionalChain([n, 'access', _83 => _83.apiRef, 'access', _84 => _84.current, 'optionalAccess', _85 => _85.view, 'access', _86 => _86.refreshCells, 'call', _87 => _87()])},[i,n.apiRef]),b=_react.useMemo.call(void 0, ()=>_machtable.createMachTableCommands.call(void 0, {getApi:()=>n.apiRef.current,reload:w}),[w,n.apiRef]),g=_nullishCoalesce(_optionalChain([i, 'optionalAccess', _88 => _88.selectedRows]), () => (A)),U=i?i.selectionState.mode==="allMatching"?Math.max(0,i.total-i.selectionState.excludedKeys.length):i.selectionState.selectedKeys.length:g.length;return{table:n,query:i,editing:R,bindings:_nullishCoalesce(_optionalChain([i, 'optionalAccess', _89 => _89.bindings]), () => ({})),search:F,setSearch:k,selectedRows:g,selectedCount:U,busy:_optionalChain([i, 'optionalAccess', _90 => _90.loading])===!0||R.saving,error:_nullishCoalesce(_nullishCoalesce(_optionalChain([i, 'optionalAccess', _91 => _91.error]), () => (R.saveError)), () => (null)),commands:b,reload:w}}exports.useMachTableController = Ae; exports.useMachTableEditing = te; exports.useMachTableQuery = Oe;
package/dist/workflows.js CHANGED
@@ -1 +1 @@
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};
1
+ import{a as pe}from"./chunk-FN4LWAOL.js";import{useCallback as H,useEffect as Te,useMemo as ee,useRef as re,useState as J}from"react";import{resolveSaveConflict as Qe}from"@agile-team/mach-table";function te(r,n={}){let[R,F]=J([]),[k,A]=J([]),[E,i]=J(!1),[w,b]=J(null),[g,U]=J(null),v=re(!1),O=re(0),D=re(null),m=H(()=>{let a=r.apiRef.current;if(!a||a.isDestroyed()){A([]),F([]);return}A(a.editing.getDirtyRowIds()),F(a.editing.getChanges())},[r.apiRef]);Te(()=>{let a=r.api;O.current++,v.current=!1,i(!1),b(null),U(null),D.current=null,m();let l=a&&!a.isDestroyed()?a.on("dirtyStateChanged",m):void 0;return()=>{O.current++,l?.()}},[r.api,m]);let z=H(async(a,l)=>{let f=r.apiRef.current;if(!f||f.isDestroyed())throw new Error("[MachTable] Cannot save before the grid is ready.");if(v.current)throw new Error("[MachTable] A save operation is already in progress.");v.current=!0,i(!0),b(null),U(null),D.current=null;let y=O.current,c=()=>y===O.current&&r.apiRef.current===f&&!f.isDestroyed(),h=f.editing.getDirtyRowIds().filter(s=>!l||l.includes(s)).map(s=>{let P=f.rows.getById(s);return{rowId:s,node:P,data:P?.data}}),C=s=>{let P=s===void 0?h:h.filter(p=>p.rowId===s);return c()&&P.every(({rowId:p,node:I,data:x})=>f.rows.getById(p)===I&&I?.data===x)};try{let s=await f.editing.save(a,l);return C()&&(D.current=C,U(s),m(),n.onSaveSuccess?.(s.saved),n.onSaveResult?.(s)),s}catch(s){throw C()&&(b(s),n.onSaveError?.(s)),s}finally{c()&&(v.current=!1,i(!1))}},[n,m,r.apiRef]),j=H(async(a,l)=>(await z(a,l)).saved,[z]),G=H(()=>{D.current=null,U(null)},[]),$=H((a,l)=>{let f=g?.conflicts.find(c=>c.rowId===a),y=r.apiRef.current;return!g||!f||!y||!D.current?.(a)||!Qe(y,f,l)?!1:(U(c=>c&&{...c,conflicts:c.conflicts.filter(h=>h.rowId!==a)}),m(),!0)},[g,m,r.apiRef]),K=H(a=>{let l=r.apiRef.current?.editing.rollback(a)??!1;return m(),l},[m,r.apiRef]),V=H(a=>{r.apiRef.current?.editing.markSaved(a),m()},[m,r.apiRef]),W=H((a,l,f=!1)=>{let y=r.apiRef.current,c=y?.rows.getById(a);return!y||!c||c.rowIndex<0?!1:(y.view.scrollToRow(c.rowIndex,"middle"),l&&f?y.editing.startCell({rowIndex:c.rowIndex,colId:l}):!0)},[r.apiRef]);Te(()=>{if(!n.guardBeforeUnload||typeof window>"u")return;let a=l=>{if(k.length===0)return;let f=n.beforeUnloadMessage??"\u5B58\u5728\u672A\u4FDD\u5B58\u7684\u8868\u683C\u4FEE\u6539\u3002";return l.preventDefault(),l.returnValue=f,f};return window.addEventListener("beforeunload",a),()=>window.removeEventListener("beforeunload",a)},[k.length,n.beforeUnloadMessage,n.guardBeforeUnload]);let o=ee(()=>[...g?.failures??[],...g?.conflicts??[]],[g]),Q=ee(()=>[...new Set(o.map(a=>a.rowId))],[o]);return ee(()=>({changes:R,dirtyRowIds:k,dirty:k.length>0,saving:E,saveError:w,lastSaveResult:g,saveIssues:o,failedRowIds:Q,save:j,saveDetailed:z,clearSaveIssues:G,resolveConflict:$,rollback:K,markSaved:V,reveal:W,refresh:m}),[R,G,k,Q,g,V,m,$,W,K,j,z,w,o,E])}import{useCallback as T,useEffect as he,useMemo as me,useReducer as Fe,useRef as S,useState as q}from"react";import{getByPath as Pe,normalizeAdvancedFilterModel as be}from"@agile-team/mach-table";function ne(r,n){return typeof r=="number"&&Number.isFinite(r)&&r>0?Math.floor(r):n}function qe(r){return(r instanceof DOMException||typeof r=="object"&&r!=null&&"name"in r)&&r.name==="AbortError"}function Ue(r){return typeof r=="function"?r():r}function Oe(r){let n=S(r);n.current=r;let[R,F]=q([]),[k,A]=q(!1),[E,i]=q(null),[w,b]=q(ne(r.initialPage,1)),[g,U]=q(ne(r.pageSize,20)),[v,O]=q(0),[D,m]=q([]),[z,j]=q({}),[G,$]=q(null),[K,V]=q(r.initialQuickFilterText??null),[,W]=Fe(e=>e+1,0),o=S({page:w,pageSize:g,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,rows:R});o.current={page:w,pageSize:g,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,rows:R};let Q=S(null),a=S(null),l=S(null),f=S(0),y=S(new Set),c=S(new Set),h=S(new Map),C=S(!1),s=S(!1),P=S(!1),p=T(e=>{let t=n.current.rowKey,u=typeof t=="function"?t(e):Pe(e,t);if(u==null||String(u).length===0)throw new Error(`[MachTable] useMachTableQuery rowKey "${String(t)}" returned an empty value.`);return String(u)},[]),I=T(e=>C.current?!c.current.has(e):y.current.has(e),[]),x=T(()=>W(),[]),B=T(()=>{let e=Q.current;if(!(!e||e.isDestroyed())){P.current=!0;try{e.selection.setRows(o.current.rows.filter(t=>I(p(t))),!0)}finally{P.current=!1}}},[p,I]),ae=T(()=>{f.current++,a.current?.abort(),a.current=null,l.current&&clearTimeout(l.current),l.current=null,A(!1)},[]),X=T((e,t)=>e.signal.aborted||t!==f.current,[]),oe=T((e,t,u)=>{if(X(t,u))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 d=[...e.rows];for(let Z of d){let _=p(Z);I(_)?h.current.set(_,Z):h.current.delete(_)}o.current.rows=d,F(d),O(Math.floor(e.total)),x(),n.current.onSuccess?.(e),queueMicrotask(B)},[X,x,p,I,B]),le=T((e,t,u)=>{if(X(t,u)||qe(e))return;let d=e??new Error("Remote request failed");i(d),n.current.onError?.(d)},[X]),ie=T((e,t)=>{t===f.current&&(A(!1),a.current===e&&(a.current=null))},[]),M=T(async()=>{l.current&&clearTimeout(l.current),l.current=null,a.current?.abort();let e=new AbortController;a.current=e;let t=++f.current;A(!0),i(null),n.current.keepPreviousData===!1&&(o.current.rows=[],F([]));let u=o.current;try{let d=await n.current.request({page:u.page,pageSize:u.pageSize,query:Ue(n.current.query),sortModel:u.sortModel.map(Z=>({...Z})),filterModel:{...u.filterModel},advancedFilterModel:be(u.advancedFilterModel),quickFilterText:u.quickFilterText,signal:e.signal});oe(d,e,t)}catch(d){le(d,e,t)}finally{ie(e,t)}},[oe,ie,le]),N=T(e=>{e&&(o.current.page=1,b(1)),a.current?.abort(),a.current=null;let t=Math.max(0,n.current.debounceMs??0);l.current&&clearTimeout(l.current),t===0?M():l.current=setTimeout(()=>{M()},t)},[M]),L=T(()=>{let e=C.current||y.current.size>0||c.current.size>0||h.current.size>0;C.current=!1,y.current.clear(),c.current.clear(),h.current.clear(),e&&x(),P.current=!0;try{Q.current?.selection.clear()}finally{P.current=!1}},[x]),se=T(e=>{if(s.current)return;let t=o.current;e.page===t.page&&e.pageSize===t.pageSize||(t.page=e.page,t.pageSize=e.pageSize,b(e.page),U(e.pageSize),n.current.mode!=="manual"&&M())},[M]),ce=T(e=>{if(s.current)return;let t=e.sortModel.map(u=>({...u}));o.current.sortModel=t,m(t),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))},[N]),ue=T(e=>{if(s.current)return;let t={...e.filterModel};o.current.filterModel=t;let u=be(e.advancedFilterModel);o.current.advancedFilterModel=u,o.current.quickFilterText=e.api.filtering.getQuickText(),j(t),$(u),V(o.current.quickFilterText),n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))},[L,N]),de=T(e=>{if(P.current)return;let t=new Set(o.current.rows.map(p)),u=new Set(e.selectedRows.map(p));if(C.current)for(let d of t)u.has(d)?c.current.delete(d):(c.current.add(d),h.current.delete(d));else{if((n.current.selectionScope??"preserve")==="page")y.current.clear(),h.current.clear();else for(let d of t)y.current.delete(d),h.current.delete(d);for(let d of e.selectedRows)y.current.add(p(d))}for(let d of e.selectedRows)h.current.set(p(d),d);x()},[x,p]),Re=T(async(e={})=>{e.resetPage&&(o.current.page=1,b(1)),await M()},[M]),we=T(async()=>{o.current.page=1,o.current.sortModel=[],o.current.filterModel={},o.current.advancedFilterModel=null,o.current.quickFilterText=null,b(1),m([]),j({}),$(null),V(null),L(),s.current=!0;try{Q.current?.sorting.setModel(null),Q.current?.filtering.setModel(null),Q.current?.filtering.setAdvancedModel(null),Q.current?.filtering.setQuickText(null)}finally{s.current=!1}await M()},[L,M]),De=T(()=>{C.current=!0,y.current.clear(),c.current.clear(),h.current.clear();for(let e of o.current.rows)h.current.set(p(e),e);x(),B()},[x,p,B]),Ce=T(e=>{y.current.clear(),c.current.clear(),h.current.clear(),C.current=e.mode==="allMatching";for(let t of(e.mode==="allMatching"?e.excludedKeys:e.selectedKeys).map(String))e.mode==="allMatching"?c.current.add(t):y.current.add(t);for(let t of o.current.rows)I(p(t))&&h.current.set(p(t),t);x(),B()},[x,p,I,B]),Y=r.queryKey===void 0?r.query:r.queryKey,fe=S(Y);he(()=>{Object.is(fe.current,Y)||(fe.current=Y,n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1)))},[Y,L,N]),he(()=>(r.mode!=="manual"&&r.immediate!==!1&&M(),ae),[]);let ge=me(()=>{let e=[...new Set((r.pageSizeOptions??[10,20,50,100]).map(t=>ne(t,0)).filter(Boolean))];return e.includes(g)||e.push(g),e.sort((t,u)=>t-u)},[r.pageSizeOptions,g]),xe=me(()=>({rowData:R,loading:k,error:E,rowKey:p,manualSorting:!0,manualFiltering:!0,advancedFilterModel:G,quickFilterText:K,overlayErrorTemplate:E?()=>n.current.errorOverlay?.({error:E,retry:M})??"Remote request failed. Please retry.":void 0,overlayNoRowsTemplate:r.emptyOverlay,pagination:{mode:"server",page:w,pageSize:g,pageSizeOptions:ge,total:v,showTotal:!0,showPageSizeSelector:!0},onGridReady:({api:e})=>{Q.current=e,queueMicrotask(B)},onPaginationChanged:se,onSortChanged:ce,onFilterChanged:ue,onSelectionChanged:de}),[G,E,M,k,ue,se,de,ce,r.emptyOverlay,w,g,ge,K,p,R,B,v]),ye=C.current?[]:[...y.current],ke=[...h.current.entries()].filter(([e])=>!c.current.has(e)).map(([,e])=>e),Ee=C.current?{mode:"allMatching",excludedKeys:[...c.current]}:{mode:"explicit",selectedKeys:ye};return{rows:R,loading:k,error:E,page:w,pageSize:g,total:v,sortModel:D,filterModel:z,advancedFilterModel:G,quickFilterText:K,setQuickFilterText(e){if(o.current.quickFilterText!==e){o.current.quickFilterText=e,V(e),s.current=!0;try{Q.current?.filtering.setQuickText(e)}finally{s.current=!1}n.current.clearSelectionOnQueryChange!==!1&&L(),n.current.mode!=="manual"?N(!0):(o.current.page=1,b(1))}},selectedKeys:ye,selectedRows:ke,selectionState:Ee,bindings:xe,reload:Re,retry:M,reset:we,abort:ae,clearSelection:L,selectAllMatching:De,applySelectionState:Ce}}import{useEffect as ve,useMemo as Me,useState as Se}from"react";import{createMachTableCommands as Ie}from"@agile-team/mach-table";function Ae(r={}){let n=pe(),R=te(n,r.editing),[F,k]=Se(r.initialSearch??""),[A,E]=Se([]),i=r.query??null;ve(()=>{let v=n.api;if(i)return;if(!v||v.isDestroyed()){E(D=>D.length?[]:D);return}let O=()=>E(v.selection.getRows());return O(),v.on("selectionChanged",O)},[i,n.api]),ve(()=>{i?i.setQuickFilterText(F||null):n.apiRef.current?.filtering.setQuickText(F||null)},[i,F,n.api,n.apiRef]);let w=Me(()=>async()=>{i?await i.reload():n.apiRef.current?.rows.isRemote()?await n.apiRef.current.rows.reload():n.apiRef.current?.view.refreshCells()},[i,n.apiRef]),b=Me(()=>Ie({getApi:()=>n.apiRef.current,reload:w}),[w,n.apiRef]),g=i?.selectedRows??A,U=i?i.selectionState.mode==="allMatching"?Math.max(0,i.total-i.selectionState.excludedKeys.length):i.selectionState.selectedKeys.length:g.length;return{table:n,query:i,editing:R,bindings:i?.bindings??{},search:F,setSearch:k,selectedRows:g,selectedCount:U,busy:i?.loading===!0||R.saving,error:i?.error??R.saveError??null,commands:b,reload:w}}export{Ae as useMachTableController,te 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.31.1",
3
+ "version": "0.31.2",
4
4
  "description": "Official React 18+ adapter for the MachTable enterprise data grid",
5
5
  "keywords": [
6
6
  "react",
@@ -97,7 +97,7 @@
97
97
  "**/*.css"
98
98
  ],
99
99
  "dependencies": {
100
- "@agile-team/mach-table": "0.31.1"
100
+ "@agile-team/mach-table": "0.31.2"
101
101
  },
102
102
  "peerDependencies": {
103
103
  "react": ">=18.0.0",
@@ -113,5 +113,5 @@
113
113
  "test": "vitest run",
114
114
  "test:coverage": "vitest run --coverage"
115
115
  },
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.31.1 的官方 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, indexColumn, 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 () => [indexColumn({ headerName: \"序号\" }), { 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## 行拖拽与条件整行颜色\n\n```ts\nimport { dragColumn, type GridOptions } from \"@agile-team/mach-table-react\";\n\ninterface Plan { id: string; name: string; status: string }\nconst options: GridOptions<Plan> = {\n rowKey: \"id\",\n columnDefs: [dragColumn(), { field: \"name\" }, { field: \"status\" }],\n rowStyleRules: [\n { when: ({ data }) => data.status === \"pending\", tone: \"warning\" },\n { when: ({ data }) => data.status === \"failed\", tone: \"danger\" },\n { when: ({ data }) => data.status === \"done\", tone: \"success\" }\n ]\n};\n```\n\n状态码由应用定义,包内不识别业务状态。颜色规则取第一条命中结果,未命中时沿用默认样式;支持自定义背景/文字颜色、固定列、明暗主题、选择和虚拟行复用。拖拽提供主题手柄、落点线、位置浮层、边缘滚动、Esc 取消和 Alt + ↑/↓ 移动。扁平外部数据设置 `applyRowDrag: false`,由 `onRowDragEnd` 处理持久化;自动模式先完成移动再发出事件,使用 `targetIndex` 读取最终下标。树、分组及排序等自动模式限制见[完整配方](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/recipes/row-presentation.md)。\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"
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.31.2 的官方 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, indexColumn, 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 () => [indexColumn({ headerName: \"序号\" }), { 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编辑、粘贴、清空和填充复用已有列与整行校验。`useMachTableEditing()` 隔离重挂载或数据替换前的保存结果、错误和冲突;查询工作流在 StrictMode 下保留 `immediate: false`,重复设置相同搜索值不会重新请求。\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## 行拖拽与条件整行颜色\n\n```ts\nimport { dragColumn, type GridOptions } from \"@agile-team/mach-table-react\";\n\ninterface Plan { id: string; name: string; status: string }\nconst options: GridOptions<Plan> = {\n rowKey: \"id\",\n columnDefs: [dragColumn(), { field: \"name\" }, { field: \"status\" }],\n rowStyleRules: [\n { when: ({ data }) => data.status === \"pending\", tone: \"warning\" },\n { when: ({ data }) => data.status === \"failed\", tone: \"danger\" },\n { when: ({ data }) => data.status === \"done\", tone: \"success\" }\n ]\n};\n```\n\n状态码由应用定义,包内不识别业务状态。颜色规则取第一条命中结果,未命中时沿用默认样式;支持自定义背景/文字颜色、固定列、明暗主题、选择和虚拟行复用。拖拽提供主题手柄、落点线、位置浮层、边缘滚动、Esc 取消和 Alt + ↑/↓ 移动。扁平外部数据设置 `applyRowDrag: false`,由 `onRowDragEnd` 处理持久化;自动模式先完成移动再发出事件,使用 `targetIndex` 读取最终下标。树、分组及排序等自动模式限制见[完整配方](https://github.com/ChenyCHENYU/MachTable/blob/main/docs/recipes/row-presentation.md)。\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"
117
117
  }