@strapi/content-type-builder 5.56.0 → 5.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js +117 -13
  2. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js.map +1 -1
  3. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs +118 -13
  4. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/providers/SchemaProvider.js +31 -19
  6. package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
  7. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs +31 -19
  8. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
  9. package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
  10. package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
  11. package/dist/admin/components/DataManager/DataManagerProvider.js +166 -6
  12. package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
  13. package/dist/admin/components/DataManager/DataManagerProvider.mjs +165 -7
  14. package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
  15. package/dist/admin/components/DataManager/RenameMigrationModal.js +285 -0
  16. package/dist/admin/components/DataManager/RenameMigrationModal.js.map +1 -0
  17. package/dist/admin/components/DataManager/RenameMigrationModal.mjs +257 -0
  18. package/dist/admin/components/DataManager/RenameMigrationModal.mjs.map +1 -0
  19. package/dist/admin/components/DataManager/reducer.js +129 -2
  20. package/dist/admin/components/DataManager/reducer.js.map +1 -1
  21. package/dist/admin/components/DataManager/reducer.mjs +128 -2
  22. package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
  23. package/dist/admin/components/DataManager/utils/cleanData.js +8 -1
  24. package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
  25. package/dist/admin/components/DataManager/utils/cleanData.mjs +8 -1
  26. package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
  27. package/dist/admin/components/DataManager/utils/groupRenameChains.js +86 -0
  28. package/dist/admin/components/DataManager/utils/groupRenameChains.js.map +1 -0
  29. package/dist/admin/components/DataManager/utils/groupRenameChains.mjs +84 -0
  30. package/dist/admin/components/DataManager/utils/groupRenameChains.mjs.map +1 -0
  31. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.js +29 -0
  32. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.js.map +1 -0
  33. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.mjs +27 -0
  34. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.mjs.map +1 -0
  35. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.js +35 -0
  36. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.js.map +1 -0
  37. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.mjs +33 -0
  38. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.mjs.map +1 -0
  39. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.js +48 -0
  40. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.js.map +1 -0
  41. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.mjs +45 -0
  42. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.mjs.map +1 -0
  43. package/dist/admin/components/FormModal/FormModal.js +178 -70
  44. package/dist/admin/components/FormModal/FormModal.js.map +1 -1
  45. package/dist/admin/components/FormModal/FormModal.mjs +179 -71
  46. package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
  47. package/dist/admin/components/FormModal/attributes/validation/common.js +6 -5
  48. package/dist/admin/components/FormModal/attributes/validation/common.js.map +1 -1
  49. package/dist/admin/components/FormModal/attributes/validation/common.mjs +1 -1
  50. package/dist/admin/components/FormModal/attributes/validation/common.mjs.map +1 -1
  51. package/dist/admin/components/FormModal/component/createComponentSchema.js +10 -7
  52. package/dist/admin/components/FormModal/component/createComponentSchema.js.map +1 -1
  53. package/dist/admin/components/FormModal/component/createComponentSchema.mjs +1 -1
  54. package/dist/admin/components/FormModal/component/createComponentSchema.mjs.map +1 -1
  55. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.js +24 -21
  56. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.js.map +1 -1
  57. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.mjs +1 -1
  58. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.mjs.map +1 -1
  59. package/dist/admin/components/FormModal/forms/utils/createCollectionName.js +3 -2
  60. package/dist/admin/components/FormModal/forms/utils/createCollectionName.js.map +1 -1
  61. package/dist/admin/components/FormModal/forms/utils/createCollectionName.mjs +1 -1
  62. package/dist/admin/components/FormModal/forms/utils/createCollectionName.mjs.map +1 -1
  63. package/dist/admin/components/FormModal/utils/getRenameStorageChange.js +73 -0
  64. package/dist/admin/components/FormModal/utils/getRenameStorageChange.js.map +1 -0
  65. package/dist/admin/components/FormModal/utils/getRenameStorageChange.mjs +70 -0
  66. package/dist/admin/components/FormModal/utils/getRenameStorageChange.mjs.map +1 -0
  67. package/dist/admin/src/components/AIChat/lib/transforms/schemas/toCTB.d.ts +4 -3
  68. package/dist/admin/src/components/AIChat/lib/types/schema.d.ts +6 -1
  69. package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +28 -2
  70. package/dist/admin/src/components/DataManager/RenameMigrationModal.d.ts +73 -0
  71. package/dist/admin/src/components/DataManager/reducer.d.ts +17 -2
  72. package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +24 -8
  73. package/dist/admin/src/components/DataManager/utils/groupRenameChains.d.ts +31 -0
  74. package/dist/admin/src/components/DataManager/utils/isStorageCompatibleRename.d.ts +10 -0
  75. package/dist/admin/src/components/DataManager/utils/resolveAfterEditRenameConsent.d.ts +24 -0
  76. package/dist/admin/src/components/DataManager/utils/splitChainsByInheritedConsent.d.ts +26 -0
  77. package/dist/admin/src/components/FormModal/utils/getRenameStorageChange.d.ts +40 -0
  78. package/dist/admin/src/types.d.ts +23 -0
  79. package/dist/admin/translations/cs.json.js +0 -2
  80. package/dist/admin/translations/cs.json.js.map +1 -1
  81. package/dist/admin/translations/cs.json.mjs +0 -2
  82. package/dist/admin/translations/cs.json.mjs.map +1 -1
  83. package/dist/admin/translations/de.json.js +0 -2
  84. package/dist/admin/translations/de.json.js.map +1 -1
  85. package/dist/admin/translations/de.json.mjs +0 -2
  86. package/dist/admin/translations/de.json.mjs.map +1 -1
  87. package/dist/admin/translations/en.json.js +12 -2
  88. package/dist/admin/translations/en.json.js.map +1 -1
  89. package/dist/admin/translations/en.json.mjs +12 -2
  90. package/dist/admin/translations/en.json.mjs.map +1 -1
  91. package/dist/admin/translations/ja.json.js +0 -2
  92. package/dist/admin/translations/ja.json.js.map +1 -1
  93. package/dist/admin/translations/ja.json.mjs +0 -2
  94. package/dist/admin/translations/ja.json.mjs.map +1 -1
  95. package/dist/admin/translations/ko.json.js +0 -2
  96. package/dist/admin/translations/ko.json.js.map +1 -1
  97. package/dist/admin/translations/ko.json.mjs +0 -2
  98. package/dist/admin/translations/ko.json.mjs.map +1 -1
  99. package/dist/admin/translations/nl.json.js +0 -2
  100. package/dist/admin/translations/nl.json.js.map +1 -1
  101. package/dist/admin/translations/nl.json.mjs +0 -2
  102. package/dist/admin/translations/nl.json.mjs.map +1 -1
  103. package/dist/admin/translations/pl.json.js +0 -2
  104. package/dist/admin/translations/pl.json.js.map +1 -1
  105. package/dist/admin/translations/pl.json.mjs +0 -2
  106. package/dist/admin/translations/pl.json.mjs.map +1 -1
  107. package/dist/admin/translations/ru.json.js +0 -2
  108. package/dist/admin/translations/ru.json.js.map +1 -1
  109. package/dist/admin/translations/ru.json.mjs +0 -2
  110. package/dist/admin/translations/ru.json.mjs.map +1 -1
  111. package/dist/admin/translations/sk.json.js +0 -2
  112. package/dist/admin/translations/sk.json.js.map +1 -1
  113. package/dist/admin/translations/sk.json.mjs +0 -2
  114. package/dist/admin/translations/sk.json.mjs.map +1 -1
  115. package/dist/server/config.js +24 -3
  116. package/dist/server/config.js.map +1 -1
  117. package/dist/server/config.mjs +21 -3
  118. package/dist/server/config.mjs.map +1 -1
  119. package/dist/server/controllers/schema.js +2 -2
  120. package/dist/server/controllers/schema.js.map +1 -1
  121. package/dist/server/controllers/schema.mjs +1 -1
  122. package/dist/server/controllers/schema.mjs.map +1 -1
  123. package/dist/server/controllers/validation/content-type.js +9 -11
  124. package/dist/server/controllers/validation/content-type.js.map +1 -1
  125. package/dist/server/controllers/validation/content-type.mjs +7 -9
  126. package/dist/server/controllers/validation/content-type.mjs.map +1 -1
  127. package/dist/server/controllers/validation/model-schema.js +2 -3
  128. package/dist/server/controllers/validation/model-schema.js.map +1 -1
  129. package/dist/server/controllers/validation/model-schema.mjs +1 -2
  130. package/dist/server/controllers/validation/model-schema.mjs.map +1 -1
  131. package/dist/server/controllers/validation/relations.js +1 -2
  132. package/dist/server/controllers/validation/relations.js.map +1 -1
  133. package/dist/server/controllers/validation/relations.mjs +1 -2
  134. package/dist/server/controllers/validation/relations.mjs.map +1 -1
  135. package/dist/server/controllers/validation/schema.js +42 -23
  136. package/dist/server/controllers/validation/schema.js.map +1 -1
  137. package/dist/server/controllers/validation/schema.mjs +43 -24
  138. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  139. package/dist/server/index.js +1 -1
  140. package/dist/server/index.js.map +1 -1
  141. package/dist/server/services/content-types.js +1 -2
  142. package/dist/server/services/content-types.js.map +1 -1
  143. package/dist/server/services/content-types.mjs +2 -3
  144. package/dist/server/services/content-types.mjs.map +1 -1
  145. package/dist/server/services/migration-builder/index.js +580 -0
  146. package/dist/server/services/migration-builder/index.js.map +1 -0
  147. package/dist/server/services/migration-builder/index.mjs +573 -0
  148. package/dist/server/services/migration-builder/index.mjs.map +1 -0
  149. package/dist/server/services/schema-builder/content-type-builder.js +31 -1
  150. package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
  151. package/dist/server/services/schema-builder/content-type-builder.mjs +31 -1
  152. package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
  153. package/dist/server/services/schema-mutation.js +30 -2
  154. package/dist/server/services/schema-mutation.js.map +1 -1
  155. package/dist/server/services/schema-mutation.mjs +10 -2
  156. package/dist/server/services/schema-mutation.mjs.map +1 -1
  157. package/dist/server/services/schema.js +312 -15
  158. package/dist/server/services/schema.js.map +1 -1
  159. package/dist/server/services/schema.mjs +305 -9
  160. package/dist/server/services/schema.mjs.map +1 -1
  161. package/dist/server/src/config.d.ts +23 -2
  162. package/dist/server/src/config.d.ts.map +1 -1
  163. package/dist/server/src/controllers/validation/content-type.d.ts +0 -1
  164. package/dist/server/src/controllers/validation/content-type.d.ts.map +1 -1
  165. package/dist/server/src/controllers/validation/relations.d.ts.map +1 -1
  166. package/dist/server/src/controllers/validation/schema.d.ts +28 -0
  167. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  168. package/dist/server/src/index.d.ts +10 -2
  169. package/dist/server/src/index.d.ts.map +1 -1
  170. package/dist/server/src/services/content-types.d.ts.map +1 -1
  171. package/dist/server/src/services/migration-builder/index.d.ts +83 -0
  172. package/dist/server/src/services/migration-builder/index.d.ts.map +1 -0
  173. package/dist/server/src/services/schema-builder/content-type-builder.d.ts.map +1 -1
  174. package/dist/server/src/services/schema-mutation.d.ts +4 -2
  175. package/dist/server/src/services/schema-mutation.d.ts.map +1 -1
  176. package/dist/server/src/services/schema.d.ts +19 -0
  177. package/dist/server/src/services/schema.d.ts.map +1 -1
  178. package/package.json +7 -6
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { useState } from 'react';
4
4
  import { useStrapiApp, useNotification, useGuidedTour, ConfirmDialog, GUIDED_TOUR_REQUIRED_ACTIONS } from '@strapi/admin/strapi-admin';
