@knovator/pagecreator-admin 1.2.6 → 1.2.7

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 (166) hide show
  1. package/index.d.ts +1 -0
  2. package/package.json +38 -42
  3. package/src/{index.d.ts → index.ts} +1 -0
  4. package/src/lib/api/index.ts +70 -0
  5. package/src/lib/api/list.ts +59 -0
  6. package/src/lib/components/Page/AddButton/AddButton.tsx +16 -0
  7. package/src/lib/components/Page/AddButton/{index.d.ts → index.ts} +1 -0
  8. package/src/lib/components/Page/Form/PageForm.tsx +194 -0
  9. package/src/lib/components/Page/Form/{index.d.ts → index.ts} +1 -0
  10. package/src/lib/components/Page/Page/Page.tsx +151 -0
  11. package/src/lib/components/Page/Page/{index.d.ts → index.ts} +1 -0
  12. package/src/lib/components/Page/PageFormActions/PageFormActions.tsx +50 -0
  13. package/src/lib/components/Page/PageFormActions/{index.d.ts → index.ts} +1 -0
  14. package/src/lib/components/Page/PageFormWrapper/PageFormWrapper.tsx +16 -0
  15. package/src/lib/components/Page/PageFormWrapper/{index.d.ts → index.ts} +1 -0
  16. package/src/lib/components/Page/Pagination/PagePagination.tsx +26 -0
  17. package/src/lib/components/Page/Pagination/{index.d.ts → index.ts} +1 -0
  18. package/src/lib/components/Page/Search/PageSearch.tsx +32 -0
  19. package/src/lib/components/Page/Search/{index.d.ts → index.tsx} +1 -0
  20. package/src/lib/components/Page/Table/PageTable.tsx +36 -0
  21. package/src/lib/components/Page/Table/{index.d.ts → index.ts} +1 -0
  22. package/src/lib/components/Page/{index.d.ts → index.ts} +1 -0
  23. package/src/lib/components/Widget/AddButton/AddButton.tsx +16 -0
  24. package/src/lib/components/Widget/AddButton/{index.d.ts → index.ts} +1 -0
  25. package/src/lib/components/Widget/Form/ItemsAccordian.tsx +354 -0
  26. package/src/lib/components/Widget/Form/Tabs/TabItem.tsx +43 -0
  27. package/src/lib/components/Widget/Form/Tabs/Tabs.tsx +190 -0
  28. package/src/lib/components/Widget/Form/Tabs/{index.d.ts → index.ts} +1 -0
  29. package/src/lib/components/Widget/Form/WidgetForm.tsx +771 -0
  30. package/src/lib/components/Widget/Form/{index.d.ts → index.ts} +1 -0
  31. package/src/lib/components/Widget/Pagination/WidgetPagination.tsx +26 -0
  32. package/src/lib/components/Widget/Pagination/{index.d.ts → index.ts} +1 -0
  33. package/src/lib/components/Widget/Search/WidgetSearch.tsx +32 -0
  34. package/src/lib/components/Widget/Search/{index.d.ts → index.tsx} +1 -0
  35. package/src/lib/components/Widget/Table/WidgetTable.tsx +70 -0
  36. package/src/lib/components/Widget/Table/{index.d.ts → index.ts} +1 -0
  37. package/src/lib/components/Widget/Widget/Widget.tsx +173 -0
  38. package/src/lib/components/Widget/Widget/{index.d.ts → index.ts} +1 -0
  39. package/src/lib/components/Widget/WidgetFormActions/WidgetFormActions.tsx +50 -0
  40. package/src/lib/components/Widget/WidgetFormActions/{index.d.ts → index.ts} +1 -0
  41. package/src/lib/components/Widget/WidgetFormWrapper/WidgetFormWrapper.tsx +16 -0
  42. package/src/lib/components/Widget/WidgetFormWrapper/{index.d.ts → index.ts} +1 -0
  43. package/src/lib/components/Widget/{index.d.ts → index.tsx} +1 -0
  44. package/src/lib/components/common/Accordian/Accordian.tsx +56 -0
  45. package/src/lib/components/common/Accordian/{index.d.ts → index.ts} +1 -0
  46. package/src/lib/components/common/Button/Button.tsx +45 -0
  47. package/src/lib/components/common/Button/{index.d.ts → index.ts} +1 -0
  48. package/src/lib/components/common/ConfirmPopover/ConfirmPopover.tsx +47 -0
  49. package/src/lib/components/common/ConfirmPopover/{index.d.ts → index.ts} +1 -0
  50. package/src/lib/components/common/DNDItemsList/DNDItemsList.tsx +77 -0
  51. package/src/lib/components/common/DNDItemsList/{index.d.ts → index.ts} +1 -0
  52. package/src/lib/components/common/DeleteModal/DeleteModal.tsx +72 -0
  53. package/src/lib/components/common/DeleteModal/index.tsx +3 -0
  54. package/src/lib/components/common/Drawer/Drawer.tsx +79 -0
  55. package/src/lib/components/common/Drawer/{index.d.ts → index.ts} +1 -0
  56. package/src/lib/components/common/Form/Form.tsx +256 -0
  57. package/src/lib/components/common/Form/SimpleForm.tsx +314 -0
  58. package/src/lib/components/common/Form/{index.d.ts → index.ts} +1 -0
  59. package/src/lib/components/common/FormActions/FormActions.tsx +37 -0
  60. package/src/lib/components/common/FormActions/{index.d.ts → index.ts} +1 -0
  61. package/src/lib/components/common/ImageUpload/ImageUpload.tsx +113 -0
  62. package/src/lib/components/common/ImageUpload/index.tsx +3 -0
  63. package/src/lib/components/common/Input/Checkbox.tsx +25 -0
  64. package/src/lib/components/common/Input/Input.tsx +51 -0
  65. package/src/lib/components/common/Input/ReactSelect.tsx +61 -0
  66. package/src/lib/components/common/Input/Select.tsx +47 -0
  67. package/src/lib/components/common/Input/SrcSet.tsx +143 -0
  68. package/src/lib/components/common/Input/index.ts +20 -0
  69. package/src/lib/components/common/Modal/Modal.tsx +57 -0
  70. package/src/lib/components/common/Modal/index.tsx +3 -0
  71. package/src/lib/components/common/Pagination/Pagination.tsx +88 -0
  72. package/src/lib/components/common/Pagination/{index.d.ts → index.ts} +1 -0
  73. package/src/lib/components/common/Table/Table.tsx +133 -0
  74. package/src/lib/components/common/Table/{index.d.ts → index.ts} +1 -0
  75. package/src/lib/components/common/Toggle/Toggle.tsx +23 -0
  76. package/src/lib/components/common/Toggle/{index.d.ts → index.ts} +1 -0
  77. package/src/lib/constants/common.ts +145 -0
  78. package/src/lib/context/PageContext.tsx +100 -0
  79. package/src/lib/context/ProviderContext.tsx +52 -0
  80. package/src/lib/context/WidgetContext.tsx +127 -0
  81. package/src/lib/helper/utils.ts +46 -0
  82. package/src/lib/hooks/usePage.tsx +306 -0
  83. package/src/lib/hooks/usePagination.tsx +41 -0
  84. package/src/lib/hooks/useWidget.tsx +503 -0
  85. package/src/lib/icons/chevronDown.tsx +21 -0
  86. package/src/lib/icons/chevronLeft.tsx +20 -0
  87. package/src/lib/icons/chevronRight.tsx +20 -0
  88. package/src/lib/icons/chevronUp.tsx +21 -0
  89. package/src/lib/icons/close.tsx +21 -0
  90. package/src/lib/icons/pencil.tsx +21 -0
  91. package/src/lib/icons/plus.tsx +23 -0
  92. package/src/lib/icons/settings.tsx +35 -0
  93. package/src/lib/icons/trash.tsx +21 -0
  94. package/src/lib/types/api.ts +44 -0
  95. package/src/lib/types/common.ts +31 -0
  96. package/src/lib/types/components.ts +428 -0
  97. package/src/lib/types/context.ts +184 -0
  98. package/src/styles/index.css +481 -0
  99. package/index.cjs +0 -7714
  100. package/index.css +0 -2
  101. package/index.js +0 -7700
  102. package/src/lib/api/index.d.ts +0 -10
  103. package/src/lib/api/list.d.ts +0 -56
  104. package/src/lib/components/Page/AddButton/AddButton.d.ts +0 -3
  105. package/src/lib/components/Page/Form/PageForm.d.ts +0 -4
  106. package/src/lib/components/Page/Page/Page.d.ts +0 -13
  107. package/src/lib/components/Page/PageFormActions/PageFormActions.d.ts +0 -4
  108. package/src/lib/components/Page/PageFormWrapper/PageFormWrapper.d.ts +0 -4
  109. package/src/lib/components/Page/Pagination/PagePagination.d.ts +0 -3
  110. package/src/lib/components/Page/Search/PageSearch.d.ts +0 -3
  111. package/src/lib/components/Page/Table/PageTable.d.ts +0 -4
  112. package/src/lib/components/Widget/AddButton/AddButton.d.ts +0 -3
  113. package/src/lib/components/Widget/Form/ItemsAccordian.d.ts +0 -4
  114. package/src/lib/components/Widget/Form/Tabs/TabItem.d.ts +0 -4
  115. package/src/lib/components/Widget/Form/Tabs/Tabs.d.ts +0 -4
  116. package/src/lib/components/Widget/Form/WidgetForm.d.ts +0 -4
  117. package/src/lib/components/Widget/Pagination/WidgetPagination.d.ts +0 -3
  118. package/src/lib/components/Widget/Search/WidgetSearch.d.ts +0 -3
  119. package/src/lib/components/Widget/Table/WidgetTable.d.ts +0 -4
  120. package/src/lib/components/Widget/Widget/Widget.d.ts +0 -13
  121. package/src/lib/components/Widget/WidgetFormActions/WidgetFormActions.d.ts +0 -4
  122. package/src/lib/components/Widget/WidgetFormWrapper/WidgetFormWrapper.d.ts +0 -4
  123. package/src/lib/components/common/Accordian/Accordian.d.ts +0 -13
  124. package/src/lib/components/common/Button/Button.d.ts +0 -4
  125. package/src/lib/components/common/ConfirmPopover/ConfirmPopover.d.ts +0 -4
  126. package/src/lib/components/common/DNDItemsList/DNDItemsList.d.ts +0 -4
  127. package/src/lib/components/common/DeleteModal/DeleteModal.d.ts +0 -4
  128. package/src/lib/components/common/DeleteModal/index.d.ts +0 -2
  129. package/src/lib/components/common/Drawer/Drawer.d.ts +0 -9
  130. package/src/lib/components/common/Form/Form.d.ts +0 -15
  131. package/src/lib/components/common/Form/SimpleForm.d.ts +0 -18
  132. package/src/lib/components/common/FormActions/FormActions.d.ts +0 -10
  133. package/src/lib/components/common/ImageUpload/ImageUpload.d.ts +0 -4
  134. package/src/lib/components/common/ImageUpload/index.d.ts +0 -2
  135. package/src/lib/components/common/Input/Checkbox.d.ts +0 -4
  136. package/src/lib/components/common/Input/Input.d.ts +0 -4
  137. package/src/lib/components/common/Input/ReactSelect.d.ts +0 -4
  138. package/src/lib/components/common/Input/Select.d.ts +0 -4
  139. package/src/lib/components/common/Input/SrcSet.d.ts +0 -4
  140. package/src/lib/components/common/Input/index.d.ts +0 -12
  141. package/src/lib/components/common/Modal/Modal.d.ts +0 -8
  142. package/src/lib/components/common/Modal/index.d.ts +0 -2
  143. package/src/lib/components/common/Pagination/Pagination.d.ts +0 -4
  144. package/src/lib/components/common/Table/Table.d.ts +0 -4
  145. package/src/lib/components/common/Toggle/Toggle.d.ts +0 -4
  146. package/src/lib/constants/common.d.ts +0 -122
  147. package/src/lib/context/PageContext.d.ts +0 -7
  148. package/src/lib/context/ProviderContext.d.ts +0 -5
  149. package/src/lib/context/WidgetContext.d.ts +0 -7
  150. package/src/lib/helper/utils.d.ts +0 -10
  151. package/src/lib/hooks/usePage.d.ts +0 -43
  152. package/src/lib/hooks/usePagination.d.ts +0 -15
  153. package/src/lib/hooks/useWidget.d.ts +0 -46
  154. package/src/lib/icons/chevronDown.d.ts +0 -4
  155. package/src/lib/icons/chevronLeft.d.ts +0 -4
  156. package/src/lib/icons/chevronRight.d.ts +0 -4
  157. package/src/lib/icons/chevronUp.d.ts +0 -4
  158. package/src/lib/icons/close.d.ts +0 -4
  159. package/src/lib/icons/pencil.d.ts +0 -4
  160. package/src/lib/icons/plus.d.ts +0 -4
  161. package/src/lib/icons/trash.d.ts +0 -4
  162. package/src/lib/types/api.d.ts +0 -34
  163. package/src/lib/types/common.d.ts +0 -29
  164. package/src/lib/types/components.d.ts +0 -420
  165. package/src/lib/types/context.d.ts +0 -135
  166. /package/src/lib/types/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,771 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useForm } from 'react-hook-form';
