@plusscommunities/pluss-feature-builder-web-d 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
@@ -1,389 +0,0 @@
1
- import React, { useEffect, useState } from "react";
2
- import { SidebarLayout } from "../components/SidebarLayout.jsx";
3
- import {
4
- GenericInput,
5
- Text,
6
- Button,
7
- LoadingState,
8
- ErrorBoundary,
9
- FeatureBuilderWelcomePopup,
10
- } from "../components";
11
- import ToastContainer from "../components/ToastContainer.jsx";
12
- import { values } from "../values.config.js";
13
- import { PlussCore } from "../feature.config";
14
- import { capitalizeTextWithFallback } from "../utils/textUtils";
15
- import styles from "./Form.module.css";
16
- import { withRouter } from "react-router-dom";
17
-
18
- import { useDispatch, useSelector } from "react-redux";
19
- import {
20
- setDisplayName,
21
- clearFormSubmissionState,
22
- setIcon,
23
- setInitialValues,
24
- setTitle,
25
- submitForm,
26
- } from "../actions/formActions";
27
- import {
28
- selectFormIcon,
29
- selectFormDisplayName,
30
- selectFormTitle,
31
- selectDefinition,
32
- selectDefinitionIsLoading,
33
- selectIsCreateMode,
34
- selectIsEditMode,
35
- selectIsStepValid,
36
- selectStepErrors,
37
- selectFormIsSubmitting,
38
- selectFormSubmitError,
39
- selectFormSubmitSuccess,
40
- } from "../selectors/featureBuilderSelectors";
41
- import { validateAndUpdateStep } from "../actions/wizardActions";
42
- import IconSelector from "../components/IconSelector.jsx";
43
- import ExampleDisplay from "../components/ExampleDisplay.jsx";
44
-
45
- /**
46
- * Form Overview Step screen component for feature builder wizard
47
- * Handles feature configuration including title, display name, and icon selection
48
- * Manages validation, submission, and error handling for overview step
49
- * Supports both create and edit modes with different behaviors
50
- *
51
- * @typedef {Object} FormOverviewStepProps
52
- * @property {Object} history - React Router history object for navigation
53
- * @property {Object} location - React Router location object
54
- *
55
- * @param {FormOverviewStepProps} props - Component props
56
- * @returns {React.ReactElement} Form overview step interface
57
- *
58
- * @example
59
- * <FormOverviewStep history={historyObject} location={locationObject} />
60
- */
61
- const FormOverviewStepInner = (props) => {
62
- const { history, location } = props;
63
- const dispatch = useDispatch();
64
- const auth = useSelector((state) => state.auth);
65
-
66
- // Get wizard state
67
- const isCreateMode = useSelector(selectIsCreateMode);
68
- const isEditMode = useSelector(selectIsEditMode);
69
- const definition = useSelector(selectDefinition);
70
- const definitionIsLoading = useSelector(selectDefinitionIsLoading);
71
-
72
- // Get form state
73
- const selectedIcon = useSelector(selectFormIcon);
74
- const title = useSelector(selectFormTitle);
75
- const displayName = useSelector(selectFormDisplayName);
76
-
77
- // Get validation state
78
- const isStepValid = useSelector(selectIsStepValid("overview"));
79
- const stepErrors = useSelector(selectStepErrors("overview"));
80
-
81
- // Get submission state
82
- const isSubmitting = useSelector(selectFormIsSubmitting);
83
- const submitError = useSelector(selectFormSubmitError);
84
- const submitSuccess = useSelector(selectFormSubmitSuccess);
85
-
86
- // State for welcome popup (only show in create mode)
87
- const [showWelcomePopup, setShowWelcomePopup] = useState(false);
88
-
89
- // Toast state
90
- const [toasts, setToasts] = React.useState([]);
91
-
92
- // Toast management functions
93
- const addToast = (type, message) => {
94
- const id = Date.now();
95
- setToasts((prev) => [...prev, { id, type, message, isVisible: true }]);
96
- };
97
-
98
- const removeToast = (id) => {
99
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
100
- };
101
-
102
- // Handle redirect after successful save in edit mode
103
- useEffect(() => {
104
- if (submitSuccess && isEditMode && !isSubmitting) {
105
- // Show toast notification
106
- addToast("success", "Changes saved");
107
-
108
- // Clear the success state after a short delay and redirect to overview
109
- const timer = setTimeout(() => {
110
- dispatch(clearFormSubmissionState());
111
- history.push(values.routeFormOverviewStep);
112
- }, 1500); // Show success message for 1.5 seconds before redirect
113
-
114
- return () => clearTimeout(timer);
115
- }
116
- }, [submitSuccess, isEditMode, isSubmitting, dispatch, history]);
117
-
118
- // Show toast notification for general success cases
119
- React.useEffect(() => {
120
- if (submitSuccess) {
121
- if (!isEditMode) {
122
- addToast("success", "Step saved");
123
- }
124
-
125
- // Clear submission state after showing toast (only for non-edit cases)
126
- if (!isEditMode) {
127
- dispatch(clearFormSubmissionState());
128
- }
129
- }
130
- }, [submitSuccess, isEditMode, dispatch]);
131
-
132
- // Handle submit error
133
- useEffect(() => {
134
- if (submitError) {
135
- addToast("error", "It didn't work. Please try again.");
136
- setTimeout(() => {
137
- window.location.reload();
138
- }, 1000);
139
- }
140
- }, [submitError]);
141
-
142
- // Error boundary handlers
143
- const handleRefresh = () => {
144
- // Refresh current step data
145
- dispatch(validateAndUpdateStep("overview"));
146
- };
147
-
148
- const handleBack = () => {
149
- // Always go to listing screen when going back
150
- history.push(values.routeListingScreen);
151
- };
152
-
153
- useEffect(() => {
154
- // Check if we should populate the form from definition
155
- // Primary condition: edit mode with definition available
156
- // Fallback condition: definition exists regardless of mode (handles timing issues)
157
- const shouldPopulateForm =
158
- definition &&
159
- !definitionIsLoading &&
160
- (isEditMode || (definition && !isCreateMode)); // Fallback: if definition exists and we're not in create mode
161
-
162
- if (shouldPopulateForm) {
163
- dispatch(setInitialValues(definition));
164
-
165
- // In edit mode, trigger validation after setting initial values to enable save button
166
- if (isEditMode) {
167
- setTimeout(() => {
168
- dispatch(validateAndUpdateStep("overview"));
169
- }, 100); // Small delay to ensure state is updated
170
- }
171
- }
172
- }, [definition, definitionIsLoading, isEditMode, isCreateMode, dispatch]);
173
-
174
- // Show welcome popup on component mount for create mode
175
- useEffect(() => {
176
- if (isCreateMode && !definitionIsLoading && !definition) {
177
- setShowWelcomePopup(true);
178
- }
179
- }, [isCreateMode, definitionIsLoading, definition]);
180
-
181
- // Handle welcome popup close
182
- const handleWelcomePopupClose = () => {
183
- setShowWelcomePopup(false);
184
- };
185
-
186
- function handleNext() {
187
- // Validate before proceeding - validation will update Redux state
188
- const validationResult = dispatch(validateAndUpdateStep("overview"));
189
-
190
- // If validation passes, navigate to next step
191
- if (validationResult && validationResult.isValid) {
192
- // Clear form submission state when changing steps
193
- dispatch(clearFormSubmissionState());
194
-
195
- if (isCreateMode) {
196
- history.push(values.routeFormFieldsStep);
197
- } else {
198
- // In edit mode, navigate directly
199
- history.push(values.routeFormFieldsStep);
200
- }
201
- }
202
- // If validation fails, the validation errors will be displayed and user can fix them
203
- }
204
-
205
- function handlePrevious() {
206
- // Clear form submission state when changing steps
207
- dispatch(clearFormSubmissionState());
208
-
209
- // Always go to listing screen after completion
210
- history.push(values.routeListingScreen);
211
- }
212
-
213
- function handleSaveStep() {
214
- // Validate before saving in edit mode
215
- const validationResult = dispatch(validateAndUpdateStep("overview"));
216
-
217
- // If validation passes, save the entire form
218
- if (validationResult && validationResult.isValid) {
219
- dispatch(submitForm());
220
- }
221
- }
222
-
223
- function handleTitleChange(ev) {
224
- dispatch(setTitle(ev.target.value));
225
- }
226
-
227
- function handleSelectIcon(icon) {
228
- dispatch(setIcon(icon));
229
- }
230
-
231
- function handleDisplayNameChange(ev) {
232
- dispatch(setDisplayName(ev.target.value));
233
- }
234
-
235
- // Check for definition management permission
236
- if (
237
- !PlussCore.Session.validateAccess(
238
- auth.site,
239
- values.permissionFeatureBuilderDefinition,
240
- auth,
241
- )
242
- ) {
243
- return (
244
- <div className="hub-wrapperContainer">
245
- <div className="hub-contentWrapper">
246
- <div className={styles.welcomeContainer}>
247
- <div className={styles.welcomeHeader}>
248
- <Text type="h1" className={styles.welcomeTitle}>
249
- Access Restricted
250
- </Text>
251
- <Text type="body" className={styles.welcomeSubtitle}>
252
- You don't have permission to manage feature definitions. Please
253
- contact your administrator if you need access.
254
- </Text>
255
- </div>
256
- </div>
257
- </div>
258
- </div>
259
- );
260
- }
261
-
262
- return (
263
- <ErrorBoundary
264
- title="Unable to load overview"
265
- message="If you continue to experience issues with the overview step, please try refreshing the page or contact support."
266
- onRetry={handleRefresh}
267
- >
268
- <SidebarLayout>
269
- <Text
270
- type="formTitleLarge"
271
- className={`${isEditMode ? styles.editMode : styles.createMode}`}
272
- >
273
- {definitionIsLoading
274
- ? "Loading..."
275
- : isEditMode
276
- ? `Edit Feature: ${capitalizeTextWithFallback(title, "Unnamed")}`
277
- : "Create New Feature"}
278
- </Text>
279
- {definitionIsLoading ? (
280
- <div className={styles.overviewLoadingContainer}>
281
- <LoadingState message="Loading feature..." size={48} />
282
- </div>
283
- ) : (
284
- <>
285
- <GenericInput
286
- label="Feature Name"
287
- help="Name your feature as it should appear in the Community Manager and the app"
288
- isRequired
289
- type="text"
290
- onChange={handleTitleChange}
291
- value={title}
292
- className="mt-8"
293
- showError={() => {
294
- return !isStepValid && stepErrors && stepErrors.title;
295
- }}
296
- errorMessage="Title is required"
297
- isValid={() => {
298
- return title && title.trim().length > 0;
299
- }}
300
- />
301
-
302
- <IconSelector
303
- selectedIcon={selectedIcon}
304
- onIconSelect={handleSelectIcon}
305
- className=""
306
- stepErrors={stepErrors}
307
- showError={() => {
308
- return !isStepValid && stepErrors && stepErrors.icon;
309
- }}
310
- />
311
-
312
- <GenericInput
313
- label="Display Name"
314
- help="Display name for this feature (used in buttons, notifications, and activity feeds)"
315
- isRequired
316
- type="text"
317
- onChange={handleDisplayNameChange}
318
- value={displayName}
319
- className="mt-8"
320
- showError={() => {
321
- return !isStepValid && stepErrors && stepErrors.displayName;
322
- }}
323
- errorMessage="Display name is required"
324
- isValid={() => {
325
- return displayName && displayName.trim().length > 0;
326
- }}
327
- />
328
-
329
- {/* Examples Display */}
330
- <ExampleDisplay displayName={displayName} />
331
- </>
332
- )}
333
-
334
- {/* Top-level validation message - positioned above action buttons */}
335
- {!isStepValid && Object.keys(stepErrors).length > 0 && (
336
- <div
337
- className={styles.validationErrorMessage}
338
- role="alert"
339
- aria-live="polite"
340
- >
341
- {Object.keys(stepErrors).length}{" "}
342
- {Object.keys(stepErrors).length === 1
343
- ? "field needs"
344
- : "fields need"}{" "}
345
- attention before proceeding
346
- </div>
347
- )}
348
-
349
- {/* Mode-aware navigation buttons */}
350
- <div className={styles.navigation}>
351
- {isCreateMode ? (
352
- <Button
353
- buttonType="primary"
354
- isActive
355
- onClick={handleNext}
356
- leftIcon="arrow-right"
357
- >
358
- Next step: Configure Fields
359
- </Button>
360
- ) : (
361
- <Button
362
- buttonType="primary"
363
- isActive
364
- onClick={handleSaveStep}
365
- disabled={!isStepValid || isSubmitting}
366
- leftIcon={isSubmitting ? "sync" : "save"}
367
- loading={isSubmitting}
368
- >
369
- {isSubmitting ? "Saving..." : "Save"}
370
- </Button>
371
- )}
372
- </div>
373
-
374
- {/* Submission feedback */}
375
- </SidebarLayout>
376
-
377
- {/* Welcome popup for create mode */}
378
- <FeatureBuilderWelcomePopup
379
- isOpen={showWelcomePopup}
380
- onClose={handleWelcomePopupClose}
381
- />
382
-
383
- {/* Toast Container for Notifications */}
384
- <ToastContainer toasts={toasts} onDismiss={removeToast} />
385
- </ErrorBoundary>
386
- );
387
- };
388
-
389
- export const FormOverviewStep = withRouter(FormOverviewStepInner);