@dovetail-v2/refine 0.4.2-alpha.2 → 0.4.3

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/dist/refine.js CHANGED
@@ -7,13 +7,13 @@ var __publicField = (obj, key2, value2) => {
7
7
  import dayjs from "dayjs";
8
8
  import i18n from "i18next";
9
9
  import { w as warnOnce, g as getDefaults, a as warn, b as getI18n, s as setDefaults, d as setI18n, I as I18nContext, j as jsxRuntimeExports, u as useTranslation, c as cx_default, S as SocketStatus } from "./common-241b21f8.js";
10
- import { ResourceContext, matchResourceFromRoute, useResource, useDelete, useNavigation, useBreadcrumb, useList, CanAccess, useUpdate, useForm as useForm$2, pickNotDeprecated, useWarnAboutChange, useOne, useParsed, useGo, useCan, useTable, useDeleteMany, useShow, useRefineContext, useTranslate, flattenObjectKeys, useMenu, Refine } from "@refinedev/core";
10
+ import { ResourceContext, matchResourceFromRoute, useResource, useDelete, useNavigation, useBreadcrumb, useList, CanAccess, useUpdate, useForm as useForm$2, pickNotDeprecated, useWarnAboutChange, useParsed, useGo, useCan, useTable, useDeleteMany, useShow, useRefineContext, useTranslate, flattenObjectKeys, useMenu, Refine } from "@refinedev/core";
11
11
  import { parse, stringify } from "qs";
12
12
  import React, { createElement, isValidElement, cloneElement, Children, useContext, useCallback, createContext, useState, useEffect, useMemo, useRef, useImperativeHandle, forwardRef, Suspense, lazy, memo } from "react";
13
13
  import { useLocation, useHistory, useParams, matchPath, Link, Route, NavLink, Router } from "react-router-dom";
14
14
  import { usePushModal, usePopModal, DeleteDialog, Tag, RejectDialog, RejectDialogType, OverflowTooltip, Typo, Input, Select, AntdOption, Button, Form, Space, TextArea, kitContext, Loading, Table as Table$2, Pagination, Alert, ImmersiveDialog, SmallDialog, Fields, Units, Link as Link$1, Tooltip, Divider, Icon, Dropdown, Menu as Menu$1, LegacyModal, StatusCapsule, Popover, AntdTable, Upload, TableForm, ValidateTriggerType, AutoComplete, getOptions, DonutChart, SegmentControl, Checkbox, Tabs as Tabs$1, TabsTabPane, Col, Row, useMessage, SearchInput, Token, AntdSelectOptGroup, WizardDialog, MenuItemGroup, Layout as Layout$1, InputGroup, InputInteger, Time as Time$1, ModalStack, KitStoreProvider, ConfigProvider } from "@cloudtower/eagle";
15
- import { HierarchyTriangleRight16GrayIcon, HierarchyTriangleRight16BlueIcon, ClipboardCopy16GradientGrayIcon, ClipboardCopy16GradientBlueIcon, Retry16GradientGrayIcon, Retry16GradientBlueIcon, EditPen16GradientGrayIcon, EditPen16GradientBlueIcon, Showdiff16GradientGrayIcon, Showdiff16GradientBlueIcon, XmarkFailedSeriousWarningFill16RedIcon, EditPen16PrimaryIcon, Download16GradientBlueIcon, TrashBinDelete16Icon, MoreEllipsis324BoldSecondaryIcon, MoreEllipsis324BoldBlueIcon, MoreEllipsis316BoldBlueIcon, PlusAddCreateNew16BoldOntintIcon, ViewEye16GradientGrayIcon, EntityFilterIgnoreGradient16GrayIcon, InfoICircleFill16GrayIcon, InfoICircleFill16Gray70Icon, RecoverContinue16GradientBlueIcon, SuspendedPause16GradientBlueIcon, ArrowChevronLeft16BoldTertiaryIcon, ArrowChevronLeftSmall16BoldBlueIcon, OpenTerminal16GradientBlueIcon, ArrowChevronDown16BlueIcon, ArrowChevronUp16BlueIcon, Pause16GradientBlueIcon, EditPen16BlueIcon } from "@cloudtower/icons-react";
16
- import { first, get as get$2, cloneDeep, set, setWith, clone, debounce, isEqual as isEqual$1, isObject as isObject$4, uniq, omit as omit$1, merge, last, keyBy } from "lodash-es";
15
+ import { HierarchyTriangleRight16GrayIcon, HierarchyTriangleRight16BlueIcon, ClipboardCopy16GradientGrayIcon, ClipboardCopy16GradientBlueIcon, Retry16GradientGrayIcon, Retry16GradientBlueIcon, EditPen16GradientGrayIcon, EditPen16GradientBlueIcon, Showdiff16GradientGrayIcon, Showdiff16GradientBlueIcon, XmarkFailedSeriousWarningFill16RedIcon, EditPen16PrimaryIcon, Download16GradientBlueIcon, TrashBinDelete16Icon, MoreEllipsis324BoldSecondaryIcon, MoreEllipsis324BoldBlueIcon, MoreEllipsis316BoldBlueIcon, PlusAddCreateNew16BoldOntintIcon, ViewEye16GradientGrayIcon, EntityFilterIgnoreGradient16GrayIcon, InfoICircleFill16GrayIcon, InfoICircleFill16Gray70Icon, RecoverContinue16GradientBlueIcon, SuspendedPause16GradientBlueIcon, ArrowChevronLeft16BoldTertiaryIcon, ArrowChevronLeftSmall16BoldBlueIcon, OpenTerminal16GradientBlueIcon, ArrowChevronLeft16BoldBlueIcon, ExclamationErrorCircleFill16RedIcon, ArrowChevronDown16BlueIcon, ArrowChevronUp16BlueIcon, Pause16GradientBlueIcon, EditPen16BlueIcon } from "@cloudtower/icons-react";
16
+ import { first, get as get$2, cloneDeep, set, setWith, clone, debounce, isEqual as isEqual$1, omit as omit$1, isObject as isObject$4, uniq, merge, last, keyBy } from "lodash-es";
17
17
  import yaml$2 from "js-yaml";
18
18
  import { useForm as useForm$1 } from "sunflower-antd";
19
19
  import { useLocalStorage } from "usehooks-ts";
@@ -456,6 +456,8 @@ const state$1 = "Status";
456
456
  const name$1 = "Name";
457
457
  const pod$1 = "Pod";
458
458
  const cancel$1 = "Cancel";
459
+ const prev_step$1 = "Previous";
460
+ const next_step$1 = "Next";
459
461
  const create$1 = "Create";
460
462
  const confirm_delete_text$1 = "Are you sure you want to delete the {{kind}} <0>{{target}}</0>?";
461
463
  const edit$1 = "Edit";
@@ -618,6 +620,7 @@ const edit_form$1 = "Edit form";
618
620
  const data_expired$1 = "Data expired";
619
621
  const data_expired_body$1 = "The data in this form is no longer the latest version. To avoid saving errors, please discard this edit and reopen the form to edit again.";
620
622
  const data_expired_note$1 = "Your current entries will not be saved.";
623
+ const resource_version_conflict$1 = "The data in this form is no longer the latest version. Please discard this edit and reopen the form to edit again.";
621
624
  const abandon_edit$1 = "Discard edit";
622
625
  const exit_yaml_tip$1 = "If you go back to the form, any changes made to the YAML file will be lost.";
623
626
  const value_optional$1 = "Value (optional)";
@@ -734,6 +737,8 @@ const dovetail$1 = {
734
737
  name: name$1,
735
738
  pod: pod$1,
736
739
  cancel: cancel$1,
740
+ prev_step: prev_step$1,
741
+ next_step: next_step$1,
737
742
  "delete": "Delete",
738
743
  create: create$1,
739
744
  confirm_delete_text: confirm_delete_text$1,
@@ -899,6 +904,7 @@ const dovetail$1 = {
899
904
  data_expired: data_expired$1,
900
905
  data_expired_body: data_expired_body$1,
901
906
  data_expired_note: data_expired_note$1,
907
+ resource_version_conflict: resource_version_conflict$1,
902
908
  abandon_edit: abandon_edit$1,
903
909
  exit_yaml_tip: exit_yaml_tip$1,
904
910
  value_optional: value_optional$1,
@@ -1010,6 +1016,8 @@ const edit_yaml = "编辑 YAML";
1010
1016
  const copied = "已复制";
1011
1017
  const already_reset = "已重置";
1012
1018
  const cancel = "取消";
1019
+ const prev_step = "上一步";
1020
+ const next_step = "下一步";
1013
1021
  const create = "创建";
1014
1022
  const delete_resource = "删除{{resource}}";
1015
1023
  const confirm_delete_text = "确认删除{{kind}} <0>{{target}}</0> 吗?";
@@ -1182,6 +1190,7 @@ const edit_form = "编辑表单";
1182
1190
  const data_expired = "数据已过期";
1183
1191
  const data_expired_body = "当前表单中的数据已不是最新版。为避免保存失败,请放弃本次编辑,并重新打开表单进行编辑。";
1184
1192
  const data_expired_note = "当前已填写内容将不会保留。";
1193
+ const resource_version_conflict = "当前表单中的数据已不是最新版,请放弃本次编辑,并重新打开表单进行编辑。";
1185
1194
  const abandon_edit = "放弃编辑";
1186
1195
  const exit_yaml_tip = "返回编辑表单,不会保留对 YAML 文件做出的所有更改。";
1187
1196
  const form = "表单";
@@ -1287,6 +1296,8 @@ const dovetail = {
1287
1296
  copied,
1288
1297
  already_reset,
1289
1298
  cancel,
1299
+ prev_step,
1300
+ next_step,
1290
1301
  "delete": "删除",
1291
1302
  create,
1292
1303
  delete_resource,
@@ -1462,6 +1473,7 @@ const dovetail = {
1462
1473
  data_expired,
1463
1474
  data_expired_body,
1464
1475
  data_expired_note,
1476
+ resource_version_conflict,
1465
1477
  abandon_edit,
1466
1478
  exit_yaml_tip,
1467
1479
  form,
@@ -10687,26 +10699,6 @@ function usePathMap(options) {
10687
10699
  transformApplyValues
10688
10700
  };
10689
10701
  }
10690
- const useResourceVersionCheck = ({
10691
- queryResult
10692
- }) => {
10693
- var _a, _b, _c;
10694
- const initialResourceVersionRef = useRef();
10695
- const [isExpired, setIsExpired] = useState(false);
10696
- const currentResourceVersion = (_c = (_b = (_a = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a.data) == null ? void 0 : _b.metadata) == null ? void 0 : _c.resourceVersion;
10697
- useEffect(() => {
10698
- if (!currentResourceVersion)
10699
- return;
10700
- if (!initialResourceVersionRef.current) {
10701
- initialResourceVersionRef.current = currentResourceVersion;
10702
- return;
10703
- }
10704
- if (currentResourceVersion !== initialResourceVersionRef.current) {
10705
- setIsExpired(true);
10706
- }
10707
- }, [currentResourceVersion]);
10708
- return isExpired;
10709
- };
10710
10702
  function getInitialValues(resourceConfig) {
10711
10703
  return resourceConfig.initValue || {
10712
10704
  apiVersion: resourceConfig.apiVersion,
@@ -10715,42 +10707,6 @@ function getInitialValues(resourceConfig) {
10715
10707
  spec: {}
10716
10708
  };
10717
10709
  }
10718
- const button_1v659kh = "";
10719
- const WarningButtonStyle = "wwyz7ti";
10720
- const DataExpiredModal_eazxh6 = "";
10721
- const NoteStyle = "n609wlp";
10722
- function DataExpiredModal({
10723
- onAbandon
10724
- }) {
10725
- const {
10726
- t: t2
10727
- } = useTranslation();
10728
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(SmallDialog, {
10729
- title: t2("dovetail.data_expired"),
10730
- closable: false,
10731
- maskClosable: false,
10732
- cancelButtonProps: {
10733
- style: {
10734
- display: "none"
10735
- }
10736
- },
10737
- okText: t2("dovetail.abandon_edit"),
10738
- okButtonProps: {
10739
- className: WarningButtonStyle
10740
- },
10741
- onOk: (popModal) => {
10742
- popModal();
10743
- onAbandon();
10744
- },
10745
- children: [/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
10746
- className: Typo.Label.l2_regular,
10747
- children: t2("dovetail.data_expired_body")
10748
- }), /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
10749
- className: `${Typo.Label.l2_regular} ${NoteStyle}`,
10750
- children: t2("dovetail.data_expired_note")
10751
- })]
10752
- });
10753
- }
10754
10710
  const index_az4wrx = "";
10755
10711
  const WrapperStyle$5 = "w1akirqw";
10756
10712
  const TitleStyle$2 = "t30srnq";
@@ -10790,7 +10746,7 @@ const Separator = () => {
10790
10746
  const style_1o641u6 = "";
10791
10747
  const ToolBarStyle = "t1joof7s";
10792
10748
  const ToolBarHeaderStyle = "tti58uh";
10793
- const ErrorIconStyle = "e15yt16p";
10749
+ const ErrorIconStyle$1 = "e15yt16p";
10794
10750
  const WrapperStyle$4 = "w3ccqks";
10795
10751
  const TitleStyle$1 = "t7zbd78";
10796
10752
  const IconStyle = "i1e4ouxy";
@@ -11020,7 +10976,7 @@ const YamlEditorComponent = forwardRef(
11020
10976
  ] })
11021
10977
  ] }),
