@plusscommunities/pluss-feature-builder-web-a 1.0.7 → 1.0.9-beta.3

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 (119) hide show
  1. package/dist/{index.cjs.js → index.js} +3803 -3504
  2. package/dist/index.js.map +1 -0
  3. package/package.json +20 -27
  4. package/.babelrc +0 -4
  5. package/rollup.config.js +0 -69
  6. package/src/actions/featureBuilderStringsActions.js +0 -88
  7. package/src/actions/featureDefinitionsIndex.js +0 -258
  8. package/src/actions/formActions.js +0 -301
  9. package/src/actions/index.js +0 -12
  10. package/src/actions/listingActions.js +0 -352
  11. package/src/actions/wizardActions.js +0 -228
  12. package/src/components/ActivityCardExample.jsx +0 -86
  13. package/src/components/ActivityCardExample.module.css +0 -130
  14. package/src/components/BackgroundLoader.jsx +0 -33
  15. package/src/components/BackgroundLoader.module.css +0 -46
  16. package/src/components/BaseFieldConfig.jsx +0 -305
  17. package/src/components/BaseFieldConfig.module.css +0 -42
  18. package/src/components/CenteredContainer.jsx +0 -29
  19. package/src/components/CenteredContainer.module.css +0 -171
  20. package/src/components/DeleteConfirmationPopup.jsx +0 -95
  21. package/src/components/DeleteConfirmationPopup.module.css +0 -12
  22. package/src/components/ErrorBoundary.jsx +0 -134
  23. package/src/components/ErrorBoundary.module.css +0 -77
  24. package/src/components/ErrorMessage.jsx +0 -85
  25. package/src/components/ErrorMessage.module.css +0 -116
  26. package/src/components/ExampleDisplay.jsx +0 -26
  27. package/src/components/ExampleDisplay.module.css +0 -3
  28. package/src/components/FeatureBuilderSidebar.jsx +0 -84
  29. package/src/components/FeatureBuilderSuccessPopup.jsx +0 -49
  30. package/src/components/FeatureBuilderSuccessPopup.module.css +0 -41
  31. package/src/components/FeatureBuilderWelcomePopup.jsx +0 -51
  32. package/src/components/FeatureBuilderWelcomePopup.module.css +0 -21
  33. package/src/components/FeatureListingCard.jsx +0 -104
  34. package/src/components/FeatureListingCard.module.css +0 -62
  35. package/src/components/Fields.jsx +0 -423
  36. package/src/components/Fields.module.css +0 -159
  37. package/src/components/IconLoader.jsx +0 -153
  38. package/src/components/IconLoader.module.css +0 -92
  39. package/src/components/IconSelector.jsx +0 -111
  40. package/src/components/IconSelector.module.css +0 -197
  41. package/src/components/ListingEditor.jsx +0 -405
  42. package/src/components/ListingEditor.module.css +0 -14
  43. package/src/components/ListingSuccessPopup.jsx +0 -52
  44. package/src/components/LoadingScreen.jsx +0 -54
  45. package/src/components/LoadingScreen.module.css +0 -103
  46. package/src/components/LoadingState.jsx +0 -40
  47. package/src/components/LoadingState.module.css +0 -18
  48. package/src/components/PreviewFull.js +0 -24
  49. package/src/components/PreviewFull.module.css +0 -11
  50. package/src/components/PreviewGrid.js +0 -14
  51. package/src/components/PreviewWidget.js +0 -27
  52. package/src/components/PreviewWidget.module.css +0 -15
  53. package/src/components/SidebarLayout.jsx +0 -252
  54. package/src/components/SidebarLayout.module.css +0 -71
  55. package/src/components/SkeletonLoader.jsx +0 -128
  56. package/src/components/SkeletonLoader.module.css +0 -295
  57. package/src/components/SortButtonGroup.jsx +0 -34
  58. package/src/components/SortButtonGroup.module.css +0 -51
  59. package/src/components/ToastContainer.jsx +0 -98
  60. package/src/components/ToastContainer.module.css +0 -156
  61. package/src/components/ToggleSwitch.js +0 -40
  62. package/src/components/ToggleSwitch.module.css +0 -48
  63. package/src/components/TwoColumnInput.jsx +0 -29
  64. package/src/components/TwoColumnInput.module.css +0 -32
  65. package/src/components/ViewFull.js +0 -139
  66. package/src/components/ViewFull.module.css +0 -71
  67. package/src/components/ViewWidget.js +0 -62
  68. package/src/components/ViewWidget.module.css +0 -28
  69. package/src/components/iconCategories.js +0 -135
  70. package/src/components/iconImports.js +0 -409
  71. package/src/components/index.js +0 -59
  72. package/src/components/listing/FileListItem.jsx +0 -86
  73. package/src/components/listing/GalleryDisplay.jsx +0 -330
  74. package/src/components/listing/GalleryDisplay.module.css +0 -309
  75. package/src/components/listing/ListingCTAInput.jsx +0 -82
  76. package/src/components/listing/ListingDescriptionInput.jsx +0 -73
  77. package/src/components/listing/ListingField.jsx +0 -101
  78. package/src/components/listing/ListingField.module.css +0 -106
  79. package/src/components/listing/ListingFileInput.jsx +0 -273
  80. package/src/components/listing/ListingFileInput.module.css +0 -189
  81. package/src/components/listing/ListingForm.jsx +0 -90
  82. package/src/components/listing/ListingForm.module.css +0 -38
  83. package/src/components/listing/ListingGalleryInput.jsx +0 -239
  84. package/src/components/listing/ListingGalleryInput.module.css +0 -132
  85. package/src/components/listing/ListingImageInput.jsx +0 -153
  86. package/src/components/listing/ListingTextInput.jsx +0 -72
  87. package/src/feature.config.js +0 -130
  88. package/src/helper/index.js +0 -135
  89. package/src/hooks/useFeatureDefinitionLoader.js +0 -66
  90. package/src/images/full.png +0 -0
  91. package/src/images/fullNoTitle.png +0 -0
  92. package/src/images/previewWidget.png +0 -0
  93. package/src/images/widget.png +0 -0
  94. package/src/index.js +0 -38
  95. package/src/pages/CreateListingPage.jsx +0 -49
  96. package/src/pages/EditListingPage.jsx +0 -58
  97. package/src/reducers/featureBuilderReducer.js +0 -739
  98. package/src/screens/CreateListing.module.css +0 -45
  99. package/src/screens/Form.module.css +0 -744
  100. package/src/screens/FormFieldsStep.jsx +0 -626
  101. package/src/screens/FormLayoutStep.jsx +0 -405
  102. package/src/screens/FormOverviewStep.jsx +0 -389
  103. package/src/screens/ListingScreen.jsx +0 -477
  104. package/src/screens/ListingScreen.module.css +0 -333
  105. package/src/selectors/featureBuilderSelectors.js +0 -533
  106. package/src/types/index.js +0 -91
  107. package/src/utils/textUtils.js +0 -89
  108. package/src/validators/galleryValidators.js +0 -345
  109. package/src/values.config.a.js +0 -49
  110. package/src/values.config.b.js +0 -49
  111. package/src/values.config.c.js +0 -49
  112. package/src/values.config.d.js +0 -49
  113. package/src/values.config.default.js +0 -49
  114. package/src/values.config.js +0 -49
  115. package/src/webapi/featureDefinitionActions.js +0 -0
  116. package/src/webapi/featuresActions.js +0 -90
  117. package/src/webapi/helper.js +0 -4
  118. package/src/webapi/index.js +0 -12
  119. package/src/webapi/listingActions.js +0 -176
