@qfei-design/make-app-approval 0.0.0-stage → 0.2.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.
- package/PUBLIC_API.md +147 -0
- package/README.md +65 -2
- package/capabilities.json +76 -0
- package/dist/detail/approval-task-detail.d.ts +2 -0
- package/dist/detail/diagnostics.d.ts +2 -0
- package/dist/detail/field-value.d.ts +2 -0
- package/dist/detail/index.d.ts +3 -0
- package/dist/detail/task-policy.d.ts +18 -0
- package/dist/detail/types.d.ts +111 -0
- package/dist/detail.cjs +1 -0
- package/dist/detail.mjs +500 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.mjs +28 -0
- package/dist/list/approval-table.d.ts +14 -0
- package/dist/list/diagnostics.d.ts +3 -0
- package/dist/list/index.d.ts +3 -0
- package/dist/list/my-approvals-page.d.ts +2 -0
- package/dist/list/page-contract.d.ts +3 -0
- package/dist/list/status-label.d.ts +1 -0
- package/dist/list/types.d.ts +71 -0
- package/dist/list/ui-components.d.ts +51 -0
- package/dist/list/use-approval-page.d.ts +12 -0
- package/dist/list/virtual-page-loader.d.ts +26 -0
- package/dist/list.cjs +1 -0
- package/dist/list.mjs +387 -0
- package/dist/react/index.d.ts +7 -0
- package/dist/react.cjs +1 -0
- package/dist/react.mjs +17 -0
- package/dist/styles.css +102 -0
- package/dist/styles.css.d.ts +1 -0
- package/dist/withdrawal.d.ts +14 -0
- package/docs/host-integration.md +242 -0
- package/docs/implementation-plan.md +61 -0
- package/docs/publishing.md +108 -0
- package/examples/antd-components.tsx +40 -0
- package/examples/detail-integration.tsx +80 -0
- package/examples/host-integration.tsx +36 -0
- package/package.ai.json +85 -0
- package/package.json +117 -4
- package/recipes.json +114 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from "react";
|
|
2
|
+
import type { ApprovalListTab, ApprovalStatusOption } from "./types.js";
|
|
3
|
+
/** 宿主将组件库事件转换成值;包不依赖 DOM Event 或任何日期库对象。 */
|
|
4
|
+
export type ApprovalInputProps = Readonly<{
|
|
5
|
+
id: string;
|
|
6
|
+
ariaLabel: string;
|
|
7
|
+
value: string;
|
|
8
|
+
onChange: (value: string) => void;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
export type ApprovalSelectProps = ApprovalInputProps & Readonly<{
|
|
13
|
+
options: readonly ApprovalStatusOption[];
|
|
14
|
+
}>;
|
|
15
|
+
/** 一个完整范围控件;日期为 YYYY-MM-DD,清空回传 ["", ""]。 */
|
|
16
|
+
export type ApprovalDateRangePickerProps = Readonly<{
|
|
17
|
+
id: string;
|
|
18
|
+
ariaLabel: string;
|
|
19
|
+
value: readonly [string, string];
|
|
20
|
+
onChange: (value: readonly [string, string]) => void;
|
|
21
|
+
placeholder?: readonly [string, string];
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
export type ApprovalButtonProps = Readonly<{
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
htmlType: "button" | "submit";
|
|
27
|
+
variant: "primary" | "default" | "text";
|
|
28
|
+
onClick?: () => void;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
ariaLabel?: string;
|
|
32
|
+
}>;
|
|
33
|
+
export type ApprovalTabsProps = Readonly<{
|
|
34
|
+
items: readonly Readonly<{
|
|
35
|
+
value: ApprovalListTab;
|
|
36
|
+
label: string;
|
|
37
|
+
}>[];
|
|
38
|
+
value: ApprovalListTab;
|
|
39
|
+
onChange: (value: ApprovalListTab) => void;
|
|
40
|
+
ariaLabel: string;
|
|
41
|
+
/** 仅在当前激活的面板渲染一次;宿主 Tabs 负责键盘与 tab/panel 关联。 */
|
|
42
|
+
children: ReactNode;
|
|
43
|
+
}>;
|
|
44
|
+
/** 必须由宿主完整提供;应在模块作用域定义,避免重渲染时创建新的组件类型。 */
|
|
45
|
+
export type ApprovalUIComponents = Readonly<{
|
|
46
|
+
Input: ComponentType<ApprovalInputProps>;
|
|
47
|
+
Select: ComponentType<ApprovalSelectProps>;
|
|
48
|
+
DateRangePicker: ComponentType<ApprovalDateRangePickerProps>;
|
|
49
|
+
Button: ComponentType<ApprovalButtonProps>;
|
|
50
|
+
Tabs: ComponentType<ApprovalTabsProps>;
|
|
51
|
+
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ApprovalListQuery, ApprovalListProvider, ApprovalLogger, ApprovalPage } from "./types.js";
|
|
2
|
+
type LoadState = ApprovalPage & {
|
|
3
|
+
token: object;
|
|
4
|
+
status: "success" | "error";
|
|
5
|
+
};
|
|
6
|
+
export declare const useApprovalPage: (provider: ApprovalListProvider, query: ApprovalListQuery, refreshKey: string | number | undefined, logger?: ApprovalLogger) => {
|
|
7
|
+
initialPage: LoadState | undefined;
|
|
8
|
+
total: number;
|
|
9
|
+
status: string;
|
|
10
|
+
reload: () => void;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CanvasTableComponent, IVirtualPageRequestContext } from "@qfei-design/canvas-table";
|
|
2
|
+
import type { ApprovalListItem, ApprovalListProvider, ApprovalListQuery, ApprovalLogger, ApprovalPage } from "./types.js";
|
|
3
|
+
export type VirtualListSnapshot = Readonly<{
|
|
4
|
+
total: number;
|
|
5
|
+
rows: readonly ApprovalListItem[];
|
|
6
|
+
failed: boolean;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
type Table = Pick<CanvasTableComponent, "setVirtualPageData" | "markPageLoadFailed" | "getPagesInView" | "getTableData" | "scrollToRow">;
|
|
10
|
+
/** 页面交互不暴露页码;这里只负责 Canvas 的零基数据页。 */
|
|
11
|
+
export declare const createVirtualPageLoader: ({ table, query, initialPage, loadPage, onChange, retryViewport, onReload, logger }: {
|
|
12
|
+
table: Table;
|
|
13
|
+
query: ApprovalListQuery;
|
|
14
|
+
initialPage: ApprovalPage;
|
|
15
|
+
loadPage: ApprovalListProvider["loadPage"];
|
|
16
|
+
onChange: (snapshot: VirtualListSnapshot) => void;
|
|
17
|
+
retryViewport: () => void;
|
|
18
|
+
onReload: () => void;
|
|
19
|
+
logger?: ApprovalLogger;
|
|
20
|
+
}) => {
|
|
21
|
+
load(page: number, request: IVirtualPageRequestContext): void;
|
|
22
|
+
viewportChanged(): void;
|
|
23
|
+
retry(): void;
|
|
24
|
+
dispose(): void;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
package/dist/list.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var ne=Object.create;var Z=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var ce=Object.getPrototypeOf,pe=Object.prototype.hasOwnProperty;var de=(e,t,i,I)=>{if(t&&typeof t=="object"||typeof t=="function")for(let P of ie(t))!pe.call(e,P)&&P!==i&&Z(e,P,{get:()=>t[P],enumerable:!(I=le(t,P))||I.enumerable});return e};var ue=(e,t,i)=>(i=e!=null?ne(ce(e)):{},de(t||!e||!e.__esModule?Z(i,"default",{value:e,enumerable:!0}):i,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),l=require("react"),fe=require("./index.cjs"),te=e=>e==null||e==="UNSUBMITTED"?"状态未知":fe.getApprovalStatusDisplay(e).label,z=(e,t)=>{try{e?e(t):t.phase==="error"?console.warn("[make-app-approval]",t):console.info("[make-app-approval]",t)}catch{console.warn("[make-app-approval] diagnostic sink failed")}},ae=e=>typeof e=="object"&&e!==null,ge=e=>ae(e)?["id","entityKey","recordId"].every(t=>typeof e[t]=="string"&&e[t].trim().length>0)&&["applicationNo","applicationType","applicantName","applicationTime"].every(t=>typeof e[t]=="string")&&["taskId","processInstanceId"].every(t=>e[t]===void 0||typeof e[t]=="string"&&e[t].trim().length>0)&&(typeof e.processStatus=="string"||e.processStatus===null):!1,Y=(e,t)=>{if(!ae(e)||!Array.isArray(e.rows)||!e.rows.every(ge)||typeof e.total!="number"||!Number.isSafeInteger(e.total)||e.total<0||e.rows.length>t||e.rows.length>e.total||new Set(e.rows.map(i=>i.id)).size!==e.rows.length)throw new Error("Invalid approval page contract");return{rows:e.rows,total:e.total}},he=({table:e,query:t,initialPage:i,loadPage:I,onChange:P,retryViewport:L,onReload:V,logger:C})=>{const f=new Map,A=new Set;let N=[];const u=new WeakMap,g=new Set;let b=i,h=i.total,p=0,k=!1,x=!1,R;const M=r=>Number.isSafeInteger(r)&&r>=0&&r*t.pageSize<h,v=(r,a,d)=>z(C,{operation:"list",phase:a,tab:t.tab,page:r+1,pageSize:t.pageSize,rowCount:d}),m=()=>{k||P({total:h,rows:N,failed:x||g.size>0,loading:f.size>0})},j=r=>{r.finished||(r.finished=!0,r.removeAbort(),f.get(r.page)===r&&f.delete(r.page),e.markPageLoadFailed(r.page,r.request),r.controller.abort(),v(r.page,"cancel"))},c=r=>{p=r;const a=e.getPagesInView()??[],d=new Set([p,...a].flatMap(n=>[n-1,n,n+1]).filter(M));for(const n of f.values())d.has(n.page)||j(n);for(const n of g)d.has(n)||g.delete(n)},D=(r,a,d)=>{const n=a.rows.map(w=>{const s={...w,statusLabel:te(w.processStatus)};return u.set(s,w),s});if(!e.setVirtualPageData(n,r,a.total,d)){v(r,"skip");return}h=a.total;try{N=Y({rows:e.getTableData()??[],total:h},Number.MAX_SAFE_INTEGER).rows.map(w=>u.get(w)??w)}catch(w){x=!0,N=[],b=void 0,R&&clearTimeout(R),R=void 0;for(const s of f.values())j(s);throw w}b&&b.total!==h&&(b=void 0),g.delete(r);for(const w of f.values())M(w.page)||j(w);!M(r)&&r>0&&e.scrollToRow(Math.max(0,h-1)),v(r,"success",a.rows.length)},F=()=>{if(k||R)return;const r=[...f.values()].filter(a=>!a.running&&!a.finished).sort((a,d)=>Math.abs(a.page-p)-Math.abs(d.page-p)||a.page-d.page);for(const a of r){if(A.size>=2)break;a.running=!0,A.add(a),v(a.page,"start"),(async()=>{try{const d=await I({...t,page:a.page+1},{signal:a.controller.signal});if(k||a.finished||a.controller.signal.aborted)return;const n=Y(d,t.pageSize);a.finished=!0,a.removeAbort(),f.delete(a.page),D(a.page,n,a.request)}catch{!k&&!a.controller.signal.aborted&&(g.add(a.page),v(a.page,"error"),e.markPageLoadFailed(a.page,a.request))}finally{a.finished||(a.finished=!0,a.removeAbort(),f.get(a.page)===a&&f.delete(a.page)),A.delete(a),m(),F()}})()}m()},O=()=>{R&&clearTimeout(R),R=setTimeout(()=>{R=void 0,F()},120)};return{load(r,a){if(a.useRequestIdentity(),k||x||a.signal.aborted||!M(r)){e.markPageLoadFailed(r,a),v(r,"skip");return}const d=f.get(r);if(d?.request===a&&!d.finished)return;if(d&&j(d),c(r),r===0&&b){const w=b;b=void 0;try{D(0,w,a)}catch{g.add(r),e.markPageLoadFailed(r,a),v(r,"error")}m();return}const n={page:r,request:a,controller:new AbortController,running:!1,finished:!1,removeAbort:()=>{}},B=()=>{j(n),m()};a.signal.addEventListener("abort",B,{once:!0}),n.removeAbort=()=>a.signal.removeEventListener("abort",B),f.set(r,n),O(),m()},viewportChanged(){if(k)return;const r=e.getPagesInView();r?.length&&(c(r[0]),f.size&&O(),m())},retry(){if(!k){if(x){V();return}g.size!==0&&(g.clear(),L(),m())}},dispose(){k=!0,R&&clearTimeout(R),R=void 0;for(const r of f.values())j(r);N=[],g.clear(),b=void 0}}},me=[{key:"applicationNo",title:"申请单编号",width:260},{key:"applicationType",title:"申请单类型",width:180},{key:"applicantName",title:"申请人",width:170},{key:"applicationTime",title:"申请时间",width:220},{key:"statusLabel",title:"流程状态",width:140}].map(e=>({...e,showEllipsis:!0,sortable:!1})),q=40,ve=e=>{const t=l.useRef(void 0);return e.initialPage?o.jsx(be,{...e,initialPage:e.initialPage,restoreScroll:t.current?.query===e.query?t.current.position:void 0,rememberScroll:i=>{t.current={query:e.query,position:i}}}):o.jsx("div",{className:"make-app-approval-canvas",role:"group","aria-label":"审批记录表格"})},be=({components:{Button:e},initialPage:t,query:i,provider:I,themeKey:P,onOpen:L,onReload:V,logger:C,restoreScroll:f,rememberScroll:A})=>{const N=l.useRef(null),u=l.useRef(null),g=l.useRef(null),[b,h]=l.useState(!1),[p,k]=l.useState(0),[x,R]=l.useState({...t,failed:!1,loading:!1}),M=l.useRef(t.rows),v=l.useRef(f),m=l.useRef({provider:I,onOpen:L,onReload:V,logger:C,rememberScroll:A});m.current={provider:I,onOpen:L,onReload:V,logger:C,rememberScroll:A};const j=l.useRef(()=>{});return l.useEffect(()=>{const c=N.current;if(!c)return;let D=!1,F,O,r,a=t.total;z(m.current.logger,{operation:"table",phase:"start"});const d=()=>{D||(h(!0),z(m.current.logger,{operation:"table",phase:"error"}))};return import("@qfei-design/canvas-table").then(n=>{if(D)return;const B=()=>{const s=u.current,S=s?.getScrollState();s&&S&&n.globalEventBus.emitWithNamespace("scroll:change",s.tableId,S)},w=()=>{if(!D)try{const{width:s,height:S}=c.getBoundingClientRect();if(s<=0||S<=0)return;const E=getComputedStyle(c),G={rowHeight:q,headerHeight:40,fontSize:14,fontFamily:E.fontFamily||"Arial, sans-serif",...E.color?{textColor:E.color}:{},...E.getPropertyValue("--make-approval-bg").trim()?{rowBgColor:E.getPropertyValue("--make-approval-bg").trim()}:{},...E.getPropertyValue("--make-approval-header").trim()?{headerBgColor:E.getPropertyValue("--make-approval-header").trim()}:{},...E.getPropertyValue("--make-approval-border").trim()?{borderColor:E.getPropertyValue("--make-approval-border").trim()}:{}},re=Math.max(Math.ceil(300/i.pageSize),Math.ceil(S*3/q/i.pageSize)+2)*i.pageSize,J={enabled:!0,totalRowCount:a,pageSize:i.pageSize,maxCachedRows:re};if(u.current){u.current.updateProps({canvasWidth:s,canvasHeight:S,style:G,virtualOptions:J}),u.current.updateCanvasSize(s,S,!0),B();return}u.current=new n.CanvasTableComponent(c,{columns:me,canvasWidth:s,canvasHeight:S,style:G,rowKey:"id",showSN:{enabled:!0,width:64,formatter:(y,T)=>T+1},virtualOptions:J,selectable:{enabled:!1},rowSortable:{enabled:!1},editApplyMode:"controlled",customEdit:y=>{y.cancel()},emptyStateOptions:{text:"暂无审批记录"},bodyRowHeadSuffixOptions:{enabled:!0,width:20,render:({group:y,x:T,height:_,rowData:U})=>{const oe=U?.id,K=new n.RectShape({name:"approval-open",x:T,y:_/2-10,cursor:"pointer",tooltip:"查看审批详情",attrs:{width:20,height:20,fill:"transparent",stroke:"transparent"}});K.addChild(new n.ImgShape({name:"approval-open-icon",x:3,y:3,attrs:{width:14,height:14,img:"data:image/svg+xml;charset=utf-8,"+encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${E.color||"#64748b"}" stroke-width="1.8"><path d="M8 3H3v5m13-5h5v5M3 16v5h5m13-5v5h-5"/></svg>`)}})),K.on("mousedown",X=>X.stopPropagation?.()),K.on("click",X=>{X.stopPropagation?.();const Q=M.current.find(se=>se.id===oe);Q&&m.current.onOpen(Q)}),y.addChild(K)}}});const $=u.current,H=he({table:$,query:i,initialPage:t,retryViewport:B,onReload:()=>m.current.onReload(),loadPage:(y,T)=>m.current.provider.loadPage(y,T),logger:y=>z(m.current.logger,y),onChange:y=>{D||(a=y.total,M.current=y.rows,R(T=>T.total===y.total&&T.failed===y.failed&&T.loading===y.loading&&T.rows.length===y.rows.length&&T.rows.every((_,U)=>_===y.rows[U])?T:y))}});g.current=H,O=n.globalEventBus.onWithNamespace("data:load",$.tableId,(y,T)=>H.load(y,T)),r=n.globalEventBus.onWithNamespace("scroll:change",$.tableId,()=>H.viewportChanged()),v.current&&$.scrollTo(v.current.scrollX,v.current.scrollY),h(!1),z(m.current.logger,{operation:"table",phase:"success"})}catch{d()}};j.current=w,F=new ResizeObserver(w),F.observe(c),w()}).catch(d),()=>{D=!0,F?.disconnect(),j.current=()=>{},u.current&&(v.current=u.current.getScrollState(),v.current&&m.current.rememberScroll(v.current)),O?.(),r?.(),g.current?.dispose(),g.current=null,u.current?.destroy(),u.current=null,z(m.current.logger,{operation:"table",phase:"destroy"})}},[t,i,p]),l.useEffect(()=>{j.current()},[P]),o.jsxs("div",{className:"make-app-approval-table-frame","aria-busy":x.loading,children:[o.jsx("div",{ref:N,className:"make-app-approval-canvas",role:"group","aria-label":"审批记录表格"}),b&&o.jsxs("div",{className:"make-app-approval-overlay",role:"alert",children:["表格加载失败 ",o.jsx(e,{htmlType:"button",variant:"default",onClick:()=>{h(!1),k(c=>c+1)},children:"重新加载表格"})]}),!b&&x.failed&&o.jsxs("div",{className:"make-app-approval-table-feedback",role:"alert",children:["部分审批记录加载失败 ",o.jsx(e,{htmlType:"button",variant:"default",onClick:()=>g.current?.retry(),children:"重试加载"})]}),!b&&!x.failed&&x.loading&&o.jsxs("div",{className:"make-app-approval-table-loading",role:"status","aria-label":"正在加载审批记录","aria-live":"polite",children:[o.jsx("span",{className:"make-app-approval-loading-spinner","aria-hidden":"true"}),o.jsx("span",{children:"加载中"})]}),o.jsxs("ul",{className:"make-app-approval-accessible-rows","aria-label":"审批记录文字视图",children:[x.total===0&&o.jsx("li",{children:"暂无审批记录"}),x.rows.map(c=>o.jsxs("li",{children:[o.jsxs("span",{children:[c.applicationNo,",",c.applicationType,",",c.applicantName,",",c.applicationTime,",",te(c.processStatus),"。"]}),o.jsxs(e,{htmlType:"button",variant:"text",onClick:()=>L(c),children:["打开 ",c.applicationNo||c.applicationType," 的审批详情"]})]},c.id))]})]})},we=[],ye=(e,t,i,I)=>{const[P,L]=l.useState(0),[V,C]=l.useState(),f=l.useRef({provider:e,logger:I});f.current={provider:e,logger:I};const A=l.useMemo(()=>({}),[t,i,P]);l.useEffect(()=>{const u=new AbortController,{provider:g,logger:b}=f.current,h={operation:"list",tab:t.tab,page:t.page,pageSize:t.pageSize};z(b,{...h,phase:"start"});let p=!1;return(async()=>{try{const k=await g.loadPage(t,{signal:u.signal});if(u.signal.aborted)return;const x=Y(k,t.pageSize);p=!0,C({...x,token:A,status:"success"}),z(b,{...h,phase:"success",rowCount:x.rows.length})}catch{if(u.signal.aborted)return;p=!0,C({token:A,status:"error",rows:we,total:0}),z(b,{...h,phase:"error"})}})(),()=>{u.abort(),p||z(b,{...h,phase:"cancel"})}},[t,A]);const N=V?.token===A?V:void 0;return{initialPage:N?.status==="success"?N:void 0,total:N?.total??0,status:N?.status??"loading",reload:()=>L(u=>u+1)}},W={keyword:"",processStatus:"",startDate:"",endDate:""},Se=[{value:"pending",label:"待我处理"},{value:"approved",label:"已审批"}],ee=e=>{if(e==="")return!0;if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;const t=new Date(`${e}T00:00:00Z`);return Number.isFinite(t.getTime())&&t.toISOString().slice(0,10)===e},ke=({components:e,provider:t,onOpenApproval:i,statusOptions:I=[],pageSize:P=20,refreshKey:L,themeKey:V,logger:C,className:f})=>{const{Input:A,Select:N,DateRangePicker:u,Button:g,Tabs:b}=e,h=l.useId(),[p,k]=l.useState(W),[x,R]=l.useState(0),[M,v]=l.useState(""),[m,j]=l.useState(""),[c,D]=l.useState({...W,tab:"pending",page:1,pageSize:P}),{initialPage:F,status:O,reload:r}=ye(t,c,L,C),a=l.useRef(!1),d=l.useRef(!0);l.useEffect(()=>(d.current=!0,()=>{d.current=!1}),[]);const n=O==="loading",B=async s=>{if(!a.current){a.current=!0,j(""),z(C,{operation:"open",phase:"start"});try{await i(s),z(C,{operation:"open",phase:"success"})}catch{d.current&&j("审批详情打开失败,请重试"),z(C,{operation:"open",phase:"error"})}finally{a.current=!1}}},w=s=>{s!==c.tab&&(v(""),j(""),D(S=>({...S,tab:s,page:1})))};return o.jsx("section",{className:["make-app-approval",f].filter(Boolean).join(" "),"aria-label":"我的审批",children:o.jsxs(b,{items:Se,value:c.tab,onChange:w,ariaLabel:"审批分类",children:[o.jsxs("form",{className:"make-app-approval-filters",onSubmit:s=>{if(s.preventDefault(),!ee(p.startDate)||!ee(p.endDate)){v("请选择有效日期");return}if(p.startDate&&p.endDate&&p.startDate>p.endDate){v("开始日期不能晚于结束日期");return}v(""),j(""),D(S=>({...S,...p,keyword:p.keyword.trim(),page:1}))},children:[o.jsxs("div",{className:"make-app-approval-filter-field",children:[o.jsx("label",{htmlFor:`${h}-keyword`,children:"申请单号或申请人"}),o.jsx(A,{id:`${h}-keyword`,ariaLabel:"申请单号或申请人",placeholder:"搜索申请单号、申请人",value:p.keyword,onChange:s=>k(S=>({...S,keyword:s}))})]}),o.jsxs("div",{className:"make-app-approval-filter-field",children:[o.jsx("label",{htmlFor:`${h}-status`,children:"流程状态"}),o.jsx(N,{id:`${h}-status`,ariaLabel:"流程状态",value:p.processStatus,options:[{value:"",label:"全部流程状态"},...I],onChange:s=>k(S=>({...S,processStatus:s}))})]}),o.jsxs("fieldset",{className:"make-app-approval-date-field",children:[o.jsx("legend",{children:"申请时间"}),o.jsx("div",{className:"make-app-approval-date-control",children:o.jsx(u,{id:`${h}-period`,ariaLabel:"申请时间",placeholder:["开始日期","结束日期"],value:[p.startDate,p.endDate],onChange:([s,S])=>k(E=>({...E,startDate:s,endDate:S}))},x)})]}),o.jsxs("div",{className:"make-app-approval-filter-actions",children:[o.jsx(g,{htmlType:"submit",variant:"primary",children:"查询"}),o.jsx(g,{htmlType:"button",variant:"default",onClick:()=>{k(W),R(s=>s+1),v(""),j(""),D(s=>({...s,...W,page:1}))},children:"重置"}),o.jsx(g,{htmlType:"button",variant:"default",disabled:n,loading:n,onClick:r,children:"刷新"})]})]}),M&&o.jsx("p",{role:"alert",className:"make-app-approval-error",children:M}),m&&o.jsx("p",{role:"alert",className:"make-app-approval-error",children:m}),o.jsxs("div",{className:"make-app-approval-results","aria-busy":n,children:[o.jsx(ve,{components:e,initialPage:F,query:c,provider:t,onOpen:s=>{B(s)},onReload:r,themeKey:V,logger:C}),n&&o.jsx("div",{className:"make-app-approval-overlay",role:"status",children:"正在加载审批记录…"}),O==="error"&&o.jsxs("div",{className:"make-app-approval-overlay",role:"alert",children:[o.jsx("span",{children:"审批列表加载失败,请重试"}),o.jsx(g,{htmlType:"button",variant:"default",onClick:r,children:"重试"})]})]})]})})},xe=e=>{const t=e.pageSize??20;if(!e.scopeKey.trim())throw new Error("MyApprovalsPage requires scopeKey");for(const i of["Input","Select","DateRangePicker","Button","Tabs"])if(!e.components?.[i])throw new Error(`MyApprovalsPage requires components.${i}`);if(!Number.isSafeInteger(t)||t<1||t>200)throw new Error("pageSize must be an integer from 1 to 200");return o.jsx(ke,{...e,pageSize:t},JSON.stringify([e.scopeKey,t]))};exports.MyApprovalsPage=xe;
|
package/dist/list.mjs
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { jsx as s, jsxs as T } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as M, useState as V, useEffect as j, useMemo as ie, useId as ce } from "react";
|
|
3
|
+
import { getApprovalStatusDisplay as pe } from "./index.mjs";
|
|
4
|
+
const re = (e) => e == null || e === "UNSUBMITTED" ? "状态未知" : pe(e).label, I = (e, a) => {
|
|
5
|
+
try {
|
|
6
|
+
e ? e(a) : a.phase === "error" ? console.warn("[make-app-approval]", a) : console.info("[make-app-approval]", a);
|
|
7
|
+
} catch {
|
|
8
|
+
console.warn("[make-app-approval] diagnostic sink failed");
|
|
9
|
+
}
|
|
10
|
+
}, oe = (e) => typeof e == "object" && e !== null, de = (e) => oe(e) ? ["id", "entityKey", "recordId"].every((a) => typeof e[a] == "string" && e[a].trim().length > 0) && ["applicationNo", "applicationType", "applicantName", "applicationTime"].every((a) => typeof e[a] == "string") && ["taskId", "processInstanceId"].every((a) => e[a] === void 0 || typeof e[a] == "string" && e[a].trim().length > 0) && (typeof e.processStatus == "string" || e.processStatus === null) : !1, Q = (e, a) => {
|
|
11
|
+
if (!oe(e) || !Array.isArray(e.rows) || !e.rows.every(de) || typeof e.total != "number" || !Number.isSafeInteger(e.total) || e.total < 0 || e.rows.length > a || e.rows.length > e.total || new Set(e.rows.map((h) => h.id)).size !== e.rows.length)
|
|
12
|
+
throw new Error("Invalid approval page contract");
|
|
13
|
+
return { rows: e.rows, total: e.total };
|
|
14
|
+
}, ue = ({ table: e, query: a, initialPage: h, loadPage: F, onChange: W, retryViewport: B, onReload: O, logger: z }) => {
|
|
15
|
+
const d = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Set();
|
|
16
|
+
let C = [];
|
|
17
|
+
const p = /* @__PURE__ */ new WeakMap(), u = /* @__PURE__ */ new Set();
|
|
18
|
+
let v = h, f = h.total, i = 0, k = !1, S = !1, R;
|
|
19
|
+
const L = (r) => Number.isSafeInteger(r) && r >= 0 && r * a.pageSize < f, m = (r, t, c) => I(z, { operation: "list", phase: t, tab: a.tab, page: r + 1, pageSize: a.pageSize, rowCount: c }), g = () => {
|
|
20
|
+
k || W({ total: f, rows: C, failed: S || u.size > 0, loading: d.size > 0 });
|
|
21
|
+
}, N = (r) => {
|
|
22
|
+
r.finished || (r.finished = !0, r.removeAbort(), d.get(r.page) === r && d.delete(r.page), e.markPageLoadFailed(r.page, r.request), r.controller.abort(), m(r.page, "cancel"));
|
|
23
|
+
}, l = (r) => {
|
|
24
|
+
i = r;
|
|
25
|
+
const t = e.getPagesInView() ?? [], c = new Set([i, ...t].flatMap((n) => [n - 1, n, n + 1]).filter(L));
|
|
26
|
+
for (const n of d.values()) c.has(n.page) || N(n);
|
|
27
|
+
for (const n of u) c.has(n) || u.delete(n);
|
|
28
|
+
}, D = (r, t, c) => {
|
|
29
|
+
const n = t.rows.map((b) => {
|
|
30
|
+
const o = { ...b, statusLabel: re(b.processStatus) };
|
|
31
|
+
return p.set(o, b), o;
|
|
32
|
+
});
|
|
33
|
+
if (!e.setVirtualPageData(n, r, t.total, c)) {
|
|
34
|
+
m(r, "skip");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
f = t.total;
|
|
38
|
+
try {
|
|
39
|
+
C = Q({ rows: e.getTableData() ?? [], total: f }, Number.MAX_SAFE_INTEGER).rows.map((b) => p.get(b) ?? b);
|
|
40
|
+
} catch (b) {
|
|
41
|
+
S = !0, C = [], v = void 0, R && clearTimeout(R), R = void 0;
|
|
42
|
+
for (const o of d.values()) N(o);
|
|
43
|
+
throw b;
|
|
44
|
+
}
|
|
45
|
+
v && v.total !== f && (v = void 0), u.delete(r);
|
|
46
|
+
for (const b of d.values()) L(b.page) || N(b);
|
|
47
|
+
!L(r) && r > 0 && e.scrollToRow(Math.max(0, f - 1)), m(r, "success", t.rows.length);
|
|
48
|
+
}, $ = () => {
|
|
49
|
+
if (k || R) return;
|
|
50
|
+
const r = [...d.values()].filter((t) => !t.running && !t.finished).sort((t, c) => Math.abs(t.page - i) - Math.abs(c.page - i) || t.page - c.page);
|
|
51
|
+
for (const t of r) {
|
|
52
|
+
if (A.size >= 2) break;
|
|
53
|
+
t.running = !0, A.add(t), m(t.page, "start"), (async () => {
|
|
54
|
+
try {
|
|
55
|
+
const c = await F({ ...a, page: t.page + 1 }, { signal: t.controller.signal });
|
|
56
|
+
if (k || t.finished || t.controller.signal.aborted) return;
|
|
57
|
+
const n = Q(c, a.pageSize);
|
|
58
|
+
t.finished = !0, t.removeAbort(), d.delete(t.page), D(t.page, n, t.request);
|
|
59
|
+
} catch {
|
|
60
|
+
!k && !t.controller.signal.aborted && (u.add(t.page), m(t.page, "error"), e.markPageLoadFailed(t.page, t.request));
|
|
61
|
+
} finally {
|
|
62
|
+
t.finished || (t.finished = !0, t.removeAbort(), d.get(t.page) === t && d.delete(t.page)), A.delete(t), g(), $();
|
|
63
|
+
}
|
|
64
|
+
})();
|
|
65
|
+
}
|
|
66
|
+
g();
|
|
67
|
+
}, x = () => {
|
|
68
|
+
R && clearTimeout(R), R = setTimeout(() => {
|
|
69
|
+
R = void 0, $();
|
|
70
|
+
}, 120);
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
load(r, t) {
|
|
74
|
+
if (t.useRequestIdentity(), k || S || t.signal.aborted || !L(r)) {
|
|
75
|
+
e.markPageLoadFailed(r, t), m(r, "skip");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const c = d.get(r);
|
|
79
|
+
if (c?.request === t && !c.finished) return;
|
|
80
|
+
if (c && N(c), l(r), r === 0 && v) {
|
|
81
|
+
const b = v;
|
|
82
|
+
v = void 0;
|
|
83
|
+
try {
|
|
84
|
+
D(0, b, t);
|
|
85
|
+
} catch {
|
|
86
|
+
u.add(r), e.markPageLoadFailed(r, t), m(r, "error");
|
|
87
|
+
}
|
|
88
|
+
g();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const n = { page: r, request: t, controller: new AbortController(), running: !1, finished: !1, removeAbort: () => {
|
|
92
|
+
} }, K = () => {
|
|
93
|
+
N(n), g();
|
|
94
|
+
};
|
|
95
|
+
t.signal.addEventListener("abort", K, { once: !0 }), n.removeAbort = () => t.signal.removeEventListener("abort", K), d.set(r, n), x(), g();
|
|
96
|
+
},
|
|
97
|
+
viewportChanged() {
|
|
98
|
+
if (k) return;
|
|
99
|
+
const r = e.getPagesInView();
|
|
100
|
+
r?.length && (l(r[0]), d.size && x(), g());
|
|
101
|
+
},
|
|
102
|
+
retry() {
|
|
103
|
+
if (!k) {
|
|
104
|
+
if (S) {
|
|
105
|
+
O();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
u.size !== 0 && (u.clear(), B(), g());
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
dispose() {
|
|
112
|
+
k = !0, R && clearTimeout(R), R = void 0;
|
|
113
|
+
for (const r of d.values()) N(r);
|
|
114
|
+
C = [], u.clear(), v = void 0;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}, fe = [
|
|
118
|
+
{ key: "applicationNo", title: "申请单编号", width: 260 },
|
|
119
|
+
{ key: "applicationType", title: "申请单类型", width: 180 },
|
|
120
|
+
{ key: "applicantName", title: "申请人", width: 170 },
|
|
121
|
+
{ key: "applicationTime", title: "申请时间", width: 220 },
|
|
122
|
+
{ key: "statusLabel", title: "流程状态", width: 140 }
|
|
123
|
+
].map((e) => ({ ...e, showEllipsis: !0, sortable: !1 })), te = 40, ge = (e) => {
|
|
124
|
+
const a = M(void 0);
|
|
125
|
+
return e.initialPage ? /* @__PURE__ */ s(
|
|
126
|
+
he,
|
|
127
|
+
{
|
|
128
|
+
...e,
|
|
129
|
+
initialPage: e.initialPage,
|
|
130
|
+
restoreScroll: a.current?.query === e.query ? a.current.position : void 0,
|
|
131
|
+
rememberScroll: (h) => {
|
|
132
|
+
a.current = { query: e.query, position: h };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
) : /* @__PURE__ */ s("div", { className: "make-app-approval-canvas", role: "group", "aria-label": "审批记录表格" });
|
|
136
|
+
}, he = ({ components: { Button: e }, initialPage: a, query: h, provider: F, themeKey: W, onOpen: B, onReload: O, logger: z, restoreScroll: d, rememberScroll: A }) => {
|
|
137
|
+
const C = M(null), p = M(null), u = M(null), [v, f] = V(!1), [i, k] = V(0), [S, R] = V({ ...a, failed: !1, loading: !1 }), L = M(a.rows), m = M(d), g = M({ provider: F, onOpen: B, onReload: O, logger: z, rememberScroll: A });
|
|
138
|
+
g.current = { provider: F, onOpen: B, onReload: O, logger: z, rememberScroll: A };
|
|
139
|
+
const N = M(() => {
|
|
140
|
+
});
|
|
141
|
+
return j(() => {
|
|
142
|
+
const l = C.current;
|
|
143
|
+
if (!l) return;
|
|
144
|
+
let D = !1, $, x, r, t = a.total;
|
|
145
|
+
I(g.current.logger, { operation: "table", phase: "start" });
|
|
146
|
+
const c = () => {
|
|
147
|
+
D || (f(!0), I(g.current.logger, { operation: "table", phase: "error" }));
|
|
148
|
+
};
|
|
149
|
+
return import("@qfei-design/canvas-table").then((n) => {
|
|
150
|
+
if (D) return;
|
|
151
|
+
const K = () => {
|
|
152
|
+
const o = p.current, y = o?.getScrollState();
|
|
153
|
+
o && y && n.globalEventBus.emitWithNamespace("scroll:change", o.tableId, y);
|
|
154
|
+
}, b = () => {
|
|
155
|
+
if (!D)
|
|
156
|
+
try {
|
|
157
|
+
const { width: o, height: y } = l.getBoundingClientRect();
|
|
158
|
+
if (o <= 0 || y <= 0) return;
|
|
159
|
+
const E = getComputedStyle(l), Z = {
|
|
160
|
+
rowHeight: te,
|
|
161
|
+
headerHeight: 40,
|
|
162
|
+
fontSize: 14,
|
|
163
|
+
fontFamily: E.fontFamily || "Arial, sans-serif",
|
|
164
|
+
...E.color ? { textColor: E.color } : {},
|
|
165
|
+
...E.getPropertyValue("--make-approval-bg").trim() ? { rowBgColor: E.getPropertyValue("--make-approval-bg").trim() } : {},
|
|
166
|
+
...E.getPropertyValue("--make-approval-header").trim() ? { headerBgColor: E.getPropertyValue("--make-approval-header").trim() } : {},
|
|
167
|
+
...E.getPropertyValue("--make-approval-border").trim() ? { borderColor: E.getPropertyValue("--make-approval-border").trim() } : {}
|
|
168
|
+
}, ne = Math.max(Math.ceil(300 / h.pageSize), Math.ceil(y * 3 / te / h.pageSize) + 2) * h.pageSize, q = { enabled: !0, totalRowCount: t, pageSize: h.pageSize, maxCachedRows: ne };
|
|
169
|
+
if (p.current) {
|
|
170
|
+
p.current.updateProps({ canvasWidth: o, canvasHeight: y, style: Z, virtualOptions: q }), p.current.updateCanvasSize(o, y, !0), K();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
p.current = new n.CanvasTableComponent(l, {
|
|
174
|
+
columns: fe,
|
|
175
|
+
canvasWidth: o,
|
|
176
|
+
canvasHeight: y,
|
|
177
|
+
style: Z,
|
|
178
|
+
rowKey: "id",
|
|
179
|
+
showSN: { enabled: !0, width: 64, formatter: (w, P) => P + 1 },
|
|
180
|
+
virtualOptions: q,
|
|
181
|
+
selectable: { enabled: !1 },
|
|
182
|
+
rowSortable: { enabled: !1 },
|
|
183
|
+
editApplyMode: "controlled",
|
|
184
|
+
customEdit: (w) => {
|
|
185
|
+
w.cancel();
|
|
186
|
+
},
|
|
187
|
+
emptyStateOptions: { text: "暂无审批记录" },
|
|
188
|
+
bodyRowHeadSuffixOptions: {
|
|
189
|
+
enabled: !0,
|
|
190
|
+
width: 20,
|
|
191
|
+
render: ({ group: w, x: P, height: Y, rowData: G }) => {
|
|
192
|
+
const se = G?.id, _ = new n.RectShape({ name: "approval-open", x: P, y: Y / 2 - 10, cursor: "pointer", tooltip: "查看审批详情", attrs: { width: 20, height: 20, fill: "transparent", stroke: "transparent" } });
|
|
193
|
+
_.addChild(new n.ImgShape({ name: "approval-open-icon", x: 3, y: 3, attrs: {
|
|
194
|
+
width: 14,
|
|
195
|
+
height: 14,
|
|
196
|
+
img: "data:image/svg+xml;charset=utf-8," + encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${E.color || "#64748b"}" stroke-width="1.8"><path d="M8 3H3v5m13-5h5v5M3 16v5h5m13-5v5h-5"/></svg>`)
|
|
197
|
+
} })), _.on("mousedown", (J) => J.stopPropagation?.()), _.on("click", (J) => {
|
|
198
|
+
J.stopPropagation?.();
|
|
199
|
+
const ee = L.current.find((le) => le.id === se);
|
|
200
|
+
ee && g.current.onOpen(ee);
|
|
201
|
+
}), w.addChild(_);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
const H = p.current, X = ue({
|
|
206
|
+
table: H,
|
|
207
|
+
query: h,
|
|
208
|
+
initialPage: a,
|
|
209
|
+
// 公开滚动同步事件会重新检测缺页,不移动视口,也不复用失败身份。
|
|
210
|
+
retryViewport: K,
|
|
211
|
+
onReload: () => g.current.onReload(),
|
|
212
|
+
loadPage: (w, P) => g.current.provider.loadPage(w, P),
|
|
213
|
+
logger: (w) => I(g.current.logger, w),
|
|
214
|
+
onChange: (w) => {
|
|
215
|
+
D || (t = w.total, L.current = w.rows, R((P) => P.total === w.total && P.failed === w.failed && P.loading === w.loading && P.rows.length === w.rows.length && P.rows.every((Y, G) => Y === w.rows[G]) ? P : w));
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
u.current = X, x = n.globalEventBus.onWithNamespace("data:load", H.tableId, (w, P) => X.load(w, P)), r = n.globalEventBus.onWithNamespace("scroll:change", H.tableId, () => X.viewportChanged()), m.current && H.scrollTo(m.current.scrollX, m.current.scrollY), f(!1), I(g.current.logger, { operation: "table", phase: "success" });
|
|
219
|
+
} catch {
|
|
220
|
+
c();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
N.current = b, $ = new ResizeObserver(b), $.observe(l), b();
|
|
224
|
+
}).catch(c), () => {
|
|
225
|
+
D = !0, $?.disconnect(), N.current = () => {
|
|
226
|
+
}, p.current && (m.current = p.current.getScrollState(), m.current && g.current.rememberScroll(m.current)), x?.(), r?.(), u.current?.dispose(), u.current = null, p.current?.destroy(), p.current = null, I(g.current.logger, { operation: "table", phase: "destroy" });
|
|
227
|
+
};
|
|
228
|
+
}, [a, h, i]), j(() => {
|
|
229
|
+
N.current();
|
|
230
|
+
}, [W]), /* @__PURE__ */ T("div", { className: "make-app-approval-table-frame", "aria-busy": S.loading, children: [
|
|
231
|
+
/* @__PURE__ */ s("div", { ref: C, className: "make-app-approval-canvas", role: "group", "aria-label": "审批记录表格" }),
|
|
232
|
+
v && /* @__PURE__ */ T("div", { className: "make-app-approval-overlay", role: "alert", children: [
|
|
233
|
+
"表格加载失败 ",
|
|
234
|
+
/* @__PURE__ */ s(e, { htmlType: "button", variant: "default", onClick: () => {
|
|
235
|
+
f(!1), k((l) => l + 1);
|
|
236
|
+
}, children: "重新加载表格" })
|
|
237
|
+
] }),
|
|
238
|
+
!v && S.failed && /* @__PURE__ */ T("div", { className: "make-app-approval-table-feedback", role: "alert", children: [
|
|
239
|
+
"部分审批记录加载失败 ",
|
|
240
|
+
/* @__PURE__ */ s(e, { htmlType: "button", variant: "default", onClick: () => u.current?.retry(), children: "重试加载" })
|
|
241
|
+
] }),
|
|
242
|
+
!v && !S.failed && S.loading && /* @__PURE__ */ T("div", { className: "make-app-approval-table-loading", role: "status", "aria-label": "正在加载审批记录", "aria-live": "polite", children: [
|
|
243
|
+
/* @__PURE__ */ s("span", { className: "make-app-approval-loading-spinner", "aria-hidden": "true" }),
|
|
244
|
+
/* @__PURE__ */ s("span", { children: "加载中" })
|
|
245
|
+
] }),
|
|
246
|
+
/* @__PURE__ */ T("ul", { className: "make-app-approval-accessible-rows", "aria-label": "审批记录文字视图", children: [
|
|
247
|
+
S.total === 0 && /* @__PURE__ */ s("li", { children: "暂无审批记录" }),
|
|
248
|
+
S.rows.map((l) => /* @__PURE__ */ T("li", { children: [
|
|
249
|
+
/* @__PURE__ */ T("span", { children: [
|
|
250
|
+
l.applicationNo,
|
|
251
|
+
",",
|
|
252
|
+
l.applicationType,
|
|
253
|
+
",",
|
|
254
|
+
l.applicantName,
|
|
255
|
+
",",
|
|
256
|
+
l.applicationTime,
|
|
257
|
+
",",
|
|
258
|
+
re(l.processStatus),
|
|
259
|
+
"。"
|
|
260
|
+
] }),
|
|
261
|
+
/* @__PURE__ */ T(e, { htmlType: "button", variant: "text", onClick: () => B(l), children: [
|
|
262
|
+
"打开 ",
|
|
263
|
+
l.applicationNo || l.applicationType,
|
|
264
|
+
" 的审批详情"
|
|
265
|
+
] })
|
|
266
|
+
] }, l.id))
|
|
267
|
+
] })
|
|
268
|
+
] });
|
|
269
|
+
}, me = [], ve = (e, a, h, F) => {
|
|
270
|
+
const [W, B] = V(0), [O, z] = V(), d = M({ provider: e, logger: F });
|
|
271
|
+
d.current = { provider: e, logger: F };
|
|
272
|
+
const A = ie(() => ({}), [a, h, W]);
|
|
273
|
+
j(() => {
|
|
274
|
+
const p = new AbortController(), { provider: u, logger: v } = d.current, f = { operation: "list", tab: a.tab, page: a.page, pageSize: a.pageSize };
|
|
275
|
+
I(v, { ...f, phase: "start" });
|
|
276
|
+
let i = !1;
|
|
277
|
+
return (async () => {
|
|
278
|
+
try {
|
|
279
|
+
const k = await u.loadPage(a, { signal: p.signal });
|
|
280
|
+
if (p.signal.aborted) return;
|
|
281
|
+
const S = Q(k, a.pageSize);
|
|
282
|
+
i = !0, z({ ...S, token: A, status: "success" }), I(v, { ...f, phase: "success", rowCount: S.rows.length });
|
|
283
|
+
} catch {
|
|
284
|
+
if (p.signal.aborted) return;
|
|
285
|
+
i = !0, z({ token: A, status: "error", rows: me, total: 0 }), I(v, { ...f, phase: "error" });
|
|
286
|
+
}
|
|
287
|
+
})(), () => {
|
|
288
|
+
p.abort(), i || I(v, { ...f, phase: "cancel" });
|
|
289
|
+
};
|
|
290
|
+
}, [a, A]);
|
|
291
|
+
const C = O?.token === A ? O : void 0;
|
|
292
|
+
return {
|
|
293
|
+
initialPage: C?.status === "success" ? C : void 0,
|
|
294
|
+
total: C?.total ?? 0,
|
|
295
|
+
status: C?.status ?? "loading",
|
|
296
|
+
reload: () => B((p) => p + 1)
|
|
297
|
+
};
|
|
298
|
+
}, U = { keyword: "", processStatus: "", startDate: "", endDate: "" }, be = [{ value: "pending", label: "待我处理" }, { value: "approved", label: "已审批" }], ae = (e) => {
|
|
299
|
+
if (e === "") return !0;
|
|
300
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(e)) return !1;
|
|
301
|
+
const a = /* @__PURE__ */ new Date(`${e}T00:00:00Z`);
|
|
302
|
+
return Number.isFinite(a.getTime()) && a.toISOString().slice(0, 10) === e;
|
|
303
|
+
}, we = ({ components: e, provider: a, onOpenApproval: h, statusOptions: F = [], pageSize: W = 20, refreshKey: B, themeKey: O, logger: z, className: d }) => {
|
|
304
|
+
const { Input: A, Select: C, DateRangePicker: p, Button: u, Tabs: v } = e, f = ce(), [i, k] = V(U), [S, R] = V(0), [L, m] = V(""), [g, N] = V(""), [l, D] = V({ ...U, tab: "pending", page: 1, pageSize: W }), { initialPage: $, status: x, reload: r } = ve(a, l, B, z), t = M(!1), c = M(!0);
|
|
305
|
+
j(() => (c.current = !0, () => {
|
|
306
|
+
c.current = !1;
|
|
307
|
+
}), []);
|
|
308
|
+
const n = x === "loading", K = async (o) => {
|
|
309
|
+
if (!t.current) {
|
|
310
|
+
t.current = !0, N(""), I(z, { operation: "open", phase: "start" });
|
|
311
|
+
try {
|
|
312
|
+
await h(o), I(z, { operation: "open", phase: "success" });
|
|
313
|
+
} catch {
|
|
314
|
+
c.current && N("审批详情打开失败,请重试"), I(z, { operation: "open", phase: "error" });
|
|
315
|
+
} finally {
|
|
316
|
+
t.current = !1;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}, b = (o) => {
|
|
320
|
+
o !== l.tab && (m(""), N(""), D((y) => ({ ...y, tab: o, page: 1 })));
|
|
321
|
+
};
|
|
322
|
+
return /* @__PURE__ */ s("section", { className: ["make-app-approval", d].filter(Boolean).join(" "), "aria-label": "我的审批", children: /* @__PURE__ */ T(v, { items: be, value: l.tab, onChange: b, ariaLabel: "审批分类", children: [
|
|
323
|
+
/* @__PURE__ */ T("form", { className: "make-app-approval-filters", onSubmit: (o) => {
|
|
324
|
+
if (o.preventDefault(), !ae(i.startDate) || !ae(i.endDate)) {
|
|
325
|
+
m("请选择有效日期");
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (i.startDate && i.endDate && i.startDate > i.endDate) {
|
|
329
|
+
m("开始日期不能晚于结束日期");
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
m(""), N(""), D((y) => ({ ...y, ...i, keyword: i.keyword.trim(), page: 1 }));
|
|
333
|
+
}, children: [
|
|
334
|
+
/* @__PURE__ */ T("div", { className: "make-app-approval-filter-field", children: [
|
|
335
|
+
/* @__PURE__ */ s("label", { htmlFor: `${f}-keyword`, children: "申请单号或申请人" }),
|
|
336
|
+
/* @__PURE__ */ s(A, { id: `${f}-keyword`, ariaLabel: "申请单号或申请人", placeholder: "搜索申请单号、申请人", value: i.keyword, onChange: (o) => k((y) => ({ ...y, keyword: o })) })
|
|
337
|
+
] }),
|
|
338
|
+
/* @__PURE__ */ T("div", { className: "make-app-approval-filter-field", children: [
|
|
339
|
+
/* @__PURE__ */ s("label", { htmlFor: `${f}-status`, children: "流程状态" }),
|
|
340
|
+
/* @__PURE__ */ s(C, { id: `${f}-status`, ariaLabel: "流程状态", value: i.processStatus, options: [{ value: "", label: "全部流程状态" }, ...F], onChange: (o) => k((y) => ({ ...y, processStatus: o })) })
|
|
341
|
+
] }),
|
|
342
|
+
/* @__PURE__ */ T("fieldset", { className: "make-app-approval-date-field", children: [
|
|
343
|
+
/* @__PURE__ */ s("legend", { children: "申请时间" }),
|
|
344
|
+
/* @__PURE__ */ s("div", { className: "make-app-approval-date-control", children: /* @__PURE__ */ s(
|
|
345
|
+
p,
|
|
346
|
+
{
|
|
347
|
+
id: `${f}-period`,
|
|
348
|
+
ariaLabel: "申请时间",
|
|
349
|
+
placeholder: ["开始日期", "结束日期"],
|
|
350
|
+
value: [i.startDate, i.endDate],
|
|
351
|
+
onChange: ([o, y]) => k((E) => ({ ...E, startDate: o, endDate: y }))
|
|
352
|
+
},
|
|
353
|
+
S
|
|
354
|
+
) })
|
|
355
|
+
] }),
|
|
356
|
+
/* @__PURE__ */ T("div", { className: "make-app-approval-filter-actions", children: [
|
|
357
|
+
/* @__PURE__ */ s(u, { htmlType: "submit", variant: "primary", children: "查询" }),
|
|
358
|
+
/* @__PURE__ */ s(u, { htmlType: "button", variant: "default", onClick: () => {
|
|
359
|
+
k(U), R((o) => o + 1), m(""), N(""), D((o) => ({ ...o, ...U, page: 1 }));
|
|
360
|
+
}, children: "重置" }),
|
|
361
|
+
/* @__PURE__ */ s(u, { htmlType: "button", variant: "default", disabled: n, loading: n, onClick: r, children: "刷新" })
|
|
362
|
+
] })
|
|
363
|
+
] }),
|
|
364
|
+
L && /* @__PURE__ */ s("p", { role: "alert", className: "make-app-approval-error", children: L }),
|
|
365
|
+
g && /* @__PURE__ */ s("p", { role: "alert", className: "make-app-approval-error", children: g }),
|
|
366
|
+
/* @__PURE__ */ T("div", { className: "make-app-approval-results", "aria-busy": n, children: [
|
|
367
|
+
/* @__PURE__ */ s(ge, { components: e, initialPage: $, query: l, provider: a, onOpen: (o) => {
|
|
368
|
+
K(o);
|
|
369
|
+
}, onReload: r, themeKey: O, logger: z }),
|
|
370
|
+
n && /* @__PURE__ */ s("div", { className: "make-app-approval-overlay", role: "status", children: "正在加载审批记录…" }),
|
|
371
|
+
x === "error" && /* @__PURE__ */ T("div", { className: "make-app-approval-overlay", role: "alert", children: [
|
|
372
|
+
/* @__PURE__ */ s("span", { children: "审批列表加载失败,请重试" }),
|
|
373
|
+
/* @__PURE__ */ s(u, { htmlType: "button", variant: "default", onClick: r, children: "重试" })
|
|
374
|
+
] })
|
|
375
|
+
] })
|
|
376
|
+
] }) });
|
|
377
|
+
}, Ne = (e) => {
|
|
378
|
+
const a = e.pageSize ?? 20;
|
|
379
|
+
if (!e.scopeKey.trim()) throw new Error("MyApprovalsPage requires scopeKey");
|
|
380
|
+
for (const h of ["Input", "Select", "DateRangePicker", "Button", "Tabs"])
|
|
381
|
+
if (!e.components?.[h]) throw new Error(`MyApprovalsPage requires components.${h}`);
|
|
382
|
+
if (!Number.isSafeInteger(a) || a < 1 || a > 200) throw new Error("pageSize must be an integer from 1 to 200");
|
|
383
|
+
return /* @__PURE__ */ s(we, { ...e, pageSize: a }, JSON.stringify([e.scopeKey, a]));
|
|
384
|
+
};
|
|
385
|
+
export {
|
|
386
|
+
Ne as MyApprovalsPage
|
|
387
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
export type ApprovalStatusProps = {
|
|
3
|
+
value: unknown;
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: CSSProperties;
|
|
6
|
+
};
|
|
7
|
+
export declare const ApprovalStatus: ({ value, className, style }: ApprovalStatusProps) => import("react").JSX.Element;
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("./index.cjs"),n=({value:e,className:a,style:s})=>{const t=r.getApprovalStatusDisplay(e);return o.jsx("span",{className:["make-app-approval-status",a].filter(Boolean).join(" "),"data-tone":t.tone,style:s,children:t.label})};exports.ApprovalStatus=n;
|
package/dist/react.mjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { getApprovalStatusDisplay as r } from "./index.mjs";
|
|
3
|
+
const n = ({ value: a, className: o, style: p }) => {
|
|
4
|
+
const t = r(a);
|
|
5
|
+
return /* @__PURE__ */ s(
|
|
6
|
+
"span",
|
|
7
|
+
{
|
|
8
|
+
className: ["make-app-approval-status", o].filter(Boolean).join(" "),
|
|
9
|
+
"data-tone": t.tone,
|
|
10
|
+
style: p,
|
|
11
|
+
children: t.label
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
n as ApprovalStatus
|
|
17
|
+
};
|