@plusscommunities/pluss-feature-builder-web-a 1.0.2-beta.4 → 1.0.2-beta.6

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.
@@ -1,243 +1,228 @@
1
- /**
2
- * Wizard Actions for Feature Builder
3
- * Manages wizard state including navigation, step validation, and mode switching
4
- * Provides validation logic for overview, fields, and layout steps
5
- * Coordinates with form state and step progression
6
- *
7
- * @namespace wizardActions
8
- */
9
-
10
- // Import selectors for form state access
11
1
  import {
12
- selectFormTitle,
13
- selectFormIcon,
14
- selectFormDisplayName,
15
- selectFormLayout,
16
- selectFormFields,
2
+ selectFormTitle,
3
+ selectFormIcon,
4
+ selectFormDisplayName,
5
+ selectFormLayout,
6
+ selectFormFields,
17
7
  } from "../selectors/featureBuilderSelectors";
18
8
 
19
- // Import values config and form actions
9
+ import { clearFormSubmissionState } from "./formActions"
10
+
20
11
  import { values } from "../values.config";
21
- import { clearFormSubmissionState } from "./formActions";
22
12
 
23
13
  // Wizard action types
24
- export const SET_WIZARD_MODE = "SET_WIZARD_MODE";
25
- export const SET_NAVIGATION_STATE = "SET_NAVIGATION_STATE";
26
- export const UPDATE_STEP_VALIDATION = "UPDATE_STEP_VALIDATION";
27
- export const MARK_STEP_COMPLETE = "MARK_STEP_COMPLETE";
28
- export const RESET_WIZARD_STATE = "RESET_WIZARD_STATE";
29
- export const VALIDATE_AND_UPDATE_STEP = "VALIDATE_AND_UPDATE_STEP";
14
+ const REDUCER_PREFIX = values.reducerKey.toUpperCase();
15
+ export const SET_WIZARD_MODE = `${REDUCER_PREFIX}_SET_WIZARD_MODE`;
16
+ export const SET_NAVIGATION_STATE = `${REDUCER_PREFIX}_SET_NAVIGATION_STATE`;
17
+ export const UPDATE_STEP_VALIDATION = `${REDUCER_PREFIX}_UPDATE_STEP_VALIDATION`;
18
+ export const MARK_STEP_COMPLETE = `${REDUCER_PREFIX}_MARK_STEP_COMPLETE`;
19
+ export const RESET_WIZARD_STATE = `${REDUCER_PREFIX}_RESET_WIZARD_STATE`;
20
+ export const VALIDATE_AND_UPDATE_STEP = `${REDUCER_PREFIX}_VALIDATE_AND_UPDATE_STEP`;
30
21
 
31
22
  // Mode setters
32
23
  export const setWizardMode = (mode) => ({
33
- type: SET_WIZARD_MODE,
34
- payload: mode,
24
+ type: SET_WIZARD_MODE,
25
+ payload: mode,
35
26
  });
36
27
 
37
28
  // Navigation actions
38
29
  export const setNavigationState = (navigationState) => ({
39
- type: SET_NAVIGATION_STATE,
40
- payload: navigationState,
30
+ type: SET_NAVIGATION_STATE,
31
+ payload: navigationState,
41
32
  });
42
33
 
43
34
  export const setCurrentStep = (step, previousStep = null) => ({
44
- type: SET_NAVIGATION_STATE,
45
- payload: {
46
- currentStep: step,
47
- previousStep,
48
- canGoBack: step !== "welcome",
49
- canGoForward: true,
50
- },
35
+ type: SET_NAVIGATION_STATE,
36
+ payload: {
37
+ currentStep: step,
38
+ previousStep,
39
+ canGoBack: step !== "welcome",
40
+ canGoForward: true,
41
+ },
51
42
  });
52
43
 
53
44
  export const goToStep = (step) => (dispatch, getState) => {
54
- const state = getState()[values.reducerKey];
55
- const currentStep =
56
- state &&
57
- state.wizard &&
58
- state.wizard.navigation &&
59
- state.wizard.navigation.currentStep;
45
+ const state = getState()[values.reducerKey];
46
+ const currentStep = state?.wizard?.navigation?.currentStep;
60
47
 
61
- // Clear form submission state when changing steps
62
- dispatch(clearFormSubmissionState());
48
+ // Clear form submission state when changing steps
49
+ dispatch(clearFormSubmissionState());
63
50
 
64
- dispatch(setCurrentStep(step, currentStep));
51
+ dispatch(setCurrentStep(step, currentStep));
65
52
  };
66
53
 
67
54
  export const updateStepValidation = (step, isValid, errors = {}) => ({
68
- type: UPDATE_STEP_VALIDATION,
69
- payload: {
70
- step,
71
- isValid,
72
- errors,
73
- },
55
+ type: UPDATE_STEP_VALIDATION,
56
+ payload: {
57
+ step,
58
+ isValid,
59
+ errors,
60
+ },
74
61
  });
75
62
 