package/package.json CHANGED
@@ -1,53 +1,46 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-feature-builder-web-a",
3
- "version": "1.0.7",
3
+ "version": "1.0.9-beta.3",
4
4
  "description": "Contains the feature builder extension for the pluss communities ",
5
- "main": "dist/index.cjs.js",
5
+ "exports": {
6
+ ".": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist/"
10
+ ],
6
11
  "scripts": {
7
- "build": "npm i && rollup -c",
12
+ "build": "rollup -c",
13
+ "prepublishOnly": "(cd .. && npm install) && npm run build",
8
14
  "betapatch": "npm version prepatch --preid=beta",
9
15
  "patch": "npm version patch",
10
- "betaupload": "npm run build && npm publish --access public --tag beta && rm -rf node_modules",
16
+ "betaupload": "npm publish --access public --tag beta",
11
17
  "betaupload:p": "npm run betapatch && npm run betaupload",
12
- "upload": "npm run build && npm publish --access public && rm -rf node_modules",
18
+ "upload": "npm publish --access public",
13
19
  "upload:p": "npm run patch && npm run upload",
14
20
  "copy:add": "run(){ ext=${1:-default}; test -f src/values.config.$ext.js || cp src/values.config.default.js src/values.config.$ext.js; }; run",
15
21
  "copy:get": "echo $npm_package_name",
16
22
  "copy:set": "run(){ target='@plusscommunities/pluss-feature-builder-web'; ext=${1:-default}; [ $ext == 'default' ] && replace=$target || replace=$target'-'$ext; echo 'Setting target to '$replace; test -f src/values.config.$ext.js && cp -f src/values.config.$ext.js src/values.config.js; REPLACE=$replace node -e 'const pkg=require(\"./package.json\"); pkg.name=process.env.REPLACE; require(\"fs\").writeFileSync(\"./package.json\", JSON.stringify(pkg, null, 2))'; }; run",
17
- "copy:betaupload": "npm run betapatch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run betaupload; done; npm run copy:set;",
23
+ "copy:betaupload": "for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run betaupload; done; npm run copy:set;",
18
24
  "copy:upload": "npm run patch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run upload; done; npm run copy:set;"
19
25
  },