11022
10978
  errorMsgs.length ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Space, { className: ErrorWrapperStyle, size: 8, align: "start", children: [
11023
- /* @__PURE__ */ jsxRuntimeExports.jsx(XmarkFailedSeriousWarningFill16RedIcon, { className: ErrorIconStyle }),
10979
+ /* @__PURE__ */ jsxRuntimeExports.jsx(XmarkFailedSeriousWarningFill16RedIcon, { className: ErrorIconStyle$1 }),
11024
10980
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: errorMsgs.map((errorMsg, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("pre", { className: ErrorMsgStyle, children: [
11025
10981
  errorMsgs.length > 1 ? `${index2 + 1}. ` : "",
11026
10982
  errorMsg
@@ -11080,6 +11036,67 @@ function copyToClipboard(text) {
11080
11036
  document.execCommand("copy");
11081
11037
  document.body.removeChild(input);
11082
11038
  }
11039
+ const useGlobalStore = (name2 = "default") => {
11040
+ const globalStores = useContext(GlobalStoreContext);
11041
+ return globalStores[name2];
11042
+ };
11043
+ const ResourceVersionConflictRetryContext = createContext(null);
11044
+ function Retry409Provider({
11045
+ children
11046
+ }) {
11047
+ const initialResourceRef = useRef();
11048
+ return createElement(
11049
+ ResourceVersionConflictRetryContext.Provider,
11050
+ {
11051
+ value: initialResourceRef
11052
+ },
11053
+ children
11054
+ );
11055
+ }
11056
+ function use409Retry({
11057
+ action,
11058
+ dataProviderName,
11059
+ id,
11060
+ mutationMeta
11061
+ }) {
11062
+ const { t: t2 } = useTranslation();
11063
+ const globalStore = useGlobalStore(dataProviderName);
11064
+ const sharedInitialResourceRef = useContext(ResourceVersionConflictRetryContext);
11065
+ const localInitialResourceRef = useRef();
11066
+ const initialResourceRef = sharedInitialResourceRef || localInitialResourceRef;
11067
+ const isEditAction = action === "edit" || !!id;
11068
+ const captureInitialResource = useCallback((resource) => {
11069
+ var _a;
11070
+ if (!isEditAction || initialResourceRef.current || !resource) {
11071
+ return;
11072
+ }
11073
+ const rawResource = (_a = globalStore == null ? void 0 : globalStore.restoreItem) == null ? void 0 : _a.call(globalStore, resource);
11074
+ if (!rawResource) {
11075
+ return;
11076
+ }
11077
+ initialResourceRef.current = cloneDeep(rawResource);
11078
+ }, [globalStore, initialResourceRef, isEditAction]);
11079
+ const retryMutationMeta = useMemo(() => {
11080
+ const restMutationMeta = omit$1(mutationMeta, "resourceVersionConflictRetry");
11081
+ if (!isEditAction) {
11082
+ return restMutationMeta;
11083
+ }
11084
+ return {
11085
+ ...restMutationMeta,
11086
+ resourceVersionConflictRetry: {
11087
+ // refine 的 mutationMeta 在 hook 创建时就会固定;用 getter 让 provider 在保存瞬间读取最新的初始版本。
11088
+ get initialResource() {
11089
+ return initialResourceRef.current;
11090
+ },
11091
+ conflictMessage: t2("dovetail.resource_version_conflict")
11092
+ }
11093
+ };
11094
+ }, [initialResourceRef, isEditAction, mutationMeta, t2]);
11095
+ return {
11096
+ captureInitialResource,
11097
+ mutationMeta: retryMutationMeta
11098
+ };
11099
+ }
11083
11100
  function useK8sYamlEditor() {
11084
11101
  const foldSymbol = useCallback(function(editor, symbol) {
11085
11102
  const model = editor.getModel();
@@ -11190,10 +11207,6 @@ function generateYamlBySchema(defaultValue, schema) {
11190
11207
  const content = yaml$2.dump(merged);
11191
11208
  return content.replace(/(')(#.+?)(')/g, "$2").replace(/( +)(#)/g, "$2$1");
11192
11209
  }
11193
- const useGlobalStore = (name2 = "default") => {
11194
- const globalStores = useContext(GlobalStoreContext);
11195
- return globalStores[name2];
11196
- };
11197
11210
  const useYamlForm = ({
11198
11211
  action: actionFromProps,
11199
11212
  resource,
@@ -11231,7 +11244,7 @@ const useYamlForm = ({
11231
11244
  onSubmitAbort,
11232
11245
  rules
11233
11246
  } = {}) => {
11234
- var _a;
11247
+ var _a, _b;
11235
11248
  const editor = useRef(null);
11236
11249
  const { t: t2 } = useTranslation();
11237
11250
  const [isYamlValid, setIsYamlValid] = useState(true);
@@ -11242,7 +11255,17 @@ const useYamlForm = ({
11242
11255
  const [beforeSubmitErrors, setBeforeSubmitErrors] = useState([]);
11243
11256
  const [errorResponseBody, setErrorResponseBody] = useState(null);
11244
11257
  const useResourceResult = useResource();
11245
- const globalStore = useGlobalStore();
11258
+ const globalStore = useGlobalStore(dataProviderName);
11259
+ const action = useMemo(
11260
+ () => actionFromProps || useResourceResult.action,
11261
+ [actionFromProps, useResourceResult.action]
11262
+ );
11263
+ const { captureInitialResource, mutationMeta: finalMutationMeta } = use409Retry({
11264
+ action,
11265
+ dataProviderName,
11266
+ id: idFromProps,
11267
+ mutationMeta
11268
+ });
11246
11269
  const {
11247
11270
  schema,
11248
11271
  loading: isLoadingSchema,
@@ -11279,7 +11302,7 @@ const useYamlForm = ({
11279
11302
  meta: pickNotDeprecated(meta, metaData),
11280
11303
  metaData: pickNotDeprecated(meta, metaData),
11281
11304
  queryMeta,
11282
- mutationMeta,
11305
+ mutationMeta: finalMutationMeta,
11283
11306
  liveMode,
11284
11307
  liveParams,
11285
11308
  mutationMode,
@@ -11294,12 +11317,12 @@ const useYamlForm = ({
11294
11317
  overtimeOptions
11295
11318
  });
11296
11319
  const { formLoading, onFinish, queryResult } = useFormCoreResult;
11320
+ useEffect(() => {
11321
+ var _a2;
11322
+ captureInitialResource((_a2 = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a2.data);
11323
+ }, [captureInitialResource, (_a = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a.data]);
11297
11324
  const { warnWhenUnsavedChanges: warnWhenUnsavedChangesRefine, setWarnWhen } = useWarnAboutChange();
11298
11325
  const warnWhenUnsavedChanges = warnWhenUnsavedChangesProp ?? warnWhenUnsavedChangesRefine;
11299
- const action = useMemo(
11300
- () => actionFromProps || useResourceResult.action,
11301
- [actionFromProps, useResourceResult.action]
11302
- );
11303
11326
  const initialValues = useMemo(() => {
11304
11327
  var _a2;
11305
11328
  const initialValues2 = (action === "edit" && ((_a2 = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a2.data) ? initialValuesForEdit || (globalStore == null ? void 0 : globalStore.restoreItem(queryResult.data.data)) : initialValuesForCreate) || {};
@@ -11342,10 +11365,10 @@ const useYamlForm = ({
11342
11365
  }
11343
11366
  },
11344
11367
  onEditorCreate(editorInstance) {
11345
- var _a3, _b;
11368
+ var _a3, _b2;
11346
11369
  const editorValue = yaml$2.dump(initialValues);
11347
11370
  (_a3 = editor.current) == null ? void 0 : _a3.setEditorValue(editorValue);
11348
- (_b = editor.current) == null ? void 0 : _b.setValue(editorValue);
11371
+ (_b2 = editor.current) == null ? void 0 : _b2.setValue(editorValue);
11349
11372
  if (action === "edit") {
11350
11373
  fold2(editorInstance);
11351
11374
  }
@@ -11358,7 +11381,7 @@ const useYamlForm = ({
11358
11381
  initialValues,
11359
11382
  schemas,
11360
11383
  resource,
11361
- (_a = useResourceResult.resource) == null ? void 0 : _a.name,
11384
+ (_b = useResourceResult.resource) == null ? void 0 : _b.name,
11362
11385
  action,
11363
11386
  finalErrors,
11364
11387
  fold2
@@ -11398,7 +11421,7 @@ const useYamlForm = ({
11398
11421
  formProps: {
11399
11422
  ...formSF.formProps,
11400
11423
  onFinish: async (values) => {
11401
- var _a2, _b;
11424
+ var _a2, _b2;
11402
11425
  setBeforeSubmitErrors([]);
11403
11426
  onSubmitStart == null ? void 0 : onSubmitStart();
11404
11427
  const errors = [
@@ -11418,7 +11441,7 @@ const useYamlForm = ({
11418
11441
  return;
11419
11442
  }
11420
11443
  try {
11421
- const objectValues = editor.current ? yaml$2.load(((_b = editor.current) == null ? void 0 : _b.getEditorValue()) || "") : values;
11444
+ const objectValues = editor.current ? yaml$2.load(((_b2 = editor.current) == null ? void 0 : _b2.getEditorValue()) || "") : values;
11422
11445
  let finalValues = (transformApplyValues == null ? void 0 : transformApplyValues(objectValues)) || objectValues;
11423
11446
  if (beforeSubmit) {
11424
11447
  try {
@@ -11520,6 +11543,7 @@ function YamlForm(props) {
11520
11543
  id,
11521
11544
  action: actionFromProps,
11522
11545
  resource: resource == null ? void 0 : resource.name,
11546
+ dataProviderName: resourceConfig.dataProviderName,
11523
11547
  editorOptions: {
11524
11548
  isSkipSchema: schemaStrategy === "None"
11525
11549
  /* None */
@@ -11642,31 +11666,6 @@ function YamlFormContainer({
11642
11666
  onSaveButtonPropsChange
11643
11667
  }) {
11644
11668
  const action = id ? "edit" : "create";
11645
- const pushModal = usePushModal();
11646
- const popModal = usePopModal();
11647
- const hasShownExpiredRef = useRef(false);
11648
- const [isSubmitting, setIsSubmitting] = useState(false);
11649
- const queryResult = useOne({
11650
- resource: resourceConfig.name,
11651
- id,
11652
- liveMode: id ? "auto" : "off",
11653
- queryOptions: { enabled: !!id }
11654
- });
11655
- const isExpired = useResourceVersionCheck({ queryResult });
11656
- useEffect(() => {
11657
- if (!isExpired || isSubmitting || hasShownExpiredRef.current) {
11658
- return;
11659
- }
11660
- hasShownExpiredRef.current = true;
11661
- pushModal({
11662
- component: DataExpiredModal,
11663
- props: {
11664
- onAbandon: () => {
11665
- popModal();
11666
- }
11667
- }
11668
- });
11669
- }, [isExpired, isSubmitting, pushModal, popModal]);
11670
11669
  const { transformInitValues, transformApplyValues } = usePathMap({
11671
11670
  pathMap: formConfig == null ? void 0 : formConfig.pathMap,
11672
11671
  transformInitValues: formConfig == null ? void 0 : formConfig.transformInitValues,
@@ -11686,13 +11685,7 @@ function YamlFormContainer({
11686
11685
  action,
11687
11686
  isShowLayout: false,
11688
11687
  useFormProps: {
11689
- redirect: false,
11690
- onSubmitStart: () => {
11691
- setIsSubmitting(true);
11692
- },
11693
- onSubmitAbort: () => {
11694
- setIsSubmitting(false);
11695
- }
11688
+ redirect: false
11696
11689
  },
11697
11690
  rules: void 0,
11698
11691
  onSaveButtonPropsChange,
@@ -16074,8 +16067,121 @@ function ResourceShow(props) {
16074
16067
  }
16075
16068
  );
16076
16069
  }
16070
+ const button_1v659kh = "";
16071
+ const WarningButtonStyle = "wwyz7ti";
16077
16072
  const modal_1eijuvm = "";
16078
16073
  const SmallModalStyle = "s1nc293e";
16074
+ const ExtraSubmitFooter_15u4r8u = "";
16075
+ const FooterStyle = "f16wn4bu";
16076
+ const FooterLeftStyle = "fk5l2b4";
16077
+ const FooterRightStyle = "f1r3vl4u";
16078
+ const ErrorStyle = "e1y8i1r4";
16079
+ const ErrorIconStyle = "e16fn5cj";
16080
+ const PrevIconStyle = "prji3wx";
16081
+ function useExtraSubmitFooter({
16082
+ action,
16083
+ cancelText,
16084
+ defaultSubmitText,
16085
+ errorText,
16086
+ extraSubmitButton,
16087
+ fallbackFooter,
16088
+ isYamlMode,
16089
+ nextStepText,
16090
+ prevStepText,
16091
+ saveButtonProps,
16092
+ step,
16093
+ stepCount,
16094
+ onCancel,
16095
+ onNextStep,
16096
+ onPrevStep,
16097
+ onSubmit
16098
+ }) {
16099
+ const shouldShowExtraSubmitButton = useMemo(() => {
16100
+ if (!extraSubmitButton || isYamlMode) {
16101
+ return false;
16102
+ }
16103
+ if (extraSubmitButton.action && extraSubmitButton.action !== action) {
16104
+ return false;
16105
+ }
16106
+ if (extraSubmitButton.step !== step) {
16107
+ return false;
16108
+ }
16109
+ return step < stepCount - 1;
16110
+ }, [action, extraSubmitButton, isYamlMode, step, stepCount]);
16111
+ return useMemo(() => {
16112
+ if (!shouldShowExtraSubmitButton) {
16113
+ return fallbackFooter;
16114
+ }
16115
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ExtraSubmitFooter, {
16116
+ cancelText,
16117
+ errorText,
16118
+ extraSubmitText: (extraSubmitButton == null ? void 0 : extraSubmitButton.text) || defaultSubmitText,
16119
+ nextStepText,
16120
+ prevText: prevStepText,
16121
+ saveButtonProps,
16122
+ showPrevButton: step > 0,
16123
+ onCancel,
16124
+ onNextStep,
16125
+ onPrevStep,
16126
+ onSubmit
16127
+ });
16128
+ }, [cancelText, defaultSubmitText, errorText, extraSubmitButton == null ? void 0 : extraSubmitButton.text, fallbackFooter, onCancel, onNextStep, onPrevStep, onSubmit, nextStepText, prevStepText, saveButtonProps, shouldShowExtraSubmitButton, step]);
16129
+ }
16130
+ const ExtraSubmitFooter = ({
16131
+ cancelText,
16132
+ errorText,
16133
+ extraSubmitText,
16134
+ nextStepText,
16135
+ prevText,
16136
+ saveButtonProps,
16137
+ showPrevButton,
16138
+ onCancel,
16139
+ onNextStep,
16140
+ onPrevStep,
16141
+ onSubmit
16142
+ }) => {
16143
+ const finalSaveButtonProps = omit$1(saveButtonProps, "onClick");
16144
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
16145
+ className: FooterStyle,
16146
+ children: [/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
16147
+ className: FooterLeftStyle,
16148
+ children: [showPrevButton ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, {
16149
+ type: "link",
16150
+ onClick: onPrevStep,
16151
+ children: [/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowChevronLeft16BoldBlueIcon, {
16152
+ className: PrevIconStyle
16153
+ }), prevText]
16154
+ }) : null, errorText ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", {
16155
+ className: cx_default(ErrorStyle, Typo.Label.l2_regular),
16156
+ children: [/* @__PURE__ */ jsxRuntimeExports.jsx(ExclamationErrorCircleFill16RedIcon, {
16157
+ className: ErrorIconStyle
16158
+ }), errorText]
16159
+ }) : null]
16160
+ }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
16161
+ className: FooterRightStyle,
16162
+ children: [/* @__PURE__ */ jsxRuntimeExports.jsx(Button, {
16163
+ type: "quiet",
16164
+ size: "large",
16165
+ onClick: onCancel,
16166
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", {
16167
+ className: Typo.Label.l1_bold_title,
16168
+ children: cancelText
16169
+ })
16170
+ }), /* @__PURE__ */ jsxRuntimeExports.jsx(Button, {
16171
+ size: "large",
16172
+ type: "secondary",
16173
+ onClick: onNextStep,
16174
+ children: nextStepText
16175
+ }), /* @__PURE__ */ jsxRuntimeExports.jsx(Button, {
16176
+ ...finalSaveButtonProps,
16177
+ size: "large",
16178
+ type: "primary",
16179
+ onClick: onSubmit,
16180
+ children: extraSubmitText
16181
+ })]
16182
+ })]
16183
+ });
16184
+ };
16079
16185
  function FormModeSegmentControl({
16080
16186
  formConfig,
16081
16187
  mode,
@@ -16909,9 +17015,16 @@ const useForm = ({
16909
17015
  onSubmitAbort,
16910
17016
  ...rest
16911
17017
  } = {}) => {
17018
+ var _a;
16912
17019
  const { options } = useRefineContext();
16913
17020
  const disableServerSideValidation = (options == null ? void 0 : options.disableServerSideValidation) || disableServerSideValidationProp;
16914
17021
  const translate = useTranslate();
17022
+ const { captureInitialResource, mutationMeta } = use409Retry({
17023
+ action: refineCoreProps == null ? void 0 : refineCoreProps.action,
17024
+ dataProviderName: refineCoreProps == null ? void 0 : refineCoreProps.dataProviderName,
17025
+ id: refineCoreProps == null ? void 0 : refineCoreProps.id,
17026
+ mutationMeta: refineCoreProps == null ? void 0 : refineCoreProps.mutationMeta
17027
+ });
16915
17028
  const { warnWhenUnsavedChanges: warnWhenUnsavedChangesRefine, setWarnWhen } = useWarnAboutChange();
16916
17029
  const warnWhenUnsavedChanges = warnWhenUnsavedChangesProp ?? warnWhenUnsavedChangesRefine;
16917
17030
  const useHookFormResult = useForm$3({
@@ -16931,10 +17044,11 @@ const useForm = ({
16931
17044
  } = useHookFormResult;
16932
17045
  const useFormCoreResult = useForm$2({
16933
17046
  ...refineCoreProps,
17047
+ mutationMeta,
16934
17048
  onMutationError: (error, _variables, _context) => {
16935
- var _a, _b;
17049
+ var _a2, _b;
16936
17050
  if (disableServerSideValidation) {
16937
- (_a = refineCoreProps == null ? void 0 : refineCoreProps.onMutationError) == null ? void 0 : _a.call(refineCoreProps, error, _variables, _context);
17051
+ (_a2 = refineCoreProps == null ? void 0 : refineCoreProps.onMutationError) == null ? void 0 : _a2.call(refineCoreProps, error, _variables, _context);
16938
17052
  return;
16939
17053
  }
16940
17054
  const errors = error == null ? void 0 : error.errors;
@@ -16967,10 +17081,14 @@ const useForm = ({
16967
17081
  });
16968
17082
  const { queryResult, onFinish, formLoading, onFinishAutoSave } = useFormCoreResult;
16969
17083
  useEffect(() => {
16970
- var _a;
17084
+ var _a2;
17085
+ captureInitialResource((_a2 = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a2.data);
17086
+ }, [captureInitialResource, (_a = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a.data]);
17087
+ useEffect(() => {
17088
+ var _a2;
16971
17089
  if (formState.isDirty)
16972
17090
  return;
16973
- const data2 = (_a = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a.data;
17091
+ const data2 = (_a2 = queryResult == null ? void 0 : queryResult.data) == null ? void 0 : _a2.data;
16974
17092
  if (!data2)
16975
17093
  return;
16976
17094
  const transformedData = transformInitValues ? transformInitValues(data2) : data2;
@@ -16998,13 +17116,13 @@ const useForm = ({
16998
17116
  }, [watch]);
16999
17117
  const onValuesChange = useCallback(
17000
17118
  (changeValues) => {
17001
- var _a;
17119
+ var _a2;
17002
17120
  if (warnWhenUnsavedChanges) {
17003
17121
  setWarnWhen(true);
17004
17122
  }
17005
17123
  if (refineCoreProps == null ? void 0 : refineCoreProps.autoSave) {
17006
17124
  setWarnWhen(false);
17007
- const onFinishProps = (_a = refineCoreProps.autoSave) == null ? void 0 : _a.onFinish;
17125
+ const onFinishProps = (_a2 = refineCoreProps.autoSave) == null ? void 0 : _a2.onFinish;
17008
17126
  if (onFinishProps) {
17009
17127
  return onFinishAutoSave(onFinishProps(changeValues));
17010
17128
  }
@@ -17122,6 +17240,7 @@ const useRefineForm = (props) => {
17122
17240
  resource: resourceConfig.name,
17123
17241
  action: id ? "edit" : "create",
17124
17242
  id,
17243
+ dataProviderName: resourceConfig.dataProviderName,
17125
17244
  liveMode: id ? "auto" : "off",
17126
17245
  ...refineProps
17127
17246
  },
@@ -17135,10 +17254,11 @@ const useRefineForm = (props) => {
17135
17254
  ...formConfig == null ? void 0 : formConfig.useFormProps
17136
17255
  });
17137
17256
  useEffect(() => {
17138
- var _a, _b;
17257
+ var _a, _b, _c;
17139
17258
  const response = (_a = result.refineCore.mutationResult.error) == null ? void 0 : _a.response;
17259
+ const message2 = (_b = result.refineCore.mutationResult.error) == null ? void 0 : _b.message;
17140
17260
  if (response && !(response == null ? void 0 : response.bodyUsed)) {
17141
- (_b = response.json) == null ? void 0 : _b.call(response).then((body) => {
17261
+ (_c = response.json) == null ? void 0 : _c.call(response).then((body) => {
17142
17262
  var _a2;
17143
17263
  setResponseErrorMsgs(
17144
17264
  [].concat(
@@ -17146,8 +17266,10 @@ const useRefineForm = (props) => {
17146
17266
  )
17147
17267
  );
17148
17268
  });
17269
+ } else if (message2 && responseErrorMsgs[0] !== message2) {
17270
+ setResponseErrorMsgs([message2]);
17149
17271
  }
17150
- }, [formConfig, result, i18n2]);
17272
+ }, [formConfig, result, i18n2, responseErrorMsgs]);
17151
17273
  return {
17152
17274
  formResult: result,
17153
17275
  responseErrorMsgs,
@@ -17168,10 +17290,6 @@ const RefineFormContainer = React.forwardRef(function RefineFormContainer2({
17168
17290
  }, ref) {
17169
17291
  var _a, _b;
17170
17292
  const action = id ? "edit" : "create";
17171
- const pushModal = usePushModal();
17172
- const popModal = usePopModal();
17173
- const hasShownExpiredRef = useRef(false);
17174
- const [isSubmitting, setIsSubmitting] = useState(false);
17175
17293
  const refineFormResult = useRefineForm({
17176
17294
  resourceConfig,
17177
17295
  id,
@@ -17180,7 +17298,6 @@ const RefineFormContainer = React.forwardRef(function RefineFormContainer2({
17180
17298
  onSuccess == null ? void 0 : onSuccess(data2);
17181
17299
  },
17182
17300
  onMutationError() {
17183
- setIsSubmitting(false);
17184
17301
  onError == null ? void 0 : onError();
17185
17302
  },
17186
17303
  redirect: false,
@@ -17194,35 +17311,11 @@ const RefineFormContainer = React.forwardRef(function RefineFormContainer2({
17194
17311
  ...options,
17195
17312
  onBeforeSubmitError: (errors) => {
17196
17313
  if (errors.length) {
17197
- setIsSubmitting(false);
17198
17314
  onError == null ? void 0 : onError();
17199
17315
  }
17200
- },
17201
- onSubmitStart: () => {
17202
- setIsSubmitting(true);
17203
- },
17204
- onSubmitAbort: () => {
17205
- setIsSubmitting(false);
17206
17316
  }
17207
17317
  }
17208
17318
  });
17209
- const isExpired = useResourceVersionCheck({
17210
- queryResult: refineFormResult.formResult.refineCore.queryResult
17211
- });
17212
- useEffect(() => {
17213
- if (!isExpired || isSubmitting || hasShownExpiredRef.current) {
17214
- return;
17215
- }
17216
- hasShownExpiredRef.current = true;
17217
- pushModal({
17218
- component: DataExpiredModal,
17219
- props: {
17220
- onAbandon: () => {
17221
- popModal();
17222
- }
17223
- }
17224
- });
17225
- }, [isExpired, isSubmitting, pushModal, popModal]);
17226
17319
  const fieldsConfig = useFieldsConfig(
17227
17320
  resourceConfig,
17228
17321
  { fields: formConfig == null ? void 0 : formConfig.fields },
@@ -17256,13 +17349,7 @@ const RefineFormContainer = React.forwardRef(function RefineFormContainer2({
17256
17349
  isShowLayout: false,
17257
17350
  useFormProps: {
17258
17351
  redirect: false,
17259
- mutationMeta: (_a2 = formConfig == null ? void 0 : formConfig.refineCoreProps) == null ? void 0 : _a2.mutationMeta,
17260
- onSubmitStart: () => {
17261
- setIsSubmitting(true);
17262
- },
17263
- onSubmitAbort: () => {
17264
- setIsSubmitting(false);
17265
- }
17352
+ mutationMeta: (_a2 = formConfig == null ? void 0 : formConfig.refineCoreProps) == null ? void 0 : _a2.mutationMeta
17266
17353
  },
17267
17354
  rules: fieldsConfig == null ? void 0 : fieldsConfig.filter(
17268
17355
  (config) => "isSkipValidationInYaml" in config && !config.isSkipValidationInYaml
@@ -17379,7 +17466,7 @@ function ConfirmModal({
17379
17466
  });
17380
17467
  }
17381
17468
  function FormModal(props) {
17382
- var _a, _b, _c, _d, _e;
17469
+ var _a, _b, _c, _d, _e, _f;
17383
17470
  const {
17384
17471
  id,
17385
17472
  yamlFormProps: customYamlFormProps,
@@ -17517,37 +17604,59 @@ function FormModal(props) {
17517
17604
  setStep(nextStep);
17518
17605
  }
17519
17606
  }, [step]);
17520
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(WizardDialog, {
17521
- style: {
17522
- "--max-modal-width": isYamlForm || !isDisabledChangeMode ? "1024px" : "648px"
17523
- },
17524
- title: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
17525
- className: TitleWrapperStyle,
17526
- children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", {
17527
- children: title
17528
- }), ((_c = resourceConfig.formConfig) == null ? void 0 : _c.formType) === FormType.FORM ? /* @__PURE__ */ jsxRuntimeExports.jsx(FormModeSegmentControl, {
17529
- formConfig: resourceConfig.formConfig,
17530
- mode,
17531
- onChangeMode
17532
- }) : null]
17533
- }),
17534
- error: errorText,
17535
- steps,
17607
+ const extraSubmitButton = ((_c = resourceConfig.formConfig) == null ? void 0 : _c.formType) === FormType.FORM ? resourceConfig.formConfig.extraSubmitButton : void 0;
17608
+ const footer = useExtraSubmitFooter({
17609
+ action,
17610
+ cancelText: (modalProps == null ? void 0 : modalProps.cancelText) || i18n2.t("dovetail.cancel"),
17611
+ defaultSubmitText: okText,
17612
+ errorText,
17613
+ extraSubmitButton,
17614
+ fallbackFooter: modalProps == null ? void 0 : modalProps.footer,
17615
+ isYamlMode,
17616
+ nextStepText: (modalProps == null ? void 0 : modalProps.nextText) || i18n2.t("dovetail.next_step"),
17617
+ prevStepText: (modalProps == null ? void 0 : modalProps.prevText) || i18n2.t("dovetail.prev_step"),
17618
+ saveButtonProps,
17536
17619
  step,
17537
- onStepChange: handleStepChange,
17538
- onOk,
17539
- okButtonProps: {
17540
- ...omit$1(saveButtonProps, "onClick"),
17541
- children: (_d = resourceConfig.formConfig) == null ? void 0 : _d.saveButtonText
17542
- },
17543
- okText: ((_e = resourceConfig.formConfig) == null ? void 0 : _e.saveButtonText) || okText,
17544
- destroyOnClose: true,
17545
- destroyOtherStep: true,
17546
- ...modalProps,
17547
- children: [desc ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
17548
- className: FormDescStyle,
17549
- children: desc
17550
- }) : void 0, formEle]
17620
+ stepCount: (steps == null ? void 0 : steps.length) || 0,
17621
+ onCancel: popModal,
17622
+ onNextStep: () => handleStepChange(step + 1),
17623
+ onPrevStep: () => handleStepChange(step - 1),
17624
+ onSubmit: onOk
17625
+ });
17626
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Retry409Provider, {
17627
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(WizardDialog, {
17628
+ style: {
17629
+ "--max-modal-width": isYamlForm || !isDisabledChangeMode ? "1024px" : "648px"
17630
+ },
17631
+ title: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
17632
+ className: TitleWrapperStyle,
17633
+ children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", {
17634
+ children: title
17635
+ }), ((_d = resourceConfig.formConfig) == null ? void 0 : _d.formType) === FormType.FORM ? /* @__PURE__ */ jsxRuntimeExports.jsx(FormModeSegmentControl, {
17636
+ formConfig: resourceConfig.formConfig,
17637
+ mode,
17638
+ onChangeMode
17639
+ }) : null]
17640
+ }),
17641
+ error: errorText,
17642
+ steps,
17643
+ step,
17644
+ onStepChange: handleStepChange,
17645
+ onOk,
17646
+ okButtonProps: {
17647
+ ...omit$1(saveButtonProps, "onClick"),
17648
+ children: (_e = resourceConfig.formConfig) == null ? void 0 : _e.saveButtonText
17649
+ },
17650
+ okText: ((_f = resourceConfig.formConfig) == null ? void 0 : _f.saveButtonText) || okText,
17651
+ footer,
17652
+ destroyOnClose: true,
17653
+ destroyOtherStep: true,
17654
+ ...modalProps,
17655
+ children: [desc ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
17656
+ className: FormDescStyle,
17657
+ children: desc
17658
+ }) : void 0, formEle]
17659
+ })
17551
17660
  });
17552
17661
  }
17553
17662
  const RefineFormPage_1v0fhor = "";