76
63
  export const validateAndUpdateStep = (step) => (dispatch, getState) => {
77
- // Use existing selectors to get form data
78
- const state = getState();
79
- const title = selectFormTitle(state);
80
- const icon = selectFormIcon(state);
81
- const displayName = selectFormDisplayName(state);
82
- const layout = selectFormLayout(state);
83
- const fields = selectFormFields(state);
64
+ // Use existing selectors to get form data
65
+ const state = getState();
66
+ const title = selectFormTitle(state);
67
+ const icon = selectFormIcon(state);
68
+ const displayName = selectFormDisplayName(state);
69
+ const layout = selectFormLayout(state);
70
+ const fields = selectFormFields(state);
84
71
 
85
- const form = { title, icon, displayName, layout, fields };
72
+ const form = { title, icon, displayName, layout, fields };
86
73
 
87
- const { isValid, errors } = getFormValidation(form, step);
74
+ const { isValid, errors } = getFormValidation(form, step);
88
75
 
89
- dispatch(updateStepValidation(step, isValid, errors));
76
+ dispatch(updateStepValidation(step, isValid, errors));
90
77
 
91
- // If valid, mark as complete
92
- if (isValid) {
93
- dispatch({
94
- type: MARK_STEP_COMPLETE,
95
- payload: step,
96
- });
97
- }
78
+ // If valid, mark as complete
79
+ if (isValid) {
80
+ dispatch({
81
+ type: MARK_STEP_COMPLETE,
82
+ payload: step,
83
+ });
84
+ }
98
85
 
99
- return { isValid, errors };
86
+ return { isValid, errors };
100
87
  };
101
88
 
102
89
  // Step completion
103
90
  export const markStepComplete = (step) => ({
104
- type: MARK_STEP_COMPLETE,
105
- payload: step,
91
+ type: MARK_STEP_COMPLETE,
92
+ payload: step,
106
93
  });
107
94
 
108
95
  // Reset wizard state
109
96
  export const resetWizardState = () => ({
110
- type: RESET_WIZARD_STATE,
97
+ type: RESET_WIZARD_STATE,
111
98
  });
112
99
 
