@plusscommunities/pluss-feature-builder-web-a 1.0.2-beta.3 → 1.0.2-beta.5
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 +1203 -1206
- package/package.json +1 -1
- package/rollup.config.js +1 -0
- package/src/actions/featureDefinitionsIndex.js +14 -13
- package/src/actions/formActions.js +14 -14
- package/src/actions/listingActions.js +33 -31
- package/src/actions/wizardActions.js +9 -9
- package/src/components/SidebarLayout.jsx +49 -92
- package/src/components/SidebarLayout.module.css +0 -74
- package/src/hooks/useFeatureDefinitionLoader.js +6 -2
- package/src/index.js +6 -6
- package/src/screens/Form.module.css +11 -1
- package/src/screens/FormOverviewStep.jsx +1 -0
- package/src/selectors/featureBuilderSelectors.js +4 -0
package/package.json
CHANGED
package/rollup.config.js
CHANGED
|
@@ -6,25 +6,26 @@ 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
26
|
export const SYNC_WIZARD_MODE_FROM_DEFINITION =
|
|
26
|
-
|
|
27
|
-
export const SET_WIZARD_MODE =
|
|
27
|
+
`${REDUCER_PREFIX}_SYNC_WIZARD_MODE_FROM_DEFINITION`;
|
|
28
|
+
export const SET_WIZARD_MODE = `${REDUCER_PREFIX}_SET_WIZARD_MODE`;
|
|
28
29
|
|
|
29
30
|
function fetchFeaturesRequest() {
|
|
30
31
|
return { type: FETCH_FEATURES_REQUEST };
|
|
@@ -40,20 +40,20 @@ import { toTitleCase } from "../utils/textUtils";
|
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
export const actionsTypes = {
|
|
43
|
-
SET_INITIAL_VALUES:
|
|
44
|
-
SET_TITLE:
|
|
45
|
-
SET_ICON:
|
|
46
|
-
SET_DISPLAY_NAME:
|
|
47
|
-
ADD_FIELD:
|
|
48
|
-
DELETE_FIELD:
|
|
49
|
-
UPDATE_FIELD:
|
|
50
|
-
SET_LAYOUT_GRID_ICON:
|
|
51
|
-
SET_LAYOUT_TYPE:
|
|
52
|
-
SUBMIT_FORM_REQUEST:
|
|
53
|
-
SUBMIT_FORM_SUCCESS:
|
|
54
|
-
SUBMIT_FORM_FAILURE:
|
|
55
|
-
CLEAR_FORM_SUBMISSION_STATE:
|
|
56
|
-
SET_SUMMARY_FIELD:
|
|
43
|
+
SET_INITIAL_VALUES: `${values.reducerKey.toUpperCase()}_SET_INITIAL_VALUES`,
|
|
44
|
+
SET_TITLE: `${values.reducerKey.toUpperCase()}_SET_TITLE`,
|
|
45
|
+
SET_ICON: `${values.reducerKey.toUpperCase()}_SET_ICON`,
|
|
46
|
+
SET_DISPLAY_NAME: `${values.reducerKey.toUpperCase()}_SET_DISPLAY_NAME`,
|
|
47
|
+
ADD_FIELD: `${values.reducerKey.toUpperCase()}_ADD_FIELD`,
|
|
48
|
+
DELETE_FIELD: `${values.reducerKey.toUpperCase()}_DELETE_FIELD`,
|
|
49
|
+
UPDATE_FIELD: `${values.reducerKey.toUpperCase()}_UPDATE_FIELD`,
|
|
50
|
+
SET_LAYOUT_GRID_ICON: `${values.reducerKey.toUpperCase()}_SET_LAYOUT_GRID_ICON`,
|
|
51
|
+
SET_LAYOUT_TYPE: `${values.reducerKey.toUpperCase()}_SET_LAYOUT_TYPE`,
|
|
52
|
+
SUBMIT_FORM_REQUEST: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_REQUEST`,
|
|
53
|
+
SUBMIT_FORM_SUCCESS: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_SUCCESS`,
|
|
54
|
+
SUBMIT_FORM_FAILURE: `${values.reducerKey.toUpperCase()}_SUBMIT_FORM_FAILURE`,
|
|
55
|
+
CLEAR_FORM_SUBMISSION_STATE: `${values.reducerKey.toUpperCase()}_CLEAR_FORM_SUBMISSION_STATE`,
|
|
56
|
+
SET_SUMMARY_FIELD: `${values.reducerKey.toUpperCase()}_SET_SUMMARY_FIELD`,
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
/**
|
|
@@ -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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export const
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export const
|
|
20
|
-
export const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export const
|
|
24
|
-
export const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export const
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export const
|
|
32
|
-
export const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
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`;
|
|
12
|
+
|
|
13
|
+
export const REORDER_LISTING_SUCCESS = `${REDUCER_PREFIX}_REORDER_LISTING_SUCCESS`;
|
|
14
|
+
export const REORDER_LISTING_FAILURE = `${REDUCER_PREFIX}_REORDER_LISTING_FAILURE`;
|
|
15
|
+
|
|
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`;
|
|
19
|
+
|
|
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`;
|
|
23
|
+
|
|
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`;
|
|
27
|
+
|
|
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`;
|
|
31
|
+
|
|
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`;
|
|
35
|
+
|
|
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) => ({
|
|
@@ -16,17 +16,16 @@ import {
|
|
|
16
16
|
selectFormFields,
|
|
17
17
|
} from "../selectors/featureBuilderSelectors";
|
|
18
18
|
|
|
19
|
-
// Import values config and form actions
|
|
20
19
|
import { values } from "../values.config";
|
|
21
|
-
import { clearFormSubmissionState } from "./formActions";
|
|
22
20
|
|
|
23
21
|
// Wizard action types
|
|
24
|
-
|
|
25
|
-
export const
|
|
26
|
-
export const
|
|
27
|
-
export const
|
|
28
|
-
export const
|
|
29
|
-
export const
|
|
22
|
+
const REDUCER_PREFIX = values.reducerKey.toUpperCase();
|
|
23
|
+
export const SET_WIZARD_MODE = `${REDUCER_PREFIX}_SET_WIZARD_MODE`;
|
|
24
|
+
export const SET_NAVIGATION_STATE = `${REDUCER_PREFIX}_SET_NAVIGATION_STATE`;
|
|
25
|
+
export const UPDATE_STEP_VALIDATION = `${REDUCER_PREFIX}_UPDATE_STEP_VALIDATION`;
|
|
26
|
+
export const MARK_STEP_COMPLETE = `${REDUCER_PREFIX}_MARK_STEP_COMPLETE`;
|
|
27
|
+
export const RESET_WIZARD_STATE = `${REDUCER_PREFIX}_RESET_WIZARD_STATE`;
|
|
28
|
+
export const VALIDATE_AND_UPDATE_STEP = `${REDUCER_PREFIX}_VALIDATE_AND_UPDATE_STEP`;
|
|
30
29
|
|
|
31
30
|
// Mode setters
|
|
32
31
|
export const setWizardMode = (mode) => ({
|
|
@@ -51,7 +50,7 @@ export const setCurrentStep = (step, previousStep = null) => ({
|
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
export const goToStep = (step) => (dispatch, getState) => {
|
|
54
|
-
const state = getState()[values.reducerKey];
|
|
53
|
+
const state = getState()[require("../values.config").reducerKey];
|
|
55
54
|
const currentStep =
|
|
56
55
|
state &&
|
|
57
56
|
state.wizard &&
|
|
@@ -59,6 +58,7 @@ export const goToStep = (step) => (dispatch, getState) => {
|
|
|
59
58
|
state.wizard.navigation.currentStep;
|
|
60
59
|
|
|
61
60
|
// Clear form submission state when changing steps
|
|
61
|
+
const { clearFormSubmissionState } = require("./formActions");
|
|
62
62
|
dispatch(clearFormSubmissionState());
|
|
63
63
|
|
|
64
64
|
dispatch(setCurrentStep(step, currentStep));
|
|
@@ -1,32 +1,23 @@
|
|
|
1
|
-
import React, { useEffect
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import { useSelector } from "react-redux";
|
|
3
3
|
import { withRouter } from "react-router";
|
|
4
|
-
import { HubSidebar
|
|
4
|
+
import { HubSidebar } from "./index.js";
|
|
5
5
|
import {
|
|
6
6
|
selectWizardMode,
|
|
7
7
|
selectCurrentStep,
|
|
8
8
|
selectIsStepComplete,
|
|
9
9
|
selectIsStepAccessible,
|
|
10
|
-
selectStepProgress,
|
|
11
10
|
selectIsEditMode,
|
|
12
11
|
selectIsCreateMode,
|
|
13
|
-
selectDefinition,
|
|
14
|
-
selectDefinitionId,
|
|
15
12
|
} from "../selectors/featureBuilderSelectors";
|
|
16
13
|
import { goToStep } from "../actions/wizardActions";
|
|
17
14
|
import { useDispatch } from "react-redux";
|
|
18
|
-
import { PlussCore } from "../feature.config";
|
|
19
15
|
import { values } from "../values.config";
|
|
20
16
|
import styles from "./SidebarLayout.module.css";
|
|
21
17
|
|
|
22
|
-
const { Helper, Session } = PlussCore;
|
|
23
|
-
const { getUrl } = Helper;
|
|
24
|
-
const { authedFunction } = Session;
|
|
25
|
-
|
|
26
18
|
/**
|
|
27
19
|
* Sidebar Layout component for feature builder wizard
|
|
28
20
|
* Provides navigation sidebar with step progression, completion tracking
|
|
29
|
-
* Includes delete functionality for feature definitions
|
|
30
21
|
* Manages step accessibility based on wizard mode and validation state
|
|
31
22
|
*
|
|
32
23
|
* @param {Object} props - Component props
|
|
@@ -48,14 +39,6 @@ const SideBarInner = (props) => {
|
|
|
48
39
|
const isEditMode = useSelector(selectIsEditMode);
|
|
49
40
|
const isCreateMode = useSelector(selectIsCreateMode);
|
|
50
41
|
const currentStep = useSelector(selectCurrentStep);
|
|
51
|
-
const stepProgress = useSelector(selectStepProgress);
|
|
52
|
-
const definition = useSelector(selectDefinition);
|
|
53
|
-
const definitionId = useSelector(selectDefinitionId);
|
|
54
|
-
const auth = useSelector((state) => state.auth);
|
|
55
|
-
|
|
56
|
-
// Delete functionality state
|
|
57
|
-
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
58
|
-
const [isDeleting, setIsDeleting] = useState(false);
|
|
59
42
|
|
|
60
43
|
const goTo = (url) => history.push(url);
|
|
61
44
|
|
|
@@ -65,8 +48,17 @@ const SideBarInner = (props) => {
|
|
|
65
48
|
|
|
66
49
|
// Define step configuration with dynamic URL based on mode
|
|
67
50
|
const getStepUrl = (stepKey) => {
|
|
68
|
-
//
|
|
69
|
-
|
|
51
|
+
// Use routes from values.config to support different variants (-a, -b, -c, -d)
|
|
52
|
+
switch (stepKey) {
|
|
53
|
+
case "overview":
|
|
54
|
+
return values.routeFormOverviewStep;
|
|
55
|
+
case "fields":
|
|
56
|
+
return values.routeFormFieldsStep;
|
|
57
|
+
case "layout":
|
|
58
|
+
return values.routeFormLayoutStep;
|
|
59
|
+
default:
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
70
62
|
};
|
|
71
63
|
|
|
72
64
|
const steps = [
|
|
@@ -92,6 +84,8 @@ const SideBarInner = (props) => {
|
|
|
92
84
|
|
|
93
85
|
// Build sidebar items based on mode
|
|
94
86
|
const buildSidebarItems = () => {
|
|
87
|
+
const isWizardMode = mode === "create" || mode === "edit";
|
|
88
|
+
|
|
95
89
|
return steps.map((step, index) => {
|
|
96
90
|
const isCompleted = selectIsStepComplete(step.key);
|
|
97
91
|
const isAccessible = selectIsStepAccessible(step.key);
|
|
@@ -104,17 +98,19 @@ const SideBarInner = (props) => {
|
|
|
104
98
|
text: stepText,
|
|
105
99
|
icon: step.icon,
|
|
106
100
|
selected: isSelected(step.url),
|
|
107
|
-
onclick:
|
|
108
|
-
?
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
101
|
+
onclick: isWizardMode
|
|
102
|
+
? null
|
|
103
|
+
: isAccessible
|
|
104
|
+
? () => {
|
|
105
|
+
goTo(step.url);
|
|
106
|
+
dispatch(goToStep(step.key));
|
|
107
|
+
}
|
|
108
|
+
: null,
|
|
113
109
|
isFontAwesome: true,
|
|
114
110
|
// Enhanced completion indicator
|
|
115
111
|
completed: isCompleted,
|
|
116
|
-
//
|
|
117
|
-
disabled: mode === "create" && !isAccessible,
|
|
112
|
+
// Disable all navigation in wizard mode
|
|
113
|
+
disabled: isWizardMode || (mode === "create" && !isAccessible),
|
|
118
114
|
};
|
|
119
115
|
|
|
120
116
|
return itemProps;
|
|
@@ -139,36 +135,10 @@ const SideBarInner = (props) => {
|
|
|
139
135
|
},
|
|
140
136
|
];
|
|
141
137
|
|
|
142
|
-
// Delete functionality handlers
|
|
143
|
-
const handleDeleteClick = () => {
|
|
144
|
-
setShowDeleteConfirm(true);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
const handleConfirmDelete = async () => {
|
|
148
|
-
if (!definition) return;
|
|
149
|
-
|
|
150
|
-
setIsDeleting(true);
|
|
151
|
-
try {
|
|
152
|
-
await authedFunction({
|
|
153
|
-
method: "POST",
|
|
154
|
-
url: getUrl("feature-builder", "definition/update/delete"),
|
|
155
|
-
data: { id: definitionId, site: auth.site },
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Redirect to welcome screen after deletion
|
|
159
|
-
history.push("/feature-builder/definition/overview");
|
|
160
|
-
} finally {
|
|
161
|
-
setIsDeleting(false);
|
|
162
|
-
setShowDeleteConfirm(false);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const handleCancelDelete = () => {
|
|
167
|
-
setShowDeleteConfirm(false);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
138
|
// Add effect to manually attach click handlers since HubSidebar might not use onclick properly
|
|
171
139
|
useEffect(() => {
|
|
140
|
+
const isWizardMode = mode === "create" || mode === "edit";
|
|
141
|
+
|
|
172
142
|
const attachClickHandlers = () => {
|
|
173
143
|
const stepsWithUrls = [
|
|
174
144
|
{ key: "overview", url: getStepUrl("overview") },
|
|
@@ -176,20 +146,10 @@ const SideBarInner = (props) => {
|
|
|
176
146
|
{ key: "layout", url: getStepUrl("layout") },
|
|
177
147
|
];
|
|
178
148
|
|
|
179
|
-
stepsWithUrls.forEach((step) => {
|
|
149
|
+
stepsWithUrls.forEach((step, index) => {
|
|
180
150
|
const navItem = Array.from(
|
|
181
|
-
document.querySelectorAll(".sideNav-item"),
|
|
182
|
-
).find(
|
|
183
|
-
(item) =>
|
|
184
|
-
item.textContent &&
|
|
185
|
-
item.textContent.includes(
|
|
186
|
-
step.key === "overview"
|
|
187
|
-
? "Feature Overview"
|
|
188
|
-
: step.key === "fields"
|
|
189
|
-
? "Configure Fields"
|
|
190
|
-
: "Choose Layout",
|
|
191
|
-
),
|
|
192
|
-
);
|
|
151
|
+
document.querySelectorAll(".hub-wrapperContainer .sideNav-item"),
|
|
152
|
+
).find((item) => item.textContent && item.textContent.includes(`${index + 1}.`));
|
|
193
153
|
|
|
194
154
|
if (navItem) {
|
|
195
155
|
// Remove any existing click listeners
|
|
@@ -207,8 +167,12 @@ const SideBarInner = (props) => {
|
|
|
207
167
|
},
|
|
208
168
|
});
|
|
209
169
|
|
|
210
|
-
//
|
|
211
|
-
|
|
170
|
+
// Check if this is the current step (selected)
|
|
171
|
+
const isCurrentStep = isSelected(step.url);
|
|
172
|
+
|
|
173
|
+
// In wizard mode, don't attach any click handlers
|
|
174
|
+
// Only attach click handler if not in wizard mode AND accessible
|
|
175
|
+
if (!isWizardMode && isAccessible) {
|
|
212
176
|
navItem.onclick = (event) => {
|
|
213
177
|
event.preventDefault();
|
|
214
178
|
event.stopPropagation();
|
|
@@ -218,9 +182,19 @@ const SideBarInner = (props) => {
|
|
|
218
182
|
}
|
|
219
183
|
|
|
220
184
|
// Make sure it's styled appropriately
|
|
221
|
-
|
|
222
|
-
navItem.style.pointerEvents = "auto";
|
|
223
|
-
|
|
185
|
+
// In wizard mode: block clicks, but keep current step visible
|
|
186
|
+
navItem.style.pointerEvents = isWizardMode ? "none" : "auto";
|
|
187
|
+
|
|
188
|
+
if (isWizardMode) {
|
|
189
|
+
// Current step: full opacity, not-allowed cursor
|
|
190
|
+
// Other steps: reduced opacity
|
|
191
|
+
navItem.style.opacity = isCurrentStep ? "1" : "0.4";
|
|
192
|
+
navItem.style.cursor = "not-allowed";
|
|
193
|
+
} else {
|
|
194
|
+
// Not in wizard mode: normal styling based on accessibility
|
|
195
|
+
navItem.style.cursor = isAccessible ? "pointer" : "not-allowed";
|
|
196
|
+
navItem.style.opacity = isAccessible ? "1" : "0.5";
|
|
197
|
+
}
|
|
224
198
|
}
|
|
225
199
|
});
|
|
226
200
|
};
|
|
@@ -263,28 +237,11 @@ const SideBarInner = (props) => {
|
|
|
263
237
|
/>
|
|
264
238
|
)}
|
|
265
239
|
|
|
266
|
-
{/* Dev Delete Button - Absolute positioned at bottom of sidebar */}
|
|
267
|
-
{shouldShowSidebar && (
|
|
268
|
-
<button onClick={handleDeleteClick} className={styles.devDeleteButton}>
|
|
269
|
-
DELETE FEATURE DEF
|
|
270
|
-
</button>
|
|
271
|
-
)}
|
|
272
|
-
|
|
273
240
|
<div className="hub-contentWrapper">
|
|
274
241
|
<div className={styles.fullWidthContainer}>
|
|
275
242
|
<div className={styles.contentContainer}>{children}</div>
|
|
276
243
|
</div>
|
|
277
244
|
</div>
|
|
278
|
-
|
|
279
|
-
{/* Delete Confirmation Popup */}
|
|
280
|
-
<DeleteConfirmationPopup
|
|
281
|
-
isOpen={showDeleteConfirm}
|
|
282
|
-
listing={definition}
|
|
283
|
-
onConfirm={handleConfirmDelete}
|
|
284
|
-
onCancel={handleCancelDelete}
|
|
285
|
-
isDeleting={isDeleting}
|
|
286
|
-
deleteType="featureDefinition"
|
|
287
|
-
/>
|
|
288
245
|
</div>
|
|
289
246
|
);
|
|
290
247
|
};
|
|
@@ -58,40 +58,6 @@
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/* Enhanced sidebar navigation for progress indication */
|
|
61
|
-
:global(.hub-sideBar) {
|
|
62
|
-
/* Make sidebar more prominent during creation mode */
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
:global(.sideNav-item.isCurrent) {
|
|
66
|
-
background: var(--colour-purple, #6e79c5) !important;
|
|
67
|
-
color: var(--colour-white, #ffffff) !important;
|
|
68
|
-
font-weight: 600 !important;
|
|
69
|
-
border-left: 4px solid var(--colour-branding-dark, #364196) !important;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
:global(.sideNav-item.isCurrent) i {
|
|
73
|
-
color: var(--colour-white, #ffffff) !important;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
:global(.sideNav-item.isCompleted) {
|
|
77
|
-
color: var(--colour-branding-dark, #364196) !important;
|
|
78
|
-
position: relative;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
:global(.sideNav-item.isCompleted::after) {
|
|
82
|
-
content: "✓";
|
|
83
|
-
position: absolute;
|
|
84
|
-
right: 1rem;
|
|
85
|
-
top: 50%;
|
|
86
|
-
transform: translateY(-50%);
|
|
87
|
-
color: var(--colour-branding-dark, #364196);
|
|
88
|
-
font-weight: bold;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
:global(.sideNav-item.isDisabled) {
|
|
92
|
-
opacity: 0.4;
|
|
93
|
-
cursor: not-allowed;
|
|
94
|
-
}
|
|
95
61
|
|
|
96
62
|
/* Enhanced progress section */
|
|
97
63
|
:global(.hub-sideBar-section) {
|
|
@@ -103,43 +69,3 @@
|
|
|
103
69
|
:global(.hub-sideBar-section:last-child) {
|
|
104
70
|
border-bottom: none;
|
|
105
71
|
}
|
|
106
|
-
|
|
107
|
-
/* Delete button styling - bold red for development */
|
|
108
|
-
.deleteButton {
|
|
109
|
-
color: #dc3545 !important;
|
|
110
|
-
font-weight: bold !important;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
:global(.sideNav-item.deleteButton) {
|
|
114
|
-
color: #dc3545 !important;
|
|
115
|
-
font-weight: bold !important;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
:global(.sideNav-item.deleteButton:hover) {
|
|
119
|
-
background-color: rgba(220, 53, 69, 0.1) !important;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
:global(.sideNav-item.deleteButton i) {
|
|
123
|
-
color: #dc3545 !important;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/* Development delete button */
|
|
127
|
-
.devDeleteButton {
|
|
128
|
-
position: absolute;
|
|
129
|
-
bottom: 20px;
|
|
130
|
-
left: 20px;
|
|
131
|
-
background-color: #ff0000;
|
|
132
|
-
color: #ffffff;
|
|
133
|
-
border: none;
|
|
134
|
-
padding: 8px 12px;
|
|
135
|
-
border-radius: 4px;
|
|
136
|
-
cursor: pointer;
|
|
137
|
-
font-size: 12px;
|
|
138
|
-
font-weight: bold;
|
|
139
|
-
z-index: 1000;
|
|
140
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.devDeleteButton:hover {
|
|
144
|
-
background-color: #cc0000;
|
|
145
|
-
}
|
|
@@ -3,8 +3,9 @@ import { useDispatch, useSelector } from "react-redux";
|
|
|
3
3
|
import { fetchFeatureDefinitions } from "../actions/featureDefinitionsIndex";
|
|
4
4
|
import {
|
|
5
5
|
selectDefinition,
|
|
6
|
-
selectDefinitionIsLoading,
|
|
7
6
|
selectDefinitionError,
|
|
7
|
+
selectDefinitionIsLoading,
|
|
8
|
+
selectDefinitionMode,
|
|
8
9
|
} from "../selectors/featureBuilderSelectors";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -35,9 +36,12 @@ export const useFeatureDefinitionLoader = (options = {}) => {
|
|
|
35
36
|
const definition = useSelector(selectDefinition);
|
|
36
37
|
const isLoading = useSelector(selectDefinitionIsLoading);
|
|
37
38
|
const error = useSelector(selectDefinitionError);
|
|
39
|
+
const mode = useSelector(selectDefinitionMode);
|
|
38
40
|
|
|
39
41
|
// Determine if we need to load the definition
|
|
40
|
-
|
|
42
|
+
// Only load if: definition is missing AND mode is not yet set (meaning we haven't tried to fetch yet)
|
|
43
|
+
// OR forceReload is true
|
|
44
|
+
const shouldLoadDefinition = (!definition && !mode) || forceReload;
|
|
41
45
|
|
|
42
46
|
// Function to manually reload definition
|
|
43
47
|
const reloadDefinition = () => {
|
package/src/index.js
CHANGED
|
@@ -18,12 +18,12 @@ export const Reducers = (() => {
|
|
|
18
18
|
export const Screens = (() => {
|
|
19
19
|
const screens = {};
|
|
20
20
|
|
|
21
|
-
screens[
|
|
22
|
-
screens[
|
|
23
|
-
screens[
|
|
24
|
-
screens[
|
|
25
|
-
screens[
|
|
26
|
-
screens[
|
|
21
|
+
screens["FormOverviewStep"] = FormOverviewStep;
|
|
22
|
+
screens["FormFieldsStep"] = FormFieldsStep;
|
|
23
|
+
screens["FormLayoutStep"] = FormLayoutStep;
|
|
24
|
+
screens["ListingScreen"] = ListingScreen;
|
|
25
|
+
screens["CreateListingPage"] = CreateListingPage;
|
|
26
|
+
screens["EditListingPage"] = EditListingPage;
|
|
27
27
|
return screens;
|
|
28
28
|
})();
|
|
29
29
|
|
|
@@ -426,6 +426,11 @@
|
|
|
426
426
|
cursor: pointer;
|
|
427
427
|
transition: all 0.2s ease;
|
|
428
428
|
background-color: transparent;
|
|
429
|
+
opacity: 0.6;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.layoutOption:hover {
|
|
433
|
+
opacity: 1;
|
|
429
434
|
}
|
|
430
435
|
|
|
431
436
|
.layoutOptionImage {
|
|
@@ -439,10 +444,14 @@
|
|
|
439
444
|
}
|
|
440
445
|
|
|
441
446
|
.layoutOption.selected .layoutOptionImage {
|
|
442
|
-
border-color: var(--
|
|
447
|
+
border-color: var(--colour-purple, #6e79c5);
|
|
443
448
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
444
449
|
}
|
|
445
450
|
|
|
451
|
+
.layoutOption.selected {
|
|
452
|
+
opacity: 1;
|
|
453
|
+
}
|
|
454
|
+
|
|
446
455
|
.layoutOptionImg {
|
|
447
456
|
width: 100%;
|
|
448
457
|
height: 100%;
|
|
@@ -451,6 +460,7 @@
|
|
|
451
460
|
|
|
452
461
|
.layoutOptionContent {
|
|
453
462
|
max-width: 250px;
|
|
463
|
+
margin-bottom: 0.5rem;
|
|
454
464
|
}
|
|
455
465
|
|
|
456
466
|
.layoutOptionTitle {
|
|
@@ -130,6 +130,7 @@ const FormOverviewStepInner = (props) => {
|
|
|
130
130
|
|
|
131
131
|
// Clear submission state after showing toast (only for non-edit cases)
|
|
132
132
|
if (!isEditMode) {
|
|
133
|
+
const { clearFormSubmissionState } = require("../actions/formActions");
|
|
133
134
|
dispatch(clearFormSubmissionState());
|
|
134
135
|
}
|
|
135
136
|
}
|
|
@@ -124,6 +124,10 @@ export const selectDefinitionIsEditing = (state) => {
|
|
|
124
124
|
const definitionState = selectDefinitionState(state);
|
|
125
125
|
return definitionState && definitionState.isEditing;
|
|
126
126
|
};
|
|
127
|
+
export const selectDefinitionMode = (state) => {
|
|
128
|
+
const definitionState = selectDefinitionState(state);
|
|
129
|
+
return definitionState && definitionState.mode;
|
|
130
|
+
};
|
|
127
131
|
|
|
128
132
|
// Check if we have a definition loaded
|
|
129
133
|
export const selectHasDefinition = (state) => !!selectDefinition(state);
|