5
- import { Modal, Dialog, Box, Typography, Tabs, Flex, Divider, Button } from '@strapi/design-system';
5
+ import { Modal, Dialog, Box, Typography, Button, Tabs, Flex, Divider } from '@strapi/design-system';
6
6
  import get from 'lodash/get';
7
7
  import has from 'lodash/has';
8
8
  import isEqual from 'lodash/isEqual';
@@ -53,6 +53,7 @@ import { canEditContentType } from './utils/canEditContentType.mjs';
53
53
  import { createUid, createComponentUid } from './utils/createUid.mjs';
54
54
  import { getAttributesToDisplay } from './utils/getAttributesToDisplay.mjs';
55
55
  import { getFormInputNames } from './utils/getFormInputNames.mjs';
56
+ import { getRenameStorageChange } from './utils/getRenameStorageChange.mjs';
56
57
 
57
58
  const FormComponent = styled.form`
58
59
  overflow: auto;
@@ -88,44 +89,48 @@ const FormModal = ()=>{
88
89
  const ctbFormsAPI = ctbPlugin?.apis.forms;
89
90
  const inputsFromPlugins = ctbFormsAPI.components.inputs;
90
91
  const dispatchGuidedTour = useGuidedTour('FormModal', (s)=>s.dispatch);
91
- const { addAttribute, editAttribute, addCustomFieldAttribute, addCreatedComponentToDynamicZone, changeDynamicZoneComponents, contentTypes, components, createSchema, createComponentSchema, deleteComponent, deleteContentType, editCustomFieldAttribute, updateSchema, nestedComponents, sortedContentTypesList, updateComponentSchema, updateComponentUid, reservedNames } = useDataManager();
92
+ const { addAttribute, editAttribute, addCustomFieldAttribute, addCreatedComponentToDynamicZone, changeDynamicZoneComponents, contentTypes, components, createSchema, createComponentSchema, deleteComponent, deleteContentType, editCustomFieldAttribute, updateSchema, nestedComponents, sortedContentTypesList, updateComponentSchema, updateComponentUid, reservedNames, confirmAttributeRenameMigration, attributeRenameMigrationMode } = useDataManager();
92
93
  const { componentToCreate, formErrors, initialData, isCreatingComponentWhileAddingAField, modifiedData } = reducerState;
93
94
  const type = forTarget === 'component' ? components[targetUid] : contentTypes[targetUid];
94
95
  const [showWarningDialog, setShowWarningDialog] = useState(false);
95
96
  const [pendingSubmit, setPendingSubmit] = useState(null);
96
- const checkFieldNameChanges = ()=>{
97
- // Only check when editing an attribute
97
+ // Set when the edit renames an existing field *and* changes its storage: the
98
+ // data cannot be preserved, so the user confirms before the field is recreated.
99
+ const [storageChangeWarning, setStorageChangeWarning] = useState(null);
100
+ const checkRenameStorageChange = ()=>{
101
+ if (actionType !== 'edit' || modalType !== 'attribute' && modalType !== 'customField') {
102
+ return null;
103
+ }
104
+ return getRenameStorageChange(initialData, modifiedData, attributeRenameMigrationMode);
105
+ };
106
+ /**
107
+ * Fields whose visibility condition depends on this field and references an
108
+ * enum value that this edit removes or changes. Renames are followed
109
+ * automatically, so only an enum value change can break a condition.
110
+ */ const getConditionsBrokenByEnumChange = ()=>{
98
111
  if (actionType !== 'edit' || modalType !== 'attribute') {
99
112
  return false;
100
113
  }
101
- const oldName = initialData.name;
102
114
  const oldEnum = initialData.enum;
103
115
  const newEnum = modifiedData.enum;
104
- // Get all attributes from the content type schema
116
+ if (!Array.isArray(oldEnum) || !Array.isArray(newEnum)) {
117
+ return false;
118
+ }
119
+ const removedValues = oldEnum.filter((value)=>!newEnum.includes(value));
120
+ if (removedValues.length === 0) {
121
+ return false;
122
+ }
123
+ const fieldName = initialData.name;
105
124
  const contentTypeAttributes = type?.attributes ?? [];
106
- // Find all fields that reference this field in their conditions
107
- const referencedFields = contentTypeAttributes.filter((attr)=>{
125
+ const brokenFields = contentTypeAttributes.filter((attr)=>{
108
126
  const conditionEntry = getFirstVisibleConditionEntry(attr.conditions);
109
127
  if (conditionEntry === null) {
110
128
  return false;
111
129
  }
112
130
  const { fieldVar, value } = conditionEntry;
113
- // Check if this condition references our field
114
- if (fieldVar.var !== oldName) {
115
- return false;
116
- }
117
- // If it's an enum field, also check if the value is being deleted/changed
118
- if (oldEnum !== undefined && newEnum !== undefined) {
119
- const deletedOrChangedValues = oldEnum.filter((oldValue)=>!newEnum.includes(oldValue));
120
- return typeof value === 'string' && deletedOrChangedValues.includes(value);
121
- }
122
- return true;
131
+ return fieldVar.var === fieldName && typeof value === 'string' && removedValues.includes(value);
123
132
  });
124
- // If any fields reference this field, return them
125
- if (referencedFields.length > 0) {
126
- return referencedFields;
127
- }
128
- return false;
133
+ return brokenFields.length > 0 ? brokenFields : false;
129
134
  };
130
135
  React.useEffect(()=>{
131
136
  if (isOpen && modalType) {
@@ -384,9 +389,48 @@ const FormModal = ()=>{
384
389
  dispatch,
385
390
  formErrors
386
391
  ]);
387
- const submitForm = async (e, shouldContinue = isCreating)=>{
392
+ const submitForm = async (e, shouldContinue = isCreating, // The user already confirmed the field will be recreated empty (rename +
393
+ // storage change): there is no data to preserve, so don't ask about it.
394
+ { skipRenameMigration = false } = {})=>{
388
395
  try {
389
396
  await checkFormValidity();
397
+ let recordRename = !skipRenameMigration;
398
+ let declineRename = false;
399
+ if (!skipRenameMigration && actionType === 'edit' && (isCreatingAttribute || isCreatingCustomFieldAttribute) && // A field that was never saved has no data to preserve (and
400
+ // `recordRename` skips it), so there is nothing to ask about.
401
+ initialData.status !== 'NEW' && toStringValue(initialData.name) !== toStringValue(modifiedData.name)) {
402
+ const decision = await confirmAttributeRenameMigration({
403
+ forTarget,
404
+ uid: targetUid,
405
+ oldName: toStringValue(initialData.name),
406
+ newName: toStringValue(modifiedData.name)
407
+ });
408
+ if (decision === null) {
409
+ return;
410
+ }
411
+ recordRename = decision;
412
+ declineRename = !decision;
413
+ }
414
+ // Renaming the other side of a relation from this form renames a field
415
+ // of the target type, which may own the join table: ask for that one
416
+ // too, after the field's own prompt.
417
+ const oldTargetAttribute = toStringValue(initialData.targetAttribute);
418
+ const newTargetAttribute = toStringValue(modifiedData.targetAttribute);
419
+ let recordTargetRename = !skipRenameMigration;
420
+ let declineTargetRename = false;
421
+ if (!skipRenameMigration && actionType === 'edit' && isCreatingAttribute && attributeType === 'relation' && oldTargetAttribute !== '' && newTargetAttribute !== '' && oldTargetAttribute !== newTargetAttribute && toStringValue(initialData.target) === toStringValue(modifiedData.target)) {
422
+ const decision = await confirmAttributeRenameMigration({
423
+ forTarget: 'contentType',
424
+ uid: toStringValue(modifiedData.target),
425
+ oldName: oldTargetAttribute,
426
+ newName: newTargetAttribute
427
+ });
428
+ if (decision === null) {
429
+ return;
430
+ }
431
+ recordTargetRename = decision;
432
+ declineTargetRename = !decision;
433
+ }
390
434
  dispatch(actions.setErrors({
391
435
  errors: {}
392
436
  }));
@@ -505,7 +549,9 @@ const FormModal = ()=>{
505
549
  },
506
550
  forTarget,
507
551
  targetUid,
508
- name: toStringValue(initialData.name)
552
+ name: toStringValue(initialData.name),
553
+ recordRename,
554
+ declineRename
509
555
  };
510
556
  if (actionType === 'edit') {
511
557
  editCustomFieldAttribute(customFieldAttributeUpdate);
@@ -536,7 +582,9 @@ const FormModal = ()=>{
536
582
  attributeToSet: modifiedData,
537
583
  forTarget,
538
584
  targetUid,
539
- name: toStringValue(initialData.name)
585
+ name: toStringValue(initialData.name),
586
+ recordRename,
587
+ declineRename
540
588
  });
541
589
  }
542
590
  // Adding a component to a dynamiczone is not the same logic as creating a simple field
@@ -566,7 +614,11 @@ const FormModal = ()=>{
566
614
  attributeToSet: modifiedData,
567
615
  forTarget,
568
616
  targetUid,
569
- name: toStringValue(initialData.name)
617
+ name: toStringValue(initialData.name),
618
+ recordRename,
619
+ declineRename,
620
+ recordTargetRename,
621
+ declineTargetRename
570
622
  });
571
623
  }
572
624
  if (shouldContinue) {
@@ -622,7 +674,9 @@ const FormModal = ()=>{
622
674
  attributeToSet: attributeData,
623
675
  forTarget,
624
676
  targetUid,
625
- name: toStringValue(initialData.name)
677
+ name: toStringValue(initialData.name),
678
+ recordRename,
679
+ declineRename
626
680
  });
627
681
  }
628
682
  if (shouldContinue) {
@@ -743,11 +797,39 @@ const FormModal = ()=>{
743
797
  }
744
798
  }
745
799
  };
800
+ // Runs after the condition warning (if any): warn when the rename also
801
+ // changes the field's storage, otherwise submit.
802
+ const continueSubmit = async (e, shouldContinue)=>{
803
+ const storageChange = checkRenameStorageChange();
804
+ if (storageChange) {
805
+ setPendingSubmit({
806
+ e,
807
+ shouldContinue
808
+ });
809
+ setStorageChangeWarning(storageChange);
810
+ return;
811
+ }
812
+ await submitForm(e, shouldContinue);
813
+ };
814
+ const cancelStorageChange = ()=>{
815
+ setStorageChangeWarning(null);
816
+ setPendingSubmit(null);
817
+ };
818
+ const confirmStorageChange = ()=>{
819
+ if (pendingSubmit === null) {
820
+ return;
821
+ }
822
+ const { e, shouldContinue } = pendingSubmit;
823
+ cancelStorageChange();
824
+ submitForm(e, shouldContinue, {
825
+ skipRenameMigration: true
826
+ });
827
+ };
746
828
  const handleSubmit = async (e, shouldContinue = isCreating)=>{
747
829
  e.preventDefault();
748
- // Check for field name changes when clicking Finish
749
- const referencedFields = checkFieldNameChanges();
750
- if (referencedFields) {
830
+ // Check for conditions broken by an enum value change when clicking Finish
831
+ const brokenFields = getConditionsBrokenByEnumChange();
832
+ if (brokenFields) {
751
833
  setPendingSubmit({
752
834
  e,
753
835
  shouldContinue
@@ -755,7 +837,7 @@ const FormModal = ()=>{
755
837
  setShowWarningDialog(true);
756
838
  return;
757
839
  }
758
- await submitForm(e, shouldContinue);
840
+ await continueSubmit(e, shouldContinue);
759
841
  };
760
842
  const handleConfirmClose = ()=>{
761
843
  // eslint-disable-next-line no-alert
@@ -919,7 +1001,7 @@ const FormModal = ()=>{
919
1001
  const { e, shouldContinue } = pendingSubmit;
920
1002
  setShowWarningDialog(false);
921
1003
  setPendingSubmit(null);
922
- submitForm(e, shouldContinue);
1004
+ continueSubmit(e, shouldContinue);
923
1005
  }
924
1006
  },
925
1007
  onCancel: ()=>{
@@ -927,46 +1009,17 @@ const FormModal = ()=>{
927
1009
  setPendingSubmit(null);
928
1010
  },
929
1011
  children: (()=>{
930
- const referencedFields = checkFieldNameChanges();
931
- if (referencedFields === false) return null;
932
- const fieldNames = referencedFields.map((field)=>field.name).join(', ');
933
- const oldEnum = initialData.enum;
934
- const newEnum = modifiedData.enum;
935
- const isEnum = Array.isArray(oldEnum) && Array.isArray(newEnum);
936
- if (isEnum === true) {
937
- const deletedOrChangedValues = oldEnum.filter((value)=>!newEnum.includes(value));
938
- return /*#__PURE__*/ jsx(Box, {
939
- children: /*#__PURE__*/ jsxs(Typography, {
940
- children: [
941
- formatMessage({
942
- id: 'form.attribute.condition.enum-change-warning',
943
- defaultMessage: 'The following fields have conditions that depend on this field: '
944
- }),
945
- /*#__PURE__*/ jsx(Typography, {
946
- fontWeight: "bold",
947
- children: fieldNames
948
- }),
949
- formatMessage({
950
- id: 'form.attribute.condition.enum-change-warning-values',
951
- defaultMessage: '. Changing or removing the enum values '
952
- }),
953
- /*#__PURE__*/ jsx(Typography, {
954
- fontWeight: "bold",
955
- children: deletedOrChangedValues.join(', ')
956
- }),
957
- formatMessage({
958
- id: 'form.attribute.condition.enum-change-warning-end',
959
- defaultMessage: ' will break these conditions. Do you want to proceed?'
960
- })
961
- ]
962
- })
963
- });
964
- }
1012
+ const brokenFields = getConditionsBrokenByEnumChange();
1013
+ if (brokenFields === false) return null;
1014
+ const fieldNames = brokenFields.map((field)=>field.name).join(', ');
1015
+ const oldEnum = initialData.enum ?? [];
1016
+ const newEnum = modifiedData.enum ?? [];
1017
+ const deletedOrChangedValues = oldEnum.filter((value)=>!newEnum.includes(value));
965
1018
  return /*#__PURE__*/ jsx(Box, {
966
1019
  children: /*#__PURE__*/ jsxs(Typography, {
967
1020
  children: [
968
1021
  formatMessage({
969
- id: 'form.attribute.condition.field-change-warning',
1022
+ id: 'form.attribute.condition.enum-change-warning',
970
1023
  defaultMessage: 'The following fields have conditions that depend on this field: '
971
1024
  }),
972
1025
  /*#__PURE__*/ jsx(Typography, {
@@ -974,8 +1027,16 @@ const FormModal = ()=>{
974
1027
  children: fieldNames
975
1028
  }),
976
1029
  formatMessage({
977
- id: 'form.attribute.condition.field-change-warning-end',
978
- defaultMessage: '. Renaming it will break these conditions. Do you want to proceed?'
1030
+ id: 'form.attribute.condition.enum-change-warning-values',
1031
+ defaultMessage: '. Changing or removing the enum values '
1032
+ }),
1033
+ /*#__PURE__*/ jsx(Typography, {
1034
+ fontWeight: "bold",
1035
+ children: deletedOrChangedValues.join(', ')
1036
+ }),
1037
+ formatMessage({
1038
+ id: 'form.attribute.condition.enum-change-warning-end',
1039
+ defaultMessage: ' will break these conditions. Do you want to proceed?'
979
1040
  })
980
1041
  ]
981
1042
  })
@@ -984,6 +1045,53 @@ const FormModal = ()=>{
984
1045
  })
985
1046
  ]
986
1047
  }),
1048
+ /*#__PURE__*/ jsx(Dialog.Root, {
1049
+ open: storageChangeWarning !== null,
1050
+ onOpenChange: (open)=>!open && cancelStorageChange(),
1051
+ children: /*#__PURE__*/ jsx(ConfirmDialog, {
1052
+ title: formatMessage({
1053
+ id: getTrad('form.attribute.rename-type-change-warning.title'),
1054
+ defaultMessage: 'Existing data will be lost'
1055
+ }),
1056
+ onCancel: cancelStorageChange,
1057
+ endAction: /*#__PURE__*/ jsx(Dialog.Action, {
1058
+ children: /*#__PURE__*/ jsx(Button, {
1059
+ fullWidth: true,
1060
+ variant: "danger",
1061
+ onClick: confirmStorageChange,
1062
+ children: formatMessage({
1063
+ id: getTrad('form.attribute.rename-type-change-warning.confirm'),
1064
+ defaultMessage: 'Continue'
1065
+ })
1066
+ })
1067
+ }),
1068
+ children: storageChangeWarning && /*#__PURE__*/ jsx(Box, {
1069
+ children: /*#__PURE__*/ jsx(Typography, {
1070
+ children: formatMessage({
1071
+ id: getTrad('form.attribute.rename-type-change-warning.body'),
1072
+ defaultMessage: 'You are renaming {oldName} to {newName} and changing it from {oldType} to {newType}. Strapi cannot preserve the existing data of this field when both change at once. The field will be recreated empty when you save.'
1073
+ }, {
1074
+ oldName: /*#__PURE__*/ jsx(Typography, {
1075
+ fontWeight: "bold",
1076
+ children: storageChangeWarning.oldName
1077
+ }),
1078
+ newName: /*#__PURE__*/ jsx(Typography, {
1079
+ fontWeight: "bold",
1080
+ children: storageChangeWarning.newName
1081
+ }),
1082
+ oldType: /*#__PURE__*/ jsx(Typography, {
1083
+ fontWeight: "bold",
1084
+ children: storageChangeWarning.oldType
1085
+ }),
1086
+ newType: /*#__PURE__*/ jsx(Typography, {
1087
+ fontWeight: "bold",
1088
+ children: storageChangeWarning.newType
1089
+ })
1090
+ })
1091
+ })
1092
+ })
1093
+ })
1094
+ }),
987
1095
  /*#__PURE__*/ jsx(FormModalHeader, {
988
1096
  actionType: actionType,
989
1097
  attributeName: attributeName,