3
+ import { DropResult } from 'react-beautiful-dnd';
4
+
5
+ import { SimpleForm } from '../../common/Form';
6
+ import DNDItemsList from '../../common/DNDItemsList';
7
+ import ItemsAccordian from './ItemsAccordian';
8
+
9
+ import { useWidgetState } from '../../../context/WidgetContext';
10
+ import { useProviderState } from '../../../context/ProviderContext';
11
+ import {
12
+ capitalizeFirstLetter,
13
+ changeToCode,
14
+ isEmpty,
15
+ } from '../../../helper/utils';
16
+ import {
17
+ CombineObjectType,
18
+ FormProps,
19
+ ObjectType,
20
+ OptionType,
21
+ SchemaType,
22
+ } from '../../../types';
23
+ import Tabs from './Tabs';
24
+
25
+ const constants = {
26
+ widgetTypeAccessor: 'widgetType',
27
+ itemTypeAccessor: 'itemsType',
28
+ collectionNameAccessor: 'collectionName',
29
+ collectionItemsAccessor: 'collectionItems',
30
+ tabsWidgetTypeValue: 'Tabs',
31
+ fixedCardWidgetTypeValue: 'FixedCard',
32
+ carouselWidgetTypeValue: 'Carousel',
33
+ imageItemsTypeValue: 'Image',
34
+ textWidgetTypeValue: 'Text',
35
+ htmlWidgetTypeValue: 'HTML',
36
+ tabsAccessor: 'tabs',
37
+ webItems: 'webItems',
38
+ mobileItems: 'mobileItems',
39
+ tabCollectionItemsAccessor: 'collectionItems',
40
+ };
41
+
42
+ const WidgetForm = ({ formRef, customInputs }: FormProps) => {
43
+ const {
44
+ register,
45
+ formState: { errors },
46
+ handleSubmit,
47
+ reset,
48
+ setValue,
49
+ control,
50
+ watch,
51
+ clearErrors,
52
+ setError,
53
+ getValues,
54
+ } = useForm({
55
+ shouldUnregister: false,
56
+ });
57
+ const { switchClass, commonTranslations } = useProviderState();
58
+ const {
59
+ data,
60
+ canAdd,
61
+ canUpdate,
62
+ formState,
63
+ itemsTypes,
64
+ widgetTypes,
65
+ loading,
66
+ languages,
67
+ widgetTranslations,
68
+ onWidgetFormSubmit,
69
+ getCollectionData,
70
+ collectionData,
71
+ collectionDataLoading,
72
+ formatListItem,
73
+ formatOptionLabel,
74
+ reactSelectStyles,
75
+ } = useWidgetState();
76
+ const callerRef = useRef<NodeJS.Timeout | null>(null);
77
+
78
+ const [activeTab, setActiveTab] = useState(0);
79
+ const [itemsEnabled, setItemsEnabled] = useState(true);
80
+ const [webItemsVisible, setWebItemsVisible] = useState(false);
81
+ const [mobileItemsVisible, setMobileItemsVisible] = useState(false);
82
+ const [selectedWidgetType, setSelectedWidgetType] = useState<any>();
83
+ const [selectedCollectionItems, setSelectedCollectionItems] = useState<
84
+ OptionType[]
85
+ >([]);
86
+ const [tabCollectionItems, setTabCollectionItems] = useState<any[]>([]);
87
+ const [selectedCollectionType, setSelectedCollectionType] = useState<
88
+ OptionType | undefined
89
+ >();
90
+ const [collectionItemsUpdated, setCollectionItemsUpdated] = useState(false);
91
+ const [tabCollectionItemsUpdated, setTabCollectionItemsUpdated] = useState<
92
+ boolean[]
93
+ >([]);
94
+
95
+ useEffect(() => {
96
+ if (data && formState === 'UPDATE') {
97
+ const widgetType = widgetTypes.find(
98
+ (type) => type.value === data?.widgetType
99
+ );
100
+ setSelectedWidgetType(widgetType);
101
+ if (
102
+ data?.itemsType !== constants.imageItemsTypeValue ||
103
+ data?.widgetType === constants.textWidgetTypeValue ||
104
+ data?.widgetType === constants.htmlWidgetTypeValue
105
+ ) {
106
+ setItemsEnabled(false);
107
+ }
108
+ if (
109
+ data?.collectionName !== constants.imageItemsTypeValue &&
110
+ itemsTypes &&
111
+ itemsTypes.length > 0
112
+ ) {
113
+ setSelectedCollectionType(
114
+ itemsTypes.find((item) => item.value === data?.collectionName)
115
+ );
116
+ }
117
+ if (
118
+ data?.widgetType === constants.textWidgetTypeValue ||
119
+ data?.widgetType === constants.htmlWidgetTypeValue
120
+ ) {
121
+ setItemsEnabled(false);
122
+ }
123
+ }
124
+ }, [data, formState, itemsTypes, widgetTypes]);
125
+
126
+ useEffect(() => {
127
+ if (formState === 'ADD') {
128
+ setSelectedCollectionItems([]);
129
+ setItemsEnabled(true);
130
+ setTabCollectionItems([]);
131
+ }
132
+ }, [formState]);
133
+
134
+ useEffect(() => {
135
+ if (!isEmpty(data)) {
136
+ reset(data);
137
+ }
138
+ }, [data, reset]);
139
+
140
+ const onChangeSearch = (
141
+ str?: string,
142
+ callback?: (options: OptionType[]) => void
143
+ ): any => {
144
+ let collectionItems: any[] = [];
145
+ let valueToSet = '';
146
+ if (formState === 'UPDATE') {
147
+ if (
148
+ data[constants.widgetTypeAccessor] === constants.tabsWidgetTypeValue
149
+ ) {
150
+ collectionItems = data[constants.tabsAccessor][activeTab]
151
+ ? data[constants.tabsAccessor][activeTab][
152
+ constants.collectionItemsAccessor
153
+ ]
154
+ : [];
155
+ valueToSet = `${constants.tabsAccessor}.${activeTab}.${constants.tabCollectionItemsAccessor}`;
156
+ } else if (
157
+ Array.isArray(data[constants.collectionItemsAccessor]) &&
158
+ data[constants.collectionItemsAccessor].length > 0
159
+ ) {
160
+ if (collectionItemsUpdated)
161
+ collectionItems = selectedCollectionItems.map(
162
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
163
+ // @ts-ignore
164
+ (collectionItem) => collectionItem._id
165
+ );
166
+ else collectionItems = data[constants.collectionItemsAccessor];
167
+ // valueToSet = constants.collectionItemsAccessor;
168
+ }
169
+ }
170
+ if (callerRef.current) clearTimeout(callerRef.current);
171
+ let item: any;
172
+
173
+ callerRef.current = setTimeout(() => {
174
+ if (selectedCollectionType)
175
+ getCollectionData(
176
+ selectedCollectionType.value,
177
+ str,
178
+ (options) => {
179
+ if (typeof callback === 'function')
180
+ callback(
181
+ options.map((item: ObjectType) => ({
182
+ value: item['_id'] || item['id'],
183
+ label: item['name'],
184
+ ...item,
185
+ }))
186
+ );
187
+ if (formState === 'UPDATE') {
188
+ let selectedOptions =
189
+ collectionItems?.map((itemId: string) => {
190
+ item = (options as any[]).find(
191
+ (item) => item._id === itemId || item.id === itemId
192
+ );
193
+ return item
194
+ ? {
195
+ label: item.name,
196
+ value: item._id || item.id,
197
+ ...item,
198
+ }
199
+ : {};
200
+ }) || [];
201
+ selectedOptions = selectedOptions.filter((obj) => !!obj.value);
202
+ if (valueToSet) {
203
+ // only set tabcollection items, when they are not set
204
+ if (!tabCollectionItemsUpdated[activeTab]) {
205
+ const updatedArr = tabCollectionItemsUpdated;
206
+ updatedArr[activeTab] = true;
207
+ setTabCollectionItemsUpdated(updatedArr);
208
+ setValue(valueToSet, selectedOptions);
209
+ }
210
+ } else {
211
+ setSelectedCollectionItems(selectedOptions);
212
+ setCollectionItemsUpdated(true);
213
+ }
214
+ }
215
+ },
216
+ collectionItems
217
+ );
218
+ }, 300);
219
+ };
220
+
221
+ // Form Utility Functions
222
+ function handleCapitalize(event: React.ChangeEvent<HTMLInputElement>) {
223
+ event.target.value = capitalizeFirstLetter(event.target.value);
224
+ return event;
225
+ }
226
+ function handleCode(event: React.ChangeEvent<HTMLInputElement>) {
227
+ event.target.value = changeToCode(event.target.value);
228
+ return event;
229
+ }
230
+ const getFirstItemTypeValue = useCallback(
231
+ (widgetType: string) => {
232
+ const derivedItemTypes =
233
+ widgetType === constants.tabsWidgetTypeValue
234
+ ? itemsTypes.filter(
235
+ (item) => item.label !== constants.imageItemsTypeValue
236
+ )
237
+ : itemsTypes;
238
+ const firstItemType = derivedItemTypes[0];
239
+ setValue(constants.itemTypeAccessor, firstItemType?.value);
240
+ return firstItemType;
241
+ },
242
+ [itemsTypes, setValue]
243
+ );
244
+
245
+
246
+ const getFirstWidgetTypeValue = useCallback(() => {
247
+ return widgetTypes[0].value;
248
+ }, [widgetTypes]);
249
+
250
+ // Widget Form Functions
251
+ const onWidgetFormInputChange = useCallback(
252
+ (value: ObjectType, name: string | undefined) => {
253
+ if (name === constants.widgetTypeAccessor) {
254
+ const widgetType = widgetTypes.find(
255
+ (type) => type.value === value[name]
256
+ );
257
+ setSelectedWidgetType(widgetType);
258
+
259
+ if (
260
+ widgetType?.value === constants.textWidgetTypeValue ||
261
+ widgetType?.value === constants.htmlWidgetTypeValue
262
+ ) {
263
+ setItemsEnabled(false);
264
+ } else {
265
+ setItemsEnabled(true);
266
+ }
267
+
268
+ if (
269
+ widgetType?.value === constants.carouselWidgetTypeValue ||
270
+ widgetType?.value === constants.fixedCardWidgetTypeValue
271
+ ) {
272
+ setValue(constants.itemTypeAccessor, "Image");
273
+ }
274
+
275
+ if (widgetType?.value === constants.tabsWidgetTypeValue) {
276
+ const firstItemType = getFirstItemTypeValue(value[name]);
277
+ if (firstItemType) {
278
+ setSelectedCollectionType(firstItemType);
279
+ }
280
+ setValue(constants.itemTypeAccessor, firstItemType?.value);
281
+ }
282
+ } else if (name === constants.itemTypeAccessor) {
283
+ if (
284
+ value[constants.itemTypeAccessor] === constants.imageItemsTypeValue
285
+ ) {
286
+ setSelectedCollectionType(undefined);
287
+ setItemsEnabled(true);
288
+ } else {
289
+ const selectedWType = itemsTypes.find(
290
+ (wType) => wType.value === value[constants.itemTypeAccessor]
291
+ );
292
+ setSelectedCollectionType(selectedWType);
293
+ setItemsEnabled(false);
294
+ }
295
+ } else if (
296
+ name?.includes(constants.tabsAccessor) &&
297
+ Array.isArray(value[constants.tabsAccessor])
298
+ ) {
299
+ setTabCollectionItems(
300
+ (value[constants.tabsAccessor] as unknown as any[]).map(
301
+ (tabItem) => tabItem[constants.tabCollectionItemsAccessor]
302
+ )
303
+ );
304
+ }
305
+ },
306
+ [getFirstItemTypeValue, itemsTypes, setValue, widgetTypes, selectedCollectionType]
307
+ );
308
+ const validateTabs = (tabsData: any) => {
309
+ const isLanguagesProvided =
310
+ Array.isArray(languages) && languages.length > 0;
311
+ let isTabsValid = true;
312
+ if (Array.isArray(tabsData) && tabsData.length > 0) {
313
+ tabsData.forEach((tabItem: any, index: number) => {
314
+ if (isLanguagesProvided) {
315
+ languages.forEach((lang: any) => {
316
+ if (!tabItem.names[lang.code]) {
317
+ setError(`tabs.${index}.names.${lang.code}`, {
318
+ type: 'manual',
319
+ message: `${widgetTranslations.tabNameRequired} (${lang.name})`,
320
+ });
321
+ isTabsValid = false;
322
+ }
323
+ });
324
+ } else if (!tabItem.name) {
325
+ setError(`tabs.${index}.name`, {
326
+ type: 'manual',
327
+ message: widgetTranslations.tabNameRequired,
328
+ });
329
+ isTabsValid = false;
330
+ }
331
+ });
332
+ }
333
+ return isTabsValid;
334
+ };
335
+ const onFormSubmit = (data: CombineObjectType) => {
336
+ const formData = { ...data };
337
+ // setting widget type if undefined
338
+ if (!formData[constants.widgetTypeAccessor] && formState === 'ADD') {
339
+ formData[constants.widgetTypeAccessor] = getFirstWidgetTypeValue();
340
+ }
341
+ // setting tabs data if widgetType tab is selected
342
+ const tabsData = getValues(constants.tabsAccessor);
343
+ if (Array.isArray(tabsData) && tabsData.length > 0) {
344
+ const isTabsValid = validateTabs(tabsData);
345
+ if (!isTabsValid) return;
346
+ }
347
+ if (
348
+ Array.isArray(tabsData) &&
349
+ (formData[constants.widgetTypeAccessor] ===
350
+ constants.tabsWidgetTypeValue ||
351
+ formState === 'UPDATE')
352
+ ) {
353
+ formData[constants.tabsAccessor] = tabsData.map((tabItem) => ({
354
+ name: tabItem.name,
355
+ names: tabItem.names,
356
+ collectionItems: tabItem.collectionItems.map(
357
+ (item: string | OptionType) =>
358
+ typeof item == 'string' ? item : item.value
359
+ ),
360
+ }));
361
+ } else formData[constants.tabsAccessor] = [];
362
+ // setting items type if undefined
363
+ if (!formData[constants.itemTypeAccessor] && formState === 'ADD') {
364
+ formData[constants.itemTypeAccessor] = getFirstItemTypeValue(
365
+ formData[constants.widgetTypeAccessor] as string
366
+ )?.value;
367
+ }
368
+ // setting collectionName if widgetType is FixedCard or Carousel and FormState
369
+ if (
370
+ formData[constants.itemTypeAccessor] !== constants.imageItemsTypeValue &&
371
+ formState === 'ADD'
372
+ ) {
373
+ formData[constants.collectionNameAccessor] = selectedCollectionType
374
+ ? selectedCollectionType.value
375
+ : getFirstItemTypeValue(
376
+ formData[constants.widgetTypeAccessor] as string
377
+ )?.value;
378
+ }
379
+ // setting colleciton items if collectionItems are there
380
+ if (
381
+ Array.isArray(selectedCollectionItems) &&
382
+ selectedCollectionItems.length > 0
383
+ ) {
384
+ formData[constants.collectionItemsAccessor] = selectedCollectionItems.map(
385
+ (item) => item.value
386
+ );
387
+ }
388
+ let items = [
389
+ ...(getValues(constants.webItems) || []),
390
+ ...(getValues(constants.mobileItems) || []),
391
+ ];
392
+ items = items.map(({ _id, __v, widgetId, ...item }) => {
393
+ if (typeof item['imgs'] === 'object' && item['imgs']) {
394
+ Object.keys(item['imgs']).forEach((key) => {
395
+ if (item['imgs'][key] && item['imgs'][key]['_id']) {
396
+ item['imgs'][key] = item['imgs'][key]['_id'];
397
+ } else if (
398
+ typeof item['imgs'][key] !== 'string' ||
399
+ !item['imgs'][key]
400
+ ) {
401
+ delete item['imgs'][key];
402
+ }
403
+ });
404
+ }
405
+ if (item['img'] && item['img']['_id']) {
406
+ item['img'] = item['img']['_id'];
407
+ } else if (typeof item['img'] !== 'string' || !item['img']) {
408
+ delete item['img'];
409
+ }
410
+ return item;
411
+ });
412
+ onWidgetFormSubmit({
413
+ ...formData,
414
+ items,
415
+ });
416
+ };
417
+ const onCollectionIndexChange = (result: DropResult) => {
418
+ const { destination, source } = result;
419
+ if (destination) {
420
+ setSelectedCollectionItems((listData) => {
421
+ const temporaryData = [...listData];
422
+ const [selectedRow] = temporaryData.splice(source.index, 1);
423
+ temporaryData.splice(destination.index, 0, selectedRow);
424
+ return temporaryData;
425
+ });
426
+ }
427
+ };
428
+ const onTabItemsIndexChange = (index: number, result: DropResult) => {
429
+ const { destination, source } = result;
430
+ if (destination) {
431
+ const tabCollectionItems = getValues(`tabs.${index}.collectionItems`);
432
+ const temporaryData = [...tabCollectionItems];
433
+ const [selectedRow] = temporaryData.splice(source.index, 1);
434
+ temporaryData.splice(destination.index, 0, selectedRow);
435
+ setValue(`tabs.${index}.collectionItems`, temporaryData);
436
+ }
437
+ };
438
+
439
+ useEffect(() => {
440
+ const subscription = watch((value, { name }) =>
441
+ onWidgetFormInputChange(value, name)
442
+ );
443
+ return () => subscription.unsubscribe();
444
+ }, [watch, onWidgetFormInputChange]);
445
+
446
+ // Schemas
447
+ const widgetFormSchema: SchemaType[] = [
448
+ {
449
+ label: commonTranslations.name,
450
+ required: true,
451
+ accessor: 'name',
452
+ type: 'text',
453
+ placeholder: commonTranslations.namePlaceholder,
454
+ onInput: handleCapitalize,
455
+ validations: {
456
+ required: commonTranslations.nameRequired,
457
+ },
458
+ wrapperClassName: 'khb_grid-item-1of2 khb_padding-right-1 khb_align-top',
459
+ },
460
+ {
461
+ label: commonTranslations.code,
462
+ accessor: 'code',
463
+ required: true,
464
+ type: 'text',
465
+ onInput: handleCode,
466
+ editable: false,
467
+ placeholder: commonTranslations.codePlaceholder,
468
+ validations: {
469
+ required: commonTranslations.codeRequired,
470
+ },
471
+ wrapperClassName:
472
+ 'khb_grid-item-1of2 khb_padding-left-1 khb_align-top khb_margin-top-0',
473
+ },
474
+ Array.isArray(languages) && languages.length > 0
475
+ ? {
476
+ label: commonTranslations.title,
477
+ accessor: 'widgetTitles',
478
+ required: false,
479
+ type:
480
+ customInputs && customInputs['widgetTitles'] ? undefined : 'text',
481
+ info: widgetTranslations.widgetTitleInfo,
482
+ placeholder: commonTranslations.titlePlaceholder,
483
+ onInput: handleCapitalize,
484
+ Input:
485
+ customInputs && customInputs['widgetTitles']
486
+ ? customInputs['widgetTitles']
487
+ : undefined,
488
+ }
489
+ : {
490
+ label: commonTranslations.title,
491
+ accessor: 'widgetTitle',
492
+ required: true,
493
+ type:
494
+ customInputs && customInputs['widgetTitle'] ? undefined : 'text',
495
+ onInput: handleCapitalize,
496
+ placeholder: commonTranslations.titlePlaceholder,
497
+ validations: {
498
+ required: commonTranslations.titleRequired,
499
+ },
500
+ info: widgetTranslations.widgetTitleInfo,
501
+ Input:
502
+ customInputs && customInputs['widgetTitle']
503
+ ? customInputs['widgetTitle']
504
+ : undefined,
505
+ },
506
+ {
507
+ label: widgetTranslations.widgetType,
508
+ required: true,
509
+ editable: false,
510
+ accessor: constants.widgetTypeAccessor,
511
+ type: 'select',
512
+ validations: {
513
+ required: widgetTranslations.widgetTypeRequired,
514
+ },
515
+ options: widgetTypes,
516
+ },
517
+ {
518
+ label: widgetTranslations.autoPlay,
519
+ accessor: 'autoPlay',
520
+ type: 'checkbox',
521
+ show: selectedWidgetType?.value === constants.carouselWidgetTypeValue,
522
+ switchClass: switchClass,
523
+ },
524
+ {
525
+ label: widgetTranslations.textContent,
526
+ accessor: 'textContent',
527
+ required: selectedWidgetType?.value === constants.textWidgetTypeValue,
528
+ type: customInputs && customInputs['textContent'] ? undefined : 'text',
529
+ placeholder: widgetTranslations.textContentPlaceholder,
530
+ validations: {
531
+ required: widgetTranslations.textContentRequired,
532
+ },
533
+ info: widgetTranslations.textContentInfo,
534
+ show: selectedWidgetType?.value === constants.textWidgetTypeValue,
535
+ Input:
536
+ customInputs && customInputs['textContent']
537
+ ? customInputs['textContent']
538
+ : undefined,
539
+ },
540
+ {
541
+ label: widgetTranslations.htmlContent,
542
+ accessor: 'htmlContent',
543
+ required: selectedWidgetType?.value === constants.htmlWidgetTypeValue,
544
+ type:
545
+ customInputs && customInputs['htmlContent'] ? undefined : 'textarea',
546
+ placeholder: widgetTranslations.htmlContentPlaceholder,
547
+ validations: {
548
+ required: widgetTranslations.htmlContentRequired,
549
+ },
550
+ show: selectedWidgetType?.value === constants.htmlWidgetTypeValue,
551
+ Input:
552
+ customInputs && customInputs['htmlContent']
553
+ ? customInputs['htmlContent']
554
+ : undefined,
555
+ },
556
+ {
557
+ label: widgetTranslations.itemsType,
558
+ required: true,
559
+ editable: false,
560
+ show:
561
+ selectedWidgetType?.value !== constants.textWidgetTypeValue &&
562
+ selectedWidgetType?.value !== constants.htmlWidgetTypeValue,
563
+ accessor: constants.itemTypeAccessor,
564
+ type: 'select',
565
+ validations: {
566
+ required: widgetTranslations.itemsTypePlaceholder,
567
+ },
568
+ options:
569
+ selectedWidgetType?.value === constants.tabsWidgetTypeValue ||
570
+ selectedWidgetType?.collectionsOnly
571
+ ? itemsTypes.filter(
572
+ (item) => item.label !== constants.imageItemsTypeValue
573
+ )
574
+ : selectedWidgetType?.imageOnly
575
+ ? itemsTypes.filter(
576
+ (item) => item.label === constants.imageItemsTypeValue
577
+ )
578
+ : itemsTypes,
579
+ },
580
+ {
581
+ label: widgetTranslations.color,
582
+ accessor: 'backgroundColor',
583
+ type: 'color',
584
+ className: 'khb_input-color',
585
+ },
586
+ {
587
+ label: widgetTranslations.webPerRow,
588
+ accessor: 'webPerRow',
589
+ type: 'number',
590
+ show:
591
+ selectedWidgetType?.value !== constants.textWidgetTypeValue &&
592
+ selectedWidgetType?.value !== constants.htmlWidgetTypeValue,
593
+ required: true,
594
+ placeholder: widgetTranslations.webPerRowPlaceholder,
595
+ wrapperClassName: 'khb_grid-item-1of3 khb_padding-right-1',
596
+ validations: {
597
+ required: widgetTranslations.webPerRowRequired,
598
+ min: {
599
+ value: 1,
600
+ message: widgetTranslations.minPerRow,
601
+ },
602
+ },
603
+ },
604
+ {
605
+ label: widgetTranslations.tabletPerRow,
606
+ accessor: 'tabletPerRow',
607
+ type: 'number',
608
+ show:
609
+ selectedWidgetType?.value !== constants.textWidgetTypeValue &&
610
+ selectedWidgetType?.value !== constants.htmlWidgetTypeValue,
611
+ required: true,
612
+ placeholder: widgetTranslations.tabletPerRowPlaceholder,
613
+ wrapperClassName: 'khb_grid-item-1of3 khb_padding-left-1',
614
+ validations: {
615
+ required: widgetTranslations.tabletPerRowRequired,
616
+ min: {
617
+ value: 1,
618
+ message: widgetTranslations.minPerRow,
619
+ },
620
+ },
621
+ },
622
+ {
623
+ label: widgetTranslations.mobilePerRow,
624
+ accessor: 'mobilePerRow',
625
+ type: 'number',
626
+ show:
627
+ selectedWidgetType?.value !== 'Text' &&
628
+ selectedWidgetType?.value !== 'HTML',
629
+ required: true,
630
+ placeholder: widgetTranslations.mobilePerRowPlaceholder,
631
+ wrapperClassName:
632
+ 'khb_grid-item-1of3 khb_padding-right-1 khb_padding-left-1',
633
+ validations: {
634
+ required: widgetTranslations.mobilePerRowRequired,
635
+ min: {
636
+ value: 1,
637
+ message: widgetTranslations.minPerRow,
638
+ },
639
+ },
640
+ },
641
+ {
642
+ label: selectedCollectionType?.label,
643
+ placeholder: `Select ${selectedCollectionType?.label}...`,
644
+ accessor: constants.collectionItemsAccessor,
645
+ type: 'ReactSelect',
646
+ options: collectionData,
647
+ selectedOptions: selectedCollectionItems,
648
+ isMulti: true,
649
+ isSearchable: true,
650
+ onChange: setSelectedCollectionItems,
651
+ loadOptions: onChangeSearch,
652
+ isLoading: collectionDataLoading,
653
+ show:
654
+ !itemsEnabled &&
655
+ (selectedWidgetType?.value === constants.carouselWidgetTypeValue ||
656
+ selectedWidgetType?.value === constants.fixedCardWidgetTypeValue || !selectedWidgetType) && !!selectedCollectionType?.value,
657
+ formatOptionLabel: formatOptionLabel,
658
+ listCode: selectedCollectionType?.value,
659
+ customStyles: reactSelectStyles || {},
660
+ selectKey: selectedCollectionType?.value,
661
+ },
662
+ ];
663
+
664
+ if (!canAdd || !canUpdate) return null;
665
+ return (
666
+ <div className="khb_form">
667
+ <SimpleForm
668
+ schema={widgetFormSchema}
669
+ onSubmit={onFormSubmit}
670
+ ref={formRef}
671
+ isUpdating={formState === 'UPDATE'}
672
+ register={register}
673
+ errors={errors}
674
+ handleSubmit={handleSubmit}
675
+ setValue={setValue}
676
+ control={control}
677
+ setError={setError}
678
+ languages={languages}
679
+ />
680
+
681
+ {selectedWidgetType?.value === constants.tabsWidgetTypeValue ? (
682
+ <Tabs
683
+ clearErrors={clearErrors}
684
+ getValues={getValues}
685
+ setValue={setValue}
686
+ control={control}
687
+ languages={languages}
688
+ deleteTitle={widgetTranslations.tabDeleteTitle}
689
+ yesButtonText={commonTranslations.yes}
690
+ noButtonText={commonTranslations.cancel}
691
+ errors={errors}
692
+ itemsPlaceholder={`Select ${selectedCollectionType?.label}...`}
693
+ loadOptions={onChangeSearch}
694
+ isItemsLoading={collectionDataLoading}
695
+ formatOptionLabel={formatOptionLabel}
696
+ listCode={selectedCollectionType?.value || ''}
697
+ onCollectionItemsIndexChange={onTabItemsIndexChange}
698
+ tabCollectionItems={tabCollectionItems}
699
+ formatItem={formatListItem}
700
+ customStyles={reactSelectStyles || {}}
701
+ activeTab={activeTab}
702
+ setActiveTab={setActiveTab}
703
+ />
704
+ ) : null}
705
+
706
+ {!itemsEnabled &&
707
+ selectedWidgetType?.value !== constants.tabsWidgetTypeValue && (
708
+ <DNDItemsList
709
+ items={selectedCollectionItems}
710
+ onDragEnd={onCollectionIndexChange}
711
+ formatItem={formatListItem}
712
+ listCode={selectedCollectionType?.value}
713
+ />
714
+ )}
715
+
716
+ {itemsEnabled &&
717
+ (selectedCollectionType === undefined ||
718
+ selectedWidgetType.value === 'Carousel' ||
719
+ selectedWidgetType.value === 'FixedCard') && (
720
+ <>
721
+ {/* Web Items */}
722
+ <ItemsAccordian
723
+ languages={languages}
724
+ clearError={clearErrors}
725
+ collapseId={constants.webItems}
726
+ title={widgetTranslations.webItems}
727
+ id={constants.webItems}
728
+ setError={setError}
729
+ show={
730
+ webItemsVisible || !!(errors && errors?.[constants.webItems])
731
+ }
732
+ toggleShow={setWebItemsVisible}
733
+ itemType="Web"
734
+ name={constants.webItems}
735
+ errors={errors}
736
+ control={control}
737
+ register={register}
738
+ loading={loading}
739
+ addText={commonTranslations.add}
740
+ deleteText={commonTranslations.delete}
741
+ />
742
+
743
+ {/* Mobile Items */}
744
+ <ItemsAccordian
745
+ languages={languages}
746
+ clearError={clearErrors}
747
+ collapseId={constants.mobileItems}
748
+ title={widgetTranslations.mobileItems}
749
+ id={constants.mobileItems}
750
+ name={constants.mobileItems}
751
+ setError={setError}
752
+ loading={loading}
753
+ show={
754
+ mobileItemsVisible ||
755
+ !!(errors && errors?.[constants.mobileItems])
756
+ }
757
+ toggleShow={setMobileItemsVisible}
758
+ itemType="Mobile"
759
+ errors={errors}
760
+ control={control}
761
+ register={register}
762
+ addText={commonTranslations.add}
763
+ deleteText={commonTranslations.delete}
764
+ />
765
+ </>
766
+ )}
767
+ </div>
768
+ );
769
+ };
770
+
771
+ export default WidgetForm;