@plusscommunities/pluss-feature-builder-web-d 1.0.2-beta.7 → 1.0.2-beta.9

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.
@@ -5,18 +5,14 @@ import { SidebarLayout } from "../components/SidebarLayout.jsx";
5
5
  import { values } from "../values.config.js";
6
6
  import { PlussCore } from "../feature.config";
7
7
  import styles from "./Form.module.css";
8
- import fieldStyles from "../components/Fields.module.css";
9
8
  import { Field } from "../components/Fields.jsx";
10
9
  import { iconImports } from "../components/iconImports";
11
10
  import {
12
11
  Text,
13
12
  LoadingState,
14
- SkeletonLoader,
15
- DropdownInput,
16
13
  Button,
17
14
  ErrorBoundary,
18
15
  Popup,
19
- CenteredContainer,
20
16
  } from "../components";
21
17
 
22
18
  import ToastContainer from "../components/ToastContainer.jsx";
@@ -31,7 +27,6 @@ import {
31
27
  selectIsEditMode,
32
28
  selectIsStepValid,
33
29
  selectStepErrors,
34
- selectCurrentStep,
35
30
  selectFormIsSubmitting,
36
31
  selectFormSubmitError,
37
32
  selectFormSubmitSuccess,
@@ -122,28 +117,20 @@ const FormFieldsStepInner = (props) => {
122
117
  },
123
118
  ];
124
119
 
125
- // Use custom hook to handle definition loading
126
120
  const { definition, definitionIsLoading, reloadDefinition } =
127
121
  useFeatureDefinitionLoader();
128
122
 
129
- // Get form state for display name
130
123
  const formDisplayName = useSelector(selectFormDisplayName);
131
124
 
132
- // Get wizard state
133
125
  const isCreateMode = useSelector(selectIsCreateMode);
134
126
  const isEditMode = useSelector(selectIsEditMode);
135
-
136
- // Get validation state
137
127
  const isStepValid = useSelector(selectIsStepValid("fields"));
138
128
  const stepErrors = useSelector(selectStepErrors("fields"));
139
129
  const showWarnings = !isStepValid && Object.keys(stepErrors).length > 0;
140
-
141
- // Get submission state
142
130
  const isSubmitting = useSelector(selectFormIsSubmitting);
143
131
  const submitError = useSelector(selectFormSubmitError);
144
132
  const submitSuccess = useSelector(selectFormSubmitSuccess);
145
133
 
146
- // Toast management functions
147
134
  const addToast = (type, message) => {
148
135
  const id = Date.now();
149
136
  setToasts((prev) => [...prev, { id, type, message, isVisible: true }]);
@@ -153,9 +140,6 @@ const FormFieldsStepInner = (props) => {
153
140
  setToasts((prev) => prev.filter((toast) => toast.id !== id));
154
141
  };
155
142
 
156
- // Note: Removed automatic redirect after successful save in edit mode
157
- // User should stay on the current step until they manually navigate
158
-
159
143
  // Handle successful submission with optimistic update and redirect
160
144
  React.useEffect(() => {
161
145
  if (submitSuccess && !isSubmitting) {
@@ -163,14 +147,11 @@ const FormFieldsStepInner = (props) => {
163
147
  addToast("success", "Changes saved");
164
148
  dispatch(clearFormSubmissionState());
165
149
  } else {
166
- // In create mode, show success toast and redirect immediately
167
150
  addToast("success", "Feature created successfully");
168
-
169
- // Clear submission state and redirect to overview step
170
151
  dispatch(clearFormSubmissionState());
171
152
  setTimeout(() => {
172
153
  history.push(values.routeFormOverviewStep);
173
- }, 1000); // Brief delay to show toast
154
+ }, 1000);
174
155
  }
175
156
  }
176
157
  }, [submitSuccess, isEditMode, isSubmitting, dispatch, history]);
@@ -185,7 +166,6 @@ const FormFieldsStepInner = (props) => {
185
166
  }
186
167
  }, [submitError]);
187
168
 
