@open-mercato/ui 0.9.0 → 0.9.1-develop.7459.1.99e3accd30

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.
@@ -553,7 +553,13 @@ function CrudForm({
553
553
  const navigationConfirmPendingRef = React.useRef(false);
554
554
  const submitNavigationBypassRef = React.useRef(false);
555
555
  const submitNavigationBypassTimeoutRef = React.useRef(null);
556
- const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false);
556
+ const [hasUnsavedChanges, setHasUnsavedChangesState] = React.useState(false);
557
+ const hasUnsavedChangesRef = React.useRef(false);
558
+ const setHasUnsavedChanges = React.useCallback((next) => {
559
+ if (hasUnsavedChangesRef.current === next) return;
560
+ hasUnsavedChangesRef.current = next;
561
+ setHasUnsavedChangesState(next);
562
+ }, []);
557
563
  const popStateRollbackRef = React.useRef(false);
558
564
  const shouldBypassUnsavedChangesGuardRef = React.useRef(shouldBypassUnsavedChangesGuard);
559
565
  React.useEffect(() => {
@@ -575,7 +581,7 @@ function CrudForm({
575
581
  const dirty = currentSnapshot !== snapshot;
576
582
  isDirtyRef.current = dirty;
577
583
  setHasUnsavedChanges(dirty);
578
- }, [embedded, trackDirtyWhenEmbedded, values]);
584
+ }, [embedded, trackDirtyWhenEmbedded, values, setHasUnsavedChanges]);
579
585
  React.useEffect(() => {
580
586
  onDirtyChange?.(hasUnsavedChanges);
581
587
  }, [hasUnsavedChanges, onDirtyChange]);
@@ -619,7 +625,7 @@ function CrudForm({
619
625
  everEditedFieldIdsRef.current.clear();
620
626
  isDirtyRef.current = false;
621
627
  setHasUnsavedChanges(false);
622
- }, []);
628
+ }, [setHasUnsavedChanges]);
623
629
  const confirmUnsavedChanges = React.useCallback(async () => {
624
630
  if (!isDirtyRef.current || typeof window === "undefined") return true;
625
631
  if (navigationPromptBypassRef.current || submitNavigationBypassRef.current) return true;
@@ -725,7 +731,7 @@ function CrudForm({
725
731
  window.history.pushState = originalPushState;
726
732
  window.history.replaceState = originalReplaceState;
727
733
  };
728
- }, [allowNextNavigation, clearDirtyState, confirmUnsavedChanges, embedded, hasUnsavedChanges, router, trackDirtyWhenEmbedded]);
734
+ }, [allowNextNavigation, clearDirtyState, confirmUnsavedChanges, embedded, hasUnsavedChanges, router, trackDirtyWhenEmbedded, setHasUnsavedChanges]);
729
735
  const { widgets: primaryInjectionWidgets } = useInjectionWidgets(resolvedInjectionSpotId, {
730
736
  context: injectionContext,
731
737
  triggerOnLoad: true
@@ -1115,6 +1121,13 @@ function CrudForm({
1115
1121
  headerInjectionAction,
1116
1122
  extraActions
1117
1123
  ] }) : void 0;
1124
+ const renderFooterActions = !hideFooterActions && !formReadOnly;
1125
+ const embeddedExtraActions = renderFooterActions ? void 0 : extraActions;
1126
+ const embeddedHeaderActions = versionHistoryEnabled || headerInjectionAction || embeddedExtraActions ? /* @__PURE__ */ jsxs(Fragment, { children: [
1127
+ versionHistoryEnabled ? versionHistoryAction : null,
1128
+ headerInjectionAction,
1129
+ embeddedExtraActions
1130
+ ] }) : void 0;
1118
1131
  React.useEffect(() => {
1119
1132
  let cancelled = false;
1120
1133
  async function load() {
@@ -1964,14 +1977,18 @@ function CrudForm({
1964
1977
  if (activeDispatch?.eventId === dispatchToken.eventId && activeDispatch.formGeneration === dispatchToken.formGeneration) {
1965
1978
  activeFieldChangeDispatchRef.current = null;
1966
1979
  }
1967
- if (fieldChangeDispatcherMountedRef.current && fieldChangeFormGenerationRef.current === dispatchToken.formGeneration) {
1980
+ if (fieldChangeDispatcherMountedRef.current && fieldChangeFormGenerationRef.current === dispatchToken.formGeneration && pendingFieldChangeEventsRef.current.length > 0) {
1968
1981
  setFieldChangeDispatchVersion((version) => version + 1);
1969
1982
  }
1970
1983
  });
1971
1984
  }, [extendedInjectionEventsEnabled, fieldChangeDispatchVersion, triggerInjectionEvent, values]);
1972
- const onBlurRequest = React.useCallback((fieldId) => {
1973
- void validateFieldOnBlur(fieldId);
1985
+ const validateFieldOnBlurRef = React.useRef(validateFieldOnBlur);
1986
+ React.useLayoutEffect(() => {
1987
+ validateFieldOnBlurRef.current = validateFieldOnBlur;
1974
1988
  }, [validateFieldOnBlur]);
1989
+ const onBlurRequest = React.useCallback((fieldId) => {
1990
+ void validateFieldOnBlurRef.current(fieldId);
1991
+ }, []);
1975
1992
  const handleFieldsetSelectionChange = React.useCallback(
1976
1993
  (entityId2, nextCode) => {
1977
1994
  if (!nextCode) return;
@@ -2953,7 +2970,7 @@ function CrudForm({
2953
2970
  submit: formReadOnly ? void 0 : { formId, pending, label: resolvedSubmitLabel, pendingLabel: savingLabel, icon: submitIcon }
2954
2971
  }
2955
2972
  }
2956
- ) : headerExtraActions ? /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 mb-2", children: headerExtraActions }) : null,
2973
+ ) : embeddedHeaderActions ? /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 mb-2", children: embeddedHeaderActions }) : null,
2957
2974
  contentHeader,
2958
2975
  /* @__PURE__ */ jsx(
2959
2976
  DataLoader,
@@ -2986,7 +3003,7 @@ function CrudForm({
2986
3003
  }
2987
3004
  ),
2988
3005
  formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-status-error-text", children: formError }) : null,
2989
- hideFooterActions || formReadOnly ? null : /* @__PURE__ */ jsx(
3006
+ renderFooterActions ? /* @__PURE__ */ jsx(
2990
3007
  FormFooter,
2991
3008
  {
2992
3009
  embedded,
@@ -3002,7 +3019,7 @@ function CrudForm({
3002
3019
  submit: { pending, label: resolvedSubmitLabel, pendingLabel: savingLabel, icon: submitIcon }
3003
3020
  }
3004
3021
  }
3005
- )
3022
+ ) : null
3006
3023
  ] })
3007
3024
  )
3008
3025
  }
@@ -3031,7 +3048,7 @@ function CrudForm({
3031
3048
  submit: formReadOnly ? void 0 : { formId, pending, label: resolvedSubmitLabel, pendingLabel: savingLabel, icon: submitIcon }
3032
3049
  }
3033
3050
  }
3034
- ) : headerExtraActions ? /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 mb-2", children: headerExtraActions }) : null,
3051
+ ) : embeddedHeaderActions ? /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2 mb-2", children: embeddedHeaderActions }) : null,
3035
3052
  contentHeader,
3036
3053
  /* @__PURE__ */ jsx(
3037
3054
  DataLoader,
@@ -3085,7 +3102,7 @@ function CrudForm({
3085
3102
  );
3086
3103
  }) }),
3087
3104
  formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-status-error-text", children: formError }) : null,
3088
- hideFooterActions || formReadOnly ? null : /* @__PURE__ */ jsx(
3105
+ renderFooterActions ? /* @__PURE__ */ jsx(
3089
3106
  FormFooter,
3090
3107
  {
3091
3108
  embedded,
@@ -3101,7 +3118,7 @@ function CrudForm({
3101
3118
  submit: { pending, label: resolvedSubmitLabel, pendingLabel: savingLabel, icon: submitIcon }
3102
3119
  }
3103
3120
  }
3104
- )
3121
+ ) : null
3105
3122
  ]
3106
3123
  }
3107
3124
  ) })