20
26
  "author": "Phillip Suh",
21
- "devDependencies": {
22
- "@babel/cli": "^7.14.3",
23
- "@babel/core": "^7.14.3",
24
- "@babel/plugin-transform-class-properties": "^7.27.1",
25
- "@babel/plugin-transform-optional-chaining": "^7.14.5",
26
- "@babel/plugin-transform-react-jsx": "^7.14.3",
27
- "@babel/plugin-transform-runtime": "^7.14.3",
28
- "@babel/preset-env": "^7.14.2",
29
- "@babel/preset-react": "^7.13.13",
30
- "@rollup/plugin-babel": "^5.3.0",
31
- "@rollup/plugin-image": "^2.0.6",
32
- "@rollup/plugin-json": "^4.1.0",
33
- "autoprefixer": "^10.2.6",
34
- "rollup": "^2.50.1",
35
- "rollup-plugin-local-resolve": "^1.0.7",
36
- "rollup-plugin-styles": "^3.14.1"
37
- },
38
27
  "dependencies": {
39
- "@babel/runtime": "^7.14.0"
28
+ "@babel/runtime": "^7.14.0",
29
+ "@fortawesome/free-solid-svg-icons": "^6.0.0",
30
+ "@fortawesome/react-fontawesome": "^0.2.0",
31
+ "@dnd-kit/sortable": "^7.0.0",
32
+ "@dnd-kit/core": "^6.0.0"
40
33
  },
41
34
  "peerDependencies": {
42
- "@fortawesome/fontawesome-svg-core": "*",
43
- "@fortawesome/free-solid-svg-icons": "*",
44
- "@fortawesome/react-fontawesome": "*",
45
35
  "@plusscommunities/pluss-core-web": "*",
46
36
  "lodash": "*",
47
37
  "moment": "*",
48
38
  "react": "*",
49
39
  "react-bootstrap": "*",
50
40
  "react-dom": "*",
41
+ "react-redux": "*",
42
+ "react-router-dom": "*",
43
+ "react-router": "*",
51
44
  "react-fontawesome": "*"
52
45
  },
53
46
  "keywords": []