113
100
  const getFormValidation = (form, step) => {
114
- // Return validation results for undefined form (prevent crashes)
115
- if (!form) {
116
- switch (step) {
117
- case "overview":
118
- return {
119
- isValid: false,
120
- errors: {
121
- title: "Title is required",
122
- displayName: "Display name is required",
123
- icon: "Icon is required",
124
- },
125
- };
126
- case "fields":
127
- return {
128
- isValid: false,
129
- errors: {
130
- missingTitle: "Title field is required",
131
- missingImage: "Feature image field is required",
132
- fieldLabels: "Some fields are missing labels",
133
- },
134
- };
135
- case "layout":
136
- return {
137
- isValid: false,
138
- errors: {
139
- layoutType: "Layout type is required",
140
- },
141
- };
142
- default:
143
- return { isValid: false, errors: {} };
144
- }
145
- }
146
-
147
- switch (step) {
148
- case "overview": {
149
- const hasTitle = form.title && form.title.trim().length > 0;
150
- const hasDisplayName =
151
- form.displayName && form.displayName.trim().length > 0;
152
- const hasIcon = form.icon && form.icon.length > 0;
153
-
154
- return {
155
- isValid: hasTitle && hasDisplayName && hasIcon,
156
- errors: {
157
- title: !hasTitle ? "Title is required" : null,
158
- displayName: !hasDisplayName ? "Display name is required" : null,
159
- icon: !hasIcon ? "Icon is required" : null,
160
- },
161
- };
162
- }
163
- case "fields": {
164
- const hasTitleField =
165
- form.fields &&
166
- form.fields.some((field) => field.id === "mandatory-title");
167
- const hasImageField =
168
- form.fields &&
169
- form.fields.some((field) => field.id === "mandatory-feature-image");
170
-
171
- // Check each field for missing labels and create field-specific errors
172
- const fieldErrors = {};
173
- let allFieldsHaveLabels = true;
174
-
175
- if (form.fields) {
176
- form.fields.forEach((field) => {
177
- if (
178
- (field.type === "text" ||
179
- field.type === "description" ||
180
- field.type === "title" ||
181
- field.type === "image" ||
182
- field.type === "gallery" ||
183
- field.type === "feature-image" ||
184
- field.type === "file" ||
185
- field.type === "cta") &&
186
- field.values
187
- ) {
188
- if (!field.values.label || field.values.label.trim().length === 0) {
189
- fieldErrors[field.id] = "Field label is required";
190
- allFieldsHaveLabels = false;
191
- }
192
- }
193
- });
194
- }
195
-
196
- return {
197
- isValid: hasTitleField && hasImageField && allFieldsHaveLabels,
198
- errors: {
199
- missingTitle: !hasTitleField ? "Title field is required" : null,
200
- missingImage: !hasImageField
201
- ? "Feature image field is required"
202
- : null,
203
- ...fieldErrors,
204
- },
205
- };
206
- }
207
- case "layout": {
208
- const hasLayoutType =
209
- form.layout && form.layout.type && form.layout.type.length > 0;
210
- return {
211
- isValid: hasLayoutType,
212
- errors: {
213
- layoutType: !hasLayoutType ? "Layout type is required" : null,
214
- },
215
- };
216
- }
217
- default:
218
- return { isValid: true, errors: {} };
219
- }
101
+ // Return validation results for undefined form (prevent crashes)
102
+ if (!form) {
103
+ switch (step) {
104
+ case "overview":
105
+ return {
106
+ isValid: false,
107
+ errors: {
108
+ title: "Title is required",
109
+ displayName: "Display name is required",
110
+ icon: "Icon is required",
111
+ },
112
+ };
113
+ case "fields":
114
+ return {
115
+ isValid: false,
116
+ errors: {
117
+ missingTitle: "Title field is required",
118
+ missingImage: "Feature image field is required",
119
+ fieldLabels: "Some fields are missing labels",
120
+ },
121
+ };
122
+ case "layout":
123
+ return {
124
+ isValid: false,
125
+ errors: {
126
+ layoutType: "Layout type is required",
127
+ },
128
+ };
129
+ default:
130
+ return { isValid: false, errors: {} };
131
+ }
132
+ }
133
+
134
+ switch (step) {
135
+ case "overview": {
136
+ const hasTitle = form.title?.trim().length > 0;
137
+ const hasDisplayName = form.displayName?.trim().length > 0;
138
+ const hasIcon = form.icon?.length > 0;
139
+
140
+ return {
141
+ isValid: hasTitle && hasDisplayName && hasIcon,
142
+ errors: {
143
+ title: !hasTitle ? "Title is required" : null,
144
+ displayName: !hasDisplayName ? "Display name is required" : null,
145
+ icon: !hasIcon ? "Icon is required" : null,
146
+ },
147
+ };
148
+ }
149
+ case "fields": {
150
+ const hasTitleField = form.fields?.some(
151
+ (field) => field.id === "mandatory-title",
152
+ );
153
+ const hasImageField = form.fields?.some(
154
+ (field) => field.id === "mandatory-feature-image",
155
+ );
156
+
157
+ // Check each field for missing labels and create field-specific errors
158
+ const fieldErrors = {};
159
+ let allFieldsHaveLabels = true;
160
+
161
+ if (form.fields) {
162
+ form.fields.forEach((field) => {
163
+ if (
164
+ (field.type === "text" ||
165
+ field.type === "description" ||
166
+ field.type === "title" ||
167
+ field.type === "image" ||
168
+ field.type === "gallery" ||
169
+ field.type === "feature-image" ||
170
+ field.type === "file" ||
171
+ field.type === "cta") &&
172
+ field.values
173
+ ) {
174
+ if (!field.values.label || field.values.label.trim().length === 0) {
175
+ fieldErrors[field.id] = "Field label is required";
176
+ allFieldsHaveLabels = false;
177
+ }
178
+ }
179
+ });
180
+ }
181
+
182
+ return {
183
+ isValid: hasTitleField && hasImageField && allFieldsHaveLabels,
184
+ errors: {
185
+ missingTitle: !hasTitleField ? "Title field is required" : null,
186
+ missingImage: !hasImageField
187
+ ? "Feature image field is required"
188
+ : null,
189
+ ...fieldErrors,
190
+ },
191
+ };
192
+ }
193
+ case "layout": {
194
+ const hasLayoutType = form.layout?.type?.length > 0;
195
+ return {
196
+ isValid: hasLayoutType,
197
+ errors: {
198
+ layoutType: !hasLayoutType ? "Layout type is required" : null,
199
+ },
200
+ };
201
+ }
202
+ default:
203
+ return { isValid: true, errors: {} };
204
+ }
220
205
  };
221
206
 
222
207
  export const setWizardModeAndSave = (mode) => (dispatch) => {
223
- dispatch(setWizardMode(mode));
208
+ dispatch(setWizardMode(mode));
224
209
  };
225
210
 
226
211
  export const setCurrentStepAndSave =
227
- (step, previousStep = null) =>
228
- (dispatch) => {
229
- dispatch(setCurrentStep(step, previousStep));
230
- };
212
+ (step, previousStep = null) =>
213
+ (dispatch) => {
214
+ dispatch(setCurrentStep(step, previousStep));
215
+ };
231
216
 
232
217
  export const updateStepValidationAndSave =
233
- (step, isValid, errors = {}) =>
234
- (dispatch) => {
235
- dispatch(updateStepValidation(step, isValid, errors));
236
- if (isValid) {
237
- dispatch(markStepComplete(step));
238
- }
239
- };
218
+ (step, isValid, errors = {}) =>
219
+ (dispatch) => {
220
+ dispatch(updateStepValidation(step, isValid, errors));
221
+ if (isValid) {
222
+ dispatch(markStepComplete(step));
223
+ }
224
+ };
240
225
 
241
226
  export const markStepCompleteAndSave = (step) => (dispatch) => {
242
- dispatch(markStepComplete(step));
227
+ dispatch(markStepComplete(step));
243
228
  };