@plusscommunities/pluss-feature-builder-web-b 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.
- package/dist/index.cjs.js +188 -144
- package/package.json +1 -1
- package/src/actions/featureDefinitionsIndex.js +15 -15
- package/src/actions/formActions.js +148 -158
- package/src/actions/listingActions.js +27 -25
- package/src/actions/wizardActions.js +174 -189
- package/src/components/BaseFieldConfig.jsx +234 -234
- package/src/components/IconLoader.jsx +138 -138
- package/src/components/IconSelector.jsx +0 -1
- package/src/components/ListingEditor.jsx +0 -1
- package/src/components/SidebarLayout.jsx +47 -25
- package/src/components/SidebarLayout.module.css +0 -34
- package/src/components/index.js +0 -2
- package/src/components/listing/GalleryDisplay.jsx +0 -1
- package/src/components/listing/ListingGalleryInput.jsx +4 -1
- package/src/hooks/useFeatureDefinitionLoader.js +6 -2
- package/src/index.js +6 -6
- package/src/reducers/featureBuilderReducer.js +14 -25
- package/src/screens/Form.module.css +11 -1
- package/src/screens/FormLayoutStep.jsx +10 -13
- package/src/screens/FormOverviewStep.jsx +351 -357
- package/src/screens/ListingScreen.jsx +0 -1
- package/src/selectors/featureBuilderSelectors.js +52 -43
package/package.json
CHANGED
|
@@ -6,25 +6,25 @@ import {
|
|
|
6
6
|
updatePermissionNames,
|
|
7
7
|
} from "./featureBuilderStringsActions";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
9
|
+
const REDUCER_PREFIX = values.reducerKey.toUpperCase();
|
|
10
|
+
export const FETCH_FEATURES_REQUEST = `${REDUCER_PREFIX}_FETCH_FEATURES_REQUEST`;
|
|
11
|
+
export const FETCH_FEATURES_SUCCESS = `${REDUCER_PREFIX}_FETCH_FEATURES_SUCCESS`;
|
|
12
|
+
export const FETCH_FEATURES_FAILURE = `${REDUCER_PREFIX}_FETCH_FEATURES_FAILURE`;
|
|
12
13
|
|
|
13
|
-
export const FEATURE_CREATE_REQUEST =
|
|
14
|
-
export const FEATURE_CREATE_SUCCESS =
|
|
15
|
-
export const FEATURE_CREATE_FAILURE =
|
|
14
|
+
export const FEATURE_CREATE_REQUEST = `${REDUCER_PREFIX}_FEATURE_CREATE_REQUEST`;
|
|
15
|
+
export const FEATURE_CREATE_SUCCESS = `${REDUCER_PREFIX}_FEATURE_CREATE_SUCCESS`;
|
|
16
|
+
export const FEATURE_CREATE_FAILURE = `${REDUCER_PREFIX}_FEATURE_CREATE_FAILURE`;
|
|
16
17
|
|
|
17
|
-
export const FEATURE_EDIT_REQUEST =
|
|
18
|
-
export const FEATURE_EDIT_SUCCESS =
|
|
19
|
-
export const FEATURE_EDIT_FAILURE =
|
|
18
|
+
export const FEATURE_EDIT_REQUEST = `${REDUCER_PREFIX}_FEATURE_EDIT_REQUEST`;
|
|
19
|
+
export const FEATURE_EDIT_SUCCESS = `${REDUCER_PREFIX}_FEATURE_EDIT_SUCCESS`;
|
|
20
|
+
export const FEATURE_EDIT_FAILURE = `${REDUCER_PREFIX}_FEATURE_EDIT_FAILURE`;
|
|
20
21
|
|
|
21
|
-
export const FEATURE_DELETE_REQUEST =
|
|
22
|
-
export const FEATURE_DELETE_FAILURE =
|
|
22
|
+
export const FEATURE_DELETE_REQUEST = `${REDUCER_PREFIX}_FEATURE_DELETE_REQUEST`;
|
|
23
|
+
export const FEATURE_DELETE_FAILURE = `${REDUCER_PREFIX}_FEATURE_DELETE_FAILURE`;
|
|
23
24
|
|
|
24
25
|
// Wizard synchronization action types
|
|
25
|
-
export const SYNC_WIZARD_MODE_FROM_DEFINITION =
|
|
26
|
-
|
|
27
|
-
export const SET_WIZARD_MODE = "SET_WIZARD_MODE";
|
|
26
|
+
export const SYNC_WIZARD_MODE_FROM_DEFINITION = `${REDUCER_PREFIX}_SYNC_WIZARD_MODE_FROM_DEFINITION`;
|
|
27
|
+
export const SET_WIZARD_MODE = `${REDUCER_PREFIX}_SET_WIZARD_MODE`;
|
|
28
28
|
|
|
29
29
|
function fetchFeaturesRequest() {
|
|
30
30
|
return { type: FETCH_FEATURES_REQUEST };
|
|
@@ -160,7 +160,7 @@ export function fetchFeatureDefinitions() {
|
|
|
160
160
|
}
|
|
161
161
|
} catch (err) {
|
|
162
162
|
// Check if it's a 404 (feature doesn't exist)
|
|
163
|
-
if (err.response
|
|
163
|
+
if (err.response?.status === 404) {
|
|
164
164
|
// 404: Feature doesn't exist → create mode
|
|
165
165
|
dispatch(fetchFeaturesSuccess(null, "create"));
|
|
166
166
|
|
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Form Actions for Feature Builder
|
|
3
|
-
* Manages form state including title, icon, fields, layout, and submission
|
|
4
|
-
* Handles CRUD operations for form fields and layout configuration
|
|
5
|
-
* Coordinates with external menu updates and feature definition actions
|
|
6
|
-
*
|
|
7
|
-
* @namespace formActions
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import { featureDefinitionActions } from "../webapi/featuresActions";
|
|
11
2
|
import { values } from "../values.config";
|
|
12
3
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
updateFeatureBuilderString,
|
|
5
|
+
updateFeatureBuilderIcon,
|
|
15
6
|
} from "./featureBuilderStringsActions";
|
|
16
|
-
import { toTitleCase } from "../utils/textUtils";
|
|
17
7
|
|
|
18
8
|
/**
|
|
19
9
|
* @typedef {Object} FieldValues
|
|
@@ -40,20 +30,20 @@ import { toTitleCase } from "../utils/textUtils";
|
|
|
40
30
|
*/
|
|
41
31
|
|
|
42
32
|
export const actionsTypes = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
33
|
+
SET_INITIAL_VALUES: `${values.reducerKey.toUpperCase()}_SET_INITIAL_VALUES`,
|
|
34
|
+
SET_TITLE: `${values.reducerKey.toUpperCase()}_SET_TITLE`,
|
|
35
|
+
SET_ICON: `${values.reducerKey.toUpperCase()}_SET_ICON`,
|
|
36
|
+
SET_DISPLAY_NAME: `${values.reducerKey.toUpperCase()}_SET_DISPLAY_NAME`,
|
|
37
|
+
ADD_FIELD: `${values.reducerKey.toUpperCase()}_ADD_FIELD`,
|
|
38
|
+
DELETE_FIELD: `${values.reducerKey.toUpperCase()}_DELETE_FIELD`,
|
|
39
|
+
UPDATE_FIELD: `${values.reducerKey.toUpperCase()}_UPDATE_FIELD`,
|
|
40
|
+
SET_LAYOUT_GRID_ICON: `${values.reducerKey.toUpperCase()}_SET_LAYOUT_GRID_ICON`,
|
|
41
|
+
SET_LAYOUT_TYPE: `${values.reducerKey.toUpperCase()}_SET_LAYOUT_TYPE`,
|
|
42
|
+
SUBMIT_FORM_REQUEST: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_REQUEST`,
|
|
43
|
+
SUBMIT_FORM_SUCCESS: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_SUCCESS`,
|
|
44
|
+
SUBMIT_FORM_FAILURE: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_FAILURE`,
|
|
45
|
+
CLEAR_FORM_SUBMISSION_STATE: `${values.reducerKey.toUpperCase()}_CLEAR_FORM_SUBMISSION_STATE`,
|
|
46
|
+
SET_SUMMARY_FIELD: `${values.reducerKey.toUpperCase()}_SET_SUMMARY_FIELD`,
|
|
57
47
|
};
|
|
58
48
|
|
|
59
49
|
/**
|
|
@@ -76,11 +66,11 @@ export const actionsTypes = {
|
|
|
76
66
|
* }));
|
|
77
67
|
*/
|
|
78
68
|
export const setInitialValues = (initialValues) => {
|
|
79
|
-
|
|
69
|
+
return { type: actionsTypes.SET_INITIAL_VALUES, payload: initialValues };
|
|
80
70
|
};
|
|
81
71
|
|
|
82
72
|
export const setTitle = (title) => {
|
|
83
|
-
|
|
73
|
+
return { type: actionsTypes.SET_TITLE, payload: title };
|
|
84
74
|
};
|
|
85
75
|
|
|
86
76
|
/**
|
|
@@ -95,16 +85,16 @@ export const setTitle = (title) => {
|
|
|
95
85
|
* dispatch(setDisplayName('Contact Information'));
|
|
96
86
|
*/
|
|
97
87
|
export const setDisplayName = (displayName) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
88
|
+
return (dispatch) => {
|
|
89
|
+
// Update menu string when display name changes (will be title cased in updateFeatureBuilderString)
|
|
90
|
+
dispatch(updateFeatureBuilderString(displayName));
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
// Dispatch the actual action
|
|
93
|
+
dispatch({
|
|
94
|
+
type: actionsTypes.SET_DISPLAY_NAME,
|
|
95
|
+
payload: displayName,
|
|
96
|
+
});
|
|
97
|
+
};
|
|
108
98
|
};
|
|
109
99
|
|
|
110
100
|
/**
|
|
@@ -118,16 +108,16 @@ export const setDisplayName = (displayName) => {
|
|
|
118
108
|
* dispatch(setIcon('fa-user'));
|
|
119
109
|
*/
|
|
120
110
|
export const setIcon = (icon) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
111
|
+
return (dispatch) => {
|
|
112
|
+
// Update menu icon when icon changes
|
|
113
|
+
dispatch(updateFeatureBuilderIcon(icon));
|
|
124
114
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
115
|
+
// Dispatch the actual action
|
|
116
|
+
dispatch({
|
|
117
|
+
type: actionsTypes.SET_ICON,
|
|
118
|
+
payload: icon,
|
|
119
|
+
});
|
|
120
|
+
};
|
|
131
121
|
};
|
|
132
122
|
|
|
133
123
|
/**
|
|
@@ -142,20 +132,20 @@ export const setIcon = (icon) => {
|
|
|
142
132
|
* dispatch(addField('image'));
|
|
143
133
|
*/
|
|
144
134
|
export const addField = (fieldType = "text") => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
135
|
+
// Generate a unique ID for the new field
|
|
136
|
+
const fieldId = `custom-field-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
137
|
+
return {
|
|
138
|
+
type: actionsTypes.ADD_FIELD,
|
|
139
|
+
payload: { id: fieldId, type: fieldType },
|
|
140
|
+
};
|
|
151
141
|
};
|
|
152
142
|
|
|
153
143
|
export const deleteField = (id) => {
|
|
154
|
-
|
|
144
|
+
return { type: actionsTypes.DELETE_FIELD, payload: id };
|
|
155
145
|
};
|
|
156
146
|
|
|
157
147
|
export const updateFieldById = (id, updatedField) => {
|
|
158
|
-
|
|
148
|
+
return { type: actionsTypes.UPDATE_FIELD, payload: { id, updatedField } };
|
|
159
149
|
};
|
|
160
150
|
|
|
161
151
|
/**
|
|
@@ -170,31 +160,31 @@ export const updateFieldById = (id, updatedField) => {
|
|
|
170
160
|
* dispatch(setSummaryField('field-description-123'));
|
|
171
161
|
*/
|
|
172
162
|
export const setSummaryField = (fieldId) => {
|
|
173
|
-
|
|
163
|
+
return { type: actionsTypes.SET_SUMMARY_FIELD, payload: fieldId };
|
|
174
164
|
};
|
|
175
165
|
|
|
176
166
|
export const setGridLayoutIcon = (imageUrl) => {
|
|
177
|
-
|
|
167
|
+
return { type: actionsTypes.SET_LAYOUT_GRID_ICON, payload: imageUrl };
|
|
178
168
|
};
|
|
179
169
|
|
|
180
170
|
export const setLayoutType = (layoutType) => {
|
|
181
|
-
|
|
171
|
+
return { type: actionsTypes.SET_LAYOUT_TYPE, payload: layoutType };
|
|
182
172
|
};
|
|
183
173
|
|
|
184
174
|
const submitFormRequest = () => {
|
|
185
|
-
|
|
175
|
+
return { type: actionsTypes.SUBMIT_FORM_REQUEST };
|
|
186
176
|
};
|
|
187
177
|
|
|
188
178
|
const submitFormSuccess = () => {
|
|
189
|
-
|
|
179
|
+
return { type: actionsTypes.SUBMIT_FORM_SUCCESS };
|
|
190
180
|
};
|
|
191
181
|
|
|
192
182
|
const submitFormFailure = (error) => {
|
|
193
|
-
|
|
183
|
+
return { type: actionsTypes.SUBMIT_FORM_FAILURE, payload: error };
|
|
194
184
|
};
|
|
195
185
|
|
|
196
186
|
export const clearFormSubmissionState = () => {
|
|
197
|
-
|
|
187
|
+
return { type: actionsTypes.CLEAR_FORM_SUBMISSION_STATE };
|
|
198
188
|
};
|
|
199
189
|
|
|
200
190
|
/**
|
|
@@ -205,107 +195,107 @@ export const clearFormSubmissionState = () => {
|
|
|
205
195
|
* @throws {Error} When form validation fails or API submission encounters error
|
|
206
196
|
*/
|
|
207
197
|
export function submitForm() {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
198
|
+
return async (dispatch, getState) => {
|
|
199
|
+
const state = getState()[values.reducerKey];
|
|
200
|
+
const form = state?.form;
|
|
201
|
+
if (!form) {
|
|
202
|
+
dispatch(
|
|
203
|
+
submitFormFailure(
|
|
204
|
+
new Error(
|
|
205
|
+
"Form data is missing. Please refresh the page and try again.",
|
|
206
|
+
),
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
221
211
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
212
|
+
dispatch(submitFormRequest());
|
|
213
|
+
try {
|
|
214
|
+
// Get site from auth store
|
|
215
|
+
const site = getState().auth.site;
|
|
216
|
+
if (!site) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
"Authentication error: Site context not found. Please refresh and login again.",
|
|
219
|
+
);
|
|
220
|
+
}
|
|
231
221
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
222
|
+
// Use mode from fetch instead of checking definition ID
|
|
223
|
+
const definitionState = state?.definition;
|
|
224
|
+
const mode = definitionState?.mode; // Use stored mode from fetch
|
|
225
|
+
const definitionId = definitionState?.id;
|
|
236
226
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
227
|
+
if (mode === "edit") {
|
|
228
|
+
// Always update when in edit mode
|
|
229
|
+
const updatedDefinition = {
|
|
230
|
+
id: definitionId,
|
|
231
|
+
site: site, // Include site from auth store
|
|
232
|
+
featureDefinition: {
|
|
233
|
+
// Wrap in expected structure for backend
|
|
234
|
+
title: form.title,
|
|
235
|
+
icon: form.icon,
|
|
236
|
+
displayName: form.displayName,
|
|
237
|
+
layout: form.layout,
|
|
238
|
+
fields: form.fields,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
await featureDefinitionActions.edit(updatedDefinition, site);
|
|
242
|
+
} else {
|
|
243
|
+
// Always create when in create mode (or mode is undefined/null)
|
|
244
|
+
if (!values.featureId || !site) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
"Authentication error: Missing required context (featureId or site).",
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
await featureDefinitionActions.create(
|
|
250
|
+
values.featureId,
|
|
251
|
+
site, // Use actual site from auth store
|
|
252
|
+
{
|
|
253
|
+
title: form.title,
|
|
254
|
+
icon: form.icon,
|
|
255
|
+
displayName: form.displayName,
|
|
256
|
+
layout: form.layout,
|
|
257
|
+
fields: form.fields,
|
|
258
|
+
},
|
|
259
|
+
);
|
|
260
|
+
}
|
|
271
261
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
262
|
+
dispatch(submitFormSuccess());
|
|
263
|
+
} catch (err) {
|
|
264
|
+
// Handle different types of errors
|
|
265
|
+
let errorToDisplay = err;
|
|
276
266
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
267
|
+
if (err.response) {
|
|
268
|
+
// API error (400, 401, 404, 500, etc.)
|
|
269
|
+
const { status, data } = err.response;
|
|
270
|
+
if (status === 400 && data?.error) {
|
|
271
|
+
errorToDisplay = new Error(`Validation error: ${data.error}`);
|
|
272
|
+
} else if (status === 401) {
|
|
273
|
+
errorToDisplay = new Error(
|
|
274
|
+
"You are not authorized to perform this action",
|
|
275
|
+
);
|
|
276
|
+
} else if (status === 404) {
|
|
277
|
+
errorToDisplay = new Error("Feature definition not found");
|
|
278
|
+
} else if (status >= 500) {
|
|
279
|
+
errorToDisplay = new Error("Server error. Please try again later.");
|
|
280
|
+
} else {
|
|
281
|
+
errorToDisplay = new Error(
|
|
282
|
+
data?.error || `Request failed with status ${status}`,
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
} else if (err.request) {
|
|
286
|
+
// Network error (no response received)
|
|
287
|
+
errorToDisplay = new Error(
|
|
288
|
+
"Network error. Please check your connection and try again.",
|
|
289
|
+
);
|
|
290
|
+
} else if (err.message) {
|
|
291
|
+
// Other JavaScript errors
|
|
292
|
+
errorToDisplay = err;
|
|
293
|
+
} else {
|
|
294
|
+
// Unknown error
|
|
295
|
+
errorToDisplay = new Error("An unexpected error occurred while saving");
|
|
296
|
+
}
|
|
307
297
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
298
|
+
dispatch(submitFormFailure(errorToDisplay));
|
|
299
|
+
}
|
|
300
|
+
};
|
|
311
301
|
}
|
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
import { arrayMove } from "@dnd-kit/sortable";
|
|
2
2
|
import { listingActions as webApiActions } from "../webapi/listingActions";
|
|
3
|
+
import { values } from "../values.config";
|
|
3
4
|
|
|
4
5
|
// Action Types
|
|
5
|
-
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
6
|
+
const REDUCER_PREFIX = values.reducerKey.toUpperCase();
|
|
7
|
+
export const FETCH_LISTING_REQUEST = `${REDUCER_PREFIX}_FETCH_LISTING_REQUEST`;
|
|
8
|
+
export const FETCH_LISTING_SUCCESS = `${REDUCER_PREFIX}_FETCH_LISTING_SUCCESS`;
|
|
9
|
+
export const FETCH_LISTING_FAILURE = `${REDUCER_PREFIX}_FETCH_LISTING_FAILURE`;
|
|
10
|
+
export const FETCH_LISTING_SILENT_SUCCESS = `${REDUCER_PREFIX}_FETCH_LISTING_SILENT_SUCCESS`;
|
|
11
|
+
export const FETCH_LISTING_SILENT_FAILURE = `${REDUCER_PREFIX}_FETCH_LISTING_SILENT_FAILURE`;
|
|
10
12
|
|
|
11
|
-
export const REORDER_LISTING_SUCCESS =
|
|
12
|
-
export const REORDER_LISTING_FAILURE =
|
|
13
|
+
export const REORDER_LISTING_SUCCESS = `${REDUCER_PREFIX}_REORDER_LISTING_SUCCESS`;
|
|
14
|
+
export const REORDER_LISTING_FAILURE = `${REDUCER_PREFIX}_REORDER_LISTING_FAILURE`;
|
|
13
15
|
|
|
14
|
-
export const DELETE_LISTING_REQUEST =
|
|
15
|
-
export const DELETE_LISTING_SUCCESS =
|
|
16
|
-
export const DELETE_LISTING_FAILURE =
|
|
16
|
+
export const DELETE_LISTING_REQUEST = `${REDUCER_PREFIX}_DELETE_LISTING_REQUEST`;
|
|
17
|
+
export const DELETE_LISTING_SUCCESS = `${REDUCER_PREFIX}_DELETE_LISTING_SUCCESS`;
|
|
18
|
+
export const DELETE_LISTING_FAILURE = `${REDUCER_PREFIX}_DELETE_LISTING_FAILURE`;
|
|
17
19
|
|
|
18
|
-
export const UNDELETE_LISTING_REQUEST =
|
|
19
|
-
export const UNDELETE_LISTING_SUCCESS =
|
|
20
|
-
export const UNDELETE_LISTING_FAILURE =
|
|
20
|
+
export const UNDELETE_LISTING_REQUEST = `${REDUCER_PREFIX}_UNDELETE_LISTING_REQUEST`;
|
|
21
|
+
export const UNDELETE_LISTING_SUCCESS = `${REDUCER_PREFIX}_UNDELETE_LISTING_SUCCESS`;
|
|
22
|
+
export const UNDELETE_LISTING_FAILURE = `${REDUCER_PREFIX}_UNDELETE_LISTING_FAILURE`;
|
|
21
23
|
|
|
22
|
-
export const CREATE_LISTING_REQUEST =
|
|
23
|
-
export const CREATE_LISTING_SUCCESS =
|
|
24
|
-
export const CREATE_LISTING_FAILURE =
|
|
24
|
+
export const CREATE_LISTING_REQUEST = `${REDUCER_PREFIX}_CREATE_LISTING_REQUEST`;
|
|
25
|
+
export const CREATE_LISTING_SUCCESS = `${REDUCER_PREFIX}_CREATE_LISTING_SUCCESS`;
|
|
26
|
+
export const CREATE_LISTING_FAILURE = `${REDUCER_PREFIX}_CREATE_LISTING_FAILURE`;
|
|
25
27
|
|
|
26
|
-
export const EDIT_LISTING_REQUEST =
|
|
27
|
-
export const EDIT_LISTING_SUCCESS =
|
|
28
|
-
export const EDIT_LISTING_FAILURE =
|
|
28
|
+
export const EDIT_LISTING_REQUEST = `${REDUCER_PREFIX}_EDIT_LISTING_REQUEST`;
|
|
29
|
+
export const EDIT_LISTING_SUCCESS = `${REDUCER_PREFIX}_EDIT_LISTING_SUCCESS`;
|
|
30
|
+
export const EDIT_LISTING_FAILURE = `${REDUCER_PREFIX}_EDIT_LISTING_FAILURE`;
|
|
29
31
|
|
|
30
|
-
export const TOGGLE_LISTING_REQUEST =
|
|
31
|
-
export const TOGGLE_LISTING_SUCCESS =
|
|
32
|
-
export const TOGGLE_LISTING_FAILURE =
|
|
32
|
+
export const TOGGLE_LISTING_REQUEST = `${REDUCER_PREFIX}_TOGGLE_LISTING_REQUEST`;
|
|
33
|
+
export const TOGGLE_LISTING_SUCCESS = `${REDUCER_PREFIX}_TOGGLE_LISTING_SUCCESS`;
|
|
34
|
+
export const TOGGLE_LISTING_FAILURE = `${REDUCER_PREFIX}_TOGGLE_LISTING_FAILURE`;
|
|
33
35
|
|
|
34
|
-
export const SET_SORT_BY =
|
|
35
|
-
export const SET_SHOW_DELETED =
|
|
36
|
+
export const SET_SORT_BY = `${REDUCER_PREFIX}_SET_SORT_BY`;
|
|
37
|
+
export const SET_SHOW_DELETED = `${REDUCER_PREFIX}_SET_SHOW_DELETED`;
|
|
36
38
|
|
|
37
39
|
export const fetchListingRequest = () => ({ type: FETCH_LISTING_REQUEST });
|
|
38
40
|
export const fetchListingSuccess = (listings) => ({
|
|
@@ -210,7 +212,7 @@ export const undeleteListing = (id) => {
|
|
|
210
212
|
const response = await webApiActions.undelete(id, site);
|
|
211
213
|
// If API returns the restored listing, use it; otherwise we'll need to refetch
|
|
212
214
|
const restoredListing = response.data;
|
|
213
|
-
if (restoredListing
|
|
215
|
+
if (restoredListing?.id) {
|
|
214
216
|
dispatch(undeleteListingSuccess(restoredListing));
|
|
215
217
|
} else {
|
|
216
218
|
// Trigger a refetch by dispatching the success with just ID, then fetch updated listings
|