package/.babelrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "presets": ["@babel/preset-react", "@babel/preset-env"],
3
- "plugins": ["@babel/plugin-transform-react-jsx", "@babel/plugin-transform-optional-chaining", "@babel/plugin-transform-class-properties"]
4
- }
package/rollup.config.js DELETED
@@ -1,69 +0,0 @@
1
- import styles from "rollup-plugin-styles";
2
- const autoprefixer = require("autoprefixer");
3
- import babel from "@rollup/plugin-babel";
4
- import json from "@rollup/plugin-json";
5
- import image from "@rollup/plugin-image";
6
- import localResolve from "rollup-plugin-local-resolve";
7
-
8
- // the entry point for the library
9
- const input = "src/index.js";
10
-
11
- var MODE = [
12
- {
13
- format: "cjs",
14
- },
15
- ];
16
-
17
- var config = [];
18
-
19
- MODE.map((m) => {
20
- var conf = {
21
- input: input,
22
- output: {
23
- // then name of your package
24
- name: "@plusscommunities/pluss-feature-builder-web",
25
- file: `dist/index.${m.format}.js`,
26
- format: m.format,
27
- exports: "auto",
28
- },
29
- // this externelizes react to prevent rollup from compiling it
30
- external: [
31
- "react",
32
- "react-dom",
33
- "react-redux",
34
- "react-router-dom",
35
- "@fortawesome/react-fontawesome",
36
- "@fortawesome/fontawesome-svg-core",
37
- "@fortawesome/free-solid-svg-icons",
38
- "@plusscommunities/pluss-core-web",
39
- /@babel\/runtime/,
40
- ],
41
- plugins: [
42
- // these are babel comfigurations
43
- babel({
44
- exclude: "node_modules/**",
45
- presets: ["@babel/preset-react", "@babel/preset-env"],
46
- plugins: [
47
- "@babel/transform-runtime",
48
- "@babel/plugin-transform-react-jsx",
49
- "@babel/plugin-transform-optional-chaining",
50
- ["@babel/plugin-transform-class-properties", { loose: true }],
51
- ],
52
- babelHelpers: "runtime",
53
- }),
54
- // this adds support for styles
55
- styles({
56
- postcss: {
57
- plugins: [autoprefixer()],
58
- },
59
- autoModules: /\.module\.css$/,
60
- }),
61
- json(),
62
- image(),
63
- localResolve(),
64
- ],
65
- };
66
- config.push(conf);
67
- });
68
-
69
- export default [...config];
@@ -1,88 +0,0 @@
1
- import {
2
- selectFormTitle,
3
- selectFormIcon,
4
- } from "../selectors/featureBuilderSelectors";
5
- import { values } from "../values.config";
6
- import { capitalizeTextWithFallback, toTitleCase } from "../utils/textUtils";
7
-
8
- // IMPORTANT: Using local UPDATE_STRINGS action type to make extension self-contained
9
- // The main app's StringsReducer will handle this action type the same way
10
- export const UPDATE_STRINGS = "UPDATE_STRINGS";
11
-
12
- export const updateFeatureBuilderString = (title) => (dispatch, getState) => {
13
- const currentStrings = getState().strings?.config || {};
14
- const titleCased = toTitleCase(title) || values.textMenuTitle;
15
- const updatedStrings = {
16
- ...currentStrings,
17
- sideNav: {
18
- ...currentStrings.sideNav,
19
- [values.featureKey]: titleCased,
20
- [values.menuKey]: `Manage ${titleCased}`,
21
- },
22
- permission: {
23
- ...currentStrings.permission,
24
- [values.permissionFeatureBuilderDefinition]: `Manage custom feature ${titleCased}`,
25
- [values.permissionFeatureBuilderContent]: `Manage ${titleCased} content`,
26
- },
27
- };
28
-
29
- dispatch({
30
- type: UPDATE_STRINGS,
31
- payload: updatedStrings,
32
- });
33
- };
34
-
35
- export const updateFeatureBuilderStringFromStore =
36
- () => (dispatch, getState) => {
37
- const title = selectFormTitle(getState());
38
- dispatch(updateFeatureBuilderString(title));
39
- };
40
-
41
- export const updateFeatureBuilderIcon = (icon) => (dispatch, getState) => {
42
- const currentStrings = getState().strings?.config || {};
43
- const updatedStrings = {
44
- ...currentStrings,
45
- sideNav: {
46
- ...currentStrings.sideNav,
47
- [values.featureKey + "-icon"]: icon,
48
- [values.menuKey + "-icon"]: icon,
49
- },
50
- };
51
-
52
- dispatch({
53
- type: UPDATE_STRINGS,
54
- payload: updatedStrings,
55
- });
56
- };
57
-
58
- export const updateFeatureBuilderStringAndIcon = () => (dispatch, getState) => {
59
- const title = selectFormTitle(getState());
60
- const icon = selectFormIcon(getState());
61
-
62
- // Update title separately (will be title cased in updateFeatureBuilderString)
63
- dispatch(updateFeatureBuilderString(title));
64
-
65
- // Update icon as string
66
- dispatch(updateFeatureBuilderIcon(icon));
67
- };
68
-
69
- export const updatePermissionNames = (featureTitle) => (dispatch, getState) => {
70
- const currentStrings = getState().strings?.config || {};
71
-
72
- const titleCasedFeature = toTitleCase(featureTitle, "");
73
- const updatedStrings = {
74
- ...currentStrings,
75
- permission: {
76
- ...currentStrings.permission,
77
- [values.permissionFeatureBuilderDefinition]: `Create and Edit ${titleCasedFeature} Features`,
78
- [values.permissionFeatureBuilderContent]: `Manage ${titleCasedFeature} Content`,
79
- },
80
- };
81
-
82
- const result = dispatch({
83
- type: UPDATE_STRINGS,
84
- payload: updatedStrings,
85
- });
86
-
87
- return result;
88
- };
@@ -1,258 +0,0 @@
1
- import { featureDefinitionActions } from "../webapi/featuresActions";
2
- import { values } from "../values.config.js";
3
- import {
4
- updateFeatureBuilderString,
5
- updateFeatureBuilderIcon,
6
- updatePermissionNames,
7
- } from "./featureBuilderStringsActions";
8
-
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`;
13
-
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`;
17
-
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`;
21
-
22
- export const FEATURE_DELETE_REQUEST = `${REDUCER_PREFIX}_FEATURE_DELETE_REQUEST`;
23
- export const FEATURE_DELETE_FAILURE = `${REDUCER_PREFIX}_FEATURE_DELETE_FAILURE`;
24
-
25
- // Wizard synchronization action types
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
-
29
- function fetchFeaturesRequest() {
30
- return { type: FETCH_FEATURES_REQUEST };
31
- }
32
-
33
- function fetchFeaturesSuccess(data, mode) {
34
- return { type: FETCH_FEATURES_SUCCESS, payload: { data, mode } };
35
- }
36
-
37
- function fetchFeaturesFailure(data) {
38
- return { type: FETCH_FEATURES_FAILURE, payload: data };
39
- }
40
-
41
- function deleteFeatureRequest(id) {
42
- return { type: FEATURE_DELETE_REQUEST, payload: id };
43
- }
44
-
45
- function deleteFeatureFailure(id) {
46
- return { type: FEATURE_DELETE_FAILURE, payload: id };
47
- }
48
-
49
- // Action creators for wizard synchronization
50
- function syncWizardModeFromDefinition(mode) {
51
- return { type: SYNC_WIZARD_MODE_FROM_DEFINITION, payload: mode };
52
- }
53
-
54
- function setWizardMode(mode) {
55
- return { type: SET_WIZARD_MODE, payload: mode };
56
- }
57
-
58
- // Action creators for create operations
59
- function createFeatureRequest() {
60
- return { type: FEATURE_CREATE_REQUEST };
61
- }
62
-
63
- function createFeatureSuccess(featureDefinition) {
64
- return (dispatch) => {
65
- // Update menu string with title and icon from created definition
66
- const title = featureDefinition?.title;
67
- const icon = featureDefinition?.icon;
68
-
69
- dispatch(updateFeatureBuilderString(title));
70
- dispatch(updateFeatureBuilderIcon(icon));
71
-
72
- // Update permission names based on feature title
73
- dispatch(updatePermissionNames(title));
74
-
75
- // Dispatch the actual success action
76
- dispatch({
77
- type: FEATURE_CREATE_SUCCESS,
78
- payload: featureDefinition,
79
- });
80
-
81
- // After creation, switch wizard to edit mode
82
- dispatch(setWizardMode("edit"));
83
- };
84
- }
85
-
86
- function createFeatureFailure(error) {
87
- return { type: FEATURE_CREATE_FAILURE, payload: error };
88
- }
89
-
90
- // Action creators for edit operations
91
- function editFeatureRequest() {
92
- return { type: FEATURE_EDIT_REQUEST };
93
- }
94
-
95
- function editFeatureSuccess(featureDefinition) {
96
- return (dispatch) => {
97
- // Update menu string with title and icon from edited definition
98
- const title = featureDefinition?.title;
99
- const icon = featureDefinition?.icon;
100
-
101
- dispatch(updateFeatureBuilderString(title));
102
- dispatch(updateFeatureBuilderIcon(icon));
103
-
104
- // Update permission names based on feature title
105
- dispatch(updatePermissionNames(title));
106
-
107
- // Dispatch the actual success action
108
- dispatch({
109
- type: FEATURE_EDIT_SUCCESS,
110
- payload: featureDefinition,
111
- });
112
- };
113
- }
114
-
115
- function editFeatureFailure(error) {
116
- return { type: FEATURE_EDIT_FAILURE, payload: error };
117
- }
118
-
119
- // Thunk actions using the new webapi
120
- export function fetchFeatureDefinitions() {
121
- return async (dispatch, getState) => {
122
- dispatch(fetchFeaturesRequest());
123
- try {
124
- // Get site from auth store
125
- const site = getState().auth.site;
126
- if (!site) {
127
- throw new Error(
128
- "Authentication error: Site context not found. Please refresh and login again.",
129
- );
130
- }
131
- const response = await featureDefinitionActions.getSingle(
132
- values.featureId,
133
- site,
134
- );
135
-
136
- // Check HTTP status to determine mode
137
- if (response.status >= 200 && response.status < 300) {
138
- // 2XX: Feature exists → edit mode
139
- dispatch(fetchFeaturesSuccess(response.data, "edit"));
140
-
141
- // Update menu string with title and icon from fetched definition
142
- const featureDefinitionWrapper =
143
- response.data?.featureDefinition || response.data;
144
- const definition =
145
- featureDefinitionWrapper?.definition || featureDefinitionWrapper;
146
- const title = definition?.title;
147
- const icon = definition?.icon;
148
- dispatch(updateFeatureBuilderString(title));
149
- dispatch(updateFeatureBuilderIcon(icon));
150
-
151
- // Synchronize wizard mode with definition
152
- dispatch(syncWizardModeFromDefinition("edit"));
153
- } else {
154
- // Unexpected success status → treat as error
155
- dispatch(
156
- fetchFeaturesFailure(
157
- new Error(`Unexpected response status: ${response.status}`),
158
- ),
159
- );
160
- }
161
- } catch (err) {
162
- // Check if it's a 404 (feature doesn't exist)
163
- if (err.response?.status === 404) {
164
- // 404: Feature doesn't exist → create mode
165
- dispatch(fetchFeaturesSuccess(null, "create"));
166
-
167
- // Reset menu string to default when no feature exists
168
- dispatch(updateFeatureBuilderString(null));
169
-
170
- // Synchronize wizard mode with definition
171
- dispatch(syncWizardModeFromDefinition("create"));
172
- } else {
173
- // Other errors: network, server, auth
174
- dispatch(fetchFeaturesFailure(err));
175
- }
176
- }
177
- };
178
- }
179
-
180
- export function fetchFeatureDefinition(id) {
181
- return async (dispatch, getState) => {
182
- dispatch(fetchFeaturesRequest());
183
- try {
184
- // Get site from auth store
185
- const site = getState().auth.site;
186
- if (!site) {
187
- throw new Error(
188
- "Authentication error: Site context not found. Please refresh and login again.",
189
- );
190
- }
191
- const { data } = await featureDefinitionActions.getSingle(id, site);
192
- dispatch(fetchFeaturesSuccess(data));
193
- } catch (err) {
194
- dispatch(fetchFeaturesFailure(err));
195
- }
196
- };
197
- }
198
-
199
- export function createFeatureDefinition(id, site, featureDefinition) {
200
- return async (dispatch) => {
201
- dispatch(createFeatureRequest());
202
- try {
203
- if (!values.featureId || !site) {
204
- throw new Error(
205
- "Authentication error: Missing required context (featureId or site).",
206
- );
207
- }
208
- const { data } = await featureDefinitionActions.create(
209
- id,
210
- site,
211
- featureDefinition,
212
- );
213
- dispatch(createFeatureSuccess(data));
214
- } catch (err) {
215
- dispatch(createFeatureFailure(err));
216
- }
217
- };
218
- }
219
-
220
- export function editFeatureDefinition(featureDefinitionData) {
221
- return async (dispatch, getState) => {
222
- dispatch(editFeatureRequest());
223
- try {
224
- // Get site from auth store
225
- const site = getState().auth.site;
226
- if (!site) {
227
- throw new Error(
228
- "Authentication error: Site context not found. Please refresh and login again.",
229
- );
230
- }
231
- const { data } = await featureDefinitionActions.edit(
232
- featureDefinitionData,
233
- site,
234
- );
235
- dispatch(editFeatureSuccess(data));
236
- } catch (err) {
237
- dispatch(editFeatureFailure(err));
238
- }
239
- };
240
- }
241
-
242
- export function deleteFeatureDefinition(id) {
243
- return async (dispatch, getState) => {
244
- dispatch(deleteFeatureRequest({ id }));
245
- try {
246
- // Get site from auth store
247
- const site = getState().auth.site;
248
- if (!site) {
249
- throw new Error(
250
- "Authentication error: Site context not found. Please refresh and login again.",
251
- );
252
- }
253
- await featureDefinitionActions.delete(id, site);
254
- } catch (err) {
255
- dispatch(deleteFeatureFailure({ id }));
256
- }
257
- };
258
- }