188
- // Scroll to top when validation errors appear
189
169
  useEffect(() => {
190
170
  if (showWarnings) {
191
171
  // Scroll to top of form to show validation errors
@@ -193,29 +173,18 @@ const FormFieldsStepInner = (props) => {
193
173
  }
194
174
  }, [showWarnings]);
195
175
 
196
- // Error boundary handlers
197
176
  const handleRefresh = () => {
198
- // Refresh current step data
199
177
  dispatch(validateAndUpdateStep("fields"));
200
178
  };
201
179
 
202
- const handleBack = () => {
203
- // Go to overview step
204
- history.push(values.routeFormOverviewStep);
205
- };
206
-
207
180
  useEffect(() => {
208
- // Set current step when component mounts
209
181
  dispatch(setCurrentStepAndSave("fields"));
210
182
  }, [dispatch]);
211
183
 
212
- // Add effect to handle definition loading and validation in edit mode
213
- // ADD THIS EFFECT: Hydrate form data from definition on refresh
214
184
  useEffect(() => {
215
185
  if (definition && !definitionIsLoading && isFormInitial) {
216
186
  dispatch(setInitialValues(definition));
217
187
 
218
- // In edit mode, trigger validation after setting initial values
219
188
  if (isEditMode) {
220
189
  setTimeout(() => {
221
190
  dispatch(validateAndUpdateStep("fields"));
@@ -226,9 +195,7 @@ const FormFieldsStepInner = (props) => {
226
195
 
227
196
  useEffect(() => {
228
197
  // In edit mode, trigger validation when definition is available
229
- // Note: The new effect above handles the data population, this handles re-validation
230
198
  if (isEditMode && definition && !definitionIsLoading && !isFormInitial) {
231
- // Only validate if form is NOT initial (meaning it has data)
232
199
  setTimeout(() => {
233
200
  dispatch(validateAndUpdateStep("fields"));
234
201
  }, 100);
@@ -237,16 +204,16 @@ const FormFieldsStepInner = (props) => {
237
204
 
238
205
  function handleAddField(fieldType) {
239
206
  dispatch(addField(fieldType));
240
- setShowFieldSelector(false); // Close popup after adding field
207
+ setShowFieldSelector(false);
241
208
  }
242
209
 
243
210
  function handleOpenFieldSelector() {
244
- setReplacingFieldIndex(null); // Reset to add mode
211
+ setReplacingFieldIndex(null);
245
212
  setShowFieldSelector(true);
246
213
  }
247
214
 
248
215
  function handleCloseFieldSelector() {
249
- setReplacingFieldIndex(null); // Reset replacement state
216
+ setReplacingFieldIndex(null);
250
217
  setShowFieldSelector(false);
251
218
  }
252
219
 
@@ -255,7 +222,6 @@ const FormFieldsStepInner = (props) => {
255
222
  }
256
223
 
257
224
  function handleReplaceField(fieldIndex) {
258
- // Store the field index to replace and open the field selector
259
225
  setReplacingFieldIndex(fieldIndex);
260
226
  setShowFieldSelector(true);
261
227
  }
@@ -263,82 +229,55 @@ const FormFieldsStepInner = (props) => {
263
229
  function handleAddReplacementField(fieldType) {
264
230
  const fieldIndex = replacingFieldIndex;
265
231
  if (fieldIndex !== null) {
266
- // Delete the current field at this index
267
232
  const currentField = allFields[fieldIndex];
268
233
  if (currentField && !currentField.isMandatory) {
269
234
  dispatch(deleteField(currentField.id));
270
235
  }
271
-
272
- // Add the new field
273
236
  dispatch(addField(fieldType));
274
-
275
- // Reset replacement state
276
237
  setReplacingFieldIndex(null);
277
238
  setShowFieldSelector(false);
278
239
  }
279
240
  }
280
241
 
281
242
  function handleNext() {
282
- // Validate before proceeding
283
243
  const validationResult = dispatch(validateAndUpdateStep("fields"));
284
-
285
- // If validation passes, navigate to next step
286
244
  if (validationResult?.isValid) {
287
- // Clear form submission state when changing steps
288
245
  dispatch(clearFormSubmissionState());
289
-
290
246
  if (isCreateMode) {
291
247
  history.push(values.routeFormLayoutStep);
292
248
  } else {
293
- // In edit mode, navigate directly
294
249
  history.push(values.routeFormLayoutStep);
295
250
  }
296
251
  }
297
252
  // If validation fails, scroll to top to show error summary
298
253
  else {
299
- // Scroll to top of form to show validation errors
300
254
  window.scrollTo({ top: 0, behavior: "smooth" });
301
255
  }
302
256
  }
303
257
 
304
258
  function handlePrevious() {
305
- // Clear form submission state when changing steps
306
259
  dispatch(clearFormSubmissionState());
307
-
308
260
  if (isCreateMode) {
309
261
  history.push(values.routeFormOverviewStep);
310
262
  } else {
311
- // In edit mode, go back to overview screen
312
263
  history.push(values.routeFormOverviewStep);
313
264
  }
314
265
  }
315
266
 
316
267
  function handleSaveStep() {
317
- // Validate before saving in edit mode
318
268
  const validationResult = dispatch(validateAndUpdateStep("fields"));
319
-
320
- // If validation passes, save the entire form
321
269
  if (validationResult?.isValid) {
322
270
  dispatch(submitForm());
323
271
  }
324
272
  // If validation fails, scroll to top to show error summary
325
273
  else {
326
- // Scroll to top of form to show validation errors
327
274
  window.scrollTo({ top: 0, behavior: "smooth" });
328
275
  }
329
276
  }
330
277
 
331
- // Get all fields in unified list (base + custom)
332
278
  const allFields = fields || [];
333
-
334
- // Create sorted copy for rendering
335
279
  const sortedFields = allFields.slice().sort((a, b) => a.order - b.order);
336
280
 
337
- // Filter description fields for summary demo
338
- const descriptionFields = allFields.filter(
339
- (field) => field.type === "description",
340
- );
341
-
342
281
  // Check for definition management permission
343
282
  if (
344
283
  !PlussCore.Session.validateAccess(
@@ -665,11 +604,9 @@ const useField = (id) => {
665
604
  }
666
605
 
667
606
  function setUseAsSummary(value) {
668
- // When setting a field as summary, use the new action to ensure only one field is selected
669
607
  if (value) {
670
608
  dispatch(setSummaryField(id));
671
609
  } else {
672
- // When unsetting, use regular update to unset this specific field
673
610
  const updatedField = { values: { ...values, useAsSummary: false } };
674
611
  dispatch(updateFieldValuesById(id, updatedField));
675
612
  }