sy-form-components 0.2.0 → 0.2.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 +5 -5
- package/dist/index.d.mts +538 -1
- package/dist/index.d.ts +538 -1
- package/dist/index.js +2287 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2250 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3672,7 +3672,12 @@ var CHUNK_UPLOAD_THRESHOLD = 10 * 1024 * 1024;
|
|
|
3672
3672
|
var trimTrailingSlash = (value) => String(value || "").replace(/\/$/, "");
|
|
3673
3673
|
var getDefaultBaseUrl = () => {
|
|
3674
3674
|
const globalEnv = globalThis.process?.env;
|
|
3675
|
-
|
|
3675
|
+
const envBaseUrl = globalEnv?.FORM_API_BASE_URL || globalEnv?.BASE_API_URL;
|
|
3676
|
+
if (envBaseUrl) return trimTrailingSlash(envBaseUrl);
|
|
3677
|
+
const browserGlobal = typeof window !== "undefined" ? window : void 0;
|
|
3678
|
+
const windowBaseUrl = browserGlobal?.FORM_API_BASE_URL || browserGlobal?.BASE_API_URL || browserGlobal?.__FORM_API_BASE_URL__ || browserGlobal?.__LOWCODE_API_BASE_URL__;
|
|
3679
|
+
if (windowBaseUrl) return trimTrailingSlash(windowBaseUrl);
|
|
3680
|
+
return typeof window !== "undefined" ? "/service" : "";
|
|
3676
3681
|
};
|
|
3677
3682
|
var appendQuery = (url, params) => {
|
|
3678
3683
|
if (!params) return url;
|
|
@@ -4036,7 +4041,7 @@ function FormProvider({
|
|
|
4036
4041
|
});
|
|
4037
4042
|
}, []);
|
|
4038
4043
|
const getFieldValue = useCallback((fieldId) => formData[fieldId], [formData]);
|
|
4039
|
-
const
|
|
4044
|
+
const getFormData2 = useCallback(() => ({ ...formData }), [formData]);
|
|
4040
4045
|
const validateFieldById = useCallback(
|
|
4041
4046
|
async (fieldId) => {
|
|
4042
4047
|
const field = schema.fields.find((f) => f.fieldId === fieldId);
|
|
@@ -4113,7 +4118,7 @@ function FormProvider({
|
|
|
4113
4118
|
},
|
|
4114
4119
|
setFieldValue,
|
|
4115
4120
|
getFieldValue,
|
|
4116
|
-
getFormData,
|
|
4121
|
+
getFormData: getFormData2,
|
|
4117
4122
|
validateField: validateFieldById,
|
|
4118
4123
|
validateAll,
|
|
4119
4124
|
resetForm,
|
|
@@ -4133,7 +4138,7 @@ function FormProvider({
|
|
|
4133
4138
|
config.submit,
|
|
4134
4139
|
setFieldValue,
|
|
4135
4140
|
getFieldValue,
|
|
4136
|
-
|
|
4141
|
+
getFormData2,
|
|
4137
4142
|
validateFieldById,
|
|
4138
4143
|
validateAll,
|
|
4139
4144
|
resetForm,
|
|
@@ -4204,14 +4209,14 @@ function FormActions({
|
|
|
4204
4209
|
showReset = true,
|
|
4205
4210
|
onSubmit
|
|
4206
4211
|
}) {
|
|
4207
|
-
const { mode, validateAll, getFormData, resetForm, api, config } = useFormContext();
|
|
4212
|
+
const { mode, validateAll, getFormData: getFormData2, resetForm, api, config } = useFormContext();
|
|
4208
4213
|
const [isSubmitting, setIsSubmitting] = useState13(false);
|
|
4209
4214
|
const [submitError, setSubmitError] = useState13(null);
|
|
4210
4215
|
const handleSubmit = useCallback2(async () => {
|
|
4211
4216
|
setSubmitError(null);
|
|
4212
4217
|
const valid = await validateAll();
|
|
4213
4218
|
if (!valid) return;
|
|
4214
|
-
const values =
|
|
4219
|
+
const values = getFormData2();
|
|
4215
4220
|
setIsSubmitting(true);
|
|
4216
4221
|
try {
|
|
4217
4222
|
const beforeResult = await config.submit?.beforeSubmit?.(values);
|
|
@@ -4242,7 +4247,7 @@ function FormActions({
|
|
|
4242
4247
|
} finally {
|
|
4243
4248
|
setIsSubmitting(false);
|
|
4244
4249
|
}
|
|
4245
|
-
}, [api, config,
|
|
4250
|
+
}, [api, config, getFormData2, mode, onSubmit, validateAll]);
|
|
4246
4251
|
const handleReset = useCallback2(() => {
|
|
4247
4252
|
resetForm();
|
|
4248
4253
|
}, [resetForm]);
|
|
@@ -4302,6 +4307,160 @@ function FormContainer({
|
|
|
4302
4307
|
] });
|
|
4303
4308
|
}
|
|
4304
4309
|
|
|
4310
|
+
// src/core/constants.ts
|
|
4311
|
+
var PROCESS_STATUS_META = {
|
|
4312
|
+
running: { label: "\u5BA1\u6279\u4E2D", tone: "brand" },
|
|
4313
|
+
waiting: { label: "\u7B49\u5F85\u4E2D", tone: "neutral" },
|
|
4314
|
+
exception: { label: "\u6D41\u7A0B\u5F02\u5E38", tone: "danger" },
|
|
4315
|
+
completed: { label: "\u5DF2\u5B8C\u6210", tone: "success" },
|
|
4316
|
+
terminated: { label: "\u5DF2\u62D2\u7EDD", tone: "danger" },
|
|
4317
|
+
withdrawn: { label: "\u5DF2\u64A4\u9500", tone: "neutral" },
|
|
4318
|
+
pending: { label: "\u5F85\u5904\u7406", tone: "brand" },
|
|
4319
|
+
cancelled: { label: "\u5DF2\u53D6\u6D88", tone: "neutral" }
|
|
4320
|
+
};
|
|
4321
|
+
var TASK_STATUS_META = {
|
|
4322
|
+
pending: { label: "\u5F85\u5904\u7406", tone: "brand" },
|
|
4323
|
+
approved: { label: "\u5DF2\u540C\u610F", tone: "success" },
|
|
4324
|
+
rejected: { label: "\u5DF2\u62D2\u7EDD", tone: "danger" },
|
|
4325
|
+
returned: { label: "\u5DF2\u9000\u56DE", tone: "warning" },
|
|
4326
|
+
suspended: { label: "\u5DF2\u6302\u8D77", tone: "neutral" },
|
|
4327
|
+
cancelled: { label: "\u5DF2\u53D6\u6D88", tone: "neutral" },
|
|
4328
|
+
copied: { label: "\u5DF2\u6284\u9001", tone: "neutral" },
|
|
4329
|
+
waiting: { label: "\u7B49\u5F85\u4E2D", tone: "neutral" },
|
|
4330
|
+
simulated: { label: "\u672A\u5F00\u59CB", tone: "neutral" }
|
|
4331
|
+
};
|
|
4332
|
+
|
|
4333
|
+
// src/core/processApi.ts
|
|
4334
|
+
async function getProcessBasic(request, formInstId) {
|
|
4335
|
+
const response = await request({
|
|
4336
|
+
url: `/workflow/instance/${formInstId}/basic`,
|
|
4337
|
+
method: "get"
|
|
4338
|
+
});
|
|
4339
|
+
return response.data || response.result;
|
|
4340
|
+
}
|
|
4341
|
+
async function getProcessProgress(request, formInstId) {
|
|
4342
|
+
const response = await request({
|
|
4343
|
+
url: `/workflow/instance/${formInstId}`,
|
|
4344
|
+
method: "get"
|
|
4345
|
+
});
|
|
4346
|
+
return response.data || response.result || [];
|
|
4347
|
+
}
|
|
4348
|
+
async function checkUserApproval(request, formInstId) {
|
|
4349
|
+
const response = await request({
|
|
4350
|
+
url: `/workflow/instance/${formInstId}/permission`,
|
|
4351
|
+
method: "get"
|
|
4352
|
+
});
|
|
4353
|
+
return response.data || response.result;
|
|
4354
|
+
}
|
|
4355
|
+
async function handleApproval(request, params) {
|
|
4356
|
+
const response = await request({
|
|
4357
|
+
url: "/workflow/approve",
|
|
4358
|
+
method: "post",
|
|
4359
|
+
data: params
|
|
4360
|
+
});
|
|
4361
|
+
return response.data || response.result;
|
|
4362
|
+
}
|
|
4363
|
+
async function withdrawProcess(request, params) {
|
|
4364
|
+
const response = await request({
|
|
4365
|
+
url: `/workflow/instance/${params.instanceId}/withdraw`,
|
|
4366
|
+
method: "put",
|
|
4367
|
+
data: { reason: params.reason }
|
|
4368
|
+
});
|
|
4369
|
+
return response.data || response.result;
|
|
4370
|
+
}
|
|
4371
|
+
async function transferTask(request, params) {
|
|
4372
|
+
const response = await request({
|
|
4373
|
+
url: `/workflow/task/${params.taskId}/transfer`,
|
|
4374
|
+
method: "put",
|
|
4375
|
+
data: { newAssignee: params.newAssignee, reason: params.reason }
|
|
4376
|
+
});
|
|
4377
|
+
return response.data || response.result;
|
|
4378
|
+
}
|
|
4379
|
+
async function returnTask(request, params) {
|
|
4380
|
+
const response = await request({
|
|
4381
|
+
url: `/workflow/task/${params.taskId}/return`,
|
|
4382
|
+
method: "put",
|
|
4383
|
+
data: { targetNodeId: params.targetNodeId, reason: params.reason }
|
|
4384
|
+
});
|
|
4385
|
+
return response.data || response.result;
|
|
4386
|
+
}
|
|
4387
|
+
async function resubmitTask(request, params) {
|
|
4388
|
+
const response = await request({
|
|
4389
|
+
url: `/workflow/task/${params.taskId}/resubmit`,
|
|
4390
|
+
method: "post",
|
|
4391
|
+
data: {
|
|
4392
|
+
formUuid: params.formUuid,
|
|
4393
|
+
appType: params.appType,
|
|
4394
|
+
updateFormDataJson: params.updateFormDataJson,
|
|
4395
|
+
comments: params.comments
|
|
4396
|
+
}
|
|
4397
|
+
});
|
|
4398
|
+
return response.data || response.result;
|
|
4399
|
+
}
|
|
4400
|
+
async function saveTask(request, params) {
|
|
4401
|
+
const response = await request({
|
|
4402
|
+
url: "/workflow/task/save",
|
|
4403
|
+
method: "post",
|
|
4404
|
+
data: params
|
|
4405
|
+
});
|
|
4406
|
+
return response.data || response.result;
|
|
4407
|
+
}
|
|
4408
|
+
async function getReturnableNodes(request, taskId) {
|
|
4409
|
+
const response = await request({
|
|
4410
|
+
url: `/workflow/task/${taskId}/returnable-nodes`,
|
|
4411
|
+
method: "get"
|
|
4412
|
+
});
|
|
4413
|
+
return response.data || response.result || [];
|
|
4414
|
+
}
|
|
4415
|
+
async function previewProcess(request, params) {
|
|
4416
|
+
const response = await request({
|
|
4417
|
+
url: "/workflow/preview",
|
|
4418
|
+
method: "post",
|
|
4419
|
+
data: params
|
|
4420
|
+
});
|
|
4421
|
+
return response.data || response.result || [];
|
|
4422
|
+
}
|
|
4423
|
+
async function getProcessDefinition(request, formUuid) {
|
|
4424
|
+
const response = await request({
|
|
4425
|
+
url: "/workflow/definition/form",
|
|
4426
|
+
method: "get",
|
|
4427
|
+
params: { formUuid }
|
|
4428
|
+
});
|
|
4429
|
+
return response.data || response.result;
|
|
4430
|
+
}
|
|
4431
|
+
async function getFormData(request, params) {
|
|
4432
|
+
const response = await request({
|
|
4433
|
+
url: "/form/queryFormDataByFormInstanceId",
|
|
4434
|
+
method: "get",
|
|
4435
|
+
params
|
|
4436
|
+
});
|
|
4437
|
+
return response.data || response.result;
|
|
4438
|
+
}
|
|
4439
|
+
async function deleteFormData(request, params) {
|
|
4440
|
+
const response = await request({
|
|
4441
|
+
url: `/${params.appType}/v1/form/deleteFormData.json`,
|
|
4442
|
+
method: "post",
|
|
4443
|
+
data: params
|
|
4444
|
+
});
|
|
4445
|
+
return response.data || response.result;
|
|
4446
|
+
}
|
|
4447
|
+
async function getChangeRecords(request, params) {
|
|
4448
|
+
const response = await request({
|
|
4449
|
+
url: "/form/getFormDataChangeRecords",
|
|
4450
|
+
method: "get",
|
|
4451
|
+
params
|
|
4452
|
+
});
|
|
4453
|
+
return response.data || response.result;
|
|
4454
|
+
}
|
|
4455
|
+
async function getViewPermission(request, params) {
|
|
4456
|
+
const response = await request({
|
|
4457
|
+
url: "/permission/form-group/view-permissions",
|
|
4458
|
+
method: "get",
|
|
4459
|
+
params
|
|
4460
|
+
});
|
|
4461
|
+
return response.data || response.result;
|
|
4462
|
+
}
|
|
4463
|
+
|
|
4305
4464
|
// src/layout/FormSection/index.tsx
|
|
4306
4465
|
import { useState as useState14 } from "react";
|
|
4307
4466
|
import { jsx as jsx70, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
@@ -4502,7 +4661,7 @@ function FormSummary({
|
|
|
4502
4661
|
const { schema, formData } = useFormContext();
|
|
4503
4662
|
const displayFields = fields ? schema.fields.filter((f) => fields.includes(f.fieldId)) : schema.fields;
|
|
4504
4663
|
const colClass = columnClasses2[columns];
|
|
4505
|
-
const
|
|
4664
|
+
const formatValue2 = (value) => {
|
|
4506
4665
|
if (value === null || value === void 0 || value === "") return "--";
|
|
4507
4666
|
if (Array.isArray(value)) {
|
|
4508
4667
|
if (value.length === 0) return "--";
|
|
@@ -4518,7 +4677,7 @@ function FormSummary({
|
|
|
4518
4677
|
"data-testid": `summary-field-${field.fieldId}`,
|
|
4519
4678
|
children: [
|
|
4520
4679
|
/* @__PURE__ */ jsx74("span", { className: labelClassName ?? "text-sm text-gray-500 mb-1", children: field.label }),
|
|
4521
|
-
/* @__PURE__ */ jsx74("span", { className: valueClassName ?? "text-sm text-gray-900", children:
|
|
4680
|
+
/* @__PURE__ */ jsx74("span", { className: valueClassName ?? "text-sm text-gray-900", children: formatValue2(formData[field.fieldId]) })
|
|
4522
4681
|
]
|
|
4523
4682
|
},
|
|
4524
4683
|
field.fieldId
|
|
@@ -4575,7 +4734,7 @@ function useFormEngine(schema, config) {
|
|
|
4575
4734
|
});
|
|
4576
4735
|
}, []);
|
|
4577
4736
|
const getFieldValue = useCallback3((fieldId) => formData[fieldId], [formData]);
|
|
4578
|
-
const
|
|
4737
|
+
const getFormData2 = useCallback3(() => ({ ...formData }), [formData]);
|
|
4579
4738
|
const validateAll = useCallback3(async () => {
|
|
4580
4739
|
const fieldRules = {};
|
|
4581
4740
|
for (const field of schema.fields) {
|
|
@@ -4602,7 +4761,7 @@ function useFormEngine(schema, config) {
|
|
|
4602
4761
|
formData,
|
|
4603
4762
|
setFieldValue,
|
|
4604
4763
|
getFieldValue,
|
|
4605
|
-
getFormData,
|
|
4764
|
+
getFormData: getFormData2,
|
|
4606
4765
|
validateAll,
|
|
4607
4766
|
resetForm,
|
|
4608
4767
|
mode: config.mode,
|
|
@@ -4631,7 +4790,7 @@ function useFormData(initialValues = {}) {
|
|
|
4631
4790
|
},
|
|
4632
4791
|
[formData]
|
|
4633
4792
|
);
|
|
4634
|
-
const
|
|
4793
|
+
const getFormData2 = useCallback4(() => {
|
|
4635
4794
|
return { ...formData };
|
|
4636
4795
|
}, [formData]);
|
|
4637
4796
|
const resetForm = useCallback4(() => {
|
|
@@ -4642,7 +4801,7 @@ function useFormData(initialValues = {}) {
|
|
|
4642
4801
|
formData,
|
|
4643
4802
|
setFieldValue,
|
|
4644
4803
|
getFieldValue,
|
|
4645
|
-
getFormData,
|
|
4804
|
+
getFormData: getFormData2,
|
|
4646
4805
|
resetForm,
|
|
4647
4806
|
dirtyFields
|
|
4648
4807
|
};
|
|
@@ -4706,60 +4865,2137 @@ function useFormSubmit(config) {
|
|
|
4706
4865
|
return { submit, isSubmitting, submitError };
|
|
4707
4866
|
}
|
|
4708
4867
|
|
|
4868
|
+
// src/hooks/useFieldPermission.ts
|
|
4869
|
+
import { useMemo as useMemo7, useCallback as useCallback6 } from "react";
|
|
4870
|
+
function useFieldPermission(options) {
|
|
4871
|
+
const { viewPermissions, processDefinition, currentTask, isApprover, mode } = options;
|
|
4872
|
+
const computeBehaviors = useCallback6(() => {
|
|
4873
|
+
const behaviors = {};
|
|
4874
|
+
if (!currentTask && viewPermissions) {
|
|
4875
|
+
const { fieldPermissions } = viewPermissions;
|
|
4876
|
+
for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
|
|
4877
|
+
if (perm === "FORM_FILED_HIDDEN") {
|
|
4878
|
+
behaviors[fieldId] = "HIDDEN";
|
|
4879
|
+
} else if (perm === "FORM_FILED_VIEW") {
|
|
4880
|
+
behaviors[fieldId] = "READONLY";
|
|
4881
|
+
} else if (perm === "FORM_FILED_EDIT") {
|
|
4882
|
+
behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
return behaviors;
|
|
4886
|
+
}
|
|
4887
|
+
if (currentTask && !isApprover && viewPermissions) {
|
|
4888
|
+
const { fieldPermissions } = viewPermissions;
|
|
4889
|
+
for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
|
|
4890
|
+
if (perm === "FORM_FILED_HIDDEN") {
|
|
4891
|
+
behaviors[fieldId] = "HIDDEN";
|
|
4892
|
+
} else {
|
|
4893
|
+
behaviors[fieldId] = "READONLY";
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
return behaviors;
|
|
4897
|
+
}
|
|
4898
|
+
if (currentTask && isApprover && currentTask.nodeType === "originator_return") {
|
|
4899
|
+
if (processDefinition?.flowConfig && processDefinition.startNodeId) {
|
|
4900
|
+
const startConfig = processDefinition.flowConfig[processDefinition.startNodeId];
|
|
4901
|
+
if (startConfig) {
|
|
4902
|
+
for (const [fieldId, behavior] of Object.entries(startConfig)) {
|
|
4903
|
+
behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
|
|
4904
|
+
}
|
|
4905
|
+
return behaviors;
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4908
|
+
if (viewPermissions) {
|
|
4909
|
+
for (const fieldId of Object.keys(viewPermissions.fieldPermissions)) {
|
|
4910
|
+
if (viewPermissions.fieldPermissions[fieldId] === "FORM_FILED_HIDDEN") {
|
|
4911
|
+
behaviors[fieldId] = "HIDDEN";
|
|
4912
|
+
} else {
|
|
4913
|
+
behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
}
|
|
4917
|
+
return behaviors;
|
|
4918
|
+
}
|
|
4919
|
+
if (currentTask && isApprover && processDefinition?.flowConfig) {
|
|
4920
|
+
const nodeConfig = processDefinition.flowConfig[currentTask.nodeId];
|
|
4921
|
+
if (nodeConfig) {
|
|
4922
|
+
for (const [fieldId, behavior] of Object.entries(nodeConfig)) {
|
|
4923
|
+
behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
|
|
4924
|
+
}
|
|
4925
|
+
return behaviors;
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
if (viewPermissions) {
|
|
4929
|
+
const { fieldPermissions } = viewPermissions;
|
|
4930
|
+
for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
|
|
4931
|
+
if (perm === "FORM_FILED_HIDDEN") {
|
|
4932
|
+
behaviors[fieldId] = "HIDDEN";
|
|
4933
|
+
} else if (perm === "FORM_FILED_VIEW") {
|
|
4934
|
+
behaviors[fieldId] = "READONLY";
|
|
4935
|
+
} else if (perm === "FORM_FILED_EDIT") {
|
|
4936
|
+
behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
return behaviors;
|
|
4941
|
+
}, [viewPermissions, processDefinition, currentTask, isApprover, mode]);
|
|
4942
|
+
const fieldBehaviors = useMemo7(() => computeBehaviors(), [computeBehaviors]);
|
|
4943
|
+
return { fieldBehaviors, computeBehaviors };
|
|
4944
|
+
}
|
|
4945
|
+
|
|
4946
|
+
// src/hooks/useFormDetail.ts
|
|
4947
|
+
import { useState as useState20, useEffect as useEffect27, useCallback as useCallback7, useRef as useRef7 } from "react";
|
|
4948
|
+
function buildFieldBehaviors(permissions, mode) {
|
|
4949
|
+
const behaviors = {};
|
|
4950
|
+
if (!permissions) return behaviors;
|
|
4951
|
+
for (const [fieldId, perm] of Object.entries(permissions.fieldPermissions)) {
|
|
4952
|
+
if (perm === "FORM_FILED_HIDDEN") {
|
|
4953
|
+
behaviors[fieldId] = "HIDDEN";
|
|
4954
|
+
} else if (perm === "FORM_FILED_VIEW") {
|
|
4955
|
+
behaviors[fieldId] = "READONLY";
|
|
4956
|
+
} else if (perm === "FORM_FILED_EDIT") {
|
|
4957
|
+
behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
|
|
4958
|
+
}
|
|
4959
|
+
}
|
|
4960
|
+
return behaviors;
|
|
4961
|
+
}
|
|
4962
|
+
function useFormDetail(options) {
|
|
4963
|
+
const { formUuid, appType, formInstanceId, onPermissionDenied } = options;
|
|
4964
|
+
const { api } = useFormContext();
|
|
4965
|
+
const request = api.request;
|
|
4966
|
+
const [loading, setLoading] = useState20(true);
|
|
4967
|
+
const [mode, setMode] = useState20("readonly");
|
|
4968
|
+
const [formData, setFormData] = useState20(null);
|
|
4969
|
+
const [instanceInfo, setInstanceInfo] = useState20(null);
|
|
4970
|
+
const [permissions, setPermissions] = useState20(null);
|
|
4971
|
+
const mountedRef = useRef7(true);
|
|
4972
|
+
useEffect27(() => {
|
|
4973
|
+
mountedRef.current = true;
|
|
4974
|
+
return () => {
|
|
4975
|
+
mountedRef.current = false;
|
|
4976
|
+
};
|
|
4977
|
+
}, []);
|
|
4978
|
+
const loadData = useCallback7(async () => {
|
|
4979
|
+
if (!mountedRef.current) return;
|
|
4980
|
+
setLoading(true);
|
|
4981
|
+
try {
|
|
4982
|
+
const [permResult, formResult] = await Promise.all([
|
|
4983
|
+
getViewPermission(request, { formUuid, appType, formInstanceId }),
|
|
4984
|
+
getFormData(request, { formInstanceId, appType, formUuid })
|
|
4985
|
+
]);
|
|
4986
|
+
if (!mountedRef.current) return;
|
|
4987
|
+
if (!permResult || !permResult.operations || permResult.operations.length === 0) {
|
|
4988
|
+
onPermissionDenied?.();
|
|
4989
|
+
}
|
|
4990
|
+
setPermissions(permResult);
|
|
4991
|
+
setInstanceInfo(formResult);
|
|
4992
|
+
setFormData(formResult?.data ?? null);
|
|
4993
|
+
} catch (error) {
|
|
4994
|
+
console.error("[useFormDetail] Failed to load data:", error);
|
|
4995
|
+
if (mountedRef.current) {
|
|
4996
|
+
setPermissions(null);
|
|
4997
|
+
setInstanceInfo(null);
|
|
4998
|
+
setFormData(null);
|
|
4999
|
+
}
|
|
5000
|
+
} finally {
|
|
5001
|
+
if (mountedRef.current) {
|
|
5002
|
+
setLoading(false);
|
|
5003
|
+
}
|
|
5004
|
+
}
|
|
5005
|
+
}, [request, formUuid, appType, formInstanceId, onPermissionDenied]);
|
|
5006
|
+
useEffect27(() => {
|
|
5007
|
+
loadData();
|
|
5008
|
+
}, [loadData]);
|
|
5009
|
+
const fieldBehaviors = buildFieldBehaviors(permissions, mode);
|
|
5010
|
+
const canEdit = permissions?.operations?.includes("EDIT") ?? false;
|
|
5011
|
+
const canDelete = permissions?.operations?.includes("DELETE") ?? false;
|
|
5012
|
+
const canViewChangeRecords = permissions?.operations?.includes("VIEW_CHANGE_RECORDS") ?? false;
|
|
5013
|
+
const switchToEdit = useCallback7(() => {
|
|
5014
|
+
setMode("edit");
|
|
5015
|
+
loadData();
|
|
5016
|
+
}, [loadData]);
|
|
5017
|
+
const switchToReadonly = useCallback7(() => {
|
|
5018
|
+
setMode("readonly");
|
|
5019
|
+
}, []);
|
|
5020
|
+
const saveChanges = useCallback7(
|
|
5021
|
+
async (values) => {
|
|
5022
|
+
try {
|
|
5023
|
+
await api.updateFormData({
|
|
5024
|
+
formInstanceId,
|
|
5025
|
+
formUuid,
|
|
5026
|
+
appType,
|
|
5027
|
+
updateFormDataJson: JSON.stringify(values)
|
|
5028
|
+
});
|
|
5029
|
+
if (mountedRef.current) {
|
|
5030
|
+
setFormData(values);
|
|
5031
|
+
setMode("readonly");
|
|
5032
|
+
}
|
|
5033
|
+
return true;
|
|
5034
|
+
} catch (error) {
|
|
5035
|
+
console.error("[useFormDetail] Failed to save changes:", error);
|
|
5036
|
+
return false;
|
|
5037
|
+
}
|
|
5038
|
+
},
|
|
5039
|
+
[api, formInstanceId, formUuid, appType]
|
|
5040
|
+
);
|
|
5041
|
+
const deleteInstance = useCallback7(async () => {
|
|
5042
|
+
try {
|
|
5043
|
+
await deleteFormData(request, { formInstanceId, appType, formUuid });
|
|
5044
|
+
return true;
|
|
5045
|
+
} catch (error) {
|
|
5046
|
+
console.error("[useFormDetail] Failed to delete instance:", error);
|
|
5047
|
+
return false;
|
|
5048
|
+
}
|
|
5049
|
+
}, [request, formInstanceId, appType, formUuid]);
|
|
5050
|
+
return {
|
|
5051
|
+
loading,
|
|
5052
|
+
mode,
|
|
5053
|
+
formData,
|
|
5054
|
+
instanceInfo,
|
|
5055
|
+
permissions,
|
|
5056
|
+
fieldBehaviors,
|
|
5057
|
+
switchToEdit,
|
|
5058
|
+
switchToReadonly,
|
|
5059
|
+
saveChanges,
|
|
5060
|
+
deleteInstance,
|
|
5061
|
+
canEdit,
|
|
5062
|
+
canDelete,
|
|
5063
|
+
canViewChangeRecords
|
|
5064
|
+
};
|
|
5065
|
+
}
|
|
5066
|
+
|
|
5067
|
+
// src/hooks/useProcessDetail.ts
|
|
5068
|
+
import { useState as useState21, useEffect as useEffect28, useCallback as useCallback8, useRef as useRef8 } from "react";
|
|
5069
|
+
function useProcessDetail(options) {
|
|
5070
|
+
const { formUuid, appType, formInstanceId } = options;
|
|
5071
|
+
const { api } = useFormContext();
|
|
5072
|
+
const request = api.request;
|
|
5073
|
+
const [loading, setLoading] = useState21(true);
|
|
5074
|
+
const [mode, setMode] = useState21("readonly");
|
|
5075
|
+
const [processInfo, setProcessInfo] = useState21(null);
|
|
5076
|
+
const [progressList, setProgressList] = useState21([]);
|
|
5077
|
+
const [formData, setFormData] = useState21(null);
|
|
5078
|
+
const [instanceInfo, setInstanceInfo] = useState21(null);
|
|
5079
|
+
const [isApprover, setIsApprover] = useState21(false);
|
|
5080
|
+
const [canWithdraw, setCanWithdraw] = useState21(false);
|
|
5081
|
+
const [permissions, setPermissions] = useState21(null);
|
|
5082
|
+
const [processDefinition, setProcessDefinition] = useState21(null);
|
|
5083
|
+
const mountedRef = useRef8(true);
|
|
5084
|
+
useEffect28(() => {
|
|
5085
|
+
mountedRef.current = true;
|
|
5086
|
+
return () => {
|
|
5087
|
+
mountedRef.current = false;
|
|
5088
|
+
};
|
|
5089
|
+
}, []);
|
|
5090
|
+
const currentTask = processInfo?.currentTask ?? null;
|
|
5091
|
+
const processStatus = processInfo?.processStatus ?? null;
|
|
5092
|
+
const isOriginatorReturn = currentTask?.nodeType === "originator_return";
|
|
5093
|
+
const isProcessCompleted = processStatus === "completed" || processStatus === "terminated";
|
|
5094
|
+
const { fieldBehaviors } = useFieldPermission({
|
|
5095
|
+
viewPermissions: permissions ?? void 0,
|
|
5096
|
+
processDefinition: processDefinition ?? void 0,
|
|
5097
|
+
currentTask: currentTask ?? void 0,
|
|
5098
|
+
isApprover,
|
|
5099
|
+
mode
|
|
5100
|
+
});
|
|
5101
|
+
const activeActions = isApprover && currentTask?.actions ? currentTask.actions : [];
|
|
5102
|
+
const loadData = useCallback8(async () => {
|
|
5103
|
+
if (!mountedRef.current) return;
|
|
5104
|
+
setLoading(true);
|
|
5105
|
+
try {
|
|
5106
|
+
const [basicResult, approvalResult, permResult, formResult] = await Promise.all([
|
|
5107
|
+
getProcessBasic(request, formInstanceId),
|
|
5108
|
+
checkUserApproval(request, formInstanceId),
|
|
5109
|
+
getViewPermission(request, { formUuid, appType, formInstanceId }),
|
|
5110
|
+
getFormData(request, { formInstanceId, appType, formUuid })
|
|
5111
|
+
]);
|
|
5112
|
+
if (!mountedRef.current) return;
|
|
5113
|
+
setProcessInfo(basicResult);
|
|
5114
|
+
setIsApprover(approvalResult?.isApprover ?? false);
|
|
5115
|
+
setCanWithdraw(approvalResult?.canUndo ?? false);
|
|
5116
|
+
setPermissions(permResult);
|
|
5117
|
+
setInstanceInfo(formResult);
|
|
5118
|
+
setFormData(formResult?.data ?? null);
|
|
5119
|
+
if (permResult?.operations?.includes("VIEW_PROCESS") || permResult?.operations?.length > 0) {
|
|
5120
|
+
try {
|
|
5121
|
+
const progress = await getProcessProgress(request, formInstanceId);
|
|
5122
|
+
if (mountedRef.current) {
|
|
5123
|
+
setProgressList(progress);
|
|
5124
|
+
}
|
|
5125
|
+
} catch (error) {
|
|
5126
|
+
console.error("[useProcessDetail] Failed to load progress:", error);
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5129
|
+
const task = basicResult?.currentTask;
|
|
5130
|
+
if (approvalResult?.isApprover && task && (task.nodeType === "originator_return" || task.nodeType === "approval")) {
|
|
5131
|
+
try {
|
|
5132
|
+
const definition = await getProcessDefinition(request, formUuid);
|
|
5133
|
+
if (mountedRef.current) {
|
|
5134
|
+
setProcessDefinition(definition);
|
|
5135
|
+
}
|
|
5136
|
+
} catch (error) {
|
|
5137
|
+
console.error("[useProcessDetail] Failed to load process definition:", error);
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
} catch (error) {
|
|
5141
|
+
console.error("[useProcessDetail] Failed to load data:", error);
|
|
5142
|
+
if (mountedRef.current) {
|
|
5143
|
+
setProcessInfo(null);
|
|
5144
|
+
setFormData(null);
|
|
5145
|
+
setInstanceInfo(null);
|
|
5146
|
+
}
|
|
5147
|
+
} finally {
|
|
5148
|
+
if (mountedRef.current) {
|
|
5149
|
+
setLoading(false);
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
}, [request, formUuid, appType, formInstanceId]);
|
|
5153
|
+
useEffect28(() => {
|
|
5154
|
+
loadData();
|
|
5155
|
+
}, [loadData]);
|
|
5156
|
+
const switchToEdit = useCallback8(() => {
|
|
5157
|
+
setMode("edit");
|
|
5158
|
+
}, []);
|
|
5159
|
+
const switchToReadonly = useCallback8(() => {
|
|
5160
|
+
setMode("readonly");
|
|
5161
|
+
}, []);
|
|
5162
|
+
const refreshProgress = useCallback8(async () => {
|
|
5163
|
+
try {
|
|
5164
|
+
const [progress, basicResult] = await Promise.all([
|
|
5165
|
+
getProcessProgress(request, formInstanceId),
|
|
5166
|
+
getProcessBasic(request, formInstanceId)
|
|
5167
|
+
]);
|
|
5168
|
+
if (mountedRef.current) {
|
|
5169
|
+
setProgressList(progress);
|
|
5170
|
+
setProcessInfo(basicResult);
|
|
5171
|
+
}
|
|
5172
|
+
} catch (error) {
|
|
5173
|
+
console.error("[useProcessDetail] Failed to refresh progress:", error);
|
|
5174
|
+
}
|
|
5175
|
+
}, [request, formInstanceId]);
|
|
5176
|
+
return {
|
|
5177
|
+
loading,
|
|
5178
|
+
processInfo,
|
|
5179
|
+
processStatus,
|
|
5180
|
+
currentTask,
|
|
5181
|
+
progressList,
|
|
5182
|
+
formData,
|
|
5183
|
+
instanceInfo,
|
|
5184
|
+
isApprover,
|
|
5185
|
+
activeActions,
|
|
5186
|
+
fieldBehaviors,
|
|
5187
|
+
mode,
|
|
5188
|
+
isOriginatorReturn,
|
|
5189
|
+
isProcessCompleted,
|
|
5190
|
+
canWithdraw,
|
|
5191
|
+
switchToEdit,
|
|
5192
|
+
switchToReadonly,
|
|
5193
|
+
refreshProgress
|
|
5194
|
+
};
|
|
5195
|
+
}
|
|
5196
|
+
|
|
5197
|
+
// src/hooks/useApprovalActions.ts
|
|
5198
|
+
import { useState as useState22, useCallback as useCallback9, useRef as useRef9, useEffect as useEffect29 } from "react";
|
|
5199
|
+
function useApprovalActions(options) {
|
|
5200
|
+
const { formInstanceId, formUuid, appType, currentTaskId, onActionComplete, getFormValues } = options;
|
|
5201
|
+
const { api } = useFormContext();
|
|
5202
|
+
const request = api.request;
|
|
5203
|
+
const [isLoading, setIsLoading] = useState22(false);
|
|
5204
|
+
const [currentAction, setCurrentAction] = useState22(null);
|
|
5205
|
+
const [returnableNodes, setReturnableNodes] = useState22([]);
|
|
5206
|
+
const mountedRef = useRef9(true);
|
|
5207
|
+
useEffect29(() => {
|
|
5208
|
+
mountedRef.current = true;
|
|
5209
|
+
return () => {
|
|
5210
|
+
mountedRef.current = false;
|
|
5211
|
+
};
|
|
5212
|
+
}, []);
|
|
5213
|
+
const resetLoading = useCallback9(() => {
|
|
5214
|
+
if (mountedRef.current) {
|
|
5215
|
+
setIsLoading(false);
|
|
5216
|
+
setCurrentAction(null);
|
|
5217
|
+
}
|
|
5218
|
+
}, []);
|
|
5219
|
+
const approve = useCallback9(
|
|
5220
|
+
async (comments) => {
|
|
5221
|
+
setIsLoading(true);
|
|
5222
|
+
setCurrentAction("approve");
|
|
5223
|
+
try {
|
|
5224
|
+
const formValues = getFormValues?.();
|
|
5225
|
+
await handleApproval(request, {
|
|
5226
|
+
instanceId: formInstanceId,
|
|
5227
|
+
action: "approved",
|
|
5228
|
+
comments,
|
|
5229
|
+
appType,
|
|
5230
|
+
formUuid,
|
|
5231
|
+
updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
|
|
5232
|
+
});
|
|
5233
|
+
resetLoading();
|
|
5234
|
+
onActionComplete?.("approve");
|
|
5235
|
+
return true;
|
|
5236
|
+
} catch (error) {
|
|
5237
|
+
console.error("[useApprovalActions] approve failed:", error);
|
|
5238
|
+
resetLoading();
|
|
5239
|
+
return false;
|
|
5240
|
+
}
|
|
5241
|
+
},
|
|
5242
|
+
[request, formInstanceId, appType, formUuid, getFormValues, onActionComplete, resetLoading]
|
|
5243
|
+
);
|
|
5244
|
+
const reject = useCallback9(
|
|
5245
|
+
async (comments) => {
|
|
5246
|
+
setIsLoading(true);
|
|
5247
|
+
setCurrentAction("reject");
|
|
5248
|
+
try {
|
|
5249
|
+
const formValues = getFormValues?.();
|
|
5250
|
+
await handleApproval(request, {
|
|
5251
|
+
instanceId: formInstanceId,
|
|
5252
|
+
action: "rejected",
|
|
5253
|
+
comments,
|
|
5254
|
+
appType,
|
|
5255
|
+
formUuid,
|
|
5256
|
+
updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
|
|
5257
|
+
});
|
|
5258
|
+
resetLoading();
|
|
5259
|
+
onActionComplete?.("reject");
|
|
5260
|
+
return true;
|
|
5261
|
+
} catch (error) {
|
|
5262
|
+
console.error("[useApprovalActions] reject failed:", error);
|
|
5263
|
+
resetLoading();
|
|
5264
|
+
return false;
|
|
5265
|
+
}
|
|
5266
|
+
},
|
|
5267
|
+
[request, formInstanceId, appType, formUuid, getFormValues, onActionComplete, resetLoading]
|
|
5268
|
+
);
|
|
5269
|
+
const transfer = useCallback9(
|
|
5270
|
+
async (userId, reason) => {
|
|
5271
|
+
if (!currentTaskId) {
|
|
5272
|
+
console.error("[useApprovalActions] transfer failed: no currentTaskId");
|
|
5273
|
+
return false;
|
|
5274
|
+
}
|
|
5275
|
+
setIsLoading(true);
|
|
5276
|
+
setCurrentAction("transfer");
|
|
5277
|
+
try {
|
|
5278
|
+
await transferTask(request, {
|
|
5279
|
+
taskId: currentTaskId,
|
|
5280
|
+
newAssignee: userId,
|
|
5281
|
+
reason
|
|
5282
|
+
});
|
|
5283
|
+
resetLoading();
|
|
5284
|
+
onActionComplete?.("transfer");
|
|
5285
|
+
return true;
|
|
5286
|
+
} catch (error) {
|
|
5287
|
+
console.error("[useApprovalActions] transfer failed:", error);
|
|
5288
|
+
resetLoading();
|
|
5289
|
+
return false;
|
|
5290
|
+
}
|
|
5291
|
+
},
|
|
5292
|
+
[request, currentTaskId, onActionComplete, resetLoading]
|
|
5293
|
+
);
|
|
5294
|
+
const returnTo = useCallback9(
|
|
5295
|
+
async (nodeId, reason) => {
|
|
5296
|
+
if (!currentTaskId) {
|
|
5297
|
+
console.error("[useApprovalActions] returnTo failed: no currentTaskId");
|
|
5298
|
+
return false;
|
|
5299
|
+
}
|
|
5300
|
+
setIsLoading(true);
|
|
5301
|
+
setCurrentAction("return");
|
|
5302
|
+
try {
|
|
5303
|
+
await returnTask(request, {
|
|
5304
|
+
taskId: currentTaskId,
|
|
5305
|
+
targetNodeId: nodeId,
|
|
5306
|
+
reason
|
|
5307
|
+
});
|
|
5308
|
+
resetLoading();
|
|
5309
|
+
onActionComplete?.("return");
|
|
5310
|
+
return true;
|
|
5311
|
+
} catch (error) {
|
|
5312
|
+
console.error("[useApprovalActions] returnTo failed:", error);
|
|
5313
|
+
resetLoading();
|
|
5314
|
+
return false;
|
|
5315
|
+
}
|
|
5316
|
+
},
|
|
5317
|
+
[request, currentTaskId, onActionComplete, resetLoading]
|
|
5318
|
+
);
|
|
5319
|
+
const withdraw = useCallback9(
|
|
5320
|
+
async (reason) => {
|
|
5321
|
+
setIsLoading(true);
|
|
5322
|
+
setCurrentAction("withdraw");
|
|
5323
|
+
try {
|
|
5324
|
+
await withdrawProcess(request, {
|
|
5325
|
+
instanceId: formInstanceId,
|
|
5326
|
+
reason
|
|
5327
|
+
});
|
|
5328
|
+
resetLoading();
|
|
5329
|
+
onActionComplete?.("withdraw");
|
|
5330
|
+
return true;
|
|
5331
|
+
} catch (error) {
|
|
5332
|
+
console.error("[useApprovalActions] withdraw failed:", error);
|
|
5333
|
+
resetLoading();
|
|
5334
|
+
return false;
|
|
5335
|
+
}
|
|
5336
|
+
},
|
|
5337
|
+
[request, formInstanceId, onActionComplete, resetLoading]
|
|
5338
|
+
);
|
|
5339
|
+
const save = useCallback9(async () => {
|
|
5340
|
+
setIsLoading(true);
|
|
5341
|
+
setCurrentAction("save");
|
|
5342
|
+
try {
|
|
5343
|
+
const formValues = getFormValues?.() ?? {};
|
|
5344
|
+
await saveTask(request, {
|
|
5345
|
+
instanceId: formInstanceId,
|
|
5346
|
+
formUuid,
|
|
5347
|
+
appType,
|
|
5348
|
+
updateFormDataJson: JSON.stringify(formValues)
|
|
5349
|
+
});
|
|
5350
|
+
resetLoading();
|
|
5351
|
+
onActionComplete?.("save");
|
|
5352
|
+
return true;
|
|
5353
|
+
} catch (error) {
|
|
5354
|
+
console.error("[useApprovalActions] save failed:", error);
|
|
5355
|
+
resetLoading();
|
|
5356
|
+
return false;
|
|
5357
|
+
}
|
|
5358
|
+
}, [request, formInstanceId, formUuid, appType, getFormValues, onActionComplete, resetLoading]);
|
|
5359
|
+
const resubmit = useCallback9(
|
|
5360
|
+
async (comments) => {
|
|
5361
|
+
if (!currentTaskId) {
|
|
5362
|
+
console.error("[useApprovalActions] resubmit failed: no currentTaskId");
|
|
5363
|
+
return false;
|
|
5364
|
+
}
|
|
5365
|
+
setIsLoading(true);
|
|
5366
|
+
setCurrentAction("resubmit");
|
|
5367
|
+
try {
|
|
5368
|
+
const formValues = getFormValues?.() ?? {};
|
|
5369
|
+
await resubmitTask(request, {
|
|
5370
|
+
taskId: currentTaskId,
|
|
5371
|
+
formUuid,
|
|
5372
|
+
appType,
|
|
5373
|
+
updateFormDataJson: JSON.stringify(formValues),
|
|
5374
|
+
comments
|
|
5375
|
+
});
|
|
5376
|
+
resetLoading();
|
|
5377
|
+
onActionComplete?.("resubmit");
|
|
5378
|
+
return true;
|
|
5379
|
+
} catch (error) {
|
|
5380
|
+
console.error("[useApprovalActions] resubmit failed:", error);
|
|
5381
|
+
resetLoading();
|
|
5382
|
+
return false;
|
|
5383
|
+
}
|
|
5384
|
+
},
|
|
5385
|
+
[request, currentTaskId, formUuid, appType, getFormValues, onActionComplete, resetLoading]
|
|
5386
|
+
);
|
|
5387
|
+
const loadReturnableNodes = useCallback9(async () => {
|
|
5388
|
+
if (!currentTaskId) return;
|
|
5389
|
+
try {
|
|
5390
|
+
const nodes = await getReturnableNodes(request, currentTaskId);
|
|
5391
|
+
if (mountedRef.current) {
|
|
5392
|
+
setReturnableNodes(nodes);
|
|
5393
|
+
}
|
|
5394
|
+
} catch (error) {
|
|
5395
|
+
console.error("[useApprovalActions] loadReturnableNodes failed:", error);
|
|
5396
|
+
}
|
|
5397
|
+
}, [request, currentTaskId]);
|
|
5398
|
+
return {
|
|
5399
|
+
approve,
|
|
5400
|
+
reject,
|
|
5401
|
+
transfer,
|
|
5402
|
+
returnTo,
|
|
5403
|
+
withdraw,
|
|
5404
|
+
save,
|
|
5405
|
+
resubmit,
|
|
5406
|
+
isLoading,
|
|
5407
|
+
currentAction,
|
|
5408
|
+
returnableNodes,
|
|
5409
|
+
loadReturnableNodes
|
|
5410
|
+
};
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5413
|
+
// src/hooks/useChangeRecords.ts
|
|
5414
|
+
import { useState as useState23, useEffect as useEffect30, useCallback as useCallback10, useRef as useRef10 } from "react";
|
|
5415
|
+
function useChangeRecords(options) {
|
|
5416
|
+
const { formUuid, appType, formInstanceId, pageSize = 20, autoLoad = true } = options;
|
|
5417
|
+
const { api } = useFormContext();
|
|
5418
|
+
const request = api.request;
|
|
5419
|
+
const [records, setRecords] = useState23([]);
|
|
5420
|
+
const [loading, setLoading] = useState23(false);
|
|
5421
|
+
const [total, setTotal] = useState23(0);
|
|
5422
|
+
const [page, setPage] = useState23(1);
|
|
5423
|
+
const mountedRef = useRef10(true);
|
|
5424
|
+
useEffect30(() => {
|
|
5425
|
+
mountedRef.current = true;
|
|
5426
|
+
return () => {
|
|
5427
|
+
mountedRef.current = false;
|
|
5428
|
+
};
|
|
5429
|
+
}, []);
|
|
5430
|
+
const fetchRecords = useCallback10(
|
|
5431
|
+
async (pageNum, append) => {
|
|
5432
|
+
if (!mountedRef.current) return;
|
|
5433
|
+
setLoading(true);
|
|
5434
|
+
try {
|
|
5435
|
+
const result = await getChangeRecords(request, {
|
|
5436
|
+
formUuid,
|
|
5437
|
+
appType,
|
|
5438
|
+
formInstanceId,
|
|
5439
|
+
page: pageNum,
|
|
5440
|
+
pageSize
|
|
5441
|
+
});
|
|
5442
|
+
if (!mountedRef.current) return;
|
|
5443
|
+
if (append) {
|
|
5444
|
+
setRecords((prev) => [...prev, ...result.records]);
|
|
5445
|
+
} else {
|
|
5446
|
+
setRecords(result.records);
|
|
5447
|
+
}
|
|
5448
|
+
setTotal(result.total);
|
|
5449
|
+
setPage(pageNum);
|
|
5450
|
+
} catch (error) {
|
|
5451
|
+
console.error("[useChangeRecords] Failed to load change records:", error);
|
|
5452
|
+
} finally {
|
|
5453
|
+
if (mountedRef.current) {
|
|
5454
|
+
setLoading(false);
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5457
|
+
},
|
|
5458
|
+
[request, formUuid, appType, formInstanceId, pageSize]
|
|
5459
|
+
);
|
|
5460
|
+
useEffect30(() => {
|
|
5461
|
+
if (autoLoad) {
|
|
5462
|
+
fetchRecords(1, false);
|
|
5463
|
+
}
|
|
5464
|
+
}, [autoLoad, fetchRecords]);
|
|
5465
|
+
const hasMore = records.length < total;
|
|
5466
|
+
const loadMore = useCallback10(async () => {
|
|
5467
|
+
if (!hasMore || loading) return;
|
|
5468
|
+
await fetchRecords(page + 1, true);
|
|
5469
|
+
}, [hasMore, loading, page, fetchRecords]);
|
|
5470
|
+
const refresh = useCallback10(async () => {
|
|
5471
|
+
setRecords([]);
|
|
5472
|
+
setPage(1);
|
|
5473
|
+
setTotal(0);
|
|
5474
|
+
await fetchRecords(1, false);
|
|
5475
|
+
}, [fetchRecords]);
|
|
5476
|
+
return {
|
|
5477
|
+
records,
|
|
5478
|
+
loading,
|
|
5479
|
+
total,
|
|
5480
|
+
page,
|
|
5481
|
+
loadMore,
|
|
5482
|
+
refresh,
|
|
5483
|
+
hasMore
|
|
5484
|
+
};
|
|
5485
|
+
}
|
|
5486
|
+
|
|
5487
|
+
// src/hooks/useFormNavigation.ts
|
|
5488
|
+
import { useState as useState24, useCallback as useCallback11, useRef as useRef11, useEffect as useEffect31 } from "react";
|
|
5489
|
+
var normalizeBasePath = (basePath) => {
|
|
5490
|
+
const normalized = String(basePath || "").replace(/^\/+|\/+$/g, "");
|
|
5491
|
+
return normalized ? `/${normalized}` : "";
|
|
5492
|
+
};
|
|
5493
|
+
var inferBasePath = (appType) => {
|
|
5494
|
+
if (typeof window === "undefined") return "";
|
|
5495
|
+
const pathname = window.location?.pathname || "";
|
|
5496
|
+
const marker = `/${appType}/`;
|
|
5497
|
+
const markerIndex = pathname.indexOf(marker);
|
|
5498
|
+
if (markerIndex <= 0) return "";
|
|
5499
|
+
return pathname.slice(0, markerIndex);
|
|
5500
|
+
};
|
|
5501
|
+
var buildDetailUrl = (appType, formUuid, formInstId, detailType, basePath) => {
|
|
5502
|
+
const prefix = normalizeBasePath(basePath ?? inferBasePath(appType));
|
|
5503
|
+
return `${prefix}/${appType}/${detailType}/${formUuid}?formInstId=${encodeURIComponent(formInstId)}`;
|
|
5504
|
+
};
|
|
5505
|
+
function useFormNavigation(options) {
|
|
5506
|
+
const {
|
|
5507
|
+
appType,
|
|
5508
|
+
formUuid,
|
|
5509
|
+
formType = "form",
|
|
5510
|
+
mode = "redirect",
|
|
5511
|
+
redirectDelay = 3e3,
|
|
5512
|
+
basePath,
|
|
5513
|
+
onStay
|
|
5514
|
+
} = options;
|
|
5515
|
+
const [isRedirecting, setIsRedirecting] = useState24(false);
|
|
5516
|
+
const [countdown, setCountdown] = useState24(0);
|
|
5517
|
+
const timerRef = useRef11(null);
|
|
5518
|
+
const redirectTargetRef = useRef11(null);
|
|
5519
|
+
const mountedRef = useRef11(true);
|
|
5520
|
+
useEffect31(() => {
|
|
5521
|
+
mountedRef.current = true;
|
|
5522
|
+
return () => {
|
|
5523
|
+
mountedRef.current = false;
|
|
5524
|
+
if (timerRef.current) {
|
|
5525
|
+
clearInterval(timerRef.current);
|
|
5526
|
+
timerRef.current = null;
|
|
5527
|
+
}
|
|
5528
|
+
};
|
|
5529
|
+
}, []);
|
|
5530
|
+
const navigateToDetail = useCallback11(
|
|
5531
|
+
(formInstId) => {
|
|
5532
|
+
window.location.href = buildDetailUrl(appType, formUuid, formInstId, "formDetail", basePath);
|
|
5533
|
+
},
|
|
5534
|
+
[appType, basePath, formUuid]
|
|
5535
|
+
);
|
|
5536
|
+
const navigateToProcessDetail = useCallback11(
|
|
5537
|
+
(formInstId) => {
|
|
5538
|
+
window.location.href = buildDetailUrl(
|
|
5539
|
+
appType,
|
|
5540
|
+
formUuid,
|
|
5541
|
+
formInstId,
|
|
5542
|
+
"processDetail",
|
|
5543
|
+
basePath
|
|
5544
|
+
);
|
|
5545
|
+
},
|
|
5546
|
+
[appType, basePath, formUuid]
|
|
5547
|
+
);
|
|
5548
|
+
const startRedirectCountdown = useCallback11(
|
|
5549
|
+
(targetUrl) => {
|
|
5550
|
+
const totalSeconds = Math.ceil(redirectDelay / 1e3);
|
|
5551
|
+
setIsRedirecting(true);
|
|
5552
|
+
setCountdown(totalSeconds);
|
|
5553
|
+
redirectTargetRef.current = targetUrl;
|
|
5554
|
+
timerRef.current = setInterval(() => {
|
|
5555
|
+
if (!mountedRef.current) {
|
|
5556
|
+
if (timerRef.current) {
|
|
5557
|
+
clearInterval(timerRef.current);
|
|
5558
|
+
timerRef.current = null;
|
|
5559
|
+
}
|
|
5560
|
+
return;
|
|
5561
|
+
}
|
|
5562
|
+
setCountdown((prev) => {
|
|
5563
|
+
const next = prev - 1;
|
|
5564
|
+
if (next <= 0) {
|
|
5565
|
+
if (timerRef.current) {
|
|
5566
|
+
clearInterval(timerRef.current);
|
|
5567
|
+
timerRef.current = null;
|
|
5568
|
+
}
|
|
5569
|
+
setIsRedirecting(false);
|
|
5570
|
+
if (redirectTargetRef.current) {
|
|
5571
|
+
window.location.href = redirectTargetRef.current;
|
|
5572
|
+
}
|
|
5573
|
+
return 0;
|
|
5574
|
+
}
|
|
5575
|
+
return next;
|
|
5576
|
+
});
|
|
5577
|
+
}, 1e3);
|
|
5578
|
+
},
|
|
5579
|
+
[redirectDelay]
|
|
5580
|
+
);
|
|
5581
|
+
const cancelRedirect = useCallback11(() => {
|
|
5582
|
+
if (timerRef.current) {
|
|
5583
|
+
clearInterval(timerRef.current);
|
|
5584
|
+
timerRef.current = null;
|
|
5585
|
+
}
|
|
5586
|
+
setIsRedirecting(false);
|
|
5587
|
+
setCountdown(0);
|
|
5588
|
+
redirectTargetRef.current = null;
|
|
5589
|
+
}, []);
|
|
5590
|
+
const handlePostSubmit = useCallback11(
|
|
5591
|
+
(formInstId) => {
|
|
5592
|
+
if (mode === "stay") {
|
|
5593
|
+
onStay?.(formInstId);
|
|
5594
|
+
return;
|
|
5595
|
+
}
|
|
5596
|
+
if (mode === "callback") {
|
|
5597
|
+
onStay?.(formInstId);
|
|
5598
|
+
return;
|
|
5599
|
+
}
|
|
5600
|
+
const targetUrl = buildDetailUrl(
|
|
5601
|
+
appType,
|
|
5602
|
+
formUuid,
|
|
5603
|
+
formInstId,
|
|
5604
|
+
formType === "process" ? "processDetail" : "formDetail",
|
|
5605
|
+
basePath
|
|
5606
|
+
);
|
|
5607
|
+
startRedirectCountdown(targetUrl);
|
|
5608
|
+
},
|
|
5609
|
+
[mode, formType, appType, formUuid, basePath, onStay, startRedirectCountdown]
|
|
5610
|
+
);
|
|
5611
|
+
return {
|
|
5612
|
+
navigateToDetail,
|
|
5613
|
+
navigateToProcessDetail,
|
|
5614
|
+
handlePostSubmit,
|
|
5615
|
+
isRedirecting,
|
|
5616
|
+
countdown,
|
|
5617
|
+
cancelRedirect
|
|
5618
|
+
};
|
|
5619
|
+
}
|
|
5620
|
+
|
|
5621
|
+
// src/hooks/useDraftStorage.ts
|
|
5622
|
+
import { useState as useState25, useCallback as useCallback12, useEffect as useEffect32 } from "react";
|
|
5623
|
+
function getDraftKey(appType, formUuid) {
|
|
5624
|
+
return `${appType}__${formUuid}__draft`;
|
|
5625
|
+
}
|
|
5626
|
+
function readDraft(key) {
|
|
5627
|
+
try {
|
|
5628
|
+
const raw = localStorage.getItem(key);
|
|
5629
|
+
if (!raw) return null;
|
|
5630
|
+
const parsed = JSON.parse(raw);
|
|
5631
|
+
if (parsed && typeof parsed.data === "object" && typeof parsed.ts === "number") {
|
|
5632
|
+
return parsed;
|
|
5633
|
+
}
|
|
5634
|
+
return null;
|
|
5635
|
+
} catch {
|
|
5636
|
+
return null;
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
function useDraftStorage(options) {
|
|
5640
|
+
const { appType, formUuid, autoRestore = false } = options;
|
|
5641
|
+
const key = getDraftKey(appType, formUuid);
|
|
5642
|
+
const [hasDraft, setHasDraft] = useState25(false);
|
|
5643
|
+
const [draftData, setDraftData] = useState25(null);
|
|
5644
|
+
const [draftTimestamp, setDraftTimestamp] = useState25(null);
|
|
5645
|
+
useEffect32(() => {
|
|
5646
|
+
const stored = readDraft(key);
|
|
5647
|
+
if (stored) {
|
|
5648
|
+
setHasDraft(true);
|
|
5649
|
+
setDraftTimestamp(stored.ts);
|
|
5650
|
+
if (autoRestore) {
|
|
5651
|
+
setDraftData(stored.data);
|
|
5652
|
+
}
|
|
5653
|
+
} else {
|
|
5654
|
+
setHasDraft(false);
|
|
5655
|
+
setDraftData(null);
|
|
5656
|
+
setDraftTimestamp(null);
|
|
5657
|
+
}
|
|
5658
|
+
}, [key, autoRestore]);
|
|
5659
|
+
const saveDraft = useCallback12(
|
|
5660
|
+
(data) => {
|
|
5661
|
+
const payload = { data, ts: Date.now() };
|
|
5662
|
+
try {
|
|
5663
|
+
localStorage.setItem(key, JSON.stringify(payload));
|
|
5664
|
+
setHasDraft(true);
|
|
5665
|
+
setDraftData(data);
|
|
5666
|
+
setDraftTimestamp(payload.ts);
|
|
5667
|
+
} catch (error) {
|
|
5668
|
+
console.error("[useDraftStorage] Failed to save draft:", error);
|
|
5669
|
+
}
|
|
5670
|
+
},
|
|
5671
|
+
[key]
|
|
5672
|
+
);
|
|
5673
|
+
const restoreDraft = useCallback12(() => {
|
|
5674
|
+
const stored = readDraft(key);
|
|
5675
|
+
if (stored) {
|
|
5676
|
+
setDraftData(stored.data);
|
|
5677
|
+
return stored.data;
|
|
5678
|
+
}
|
|
5679
|
+
return null;
|
|
5680
|
+
}, [key]);
|
|
5681
|
+
const clearDraft = useCallback12(() => {
|
|
5682
|
+
try {
|
|
5683
|
+
localStorage.removeItem(key);
|
|
5684
|
+
} catch (error) {
|
|
5685
|
+
console.error("[useDraftStorage] Failed to clear draft:", error);
|
|
5686
|
+
}
|
|
5687
|
+
setHasDraft(false);
|
|
5688
|
+
setDraftData(null);
|
|
5689
|
+
setDraftTimestamp(null);
|
|
5690
|
+
}, [key]);
|
|
5691
|
+
return {
|
|
5692
|
+
hasDraft,
|
|
5693
|
+
draftData,
|
|
5694
|
+
draftTimestamp,
|
|
5695
|
+
saveDraft,
|
|
5696
|
+
restoreDraft,
|
|
5697
|
+
clearDraft
|
|
5698
|
+
};
|
|
5699
|
+
}
|
|
5700
|
+
|
|
4709
5701
|
// src/utils/defineFormSchema.ts
|
|
4710
5702
|
function defineFormSchema(schema) {
|
|
4711
5703
|
return schema;
|
|
4712
5704
|
}
|
|
5705
|
+
|
|
5706
|
+
// src/modules/FormSummaryCard.tsx
|
|
5707
|
+
import { Fragment, jsx as jsx75, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5708
|
+
var toneClasses = {
|
|
5709
|
+
brand: "bg-blue-50 text-blue-600",
|
|
5710
|
+
success: "bg-green-50 text-green-600",
|
|
5711
|
+
danger: "bg-red-50 text-red-600",
|
|
5712
|
+
neutral: "bg-gray-100 text-gray-500",
|
|
5713
|
+
warning: "bg-amber-50 text-amber-600"
|
|
5714
|
+
};
|
|
5715
|
+
var FormSummaryCard = ({
|
|
5716
|
+
title,
|
|
5717
|
+
formInstanceId,
|
|
5718
|
+
creator,
|
|
5719
|
+
createdAt,
|
|
5720
|
+
status,
|
|
5721
|
+
className = "",
|
|
5722
|
+
children
|
|
5723
|
+
}) => {
|
|
5724
|
+
const shortId = formInstanceId ? formInstanceId.slice(0, 8) : null;
|
|
5725
|
+
const renderAvatar = () => {
|
|
5726
|
+
if (!creator) return null;
|
|
5727
|
+
if (creator.avatar) {
|
|
5728
|
+
return /* @__PURE__ */ jsx75(
|
|
5729
|
+
"img",
|
|
5730
|
+
{
|
|
5731
|
+
src: creator.avatar,
|
|
5732
|
+
alt: creator.name,
|
|
5733
|
+
className: "w-7 h-7 rounded-full object-cover"
|
|
5734
|
+
}
|
|
5735
|
+
);
|
|
5736
|
+
}
|
|
5737
|
+
const initial = creator.name.charAt(0);
|
|
5738
|
+
return /* @__PURE__ */ jsx75("span", { className: "w-7 h-7 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-xs font-medium", children: initial });
|
|
5739
|
+
};
|
|
5740
|
+
return /* @__PURE__ */ jsxs21("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 p-6 ${className}`, children: [
|
|
5741
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-start justify-between", children: [
|
|
5742
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
|
|
5743
|
+
title && /* @__PURE__ */ jsx75("h2", { className: "text-xl font-semibold text-gray-900 truncate", children: title }),
|
|
5744
|
+
shortId && /* @__PURE__ */ jsxs21("span", { className: "text-xs text-gray-400 mt-0.5 inline-block", children: [
|
|
5745
|
+
"#",
|
|
5746
|
+
shortId
|
|
5747
|
+
] })
|
|
5748
|
+
] }),
|
|
5749
|
+
status && /* @__PURE__ */ jsx75(
|
|
5750
|
+
"span",
|
|
5751
|
+
{
|
|
5752
|
+
className: `px-2.5 py-0.5 rounded-full text-xs font-medium whitespace-nowrap ${toneClasses[status.tone] || toneClasses.neutral}`,
|
|
5753
|
+
children: status.label
|
|
5754
|
+
}
|
|
5755
|
+
)
|
|
5756
|
+
] }),
|
|
5757
|
+
creator && /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 mt-4 text-sm text-gray-600", children: [
|
|
5758
|
+
renderAvatar(),
|
|
5759
|
+
/* @__PURE__ */ jsx75("span", { className: "font-medium", children: creator.name }),
|
|
5760
|
+
creator.department && /* @__PURE__ */ jsxs21(Fragment, { children: [
|
|
5761
|
+
/* @__PURE__ */ jsx75("span", { className: "text-gray-300", children: "\xB7" }),
|
|
5762
|
+
/* @__PURE__ */ jsx75("span", { children: creator.department })
|
|
5763
|
+
] }),
|
|
5764
|
+
createdAt && /* @__PURE__ */ jsxs21(Fragment, { children: [
|
|
5765
|
+
/* @__PURE__ */ jsx75("span", { className: "text-gray-300", children: "\xB7" }),
|
|
5766
|
+
/* @__PURE__ */ jsx75("span", { className: "text-gray-400", children: createdAt })
|
|
5767
|
+
] })
|
|
5768
|
+
] }),
|
|
5769
|
+
children && /* @__PURE__ */ jsx75("div", { className: "mt-4", children })
|
|
5770
|
+
] });
|
|
5771
|
+
};
|
|
5772
|
+
|
|
5773
|
+
// src/modules/ChangeRecords.tsx
|
|
5774
|
+
import { useState as useState26 } from "react";
|
|
5775
|
+
import { Skeleton } from "antd";
|
|
5776
|
+
import { DownOutlined, UpOutlined } from "@ant-design/icons";
|
|
5777
|
+
import { jsx as jsx76, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5778
|
+
var ChangeRecords = ({
|
|
5779
|
+
records = [],
|
|
5780
|
+
loading = false,
|
|
5781
|
+
defaultExpanded = false,
|
|
5782
|
+
hasMore = false,
|
|
5783
|
+
onLoadMore,
|
|
5784
|
+
onExpand,
|
|
5785
|
+
className = "",
|
|
5786
|
+
renderItem
|
|
5787
|
+
}) => {
|
|
5788
|
+
const [expanded, setExpanded] = useState26(defaultExpanded);
|
|
5789
|
+
const handleToggle = () => {
|
|
5790
|
+
const next = !expanded;
|
|
5791
|
+
setExpanded(next);
|
|
5792
|
+
if (next && onExpand) {
|
|
5793
|
+
onExpand();
|
|
5794
|
+
}
|
|
5795
|
+
};
|
|
5796
|
+
const defaultRenderItem = (record) => /* @__PURE__ */ jsxs22("div", { className: "pl-4 py-3 border-l-2 border-gray-200 ml-1", children: [
|
|
5797
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 text-xs text-gray-400", children: [
|
|
5798
|
+
/* @__PURE__ */ jsx76("span", { children: record.operatedAt }),
|
|
5799
|
+
/* @__PURE__ */ jsx76("span", { className: "text-gray-600 font-medium", children: record.operatorName }),
|
|
5800
|
+
/* @__PURE__ */ jsx76("span", { children: "\u4FEE\u6539\u4E86" }),
|
|
5801
|
+
/* @__PURE__ */ jsx76("span", { className: "text-gray-800 font-medium", children: record.fieldLabel })
|
|
5802
|
+
] }),
|
|
5803
|
+
/* @__PURE__ */ jsxs22("div", { className: "mt-1.5 text-sm text-gray-600 flex items-center gap-2", children: [
|
|
5804
|
+
/* @__PURE__ */ jsx76("span", { className: "bg-red-50 text-red-600 px-1.5 py-0.5 rounded text-xs line-through", children: formatValue(record.oldValue) }),
|
|
5805
|
+
/* @__PURE__ */ jsx76("span", { className: "text-gray-400", children: "\u2192" }),
|
|
5806
|
+
/* @__PURE__ */ jsx76("span", { className: "bg-green-50 text-green-600 px-1.5 py-0.5 rounded text-xs", children: formatValue(record.newValue) })
|
|
5807
|
+
] })
|
|
5808
|
+
] });
|
|
5809
|
+
return /* @__PURE__ */ jsxs22("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 ${className}`, children: [
|
|
5810
|
+
/* @__PURE__ */ jsxs22(
|
|
5811
|
+
"button",
|
|
5812
|
+
{
|
|
5813
|
+
type: "button",
|
|
5814
|
+
className: "w-full flex items-center justify-between p-6 text-left hover:bg-gray-50/50 transition-colors rounded-xl",
|
|
5815
|
+
onClick: handleToggle,
|
|
5816
|
+
children: [
|
|
5817
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
5818
|
+
/* @__PURE__ */ jsx76("h3", { className: "text-lg font-semibold text-gray-900", children: "\u53D8\u66F4\u8BB0\u5F55" }),
|
|
5819
|
+
/* @__PURE__ */ jsx76("span", { className: "text-xs text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded-full", children: records.length })
|
|
5820
|
+
] }),
|
|
5821
|
+
/* @__PURE__ */ jsx76("span", { className: "text-gray-400 text-xs", children: expanded ? /* @__PURE__ */ jsx76(UpOutlined, {}) : /* @__PURE__ */ jsx76(DownOutlined, {}) })
|
|
5822
|
+
]
|
|
5823
|
+
}
|
|
5824
|
+
),
|
|
5825
|
+
expanded && /* @__PURE__ */ jsxs22("div", { className: "px-6 pb-6", children: [
|
|
5826
|
+
loading && records.length === 0 ? /* @__PURE__ */ jsx76(Skeleton, { active: true, paragraph: { rows: 3 } }) : records.length === 0 ? /* @__PURE__ */ jsx76("p", { className: "text-sm text-gray-400 text-center py-4", children: "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) : /* @__PURE__ */ jsx76("div", { className: "space-y-1", children: records.map((record) => /* @__PURE__ */ jsx76("div", { children: renderItem ? renderItem(record) : defaultRenderItem(record) }, record.id)) }),
|
|
5827
|
+
hasMore && /* @__PURE__ */ jsx76(
|
|
5828
|
+
"button",
|
|
5829
|
+
{
|
|
5830
|
+
type: "button",
|
|
5831
|
+
className: "mt-4 w-full text-center text-sm text-blue-600 hover:text-blue-700 py-2 rounded-lg hover:bg-blue-50/50 transition-colors",
|
|
5832
|
+
onClick: onLoadMore,
|
|
5833
|
+
disabled: loading,
|
|
5834
|
+
children: loading ? "\u52A0\u8F7D\u4E2D..." : "\u52A0\u8F7D\u66F4\u591A"
|
|
5835
|
+
}
|
|
5836
|
+
)
|
|
5837
|
+
] })
|
|
5838
|
+
] });
|
|
5839
|
+
};
|
|
5840
|
+
function formatValue(value) {
|
|
5841
|
+
if (value === null || value === void 0) return "\u7A7A";
|
|
5842
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
5843
|
+
return String(value);
|
|
5844
|
+
}
|
|
5845
|
+
|
|
5846
|
+
// src/modules/ApprovalTimeline.tsx
|
|
5847
|
+
import { Fragment as Fragment2, jsx as jsx77, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5848
|
+
var toneClasses2 = {
|
|
5849
|
+
brand: "bg-blue-50 text-blue-600",
|
|
5850
|
+
success: "bg-green-50 text-green-600",
|
|
5851
|
+
danger: "bg-red-50 text-red-600",
|
|
5852
|
+
neutral: "bg-gray-100 text-gray-500",
|
|
5853
|
+
warning: "bg-amber-50 text-amber-600"
|
|
5854
|
+
};
|
|
5855
|
+
function getNodePhase(task) {
|
|
5856
|
+
if (task.status === "approved" || task.status === "rejected" || task.status === "returned" || task.status === "copied") {
|
|
5857
|
+
return "completed";
|
|
5858
|
+
}
|
|
5859
|
+
if (task.status === "pending" || task.status === "waiting") {
|
|
5860
|
+
return "active";
|
|
5861
|
+
}
|
|
5862
|
+
return "pending";
|
|
5863
|
+
}
|
|
5864
|
+
var ApprovalTimeline = ({
|
|
5865
|
+
tasks,
|
|
5866
|
+
className = "",
|
|
5867
|
+
renderNode,
|
|
5868
|
+
showRemarks = true,
|
|
5869
|
+
compactMode = false
|
|
5870
|
+
}) => {
|
|
5871
|
+
if (!tasks || tasks.length === 0) {
|
|
5872
|
+
return /* @__PURE__ */ jsx77("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 p-6 ${className}`, children: /* @__PURE__ */ jsx77("p", { className: "text-sm text-gray-400 text-center", children: "\u6682\u65E0\u5BA1\u6279\u8BB0\u5F55" }) });
|
|
5873
|
+
}
|
|
5874
|
+
return /* @__PURE__ */ jsx77("div", { className: `${className}`, children: tasks.map((task, index) => {
|
|
5875
|
+
if (renderNode) {
|
|
5876
|
+
return /* @__PURE__ */ jsx77("div", { children: renderNode(task, index) }, task.taskId);
|
|
5877
|
+
}
|
|
5878
|
+
const phase = getNodePhase(task);
|
|
5879
|
+
const isLast = index === tasks.length - 1;
|
|
5880
|
+
const statusMeta = TASK_STATUS_META[task.status];
|
|
5881
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex gap-4", children: [
|
|
5882
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center", children: [
|
|
5883
|
+
phase === "completed" && /* @__PURE__ */ jsx77("div", { className: "w-3 h-3 rounded-full bg-green-500 flex-shrink-0" }),
|
|
5884
|
+
phase === "active" && /* @__PURE__ */ jsx77("div", { className: "w-3 h-3 rounded-full bg-blue-500 ring-4 ring-blue-100 flex-shrink-0" }),
|
|
5885
|
+
phase === "pending" && /* @__PURE__ */ jsx77("div", { className: "w-3 h-3 rounded-full bg-gray-300 flex-shrink-0" }),
|
|
5886
|
+
!isLast && /* @__PURE__ */ jsx77(
|
|
5887
|
+
"div",
|
|
5888
|
+
{
|
|
5889
|
+
className: `w-0.5 flex-1 mt-1 ${phase === "completed" ? "bg-green-300" : phase === "active" ? "bg-blue-400" : "border-l-2 border-dashed border-gray-200"}`
|
|
5890
|
+
}
|
|
5891
|
+
)
|
|
5892
|
+
] }),
|
|
5893
|
+
/* @__PURE__ */ jsx77("div", { className: `flex-1 pb-6 ${isLast ? "pb-0" : ""}`, children: /* @__PURE__ */ jsxs23(
|
|
5894
|
+
"div",
|
|
5895
|
+
{
|
|
5896
|
+
className: `rounded-lg p-4 ${phase === "completed" ? "bg-white border border-gray-100" : phase === "active" ? "bg-white border-l-4 border-l-blue-500 border border-gray-100 shadow-sm" : "bg-gray-50 border border-gray-100 opacity-60"}`,
|
|
5897
|
+
children: [
|
|
5898
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
5899
|
+
/* @__PURE__ */ jsx77("span", { className: "text-sm font-medium text-gray-900", children: task.nodeName }),
|
|
5900
|
+
statusMeta && /* @__PURE__ */ jsx77(
|
|
5901
|
+
"span",
|
|
5902
|
+
{
|
|
5903
|
+
className: `px-2 py-0.5 rounded-full text-xs font-medium ${toneClasses2[statusMeta.tone] || toneClasses2.neutral}`,
|
|
5904
|
+
children: statusMeta.label
|
|
5905
|
+
}
|
|
5906
|
+
)
|
|
5907
|
+
] }),
|
|
5908
|
+
task.assigneeName && /* @__PURE__ */ jsxs23("div", { className: "mt-2 flex items-center gap-1.5 text-sm text-gray-600", children: [
|
|
5909
|
+
/* @__PURE__ */ jsx77("span", { className: "text-gray-400", children: "\u{1F464}" }),
|
|
5910
|
+
/* @__PURE__ */ jsxs23("span", { children: [
|
|
5911
|
+
phase === "active" ? "\u5F53\u524D\u5BA1\u6279\u4EBA: " : "",
|
|
5912
|
+
task.assigneeName
|
|
5913
|
+
] }),
|
|
5914
|
+
task.departmentName && /* @__PURE__ */ jsxs23(Fragment2, { children: [
|
|
5915
|
+
/* @__PURE__ */ jsx77("span", { className: "text-gray-300", children: "\xB7" }),
|
|
5916
|
+
/* @__PURE__ */ jsx77("span", { className: "text-gray-400", children: task.departmentName })
|
|
5917
|
+
] })
|
|
5918
|
+
] }),
|
|
5919
|
+
!compactMode && showRemarks && task.comments && /* @__PURE__ */ jsxs23("div", { className: "mt-2 bg-gray-50 rounded-md p-3 text-sm text-gray-600 italic", children: [
|
|
5920
|
+
"\u{1F4AC} \u201C",
|
|
5921
|
+
task.comments,
|
|
5922
|
+
"\u201D"
|
|
5923
|
+
] }),
|
|
5924
|
+
!compactMode && phase === "active" && !task.comments && /* @__PURE__ */ jsx77("div", { className: "mt-2 text-xs text-gray-400", children: "\u23F3 \u7B49\u5F85\u5904\u7406\u4E2D..." }),
|
|
5925
|
+
!compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ jsxs23("div", { className: "mt-2 text-xs text-gray-400", children: [
|
|
5926
|
+
"\u{1F550} ",
|
|
5927
|
+
task.actionAt || task.createdAt
|
|
5928
|
+
] }),
|
|
5929
|
+
compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ jsx77("div", { className: "mt-1 text-xs text-gray-400", children: task.actionAt || task.createdAt })
|
|
5930
|
+
]
|
|
5931
|
+
}
|
|
5932
|
+
) })
|
|
5933
|
+
] }, task.taskId);
|
|
5934
|
+
}) });
|
|
5935
|
+
};
|
|
5936
|
+
|
|
5937
|
+
// src/modules/ApprovalActions.tsx
|
|
5938
|
+
import { useState as useState27 } from "react";
|
|
5939
|
+
import { Button as Button5, Drawer, Input as Input8, Dropdown } from "antd";
|
|
5940
|
+
import { MoreOutlined, LoadingOutlined } from "@ant-design/icons";
|
|
5941
|
+
import { Fragment as Fragment3, jsx as jsx78, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5942
|
+
var { TextArea: TextArea4 } = Input8;
|
|
5943
|
+
var ApprovalActions = ({
|
|
5944
|
+
actions,
|
|
5945
|
+
onApprove,
|
|
5946
|
+
onReject,
|
|
5947
|
+
onTransfer,
|
|
5948
|
+
onReturn,
|
|
5949
|
+
onWithdraw,
|
|
5950
|
+
onSave,
|
|
5951
|
+
layout = "horizontal",
|
|
5952
|
+
maxVisible = 3,
|
|
5953
|
+
className = ""
|
|
5954
|
+
}) => {
|
|
5955
|
+
const [drawerAction, setDrawerAction] = useState27(null);
|
|
5956
|
+
const [comments, setComments] = useState27("");
|
|
5957
|
+
const [loading, setLoading] = useState27(false);
|
|
5958
|
+
const [saveLoading, setSaveLoading] = useState27(false);
|
|
5959
|
+
const handleOpenDrawer = (action) => {
|
|
5960
|
+
setComments("");
|
|
5961
|
+
setDrawerAction(action);
|
|
5962
|
+
};
|
|
5963
|
+
const handleConfirm = async () => {
|
|
5964
|
+
setLoading(true);
|
|
5965
|
+
try {
|
|
5966
|
+
if (drawerAction === "approve" && onApprove) {
|
|
5967
|
+
await onApprove(comments || void 0);
|
|
5968
|
+
} else if (drawerAction === "reject" && onReject) {
|
|
5969
|
+
await onReject(comments || void 0);
|
|
5970
|
+
} else if (drawerAction === "withdraw" && onWithdraw) {
|
|
5971
|
+
await onWithdraw(comments || void 0);
|
|
5972
|
+
}
|
|
5973
|
+
setDrawerAction(null);
|
|
5974
|
+
} finally {
|
|
5975
|
+
setLoading(false);
|
|
5976
|
+
}
|
|
5977
|
+
};
|
|
5978
|
+
const handleSave = async () => {
|
|
5979
|
+
if (!onSave) return;
|
|
5980
|
+
setSaveLoading(true);
|
|
5981
|
+
try {
|
|
5982
|
+
await onSave();
|
|
5983
|
+
} finally {
|
|
5984
|
+
setSaveLoading(false);
|
|
5985
|
+
}
|
|
5986
|
+
};
|
|
5987
|
+
const actionMap = {};
|
|
5988
|
+
actions.forEach((action) => {
|
|
5989
|
+
switch (action.action) {
|
|
5990
|
+
case "agree":
|
|
5991
|
+
actionMap["agree"] = {
|
|
5992
|
+
label: action.name.zh_CN || "\u540C\u610F",
|
|
5993
|
+
handler: () => handleOpenDrawer("approve"),
|
|
5994
|
+
type: "primary",
|
|
5995
|
+
color: "green"
|
|
5996
|
+
};
|
|
5997
|
+
break;
|
|
5998
|
+
case "rejected":
|
|
5999
|
+
actionMap["rejected"] = {
|
|
6000
|
+
label: action.name.zh_CN || "\u62D2\u7EDD",
|
|
6001
|
+
handler: () => handleOpenDrawer("reject"),
|
|
6002
|
+
type: "default"
|
|
6003
|
+
};
|
|
6004
|
+
break;
|
|
6005
|
+
case "transfer":
|
|
6006
|
+
actionMap["transfer"] = {
|
|
6007
|
+
label: action.name.zh_CN || "\u8F6C\u4EA4",
|
|
6008
|
+
handler: () => onTransfer?.(),
|
|
6009
|
+
type: "default"
|
|
6010
|
+
};
|
|
6011
|
+
break;
|
|
6012
|
+
case "return":
|
|
6013
|
+
actionMap["return"] = {
|
|
6014
|
+
label: action.name.zh_CN || "\u9000\u56DE",
|
|
6015
|
+
handler: () => onReturn?.(),
|
|
6016
|
+
type: "default"
|
|
6017
|
+
};
|
|
6018
|
+
break;
|
|
6019
|
+
case "withdraw":
|
|
6020
|
+
actionMap["withdraw"] = {
|
|
6021
|
+
label: action.name.zh_CN || "\u64A4\u9500",
|
|
6022
|
+
handler: () => handleOpenDrawer("withdraw"),
|
|
6023
|
+
type: "default"
|
|
6024
|
+
};
|
|
6025
|
+
break;
|
|
6026
|
+
case "save":
|
|
6027
|
+
actionMap["save"] = {
|
|
6028
|
+
label: action.name.zh_CN || "\u6682\u5B58",
|
|
6029
|
+
handler: handleSave,
|
|
6030
|
+
type: "default"
|
|
6031
|
+
};
|
|
6032
|
+
break;
|
|
6033
|
+
}
|
|
6034
|
+
});
|
|
6035
|
+
const allButtons = Object.entries(actionMap);
|
|
6036
|
+
const visibleButtons = allButtons.slice(0, maxVisible);
|
|
6037
|
+
const moreButtons = allButtons.slice(maxVisible);
|
|
6038
|
+
const drawerTitle = drawerAction === "approve" ? "\u5BA1\u6279\u610F\u89C1" : drawerAction === "reject" ? "\u62D2\u7EDD\u7406\u7531" : drawerAction === "withdraw" ? "\u64A4\u9500\u539F\u56E0" : "\u5BA1\u6279\u610F\u89C1";
|
|
6039
|
+
return /* @__PURE__ */ jsxs24(Fragment3, { children: [
|
|
6040
|
+
/* @__PURE__ */ jsxs24(
|
|
6041
|
+
"div",
|
|
6042
|
+
{
|
|
6043
|
+
className: `${layout === "horizontal" ? "flex items-center gap-3" : "flex flex-col gap-2"} ${className}`,
|
|
6044
|
+
children: [
|
|
6045
|
+
visibleButtons.map(([key, btn]) => /* @__PURE__ */ jsx78(
|
|
6046
|
+
Button5,
|
|
6047
|
+
{
|
|
6048
|
+
type: btn.type === "primary" ? "primary" : "default",
|
|
6049
|
+
className: btn.color === "green" ? "!bg-green-600 !border-green-600 hover:!bg-green-700" : "",
|
|
6050
|
+
onClick: btn.handler,
|
|
6051
|
+
loading: key === "save" && saveLoading,
|
|
6052
|
+
children: btn.label
|
|
6053
|
+
},
|
|
6054
|
+
key
|
|
6055
|
+
)),
|
|
6056
|
+
moreButtons.length > 0 && /* @__PURE__ */ jsx78(
|
|
6057
|
+
Dropdown,
|
|
6058
|
+
{
|
|
6059
|
+
menu: {
|
|
6060
|
+
items: moreButtons.map(([key, btn]) => ({
|
|
6061
|
+
key,
|
|
6062
|
+
label: btn.label,
|
|
6063
|
+
onClick: btn.handler
|
|
6064
|
+
}))
|
|
6065
|
+
},
|
|
6066
|
+
trigger: ["click"],
|
|
6067
|
+
children: /* @__PURE__ */ jsx78(Button5, { icon: /* @__PURE__ */ jsx78(MoreOutlined, {}), children: "\u66F4\u591A" })
|
|
6068
|
+
}
|
|
6069
|
+
)
|
|
6070
|
+
]
|
|
6071
|
+
}
|
|
6072
|
+
),
|
|
6073
|
+
/* @__PURE__ */ jsx78(
|
|
6074
|
+
Drawer,
|
|
6075
|
+
{
|
|
6076
|
+
title: drawerTitle,
|
|
6077
|
+
open: drawerAction !== null,
|
|
6078
|
+
onClose: () => setDrawerAction(null),
|
|
6079
|
+
width: 400,
|
|
6080
|
+
footer: /* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-3", children: [
|
|
6081
|
+
/* @__PURE__ */ jsx78(Button5, { onClick: () => setDrawerAction(null), children: "\u53D6\u6D88" }),
|
|
6082
|
+
/* @__PURE__ */ jsxs24(Button5, { type: "primary", onClick: handleConfirm, loading, children: [
|
|
6083
|
+
loading && /* @__PURE__ */ jsx78(LoadingOutlined, {}),
|
|
6084
|
+
"\u786E\u8BA4"
|
|
6085
|
+
] })
|
|
6086
|
+
] }),
|
|
6087
|
+
children: /* @__PURE__ */ jsx78("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs24("div", { children: [
|
|
6088
|
+
/* @__PURE__ */ jsx78("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: drawerAction === "approve" ? "\u5BA1\u6279\u610F\u89C1\uFF08\u53EF\u9009\uFF09" : "\u8BF7\u8F93\u5165\u7406\u7531" }),
|
|
6089
|
+
/* @__PURE__ */ jsx78(
|
|
6090
|
+
TextArea4,
|
|
6091
|
+
{
|
|
6092
|
+
rows: 4,
|
|
6093
|
+
value: comments,
|
|
6094
|
+
onChange: (e) => setComments(e.target.value),
|
|
6095
|
+
placeholder: drawerAction === "approve" ? "\u8BF7\u8F93\u5165\u5BA1\u6279\u610F\u89C1..." : drawerAction === "reject" ? "\u8BF7\u8F93\u5165\u62D2\u7EDD\u7406\u7531..." : "\u8BF7\u8F93\u5165\u64A4\u9500\u539F\u56E0...",
|
|
6096
|
+
maxLength: 500,
|
|
6097
|
+
showCount: true
|
|
6098
|
+
}
|
|
6099
|
+
)
|
|
6100
|
+
] }) })
|
|
6101
|
+
}
|
|
6102
|
+
)
|
|
6103
|
+
] });
|
|
6104
|
+
};
|
|
6105
|
+
|
|
6106
|
+
// src/modules/FormActionBar.tsx
|
|
6107
|
+
import { useState as useState28 } from "react";
|
|
6108
|
+
import { Button as Button6, Modal as Modal2 } from "antd";
|
|
6109
|
+
import { Fragment as Fragment4, jsx as jsx79, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
6110
|
+
var FormActionBar = ({
|
|
6111
|
+
actions,
|
|
6112
|
+
position = "bottom-fixed",
|
|
6113
|
+
className = ""
|
|
6114
|
+
}) => {
|
|
6115
|
+
const [loadingKeys, setLoadingKeys] = useState28(/* @__PURE__ */ new Set());
|
|
6116
|
+
const visibleActions = actions.filter((a) => a.visible !== false);
|
|
6117
|
+
const sortedActions = [...visibleActions].sort((a, b) => {
|
|
6118
|
+
if (a.type === "danger" && b.type !== "danger") return -1;
|
|
6119
|
+
if (a.type !== "danger" && b.type === "danger") return 1;
|
|
6120
|
+
if (a.type === "primary" && b.type !== "primary") return 1;
|
|
6121
|
+
if (a.type !== "primary" && b.type === "primary") return -1;
|
|
6122
|
+
return 0;
|
|
6123
|
+
});
|
|
6124
|
+
const handleClick = async (action) => {
|
|
6125
|
+
if (action.confirm) {
|
|
6126
|
+
Modal2.confirm({
|
|
6127
|
+
title: action.confirm.title,
|
|
6128
|
+
content: action.confirm.content,
|
|
6129
|
+
okText: "\u786E\u8BA4",
|
|
6130
|
+
cancelText: "\u53D6\u6D88",
|
|
6131
|
+
onOk: async () => {
|
|
6132
|
+
await executeAction(action);
|
|
6133
|
+
}
|
|
6134
|
+
});
|
|
6135
|
+
} else {
|
|
6136
|
+
await executeAction(action);
|
|
6137
|
+
}
|
|
6138
|
+
};
|
|
6139
|
+
const executeAction = async (action) => {
|
|
6140
|
+
setLoadingKeys((prev) => new Set(prev).add(action.key));
|
|
6141
|
+
try {
|
|
6142
|
+
await action.onClick();
|
|
6143
|
+
} finally {
|
|
6144
|
+
setLoadingKeys((prev) => {
|
|
6145
|
+
const next = new Set(prev);
|
|
6146
|
+
next.delete(action.key);
|
|
6147
|
+
return next;
|
|
6148
|
+
});
|
|
6149
|
+
}
|
|
6150
|
+
};
|
|
6151
|
+
const isFixed = position === "bottom-fixed";
|
|
6152
|
+
const bar = /* @__PURE__ */ jsx79(
|
|
6153
|
+
"div",
|
|
6154
|
+
{
|
|
6155
|
+
className: `${isFixed ? "fixed bottom-0 left-0 right-0 z-50 backdrop-blur-lg bg-white/80 border-t border-gray-200 shadow-[0_-1px_3px_rgba(0,0,0,0.05)] px-6 py-3" : ""} ${className}`,
|
|
6156
|
+
children: /* @__PURE__ */ jsx79("div", { className: "flex items-center justify-end gap-3 flex-wrap md:flex-nowrap", children: sortedActions.map((action) => {
|
|
6157
|
+
const isLoading = action.loading || loadingKeys.has(action.key);
|
|
6158
|
+
return /* @__PURE__ */ jsx79(
|
|
6159
|
+
Button6,
|
|
6160
|
+
{
|
|
6161
|
+
type: action.type === "danger" ? "primary" : action.type === "text" ? "text" : action.type || "default",
|
|
6162
|
+
danger: action.type === "danger",
|
|
6163
|
+
loading: isLoading,
|
|
6164
|
+
disabled: action.disabled,
|
|
6165
|
+
icon: action.icon,
|
|
6166
|
+
onClick: () => handleClick(action),
|
|
6167
|
+
className: "md:w-auto w-full",
|
|
6168
|
+
children: action.label
|
|
6169
|
+
},
|
|
6170
|
+
action.key
|
|
6171
|
+
);
|
|
6172
|
+
}) })
|
|
6173
|
+
}
|
|
6174
|
+
);
|
|
6175
|
+
if (isFixed) {
|
|
6176
|
+
return /* @__PURE__ */ jsxs25(Fragment4, { children: [
|
|
6177
|
+
bar,
|
|
6178
|
+
/* @__PURE__ */ jsx79("div", { className: "h-16" })
|
|
6179
|
+
] });
|
|
6180
|
+
}
|
|
6181
|
+
return bar;
|
|
6182
|
+
};
|
|
6183
|
+
|
|
6184
|
+
// src/modules/DraftManager.tsx
|
|
6185
|
+
import { Button as Button7 } from "antd";
|
|
6186
|
+
import { EditOutlined } from "@ant-design/icons";
|
|
6187
|
+
import { jsx as jsx80, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
6188
|
+
function formatRelativeTime(timestamp) {
|
|
6189
|
+
const now = Date.now();
|
|
6190
|
+
const diff = now - timestamp;
|
|
6191
|
+
const minutes = Math.floor(diff / 6e4);
|
|
6192
|
+
const hours = Math.floor(diff / 36e5);
|
|
6193
|
+
const days = Math.floor(diff / 864e5);
|
|
6194
|
+
if (minutes < 1) return "\u521A\u521A";
|
|
6195
|
+
if (minutes < 60) return `${minutes}\u5206\u949F\u524D`;
|
|
6196
|
+
if (hours < 24) return `${hours}\u5C0F\u65F6\u524D`;
|
|
6197
|
+
return `${days}\u5929\u524D`;
|
|
6198
|
+
}
|
|
6199
|
+
var DraftManager = ({
|
|
6200
|
+
hasDraft,
|
|
6201
|
+
draftTimestamp,
|
|
6202
|
+
onRestore,
|
|
6203
|
+
onDiscard,
|
|
6204
|
+
className = ""
|
|
6205
|
+
}) => {
|
|
6206
|
+
if (!hasDraft) return null;
|
|
6207
|
+
const timeLabel = draftTimestamp ? formatRelativeTime(draftTimestamp) : null;
|
|
6208
|
+
return /* @__PURE__ */ jsx80(
|
|
6209
|
+
"div",
|
|
6210
|
+
{
|
|
6211
|
+
className: `bg-blue-50 border border-blue-200 rounded-lg p-4 animate-[slideDown_0.3s_ease-out] ${className}`,
|
|
6212
|
+
children: /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
|
|
6213
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2 text-sm text-blue-700", children: [
|
|
6214
|
+
/* @__PURE__ */ jsx80(EditOutlined, { className: "text-blue-500" }),
|
|
6215
|
+
/* @__PURE__ */ jsxs26("span", { children: [
|
|
6216
|
+
"\u68C0\u6D4B\u5230\u672A\u63D0\u4EA4\u7684\u8349\u7A3F",
|
|
6217
|
+
timeLabel && /* @__PURE__ */ jsxs26("span", { className: "text-blue-500 ml-1", children: [
|
|
6218
|
+
"\uFF08\u4FDD\u5B58\u4E8E ",
|
|
6219
|
+
timeLabel,
|
|
6220
|
+
"\uFF09"
|
|
6221
|
+
] })
|
|
6222
|
+
] })
|
|
6223
|
+
] }),
|
|
6224
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2", children: [
|
|
6225
|
+
/* @__PURE__ */ jsx80(Button7, { type: "text", size: "small", onClick: onDiscard, className: "!text-gray-500", children: "\u4E22\u5F03" }),
|
|
6226
|
+
/* @__PURE__ */ jsx80(Button7, { type: "primary", size: "small", onClick: onRestore, children: "\u6062\u590D\u586B\u5199" })
|
|
6227
|
+
] })
|
|
6228
|
+
] })
|
|
6229
|
+
}
|
|
6230
|
+
);
|
|
6231
|
+
};
|
|
6232
|
+
|
|
6233
|
+
// src/modules/ProcessPreview.tsx
|
|
6234
|
+
import { Modal as Modal3, Skeleton as Skeleton2, Button as Button8 } from "antd";
|
|
6235
|
+
import { CheckCircleOutlined, UserOutlined } from "@ant-design/icons";
|
|
6236
|
+
import { jsx as jsx81, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
6237
|
+
var ProcessPreview = ({
|
|
6238
|
+
open,
|
|
6239
|
+
onClose,
|
|
6240
|
+
onConfirm,
|
|
6241
|
+
routes,
|
|
6242
|
+
loading = false
|
|
6243
|
+
}) => {
|
|
6244
|
+
return /* @__PURE__ */ jsx81(
|
|
6245
|
+
Modal3,
|
|
6246
|
+
{
|
|
6247
|
+
title: "\u6D41\u7A0B\u9884\u89C8",
|
|
6248
|
+
open,
|
|
6249
|
+
onCancel: onClose,
|
|
6250
|
+
width: 520,
|
|
6251
|
+
footer: /* @__PURE__ */ jsxs27("div", { className: "flex justify-end gap-3", children: [
|
|
6252
|
+
/* @__PURE__ */ jsx81(Button8, { onClick: onClose, children: "\u53D6\u6D88" }),
|
|
6253
|
+
/* @__PURE__ */ jsx81(Button8, { type: "primary", onClick: onConfirm, loading, children: "\u786E\u8BA4\u63D0\u4EA4" })
|
|
6254
|
+
] }),
|
|
6255
|
+
children: loading && routes.length === 0 ? /* @__PURE__ */ jsx81(Skeleton2, { active: true, paragraph: { rows: 4 } }) : routes.length === 0 ? /* @__PURE__ */ jsx81("p", { className: "text-sm text-gray-400 text-center py-8", children: "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) : /* @__PURE__ */ jsx81("div", { className: "py-2", children: routes.map((route, index) => {
|
|
6256
|
+
const isLast = index === routes.length - 1;
|
|
6257
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex gap-3", children: [
|
|
6258
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center", children: [
|
|
6259
|
+
/* @__PURE__ */ jsx81("div", { className: "w-6 h-6 rounded-full bg-blue-50 border-2 border-blue-400 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx81(CheckCircleOutlined, { className: "text-blue-500 text-xs" }) }),
|
|
6260
|
+
!isLast && /* @__PURE__ */ jsx81("div", { className: "w-0.5 flex-1 bg-blue-200 mt-1" })
|
|
6261
|
+
] }),
|
|
6262
|
+
/* @__PURE__ */ jsxs27("div", { className: `flex-1 ${isLast ? "pb-0" : "pb-5"}`, children: [
|
|
6263
|
+
/* @__PURE__ */ jsx81("div", { className: "text-sm font-medium text-gray-900", children: route.nodeName }),
|
|
6264
|
+
route.assignees && route.assignees.length > 0 && /* @__PURE__ */ jsxs27("div", { className: "mt-1 flex items-center gap-1.5 flex-wrap", children: [
|
|
6265
|
+
/* @__PURE__ */ jsx81(UserOutlined, { className: "text-gray-400 text-xs" }),
|
|
6266
|
+
route.assignees.map((assignee) => /* @__PURE__ */ jsx81(
|
|
6267
|
+
"span",
|
|
6268
|
+
{
|
|
6269
|
+
className: "text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded",
|
|
6270
|
+
children: assignee.name
|
|
6271
|
+
},
|
|
6272
|
+
assignee.id
|
|
6273
|
+
))
|
|
6274
|
+
] })
|
|
6275
|
+
] })
|
|
6276
|
+
] }, route.nodeId);
|
|
6277
|
+
}) })
|
|
6278
|
+
}
|
|
6279
|
+
);
|
|
6280
|
+
};
|
|
6281
|
+
|
|
6282
|
+
// src/templates/FormSubmitTemplate.tsx
|
|
6283
|
+
import { useState as useState29, useCallback as useCallback13 } from "react";
|
|
6284
|
+
import { Button as Button9 } from "antd";
|
|
6285
|
+
import { CheckCircleFilled } from "@ant-design/icons";
|
|
6286
|
+
import { Fragment as Fragment5, jsx as jsx82, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
6287
|
+
var pickFormInstanceId = (value) => {
|
|
6288
|
+
if (!value) return void 0;
|
|
6289
|
+
if (typeof value === "string") return value;
|
|
6290
|
+
if (typeof value !== "object") return void 0;
|
|
6291
|
+
return value.formInstanceId || value.formInstId || value.instanceId || value.id || pickFormInstanceId(value.result) || pickFormInstanceId(value.data);
|
|
6292
|
+
};
|
|
6293
|
+
var SubmitSuccessCard = ({
|
|
6294
|
+
info,
|
|
6295
|
+
mode,
|
|
6296
|
+
isRedirecting,
|
|
6297
|
+
countdown,
|
|
6298
|
+
onContinue,
|
|
6299
|
+
onViewDetail,
|
|
6300
|
+
renderSuccess
|
|
6301
|
+
}) => {
|
|
6302
|
+
if (renderSuccess) {
|
|
6303
|
+
return /* @__PURE__ */ jsx82(Fragment5, { children: renderSuccess(info) });
|
|
6304
|
+
}
|
|
6305
|
+
return /* @__PURE__ */ jsx82("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center py-16 animate-[fadeIn_0.3s_ease-out,scaleIn_0.3s_ease-out]", children: [
|
|
6306
|
+
/* @__PURE__ */ jsx82("div", { className: "w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx82(CheckCircleFilled, { className: "text-2xl text-green-500" }) }),
|
|
6307
|
+
/* @__PURE__ */ jsx82("h2", { className: "text-lg font-semibold text-gray-900 mb-1", children: "\u63D0\u4EA4\u6210\u529F" }),
|
|
6308
|
+
/* @__PURE__ */ jsx82("p", { className: "text-sm text-gray-500 mb-6", children: info.message || "\u5DF2\u6210\u529F\u521B\u5EFA\u4E00\u6761\u65B0\u8BB0\u5F55" }),
|
|
6309
|
+
/* @__PURE__ */ jsxs28("div", { className: "flex gap-3", children: [
|
|
6310
|
+
(mode === "stay" || mode === "redirect") && /* @__PURE__ */ jsx82(Button9, { onClick: onContinue, children: "\u7EE7\u7EED\u63D0\u4EA4" }),
|
|
6311
|
+
/* @__PURE__ */ jsx82(Button9, { type: "primary", onClick: onViewDetail, children: "\u67E5\u770B\u8BE6\u60C5" })
|
|
6312
|
+
] }),
|
|
6313
|
+
isRedirecting && /* @__PURE__ */ jsxs28("div", { className: "mt-6 w-48", children: [
|
|
6314
|
+
/* @__PURE__ */ jsxs28("div", { className: "text-xs text-gray-400 text-center mb-1", children: [
|
|
6315
|
+
countdown,
|
|
6316
|
+
"\u79D2\u540E\u81EA\u52A8\u8DF3\u8F6C"
|
|
6317
|
+
] }),
|
|
6318
|
+
/* @__PURE__ */ jsx82("div", { className: "h-1 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx82(
|
|
6319
|
+
"div",
|
|
6320
|
+
{
|
|
6321
|
+
className: "h-full bg-blue-500 transition-all duration-1000",
|
|
6322
|
+
style: { width: `${countdown / 3 * 100}%` }
|
|
6323
|
+
}
|
|
6324
|
+
) })
|
|
6325
|
+
] })
|
|
6326
|
+
] }) });
|
|
6327
|
+
};
|
|
6328
|
+
var InnerFormContent = ({
|
|
6329
|
+
schema,
|
|
6330
|
+
config,
|
|
6331
|
+
formType,
|
|
6332
|
+
submitSuccessMode,
|
|
6333
|
+
enableDraft,
|
|
6334
|
+
header,
|
|
6335
|
+
footer,
|
|
6336
|
+
beforeForm,
|
|
6337
|
+
afterForm,
|
|
6338
|
+
renderForm,
|
|
6339
|
+
renderSuccess,
|
|
6340
|
+
onSubmitSuccess
|
|
6341
|
+
}) => {
|
|
6342
|
+
const { validateAll, getFormData: getFormData2, resetForm, api } = useFormContext();
|
|
6343
|
+
const [submitted, setSubmitted] = useState29(false);
|
|
6344
|
+
const [successInfo, setSuccessInfo] = useState29(null);
|
|
6345
|
+
const [submitting, setSubmitting] = useState29(false);
|
|
6346
|
+
const { hasDraft, draftTimestamp, saveDraft, restoreDraft, clearDraft } = useDraftStorage({
|
|
6347
|
+
appType: config.appType,
|
|
6348
|
+
formUuid: config.formUuid
|
|
6349
|
+
});
|
|
6350
|
+
const { navigateToDetail, navigateToProcessDetail, isRedirecting, countdown, handlePostSubmit } = useFormNavigation({
|
|
6351
|
+
appType: config.appType,
|
|
6352
|
+
formUuid: config.formUuid,
|
|
6353
|
+
formType,
|
|
6354
|
+
mode: submitSuccessMode === "continue" ? "stay" : submitSuccessMode,
|
|
6355
|
+
basePath: config.navigation?.basePath
|
|
6356
|
+
});
|
|
6357
|
+
const handleSubmit = useCallback13(async () => {
|
|
6358
|
+
const valid = await validateAll();
|
|
6359
|
+
if (!valid) return;
|
|
6360
|
+
setSubmitting(true);
|
|
6361
|
+
try {
|
|
6362
|
+
const formData = getFormData2();
|
|
6363
|
+
if (config.submit?.beforeSubmit) {
|
|
6364
|
+
const shouldContinue = await config.submit.beforeSubmit(formData);
|
|
6365
|
+
if (shouldContinue === false) {
|
|
6366
|
+
setSubmitting(false);
|
|
6367
|
+
return;
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
const submitResponse = config.mode === "edit" && config.formInstanceId ? await api.updateFormData({
|
|
6371
|
+
appType: config.appType,
|
|
6372
|
+
formUuid: config.formUuid,
|
|
6373
|
+
formInstId: config.formInstanceId,
|
|
6374
|
+
formInstanceId: config.formInstanceId,
|
|
6375
|
+
updateFormDataJson: JSON.stringify(formData)
|
|
6376
|
+
}) : await api.submitFormData({
|
|
6377
|
+
appType: config.appType,
|
|
6378
|
+
formUuid: config.formUuid,
|
|
6379
|
+
data: formData
|
|
6380
|
+
});
|
|
6381
|
+
const formInstId = pickFormInstanceId(submitResponse) || config.formInstanceId || `inst_${Date.now()}`;
|
|
6382
|
+
if (config.submit?.afterSubmit) {
|
|
6383
|
+
await config.submit.afterSubmit({
|
|
6384
|
+
formInstanceId: formInstId,
|
|
6385
|
+
data: formData,
|
|
6386
|
+
response: submitResponse
|
|
6387
|
+
});
|
|
6388
|
+
}
|
|
6389
|
+
if (enableDraft) {
|
|
6390
|
+
clearDraft();
|
|
6391
|
+
}
|
|
6392
|
+
onSubmitSuccess?.(formInstId);
|
|
6393
|
+
if (submitSuccessMode === "continue") {
|
|
6394
|
+
resetForm();
|
|
6395
|
+
} else {
|
|
6396
|
+
setSuccessInfo({ formInstanceId: formInstId });
|
|
6397
|
+
setSubmitted(true);
|
|
6398
|
+
handlePostSubmit(formInstId);
|
|
6399
|
+
}
|
|
6400
|
+
} catch (error) {
|
|
6401
|
+
console.error("[FormSubmitTemplate] Submit failed:", error);
|
|
6402
|
+
} finally {
|
|
6403
|
+
setSubmitting(false);
|
|
6404
|
+
}
|
|
6405
|
+
}, [
|
|
6406
|
+
validateAll,
|
|
6407
|
+
getFormData2,
|
|
6408
|
+
config,
|
|
6409
|
+
api,
|
|
6410
|
+
enableDraft,
|
|
6411
|
+
clearDraft,
|
|
6412
|
+
onSubmitSuccess,
|
|
6413
|
+
submitSuccessMode,
|
|
6414
|
+
resetForm,
|
|
6415
|
+
handlePostSubmit
|
|
6416
|
+
]);
|
|
6417
|
+
const handleSaveDraft = useCallback13(() => {
|
|
6418
|
+
const data = getFormData2();
|
|
6419
|
+
saveDraft(data);
|
|
6420
|
+
}, [getFormData2, saveDraft]);
|
|
6421
|
+
const handleRestoreDraft = useCallback13(() => {
|
|
6422
|
+
restoreDraft();
|
|
6423
|
+
}, [restoreDraft]);
|
|
6424
|
+
const handleContinue = useCallback13(() => {
|
|
6425
|
+
setSubmitted(false);
|
|
6426
|
+
setSuccessInfo(null);
|
|
6427
|
+
resetForm();
|
|
6428
|
+
}, [resetForm]);
|
|
6429
|
+
const handleViewDetail = useCallback13(() => {
|
|
6430
|
+
if (!successInfo) return;
|
|
6431
|
+
if (formType === "process") {
|
|
6432
|
+
navigateToProcessDetail(successInfo.formInstanceId);
|
|
6433
|
+
} else {
|
|
6434
|
+
navigateToDetail(successInfo.formInstanceId);
|
|
6435
|
+
}
|
|
6436
|
+
}, [successInfo, formType, navigateToDetail, navigateToProcessDetail]);
|
|
6437
|
+
const actions = [];
|
|
6438
|
+
if (enableDraft) {
|
|
6439
|
+
actions.push({
|
|
6440
|
+
key: "draft",
|
|
6441
|
+
label: "\u6682\u5B58",
|
|
6442
|
+
type: "default",
|
|
6443
|
+
onClick: handleSaveDraft
|
|
6444
|
+
});
|
|
6445
|
+
}
|
|
6446
|
+
actions.push({
|
|
6447
|
+
key: "reset",
|
|
6448
|
+
label: "\u91CD\u7F6E",
|
|
6449
|
+
type: "default",
|
|
6450
|
+
onClick: () => resetForm()
|
|
6451
|
+
});
|
|
6452
|
+
actions.push({
|
|
6453
|
+
key: "submit",
|
|
6454
|
+
label: "\u63D0\u4EA4",
|
|
6455
|
+
type: "primary",
|
|
6456
|
+
loading: submitting,
|
|
6457
|
+
onClick: handleSubmit
|
|
6458
|
+
});
|
|
6459
|
+
return /* @__PURE__ */ jsxs28("div", { className: "min-h-screen bg-gray-50/50", children: [
|
|
6460
|
+
/* @__PURE__ */ jsxs28("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: [
|
|
6461
|
+
header || /* @__PURE__ */ jsxs28("div", { className: "mb-6", children: [
|
|
6462
|
+
/* @__PURE__ */ jsx82("h1", { className: "text-2xl font-bold text-gray-900", children: schema.formMeta.title }),
|
|
6463
|
+
/* @__PURE__ */ jsx82("p", { className: "text-sm text-gray-500 mt-1", children: "\u8BF7\u586B\u5199\u4EE5\u4E0B\u4FE1\u606F" })
|
|
6464
|
+
] }),
|
|
6465
|
+
enableDraft && hasDraft && !submitted && /* @__PURE__ */ jsx82("div", { className: "mb-6", children: /* @__PURE__ */ jsx82(
|
|
6466
|
+
DraftManager,
|
|
6467
|
+
{
|
|
6468
|
+
hasDraft,
|
|
6469
|
+
draftTimestamp,
|
|
6470
|
+
onRestore: handleRestoreDraft,
|
|
6471
|
+
onDiscard: clearDraft
|
|
6472
|
+
}
|
|
6473
|
+
) }),
|
|
6474
|
+
!submitted ? /* @__PURE__ */ jsxs28("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 animate-[fadeIn_0.2s_ease-out]", children: [
|
|
6475
|
+
beforeForm,
|
|
6476
|
+
renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ jsx82(FormRenderer, { columns: 2 }),
|
|
6477
|
+
afterForm
|
|
6478
|
+
] }) : successInfo && /* @__PURE__ */ jsx82(
|
|
6479
|
+
SubmitSuccessCard,
|
|
6480
|
+
{
|
|
6481
|
+
info: successInfo,
|
|
6482
|
+
mode: submitSuccessMode,
|
|
6483
|
+
isRedirecting,
|
|
6484
|
+
countdown,
|
|
6485
|
+
onContinue: handleContinue,
|
|
6486
|
+
onViewDetail: handleViewDetail,
|
|
6487
|
+
renderSuccess
|
|
6488
|
+
}
|
|
6489
|
+
),
|
|
6490
|
+
footer
|
|
6491
|
+
] }),
|
|
6492
|
+
!submitted && /* @__PURE__ */ jsx82(FormActionBar, { actions, position: "bottom-fixed" })
|
|
6493
|
+
] });
|
|
6494
|
+
};
|
|
6495
|
+
var FormSubmitTemplate = ({
|
|
6496
|
+
schema,
|
|
6497
|
+
config,
|
|
6498
|
+
formType = "form",
|
|
6499
|
+
submitSuccessMode = "redirect",
|
|
6500
|
+
enableDraft = false,
|
|
6501
|
+
header,
|
|
6502
|
+
footer,
|
|
6503
|
+
beforeForm,
|
|
6504
|
+
afterForm,
|
|
6505
|
+
renderForm,
|
|
6506
|
+
renderSuccess,
|
|
6507
|
+
onSubmitSuccess
|
|
6508
|
+
}) => {
|
|
6509
|
+
return /* @__PURE__ */ jsx82(FormProvider, { schema, config, children: /* @__PURE__ */ jsx82(
|
|
6510
|
+
InnerFormContent,
|
|
6511
|
+
{
|
|
6512
|
+
schema,
|
|
6513
|
+
config,
|
|
6514
|
+
formType,
|
|
6515
|
+
submitSuccessMode,
|
|
6516
|
+
enableDraft,
|
|
6517
|
+
header,
|
|
6518
|
+
footer,
|
|
6519
|
+
beforeForm,
|
|
6520
|
+
afterForm,
|
|
6521
|
+
renderForm,
|
|
6522
|
+
renderSuccess,
|
|
6523
|
+
onSubmitSuccess
|
|
6524
|
+
}
|
|
6525
|
+
) });
|
|
6526
|
+
};
|
|
6527
|
+
|
|
6528
|
+
// src/templates/FormDetailTemplate.tsx
|
|
6529
|
+
import { useCallback as useCallback14 } from "react";
|
|
6530
|
+
|
|
6531
|
+
// src/templates/PageSkeleton.tsx
|
|
6532
|
+
import { Skeleton as Skeleton3 } from "antd";
|
|
6533
|
+
import { jsx as jsx83, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
6534
|
+
var CardSkeleton = ({ children }) => /* @__PURE__ */ jsx83("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children });
|
|
6535
|
+
var SummaryCardSkeleton = () => /* @__PURE__ */ jsxs29(CardSkeleton, { children: [
|
|
6536
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-start justify-between", children: [
|
|
6537
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex-1", children: [
|
|
6538
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
|
|
6539
|
+
/* @__PURE__ */ jsx83("div", { className: "mt-2", children: /* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }) })
|
|
6540
|
+
] }),
|
|
6541
|
+
/* @__PURE__ */ jsx83(Skeleton3.Button, { active: true, size: "small", shape: "round", style: { width: 60 } })
|
|
6542
|
+
] }),
|
|
6543
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3 mt-4", children: [
|
|
6544
|
+
/* @__PURE__ */ jsx83(Skeleton3.Avatar, { active: true, size: "small" }),
|
|
6545
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "small", style: { width: 120 } })
|
|
6546
|
+
] })
|
|
6547
|
+
] });
|
|
6548
|
+
var FormGridSkeleton = () => /* @__PURE__ */ jsx83(CardSkeleton, { children: /* @__PURE__ */ jsx83("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs29("div", { className: "space-y-2", children: [
|
|
6549
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }),
|
|
6550
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, block: true, style: { width: "100%" } })
|
|
6551
|
+
] }, i)) }) });
|
|
6552
|
+
var ActionBarSkeleton = () => /* @__PURE__ */ jsx83("div", { className: "fixed bottom-0 left-0 right-0 backdrop-blur-lg bg-white/80 border-t border-gray-200 px-6 py-3", children: /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-end gap-3", children: [
|
|
6553
|
+
/* @__PURE__ */ jsx83(Skeleton3.Button, { active: true, style: { width: 80 } }),
|
|
6554
|
+
/* @__PURE__ */ jsx83(Skeleton3.Button, { active: true, style: { width: 80 } })
|
|
6555
|
+
] }) });
|
|
6556
|
+
var TimelineSkeleton = () => /* @__PURE__ */ jsxs29(CardSkeleton, { children: [
|
|
6557
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "default", style: { width: 100, marginBottom: 16 } }),
|
|
6558
|
+
/* @__PURE__ */ jsx83("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs29("div", { className: "flex gap-4", children: [
|
|
6559
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center", children: [
|
|
6560
|
+
/* @__PURE__ */ jsx83("div", { className: "w-3 h-3 rounded-full bg-gray-200 animate-pulse" }),
|
|
6561
|
+
i < 2 && /* @__PURE__ */ jsx83("div", { className: "w-0.5 flex-1 bg-gray-200 mt-1" })
|
|
6562
|
+
] }),
|
|
6563
|
+
/* @__PURE__ */ jsx83("div", { className: "flex-1 pb-4", children: /* @__PURE__ */ jsx83(Skeleton3, { active: true, paragraph: { rows: 1 }, title: { width: "60%" } }) })
|
|
6564
|
+
] }, i)) })
|
|
6565
|
+
] });
|
|
6566
|
+
var PageSkeleton = ({ type }) => {
|
|
6567
|
+
if (type === "submit") {
|
|
6568
|
+
return /* @__PURE__ */ jsxs29("div", { className: "space-y-6", children: [
|
|
6569
|
+
/* @__PURE__ */ jsxs29("div", { className: "space-y-2", children: [
|
|
6570
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
|
|
6571
|
+
/* @__PURE__ */ jsx83(Skeleton3.Input, { active: true, size: "small", style: { width: 300 } })
|
|
6572
|
+
] }),
|
|
6573
|
+
/* @__PURE__ */ jsx83(FormGridSkeleton, {}),
|
|
6574
|
+
/* @__PURE__ */ jsx83(ActionBarSkeleton, {})
|
|
6575
|
+
] });
|
|
6576
|
+
}
|
|
6577
|
+
if (type === "detail") {
|
|
6578
|
+
return /* @__PURE__ */ jsxs29("div", { className: "space-y-6", children: [
|
|
6579
|
+
/* @__PURE__ */ jsx83(SummaryCardSkeleton, {}),
|
|
6580
|
+
/* @__PURE__ */ jsx83(FormGridSkeleton, {}),
|
|
6581
|
+
/* @__PURE__ */ jsx83(ActionBarSkeleton, {})
|
|
6582
|
+
] });
|
|
6583
|
+
}
|
|
6584
|
+
return /* @__PURE__ */ jsxs29("div", { className: "space-y-6", children: [
|
|
6585
|
+
/* @__PURE__ */ jsx83(SummaryCardSkeleton, {}),
|
|
6586
|
+
/* @__PURE__ */ jsx83(FormGridSkeleton, {}),
|
|
6587
|
+
/* @__PURE__ */ jsx83(TimelineSkeleton, {}),
|
|
6588
|
+
/* @__PURE__ */ jsx83(ActionBarSkeleton, {})
|
|
6589
|
+
] });
|
|
6590
|
+
};
|
|
6591
|
+
|
|
6592
|
+
// src/templates/FormDetailTemplate.tsx
|
|
6593
|
+
import { Fragment as Fragment6, jsx as jsx84, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6594
|
+
var InnerDetailContent = ({
|
|
6595
|
+
schema,
|
|
6596
|
+
formUuid,
|
|
6597
|
+
appType,
|
|
6598
|
+
formInstanceId,
|
|
6599
|
+
enableEdit = true,
|
|
6600
|
+
enableDelete = false,
|
|
6601
|
+
enableChangeRecords = false,
|
|
6602
|
+
header,
|
|
6603
|
+
footer,
|
|
6604
|
+
renderSummary,
|
|
6605
|
+
renderActions,
|
|
6606
|
+
onDelete,
|
|
6607
|
+
onSave
|
|
6608
|
+
}) => {
|
|
6609
|
+
const {
|
|
6610
|
+
loading,
|
|
6611
|
+
mode,
|
|
6612
|
+
formData,
|
|
6613
|
+
instanceInfo,
|
|
6614
|
+
fieldBehaviors,
|
|
6615
|
+
switchToEdit,
|
|
6616
|
+
switchToReadonly,
|
|
6617
|
+
saveChanges,
|
|
6618
|
+
deleteInstance,
|
|
6619
|
+
canEdit,
|
|
6620
|
+
canDelete,
|
|
6621
|
+
canViewChangeRecords
|
|
6622
|
+
} = useFormDetail({ formUuid, appType, formInstanceId });
|
|
6623
|
+
const {
|
|
6624
|
+
records,
|
|
6625
|
+
loading: recordsLoading,
|
|
6626
|
+
hasMore,
|
|
6627
|
+
loadMore,
|
|
6628
|
+
refresh: refreshRecords
|
|
6629
|
+
} = useChangeRecords({
|
|
6630
|
+
formUuid,
|
|
6631
|
+
appType,
|
|
6632
|
+
formInstanceId,
|
|
6633
|
+
autoLoad: enableChangeRecords && canViewChangeRecords
|
|
6634
|
+
});
|
|
6635
|
+
const handleSave = useCallback14(async () => {
|
|
6636
|
+
if (!formData) return;
|
|
6637
|
+
const success = await saveChanges(formData);
|
|
6638
|
+
if (success) {
|
|
6639
|
+
onSave?.(formData);
|
|
6640
|
+
}
|
|
6641
|
+
}, [formData, saveChanges, onSave]);
|
|
6642
|
+
const handleDelete = useCallback14(async () => {
|
|
6643
|
+
const success = await deleteInstance();
|
|
6644
|
+
if (success) {
|
|
6645
|
+
onDelete?.();
|
|
6646
|
+
}
|
|
6647
|
+
}, [deleteInstance, onDelete]);
|
|
6648
|
+
const handleCancel = useCallback14(() => {
|
|
6649
|
+
switchToReadonly();
|
|
6650
|
+
}, [switchToReadonly]);
|
|
6651
|
+
const readonlyActions = [];
|
|
6652
|
+
if (enableEdit && canEdit) {
|
|
6653
|
+
readonlyActions.push({
|
|
6654
|
+
key: "edit",
|
|
6655
|
+
label: "\u7F16\u8F91",
|
|
6656
|
+
type: "primary",
|
|
6657
|
+
onClick: switchToEdit
|
|
6658
|
+
});
|
|
6659
|
+
}
|
|
6660
|
+
if (enableDelete && canDelete) {
|
|
6661
|
+
readonlyActions.push({
|
|
6662
|
+
key: "delete",
|
|
6663
|
+
label: "\u5220\u9664",
|
|
6664
|
+
type: "danger",
|
|
6665
|
+
onClick: handleDelete,
|
|
6666
|
+
confirm: { title: "\u786E\u8BA4\u5220\u9664", content: "\u5220\u9664\u540E\u5C06\u65E0\u6CD5\u6062\u590D\uFF0C\u786E\u8BA4\u8981\u5220\u9664\u5417\uFF1F" }
|
|
6667
|
+
});
|
|
6668
|
+
}
|
|
6669
|
+
const editActions = [
|
|
6670
|
+
{ key: "cancel", label: "\u53D6\u6D88", type: "default", onClick: handleCancel },
|
|
6671
|
+
{ key: "save", label: "\u4FDD\u5B58", type: "primary", onClick: handleSave }
|
|
6672
|
+
];
|
|
6673
|
+
const currentActions = mode === "readonly" ? readonlyActions : editActions;
|
|
6674
|
+
const formConfig = {
|
|
6675
|
+
mode: mode === "edit" ? "edit" : "readonly",
|
|
6676
|
+
formUuid,
|
|
6677
|
+
appType,
|
|
6678
|
+
formInstanceId,
|
|
6679
|
+
permissions: {
|
|
6680
|
+
fieldPermissions: fieldBehaviors,
|
|
6681
|
+
operations: []
|
|
6682
|
+
}
|
|
6683
|
+
};
|
|
6684
|
+
if (loading) {
|
|
6685
|
+
return /* @__PURE__ */ jsx84("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ jsx84("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ jsx84(PageSkeleton, { type: "detail" }) }) });
|
|
6686
|
+
}
|
|
6687
|
+
return /* @__PURE__ */ jsxs30("div", { className: "min-h-screen bg-gray-50/50", children: [
|
|
6688
|
+
/* @__PURE__ */ jsx84("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ jsxs30("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
|
|
6689
|
+
header,
|
|
6690
|
+
renderSummary && instanceInfo ? renderSummary(instanceInfo) : /* @__PURE__ */ jsx84(
|
|
6691
|
+
FormSummaryCard,
|
|
6692
|
+
{
|
|
6693
|
+
title: schema.formMeta.title,
|
|
6694
|
+
formInstanceId,
|
|
6695
|
+
creator: instanceInfo?.creator ? {
|
|
6696
|
+
name: instanceInfo.creator.name,
|
|
6697
|
+
avatar: instanceInfo.creator.avatar,
|
|
6698
|
+
department: instanceInfo.creator.department
|
|
6699
|
+
} : void 0,
|
|
6700
|
+
createdAt: instanceInfo?.createdAt,
|
|
6701
|
+
status: mode === "edit" ? { label: "\u7F16\u8F91\u4E2D", tone: "brand" } : void 0
|
|
6702
|
+
}
|
|
6703
|
+
),
|
|
6704
|
+
mode === "edit" && /* @__PURE__ */ jsx84("div", { className: "bg-blue-50 border border-blue-200 rounded-lg px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: "\u6B63\u5728\u7F16\u8F91\uFF0C\u4FEE\u6539\u540E\u8BF7\u4FDD\u5B58" }),
|
|
6705
|
+
/* @__PURE__ */ jsx84("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsx84(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: /* @__PURE__ */ jsx84(FormRenderer, { columns: 2 }) }) }),
|
|
6706
|
+
enableChangeRecords && canViewChangeRecords && /* @__PURE__ */ jsx84(
|
|
6707
|
+
ChangeRecords,
|
|
6708
|
+
{
|
|
6709
|
+
records,
|
|
6710
|
+
loading: recordsLoading,
|
|
6711
|
+
hasMore,
|
|
6712
|
+
onLoadMore: loadMore,
|
|
6713
|
+
onExpand: refreshRecords
|
|
6714
|
+
}
|
|
6715
|
+
),
|
|
6716
|
+
footer
|
|
6717
|
+
] }) }),
|
|
6718
|
+
currentActions.length > 0 && (renderActions ? /* @__PURE__ */ jsx84(Fragment6, { children: renderActions(currentActions) }) : /* @__PURE__ */ jsx84(FormActionBar, { position: "bottom-fixed", actions: currentActions }))
|
|
6719
|
+
] });
|
|
6720
|
+
};
|
|
6721
|
+
var FormDetailTemplate = (props) => {
|
|
6722
|
+
const { schema, formUuid, appType, formInstanceId } = props;
|
|
6723
|
+
const wrapperConfig = {
|
|
6724
|
+
mode: "readonly",
|
|
6725
|
+
formUuid,
|
|
6726
|
+
appType,
|
|
6727
|
+
formInstanceId
|
|
6728
|
+
};
|
|
6729
|
+
return /* @__PURE__ */ jsx84(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx84(InnerDetailContent, { ...props }) });
|
|
6730
|
+
};
|
|
6731
|
+
|
|
6732
|
+
// src/templates/ProcessDetailTemplate.tsx
|
|
6733
|
+
import { useCallback as useCallback15, useRef as useRef12 } from "react";
|
|
6734
|
+
import { Fragment as Fragment7, jsx as jsx85, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
6735
|
+
function FormDataBridge({
|
|
6736
|
+
formDataRef
|
|
6737
|
+
}) {
|
|
6738
|
+
const { getFormData: getFormData2 } = useFormContext();
|
|
6739
|
+
formDataRef.current = getFormData2;
|
|
6740
|
+
return null;
|
|
6741
|
+
}
|
|
6742
|
+
var InnerProcessContent = ({
|
|
6743
|
+
schema,
|
|
6744
|
+
formUuid,
|
|
6745
|
+
appType,
|
|
6746
|
+
formInstanceId,
|
|
6747
|
+
header,
|
|
6748
|
+
renderTimeline,
|
|
6749
|
+
renderActions,
|
|
6750
|
+
beforeForm,
|
|
6751
|
+
afterForm,
|
|
6752
|
+
onActionComplete
|
|
6753
|
+
}) => {
|
|
6754
|
+
const formDataRef = useRef12(void 0);
|
|
6755
|
+
const {
|
|
6756
|
+
loading,
|
|
6757
|
+
processInfo,
|
|
6758
|
+
processStatus,
|
|
6759
|
+
currentTask,
|
|
6760
|
+
progressList,
|
|
6761
|
+
formData,
|
|
6762
|
+
isApprover,
|
|
6763
|
+
activeActions,
|
|
6764
|
+
fieldBehaviors,
|
|
6765
|
+
mode,
|
|
6766
|
+
isOriginatorReturn,
|
|
6767
|
+
canWithdraw,
|
|
6768
|
+
switchToEdit,
|
|
6769
|
+
switchToReadonly,
|
|
6770
|
+
refreshProgress
|
|
6771
|
+
} = useProcessDetail({ formUuid, appType, formInstanceId });
|
|
6772
|
+
const { approve, reject, withdraw, save, resubmit } = useApprovalActions({
|
|
6773
|
+
formInstanceId,
|
|
6774
|
+
formUuid,
|
|
6775
|
+
appType,
|
|
6776
|
+
currentTaskId: currentTask?.taskId,
|
|
6777
|
+
onActionComplete: async (action) => {
|
|
6778
|
+
onActionComplete?.(action);
|
|
6779
|
+
await refreshProgress();
|
|
6780
|
+
},
|
|
6781
|
+
getFormValues: () => formDataRef.current?.() ?? {}
|
|
6782
|
+
});
|
|
6783
|
+
const handleApprove = useCallback15(
|
|
6784
|
+
async (comments) => {
|
|
6785
|
+
await approve(comments);
|
|
6786
|
+
},
|
|
6787
|
+
[approve]
|
|
6788
|
+
);
|
|
6789
|
+
const handleReject = useCallback15(
|
|
6790
|
+
async (comments) => {
|
|
6791
|
+
await reject(comments);
|
|
6792
|
+
},
|
|
6793
|
+
[reject]
|
|
6794
|
+
);
|
|
6795
|
+
const handleWithdraw = useCallback15(
|
|
6796
|
+
async (reason) => {
|
|
6797
|
+
await withdraw(reason);
|
|
6798
|
+
},
|
|
6799
|
+
[withdraw]
|
|
6800
|
+
);
|
|
6801
|
+
const handleSave = useCallback15(async () => {
|
|
6802
|
+
await save();
|
|
6803
|
+
}, [save]);
|
|
6804
|
+
const handleResubmit = useCallback15(async () => {
|
|
6805
|
+
await resubmit();
|
|
6806
|
+
}, [resubmit]);
|
|
6807
|
+
const buildActions = () => {
|
|
6808
|
+
const actions = [];
|
|
6809
|
+
if (isApprover && activeActions.length > 0) {
|
|
6810
|
+
return [];
|
|
6811
|
+
}
|
|
6812
|
+
if (isOriginatorReturn) {
|
|
6813
|
+
if (mode === "readonly") {
|
|
6814
|
+
actions.push({
|
|
6815
|
+
key: "edit",
|
|
6816
|
+
label: "\u7F16\u8F91",
|
|
6817
|
+
type: "primary",
|
|
6818
|
+
onClick: switchToEdit
|
|
6819
|
+
});
|
|
6820
|
+
} else {
|
|
6821
|
+
actions.push({
|
|
6822
|
+
key: "cancel",
|
|
6823
|
+
label: "\u53D6\u6D88",
|
|
6824
|
+
type: "default",
|
|
6825
|
+
onClick: switchToReadonly
|
|
6826
|
+
});
|
|
6827
|
+
actions.push({
|
|
6828
|
+
key: "resubmit",
|
|
6829
|
+
label: "\u91CD\u65B0\u63D0\u4EA4",
|
|
6830
|
+
type: "primary",
|
|
6831
|
+
onClick: handleResubmit
|
|
6832
|
+
});
|
|
6833
|
+
}
|
|
6834
|
+
return actions;
|
|
6835
|
+
}
|
|
6836
|
+
if (canWithdraw) {
|
|
6837
|
+
actions.push({
|
|
6838
|
+
key: "withdraw",
|
|
6839
|
+
label: "\u64A4\u9500",
|
|
6840
|
+
type: "default",
|
|
6841
|
+
onClick: () => handleWithdraw(),
|
|
6842
|
+
confirm: { title: "\u786E\u8BA4\u64A4\u9500", content: "\u786E\u8BA4\u8981\u64A4\u9500\u6B64\u6D41\u7A0B\u5417\uFF1F" }
|
|
6843
|
+
});
|
|
6844
|
+
}
|
|
6845
|
+
return actions;
|
|
6846
|
+
};
|
|
6847
|
+
const formConfig = {
|
|
6848
|
+
mode: mode === "edit" ? "edit" : "readonly",
|
|
6849
|
+
formUuid,
|
|
6850
|
+
appType,
|
|
6851
|
+
formInstanceId,
|
|
6852
|
+
permissions: {
|
|
6853
|
+
fieldPermissions: fieldBehaviors,
|
|
6854
|
+
operations: []
|
|
6855
|
+
}
|
|
6856
|
+
};
|
|
6857
|
+
if (loading) {
|
|
6858
|
+
return /* @__PURE__ */ jsx85("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ jsx85("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ jsx85(PageSkeleton, { type: "process" }) }) });
|
|
6859
|
+
}
|
|
6860
|
+
const bottomActions = buildActions();
|
|
6861
|
+
const showApprovalActions = isApprover && activeActions.length > 0;
|
|
6862
|
+
return /* @__PURE__ */ jsxs31("div", { className: "min-h-screen bg-gray-50/50", children: [
|
|
6863
|
+
/* @__PURE__ */ jsx85("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ jsxs31("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
|
|
6864
|
+
header,
|
|
6865
|
+
/* @__PURE__ */ jsx85(
|
|
6866
|
+
FormSummaryCard,
|
|
6867
|
+
{
|
|
6868
|
+
title: schema.formMeta.title,
|
|
6869
|
+
formInstanceId,
|
|
6870
|
+
creator: processInfo?.originatorName ? {
|
|
6871
|
+
name: processInfo.originatorName,
|
|
6872
|
+
department: processInfo.originatorDepartment
|
|
6873
|
+
} : void 0,
|
|
6874
|
+
createdAt: processInfo?.createdAt,
|
|
6875
|
+
status: processStatus ? PROCESS_STATUS_META[processStatus] : void 0
|
|
6876
|
+
}
|
|
6877
|
+
),
|
|
6878
|
+
beforeForm,
|
|
6879
|
+
mode === "edit" && /* @__PURE__ */ jsx85("div", { className: "bg-blue-50 border border-blue-200 rounded-lg px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: "\u6B63\u5728\u7F16\u8F91\u8868\u5355\uFF0C\u4FEE\u6539\u540E\u8BF7\u91CD\u65B0\u63D0\u4EA4" }),
|
|
6880
|
+
/* @__PURE__ */ jsx85("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsxs31(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
|
|
6881
|
+
/* @__PURE__ */ jsx85(FormDataBridge, { formDataRef }),
|
|
6882
|
+
/* @__PURE__ */ jsx85(FormRenderer, { columns: 2 })
|
|
6883
|
+
] }) }),
|
|
6884
|
+
afterForm,
|
|
6885
|
+
/* @__PURE__ */ jsxs31("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: [
|
|
6886
|
+
/* @__PURE__ */ jsx85("h3", { className: "text-lg font-semibold text-gray-900 mb-4", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
|
|
6887
|
+
renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ jsx85(ApprovalTimeline, { tasks: progressList, showRemarks: true })
|
|
6888
|
+
] })
|
|
6889
|
+
] }) }),
|
|
6890
|
+
showApprovalActions && (renderActions ? /* @__PURE__ */ jsx85(Fragment7, { children: renderActions(activeActions) }) : /* @__PURE__ */ jsx85("div", { className: "fixed bottom-0 left-0 right-0 z-50 backdrop-blur-lg bg-white/80 border-t border-gray-200 shadow-[0_-1px_3px_rgba(0,0,0,0.05)] px-6 py-3", children: /* @__PURE__ */ jsx85("div", { className: "max-w-4xl mx-auto flex items-center justify-end", children: /* @__PURE__ */ jsx85(
|
|
6891
|
+
ApprovalActions,
|
|
6892
|
+
{
|
|
6893
|
+
actions: activeActions,
|
|
6894
|
+
onApprove: handleApprove,
|
|
6895
|
+
onReject: handleReject,
|
|
6896
|
+
onWithdraw: handleWithdraw,
|
|
6897
|
+
onSave: handleSave
|
|
6898
|
+
}
|
|
6899
|
+
) }) })),
|
|
6900
|
+
!showApprovalActions && bottomActions.length > 0 && /* @__PURE__ */ jsx85(FormActionBar, { position: "bottom-fixed", actions: bottomActions })
|
|
6901
|
+
] });
|
|
6902
|
+
};
|
|
6903
|
+
var ProcessDetailTemplate = (props) => {
|
|
6904
|
+
const { schema, formUuid, appType, formInstanceId } = props;
|
|
6905
|
+
const wrapperConfig = {
|
|
6906
|
+
mode: "readonly",
|
|
6907
|
+
formUuid,
|
|
6908
|
+
appType,
|
|
6909
|
+
formInstanceId
|
|
6910
|
+
};
|
|
6911
|
+
return /* @__PURE__ */ jsx85(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx85(InnerProcessContent, { ...props }) });
|
|
6912
|
+
};
|
|
4713
6913
|
export {
|
|
4714
6914
|
AddressField,
|
|
6915
|
+
ApprovalActions,
|
|
6916
|
+
ApprovalTimeline,
|
|
4715
6917
|
AssociationFormField,
|
|
4716
6918
|
AttachmentField,
|
|
4717
6919
|
CascadeDateField,
|
|
4718
6920
|
CascadeSelectField,
|
|
6921
|
+
ChangeRecords,
|
|
4719
6922
|
CheckboxField,
|
|
4720
6923
|
ComponentRegistryContext,
|
|
4721
6924
|
ComponentRegistryProvider,
|
|
4722
6925
|
DateField,
|
|
4723
6926
|
DepartmentSelectField,
|
|
4724
6927
|
DigitalSignatureField,
|
|
6928
|
+
DraftManager,
|
|
4725
6929
|
EditorField,
|
|
4726
6930
|
UserSelectField as EmployeeSelectField,
|
|
4727
6931
|
FieldWrapper,
|
|
6932
|
+
FormActionBar,
|
|
4728
6933
|
FormActions,
|
|
4729
6934
|
FormContainer,
|
|
4730
6935
|
FormContext,
|
|
6936
|
+
FormDetailTemplate,
|
|
4731
6937
|
FormGrid,
|
|
4732
6938
|
FormProvider,
|
|
4733
6939
|
FormRenderer,
|
|
4734
6940
|
FormSection,
|
|
4735
6941
|
FormSteps,
|
|
6942
|
+
FormSubmitTemplate,
|
|
4736
6943
|
FormSummary,
|
|
6944
|
+
FormSummaryCard,
|
|
4737
6945
|
FormTabs,
|
|
4738
6946
|
ImageField,
|
|
4739
6947
|
JSONField,
|
|
4740
6948
|
LocationField,
|
|
4741
6949
|
MultiSelectField,
|
|
4742
6950
|
NumberField,
|
|
6951
|
+
PROCESS_STATUS_META,
|
|
6952
|
+
PageSkeleton,
|
|
6953
|
+
ProcessDetailTemplate,
|
|
6954
|
+
ProcessPreview,
|
|
4743
6955
|
RadioField,
|
|
4744
6956
|
SelectField,
|
|
4745
6957
|
SerialNumberField,
|
|
4746
6958
|
SubFormField,
|
|
6959
|
+
TASK_STATUS_META,
|
|
4747
6960
|
TextAreaField,
|
|
4748
6961
|
TextField,
|
|
4749
6962
|
TextAreaField as TextareaField,
|
|
4750
6963
|
UserSelectField,
|
|
6964
|
+
checkUserApproval,
|
|
4751
6965
|
createFormRuntimeApi,
|
|
4752
6966
|
defaultComponentRegistry,
|
|
4753
6967
|
defineFormSchema,
|
|
6968
|
+
deleteFormData,
|
|
4754
6969
|
evaluateEffects,
|
|
6970
|
+
getChangeRecords,
|
|
6971
|
+
getFormData,
|
|
6972
|
+
getProcessBasic,
|
|
6973
|
+
getProcessDefinition,
|
|
6974
|
+
getProcessProgress,
|
|
6975
|
+
getReturnableNodes,
|
|
6976
|
+
getViewPermission,
|
|
6977
|
+
handleApproval,
|
|
6978
|
+
previewProcess,
|
|
6979
|
+
resubmitTask,
|
|
6980
|
+
returnTask,
|
|
6981
|
+
saveTask,
|
|
6982
|
+
transferTask,
|
|
6983
|
+
useApprovalActions,
|
|
6984
|
+
useChangeRecords,
|
|
4755
6985
|
useComponent,
|
|
4756
6986
|
useDeviceDetect,
|
|
6987
|
+
useDraftStorage,
|
|
4757
6988
|
useFieldBehavior,
|
|
6989
|
+
useFieldPermission,
|
|
4758
6990
|
useFormContext,
|
|
4759
6991
|
useFormData,
|
|
6992
|
+
useFormDetail,
|
|
4760
6993
|
useFormEngine,
|
|
6994
|
+
useFormNavigation,
|
|
4761
6995
|
useFormSubmit,
|
|
6996
|
+
useProcessDetail,
|
|
4762
6997
|
validateAllFields,
|
|
4763
|
-
validateField
|
|
6998
|
+
validateField,
|
|
6999
|
+
withdrawProcess
|
|
4764
7000
|
};
|
|
4765
7001
|
//# sourceMappingURL=index.mjs.map
|