@flozy/editor 11.2.2 → 11.2.4

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 (145) hide show
  1. package/dist/Editor/ChatEditor.js +7 -7
  2. package/dist/Editor/CommonEditor.js +86 -24
  3. package/dist/Editor/DialogWrapper.js +31 -25
  4. package/dist/Editor/Editor.css +37 -4
  5. package/dist/Editor/Elements/AI/PopoverAIInput.js +11 -3
  6. package/dist/Editor/Elements/AppHeader/AppHeader.js +3 -3
  7. package/dist/Editor/Elements/Attachments/AttachmentStyles.js +16 -0
  8. package/dist/Editor/Elements/Attachments/Attachments.js +239 -11
  9. package/dist/Editor/Elements/Attachments/AttachmentsButton.js +11 -4
  10. package/dist/Editor/Elements/Button/EditorButton.js +22 -7
  11. package/dist/Editor/Elements/Color Picker/ColorButtons.js +61 -14
  12. package/dist/Editor/Elements/Color Picker/ColorPicker.css +25 -1
  13. package/dist/Editor/Elements/Color Picker/ColorPicker.js +10 -7
  14. package/dist/Editor/Elements/Color Picker/Styles.js +15 -13
  15. package/dist/Editor/Elements/DataView/Layouts/DataTypes/Components/Select.js +134 -55
  16. package/dist/Editor/Elements/DataView/Layouts/DataTypes/Components/SelectV1.js +7 -8
  17. package/dist/Editor/Elements/DataView/Layouts/DataTypes/PersonType.js +8 -3
  18. package/dist/Editor/Elements/DataView/Layouts/Options/EditProperty.js +1 -1
  19. package/dist/Editor/Elements/DataView/Layouts/TableStyles.js +1 -1
  20. package/dist/Editor/Elements/Embed/Embed.js +37 -43
  21. package/dist/Editor/Elements/Embed/Image.js +307 -26
  22. package/dist/Editor/Elements/Embed/Video.js +355 -35
  23. package/dist/Editor/Elements/EmbedScript/EmbedScriptPopup.js +9 -6
  24. package/dist/Editor/Elements/EmbedScript/styles.js +17 -1
  25. package/dist/Editor/Elements/Form/FormField.js +1 -1
  26. package/dist/Editor/Elements/Form/Workflow/Styles.js +25 -22
  27. package/dist/Editor/Elements/Form/Workflow/constant.js +25 -1
  28. package/dist/Editor/Elements/FreeGrid/FreeGrid.js +37 -76
  29. package/dist/Editor/Elements/FreeGrid/FreeGridBox.js +9 -5
  30. package/dist/Editor/Elements/FreeGrid/FreeGridItem.js +3 -1
  31. package/dist/Editor/Elements/FreeGrid/helper.js +194 -0
  32. package/dist/Editor/Elements/FreeGrid/styles.js +15 -0
  33. package/dist/Editor/Elements/Grid/GridItem.js +1 -1
  34. package/dist/Editor/Elements/PageSettings/PageSettingsButton.js +2 -1
  35. package/dist/Editor/Elements/Table/Table.js +2 -1
  36. package/dist/Editor/Elements/Table/TableCell.js +10 -3
  37. package/dist/Editor/Elements/Title/title.js +4 -5
  38. package/dist/Editor/Elements/TopBanner/TopBanner.js +4 -2
  39. package/dist/Editor/Elements/TopBanner/TopBannerButton.js +5 -3
  40. package/dist/Editor/Styles/EditorStyles.js +19 -5
  41. package/dist/Editor/Toolbar/FormatTools/Dropdown.js +27 -3
  42. package/dist/Editor/Toolbar/FormatTools/FontFamilyAutocomplete.js +4 -3
  43. package/dist/Editor/Toolbar/FormatTools/MarkButton.js +2 -2
  44. package/dist/Editor/Toolbar/FormatTools/TextSize.js +33 -29
  45. package/dist/Editor/Toolbar/Mini/MiniToolbar.js +2 -1
  46. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/MiniColorPicker.js +3 -1
  47. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectFontSize.js +25 -23
  48. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectTypography.js +167 -42
  49. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/index.js +15 -5
  50. package/dist/Editor/Toolbar/PopupTool/PopperHeader.js +2 -1
  51. package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +65 -7
  52. package/dist/Editor/Toolbar/PopupTool/TextFormat.js +66 -12
  53. package/dist/Editor/Toolbar/PopupTool/ThemeTextFormat.js +439 -0
  54. package/dist/Editor/Toolbar/PopupTool/index.js +6 -4
  55. package/dist/Editor/Toolbar/toolbarGroups.js +48 -6
  56. package/dist/Editor/assets/svg/BackIcon.js +18 -0
  57. package/dist/Editor/assets/svg/ThemeIcons.js +293 -0
  58. package/dist/Editor/common/ColorPickerButton.js +38 -19
  59. package/dist/Editor/common/CustomColorPicker/index.js +130 -0
  60. package/dist/Editor/common/CustomColorPicker/style.js +53 -0
  61. package/dist/Editor/common/CustomDialog2/index.js +94 -0
  62. package/dist/Editor/common/CustomDialog2/style.js +67 -0
  63. package/dist/Editor/common/CustomSelect.js +43 -0
  64. package/dist/Editor/common/DnD/DragHandleButton.js +1 -1
  65. package/dist/Editor/common/FontLoader/FontLoader.js +1 -0
  66. package/dist/Editor/common/Icon.js +28 -0
  67. package/dist/Editor/common/ImageSelector/ImageSelector.js +66 -13
  68. package/dist/Editor/common/ImageSelector/Options/ChooseAssets.js +1 -1
  69. package/dist/Editor/common/ImageSelector/Options/RecentUploads.js +483 -0
  70. package/dist/Editor/common/ImageSelector/Options/Upload.js +26 -11
  71. package/dist/Editor/common/ImageSelector/Styles.js +3 -9
  72. package/dist/Editor/common/RnD/ElementSettings/OtherSettings/Settings.js +2 -1
  73. package/dist/Editor/common/RnD/ElementSettings/Settings/AppHeaderSettings.js +3 -2
  74. package/dist/Editor/common/RnD/ElementSettings/Settings/BoxSettings.js +3 -2
  75. package/dist/Editor/common/RnD/ElementSettings/Settings/ButtonSettings.js +3 -2
  76. package/dist/Editor/common/RnD/ElementSettings/Settings/CodeSettings.js +3 -2
  77. package/dist/Editor/common/RnD/ElementSettings/Settings/FormSettings.js +3 -2
  78. package/dist/Editor/common/RnD/ElementSettings/Settings/ImageSettings.js +20 -7
  79. package/dist/Editor/common/RnD/ElementSettings/Settings/TableSettings.js +3 -2
  80. package/dist/Editor/common/RnD/ElementSettings/Settings/TextSettings.js +2 -0
  81. package/dist/Editor/common/RnD/ElementSettings/Settings/VideoSettings.js +20 -7
  82. package/dist/Editor/common/RnD/GuideLines/styles.js +1 -1
  83. package/dist/Editor/common/RnD/Theme/MainThemeProvider.js +17 -0
  84. package/dist/Editor/common/RnD/Theme/ViewportStimulator.js +6 -3
  85. package/dist/Editor/common/RnD/Utils/gridDropItem.js +28 -11
  86. package/dist/Editor/common/RnD/Utils/index.js +3 -1
  87. package/dist/Editor/common/RnD/VirtualElement/VirtualTextElement.js +52 -63
  88. package/dist/Editor/common/RnD/VirtualElement/helper.js +248 -68
  89. package/dist/Editor/common/RnD/VirtualElement/styles.js +22 -0
  90. package/dist/Editor/common/RnD/index.js +61 -14
  91. package/dist/Editor/common/Shorthands/elements.js +55 -3
  92. package/dist/Editor/common/StyleBuilder/buttonStyle.js +4 -2
  93. package/dist/Editor/common/StyleBuilder/embedVideoStyle.js +4 -0
  94. package/dist/Editor/common/StyleBuilder/fieldStyle.js +1 -0
  95. package/dist/Editor/common/StyleBuilder/fieldTypes/backgroundImage.js +13 -3
  96. package/dist/Editor/common/StyleBuilder/fieldTypes/bannerSpacing.js +12 -2
  97. package/dist/Editor/common/StyleBuilder/fieldTypes/borderRadius.js +15 -7
  98. package/dist/Editor/common/StyleBuilder/fieldTypes/color.js +36 -10
  99. package/dist/Editor/common/StyleBuilder/fieldTypes/fontSize.js +13 -4
  100. package/dist/Editor/common/StyleBuilder/fieldTypes/menusArray.js +2 -0
  101. package/dist/Editor/common/StyleBuilder/fieldTypes/text.js +16 -4
  102. package/dist/Editor/common/StyleBuilder/fieldTypes/textOptions.js +15 -7
  103. package/dist/Editor/common/StyleBuilder/formStyle.js +19 -13
  104. package/dist/Editor/common/StyleBuilder/index.js +8 -4
  105. package/dist/Editor/common/Uploader.js +118 -17
  106. package/dist/Editor/common/UploaderWithProgress.js +183 -0
  107. package/dist/Editor/common/iconslist.js +21 -0
  108. package/dist/Editor/commonStyle.js +111 -53
  109. package/dist/Editor/helper/index.js +4 -1
  110. package/dist/Editor/helper/theme.js +203 -2
  111. package/dist/Editor/hooks/useEditorTheme.js +153 -0
  112. package/dist/Editor/hooks/useMouseMove.js +12 -3
  113. package/dist/Editor/hooks/useTable.js +62 -1
  114. package/dist/Editor/hooks/useThemeValues.js +63 -0
  115. package/dist/Editor/plugins/withEmbeds.js +1 -1
  116. package/dist/Editor/plugins/withHTML.js +56 -3
  117. package/dist/Editor/plugins/withTable.js +1 -1
  118. package/dist/Editor/service/fileTracking.js +22 -0
  119. package/dist/Editor/service/fileupload.js +77 -0
  120. package/dist/Editor/theme/ThemeList.js +50 -173
  121. package/dist/Editor/theme/index.js +149 -0
  122. package/dist/Editor/themeSettings/ActiveTheme.js +82 -0
  123. package/dist/Editor/themeSettings/buttons/index.js +300 -0
  124. package/dist/Editor/themeSettings/buttons/style.js +23 -0
  125. package/dist/Editor/themeSettings/colorTheme/index.js +310 -0
  126. package/dist/Editor/themeSettings/colorTheme/style.js +81 -0
  127. package/dist/Editor/themeSettings/fonts/PreviewElement.js +121 -0
  128. package/dist/Editor/themeSettings/fonts/index.js +240 -0
  129. package/dist/Editor/themeSettings/fonts/style.js +62 -0
  130. package/dist/Editor/themeSettings/icons.js +60 -0
  131. package/dist/Editor/themeSettings/index.js +380 -0
  132. package/dist/Editor/themeSettings/style.js +299 -0
  133. package/dist/Editor/themeSettingsAI/icons.js +96 -0
  134. package/dist/Editor/themeSettingsAI/index.js +355 -0
  135. package/dist/Editor/themeSettingsAI/saveTheme.js +202 -0
  136. package/dist/Editor/themeSettingsAI/style.js +332 -0
  137. package/dist/Editor/utils/SlateUtilityFunctions.js +165 -40
  138. package/dist/Editor/utils/accordion.js +1 -1
  139. package/dist/Editor/utils/attachments.js +138 -2
  140. package/dist/Editor/utils/button.js +1 -17
  141. package/dist/Editor/utils/font.js +40 -37
  142. package/dist/Editor/utils/formfield.js +2 -2
  143. package/dist/Editor/utils/helper.js +101 -3
  144. package/dist/Editor/utils/insertAppHeader.js +8 -4
  145. package/package.json +1 -1
@@ -0,0 +1,483 @@
1
+ import React, { useEffect, useState, useCallback, useRef, useMemo } from "react";
2
+ import { Box, Grid, Typography, CircularProgress, ImageListItem, ImageListItemBar, IconButton } from "@mui/material";
3
+ import CheckCircleIcon from '@mui/icons-material/CheckCircle';
4
+ import { useEditorContext } from "../../../hooks/useMouseMove";
5
+
6
+ // Memoized RecentItem component to prevent unnecessary re-renders
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { jsxs as _jsxs } from "react/jsx-runtime";
9
+ const RecentItem = /*#__PURE__*/React.memo(({
10
+ item,
11
+ iconRef,
12
+ onSelect,
13
+ theme
14
+ }) => {
15
+ // Simple lazy loading image component
16
+ const LazyImage = /*#__PURE__*/React.memo(({
17
+ src,
18
+ alt,
19
+ ...props
20
+ }) => {
21
+ const [isLoaded, setIsLoaded] = useState(false);
22
+ const [isInView, setIsInView] = useState(false);
23
+ const imgRef = useRef();
24
+ useEffect(() => {
25
+ const observer = new IntersectionObserver(([entry]) => {
26
+ if (entry.isIntersecting) {
27
+ setIsInView(true);
28
+ observer.disconnect();
29
+ }
30
+ }, {
31
+ threshold: 0.1
32
+ });
33
+ if (imgRef.current) {
34
+ observer.observe(imgRef.current);
35
+ }
36
+ return () => observer.disconnect();
37
+ }, []);
38
+ const {
39
+ sx,
40
+ ...restProps
41
+ } = props;
42
+ return /*#__PURE__*/_jsxs(Box, {
43
+ ref: imgRef,
44
+ ...restProps,
45
+ sx: {
46
+ ...sx,
47
+ position: 'relative',
48
+ overflow: 'hidden'
49
+ },
50
+ children: [isInView && /*#__PURE__*/_jsx(Box, {
51
+ component: "img",
52
+ src: src,
53
+ alt: alt,
54
+ onLoad: () => setIsLoaded(true),
55
+ sx: {
56
+ width: '100%',
57
+ height: '100%',
58
+ objectFit: sx?.objectFit || 'cover',
59
+ borderRadius: sx?.borderRadius || 0,
60
+ opacity: isLoaded ? 1 : 0,
61
+ transition: 'opacity 0.3s ease-in-out',
62
+ willChange: 'opacity'
63
+ }
64
+ }), !isLoaded && isInView && /*#__PURE__*/_jsx(Box, {
65
+ sx: {
66
+ position: 'absolute',
67
+ top: 0,
68
+ left: 0,
69
+ right: 0,
70
+ bottom: 0,
71
+ backgroundColor: 'grey.100',
72
+ display: 'flex',
73
+ alignItems: 'center',
74
+ justifyContent: 'center',
75
+ borderRadius: sx?.borderRadius || 0
76
+ },
77
+ children: /*#__PURE__*/_jsx(CircularProgress, {
78
+ size: 24
79
+ })
80
+ })]
81
+ });
82
+ }, (prevProps, nextProps) => {
83
+ // Only re-render if src changes
84
+ return prevProps.src === nextProps.src && prevProps.alt === nextProps.alt;
85
+ });
86
+ LazyImage.displayName = 'LazyImage';
87
+ return /*#__PURE__*/_jsx(Grid, {
88
+ item: true,
89
+ xs: 4,
90
+ sx: {
91
+ cursor: "pointer",
92
+ "&:hover": {
93
+ opacity: 0.8
94
+ }
95
+ },
96
+ children: /*#__PURE__*/_jsxs(ImageListItem, {
97
+ sx: {
98
+ padding: "2px",
99
+ overflow: "hidden"
100
+ },
101
+ children: [(item.type === "image" || item.category === "IMAGE") && /*#__PURE__*/_jsx(LazyImage, {
102
+ src: item.file_url || item.url,
103
+ alt: item.name,
104
+ sx: {
105
+ width: "100%",
106
+ height: 145,
107
+ objectFit: "cover",
108
+ borderRadius: 1
109
+ }
110
+ }), (item.type === "video" || item.category === "VIDEO") && /*#__PURE__*/_jsx(Box, {
111
+ component: "video",
112
+ src: item.file_url || item.url,
113
+ sx: {
114
+ width: "100%",
115
+ height: 145,
116
+ borderRadius: 1,
117
+ objectFit: "cover"
118
+ }
119
+ }), (item.type === "document" || item.category === "DOCUMENT") && /*#__PURE__*/_jsxs(Box, {
120
+ sx: {
121
+ p: 2,
122
+ border: 1,
123
+ borderColor: theme?.palette?.editor?.uploadFileBorder || "#F3F3F3",
124
+ borderRadius: 1,
125
+ textAlign: "center",
126
+ height: 145,
127
+ display: "flex",
128
+ flexDirection: "column",
129
+ alignItems: "center",
130
+ justifyContent: "center",
131
+ backgroundColor: theme?.palette?.editor?.uploadFileBg || "#F3F3F3"
132
+ },
133
+ children: [/*#__PURE__*/_jsx(Typography, {
134
+ sx: {
135
+ fontSize: "24px",
136
+ mb: 1,
137
+ color: theme?.palette?.editor?.textColor || "#000000"
138
+ },
139
+ children: "\uD83D\uDCC4"
140
+ }), /*#__PURE__*/_jsx(Typography, {
141
+ sx: {
142
+ fontSize: "12px",
143
+ fontWeight: 500,
144
+ color: theme?.palette?.editor?.textColor || "#000000",
145
+ textAlign: "center",
146
+ wordBreak: "break-word",
147
+ lineHeight: 1.2,
148
+ maxHeight: "60px",
149
+ overflow: "hidden",
150
+ display: "-webkit-box",
151
+ WebkitLineClamp: 3,
152
+ WebkitBoxOrient: "vertical"
153
+ },
154
+ children: item.name || 'Untitled Document'
155
+ })]
156
+ }), /*#__PURE__*/_jsx(ImageListItemBar, {
157
+ sx: {
158
+ background: "none",
159
+ "& .MuiImageListItemBar-actionIcon": {
160
+ position: "absolute",
161
+ top: 8,
162
+ right: 8,
163
+ zIndex: 1
164
+ }
165
+ },
166
+ position: "top",
167
+ actionPosition: "right",
168
+ actionIcon: /*#__PURE__*/_jsx(IconButton, {
169
+ onClick: e => {
170
+ e.stopPropagation();
171
+ onSelect(item);
172
+ },
173
+ sx: {
174
+ transition: 'none',
175
+ '&:hover': {
176
+ backgroundColor: 'transparent'
177
+ }
178
+ },
179
+ children: /*#__PURE__*/_jsx(CheckCircleIcon, {
180
+ ref: iconRef,
181
+ sx: {
182
+ color: "#ccc",
183
+ transition: 'color 0.15s ease-in-out',
184
+ willChange: 'color'
185
+ }
186
+ })
187
+ })
188
+ })]
189
+ })
190
+ });
191
+ }, (prevProps, nextProps) => {
192
+ // Strict comparison function for React.memo
193
+ // Return true if props are equal (don't re-render), false if different (re-render)
194
+ // Note: iconRef is ignored as it's stable and doesn't cause re-renders
195
+
196
+ // Compare item properties - use strict equality for object reference first
197
+ if (prevProps.item !== nextProps.item) {
198
+ // If item reference changed, check if properties are the same
199
+ if (prevProps.item.id !== nextProps.item.id || prevProps.item.file_url !== nextProps.item.file_url || prevProps.item.url !== nextProps.item.url || prevProps.item.name !== nextProps.item.name || prevProps.item.type !== nextProps.item.type || prevProps.item.category !== nextProps.item.category) {
200
+ return false; // Re-render needed
201
+ }
202
+ }
203
+
204
+ // Compare other props (iconRef is ignored as it's stable)
205
+ return prevProps.onSelect === nextProps.onSelect && prevProps.theme === nextProps.theme;
206
+ });
207
+ RecentItem.displayName = 'RecentItem';
208
+ const RecentUploads = ({
209
+ onUploaded,
210
+ customProps,
211
+ title
212
+ }) => {
213
+ const {
214
+ theme
215
+ } = useEditorContext();
216
+ // Memoize theme to prevent unnecessary re-renders if theme object reference changes
217
+ const stableTheme = useMemo(() => theme, [theme]);
218
+ const [recent, setRecent] = useState([]);
219
+ const [loading, setLoading] = useState(true);
220
+ const [loadingMore, setLoadingMore] = useState(false);
221
+ const [selectedUrl, setSelectedUrl] = useState(null);
222
+ const [pagination, setPagination] = useState({
223
+ total: 0,
224
+ limit: 20,
225
+ offset: 0
226
+ });
227
+ const observerRef = useRef();
228
+ const loadMoreRef = useRef();
229
+
230
+ // Use ref to track selected URL without causing re-renders for comparison
231
+ const selectedUrlRef = useRef(null);
232
+
233
+ // Ref map to track icon refs for each item URL - allows imperative updates without re-renders
234
+ const iconRefsMap = useRef(new Map());
235
+
236
+ // Memoize onUploaded callback to ensure it doesn't change
237
+ const stableOnUploaded = useCallback((url, source) => {
238
+ onUploaded(url, source);
239
+ }, [onUploaded]);
240
+
241
+ // Category mapping
242
+ const categoryMap = {
243
+ 'image': 'IMAGE',
244
+ 'video': 'VIDEO',
245
+ 'document': 'DOCUMENT'
246
+ };
247
+ const fetchRecent = useCallback(async (offset = 0, append = false) => {
248
+ try {
249
+ const category = categoryMap[title] || title.toLowerCase();
250
+
251
+ // Try main app service first, fallback to direct implementation
252
+ let res;
253
+ if (customProps.services && typeof customProps.services === 'function') {
254
+ try {
255
+ res = await customProps.services('getRecentUploads', {
256
+ category,
257
+ limit: pagination.limit,
258
+ offset
259
+ });
260
+ } catch (error) {
261
+ console.warn('Main app service failed, falling back to direct API call:', error);
262
+ }
263
+ }
264
+
265
+ // Handle validation errors from getRecentUploads
266
+ if (res && res.error) {
267
+ console.warn("Recent uploads validation error:", res.error);
268
+ if (!append) {
269
+ setRecent([]);
270
+ setPagination({
271
+ total: 0,
272
+ limit: 20,
273
+ offset: 0
274
+ });
275
+ }
276
+ } else if (res) {
277
+ // Handle both direct data array and nested data structure
278
+ const dataArray = res.data?.data || res.data || [];
279
+ const paginationData = res.data?.pagination || res.pagination || {
280
+ total: res.data?.total || res.total || 0,
281
+ limit: 20,
282
+ offset: 0,
283
+ hasMore: res.data?.hasMore || false
284
+ };
285
+ console.log("RecentUploads - Processing response:", {
286
+ res,
287
+ dataArray,
288
+ paginationData,
289
+ dataArrayLength: dataArray.length
290
+ });
291
+ if (append) {
292
+ setRecent(prev => [...prev, ...dataArray]);
293
+ } else {
294
+ setRecent(dataArray);
295
+ }
296
+ setPagination(paginationData);
297
+ }
298
+ } catch (err) {
299
+ console.error("Failed to fetch recent uploads", err);
300
+ if (!append) {
301
+ setRecent([]);
302
+ setPagination({
303
+ total: 0,
304
+ limit: 20,
305
+ offset: 0
306
+ });
307
+ }
308
+ }
309
+ }, [customProps, title, pagination.limit, categoryMap]);
310
+ const loadMore = useCallback(() => {
311
+ const hasMore = recent.length < pagination.total;
312
+ if (!loadingMore && hasMore) {
313
+ setLoadingMore(true);
314
+ fetchRecent(pagination.offset + pagination.limit, true).finally(() => {
315
+ setLoadingMore(false);
316
+ });
317
+ }
318
+ }, [loadingMore, recent.length, pagination.total, pagination.offset, pagination.limit, fetchRecent]);
319
+ useEffect(() => {
320
+ setLoading(true);
321
+ fetchRecent(0, false).finally(() => {
322
+ setLoading(false);
323
+ });
324
+ }, [customProps, title]);
325
+
326
+ // Intersection observer for infinite scroll
327
+ useEffect(() => {
328
+ if (observerRef.current) {
329
+ observerRef.current.disconnect();
330
+ }
331
+ const hasMore = recent.length < pagination.total;
332
+ observerRef.current = new IntersectionObserver(entries => {
333
+ if (entries[0].isIntersecting && hasMore && !loadingMore) {
334
+ loadMore();
335
+ }
336
+ }, {
337
+ threshold: 0.1
338
+ });
339
+ if (loadMoreRef.current) {
340
+ observerRef.current.observe(loadMoreRef.current);
341
+ }
342
+ return () => {
343
+ if (observerRef.current) {
344
+ observerRef.current.disconnect();
345
+ }
346
+ };
347
+ }, [recent.length, pagination.total, loadingMore, loadMore]);
348
+ const hasMoreContent = recent.length < pagination.total && !loadingMore;
349
+
350
+ // Memoize recent array reference - only recreate if length or item IDs change
351
+ // This ensures stableRecent only changes when items actually change
352
+ const recentKey = useMemo(() => {
353
+ return recent.length > 0 ? `${recent.length}-${recent.map(item => item.id).join('-')}` : 'empty';
354
+ }, [recent]);
355
+
356
+ // Stable recent array - only changes when items actually change
357
+ const stableRecent = useMemo(() => recent, [recentKey]);
358
+ const handleItemSelect = useCallback(item => {
359
+ const imgUrl = item.file_url || item.url;
360
+ const prevSelectedUrl = selectedUrlRef.current;
361
+
362
+ // Update previously selected icon to gray (if any)
363
+ if (prevSelectedUrl && prevSelectedUrl !== imgUrl) {
364
+ const prevIconRef = iconRefsMap.current.get(prevSelectedUrl);
365
+ if (prevIconRef?.current) {
366
+ prevIconRef.current.style.color = "#ccc";
367
+ }
368
+ }
369
+
370
+ // Update newly selected icon to blue
371
+ const newIconRef = iconRefsMap.current.get(imgUrl);
372
+ if (newIconRef?.current) {
373
+ newIconRef.current.style.color = "#2563eb";
374
+ }
375
+
376
+ // Update ref immediately
377
+ selectedUrlRef.current = imgUrl;
378
+
379
+ // Update state only for external tracking (doesn't cause re-renders of items)
380
+ setSelectedUrl(imgUrl);
381
+
382
+ // Immediately call onUploaded to enable the Save button
383
+ // Pass "recent" as the source to indicate this is from recent uploads
384
+ stableOnUploaded(imgUrl, "recent");
385
+ }, [stableOnUploaded]);
386
+
387
+ // Initialize icon refs when items change
388
+ useEffect(() => {
389
+ stableRecent.forEach(item => {
390
+ const imgUrl = item.file_url || item.url;
391
+ if (!iconRefsMap.current.has(imgUrl)) {
392
+ iconRefsMap.current.set(imgUrl, /*#__PURE__*/React.createRef());
393
+ }
394
+ });
395
+ }, [stableRecent]);
396
+
397
+ // Update icon colors when selection changes (without re-rendering components)
398
+ useEffect(() => {
399
+ iconRefsMap.current.forEach((iconRef, imgUrl) => {
400
+ if (iconRef?.current) {
401
+ iconRef.current.style.color = selectedUrl === imgUrl ? "#2563eb" : "#ccc";
402
+ }
403
+ });
404
+ }, [selectedUrl]);
405
+ if (loading) return /*#__PURE__*/_jsx(Box, {
406
+ sx: {
407
+ display: 'flex',
408
+ justifyContent: 'center',
409
+ mt: 2
410
+ },
411
+ children: /*#__PURE__*/_jsx(CircularProgress, {
412
+ size: 24,
413
+ sx: {
414
+ color: stableTheme?.palette?.editor?.activeColor || "#2563EB"
415
+ }
416
+ })
417
+ });
418
+ console.log("RecentUploads - Rendering state:", {
419
+ recent,
420
+ recentLength: recent.length,
421
+ pagination,
422
+ title,
423
+ selectedUrl
424
+ });
425
+ if (!recent.length) return /*#__PURE__*/_jsxs(Typography, {
426
+ sx: {
427
+ textAlign: "center",
428
+ mt: 2,
429
+ color: stableTheme?.palette?.editor?.textColor || "#000000",
430
+ fontSize: "14px",
431
+ fontWeight: 500
432
+ },
433
+ children: ["No recent ", title.toLowerCase(), " found."]
434
+ });
435
+ return /*#__PURE__*/_jsxs(Box, {
436
+ children: [/*#__PURE__*/_jsx(Grid, {
437
+ container: true,
438
+ spacing: 2,
439
+ sx: {
440
+ mt: 1
441
+ },
442
+ children: stableRecent.map(item => {
443
+ const imgUrl = item.file_url || item.url;
444
+ // Get or create ref (should already exist from useEffect, but fallback for safety)
445
+ if (!iconRefsMap.current.has(imgUrl)) {
446
+ iconRefsMap.current.set(imgUrl, /*#__PURE__*/React.createRef());
447
+ }
448
+ return /*#__PURE__*/_jsx(RecentItem, {
449
+ item: item,
450
+ iconRef: iconRefsMap.current.get(imgUrl),
451
+ onSelect: handleItemSelect,
452
+ theme: stableTheme
453
+ }, item.id);
454
+ })
455
+ }), hasMoreContent && /*#__PURE__*/_jsx(Box, {
456
+ ref: loadMoreRef,
457
+ sx: {
458
+ display: 'flex',
459
+ justifyContent: 'center',
460
+ mt: 2,
461
+ minHeight: 50
462
+ },
463
+ children: loadingMore && /*#__PURE__*/_jsx(CircularProgress, {
464
+ size: 24,
465
+ sx: {
466
+ color: stableTheme?.palette?.editor?.activeColor || "#2563EB"
467
+ }
468
+ })
469
+ })]
470
+ });
471
+ };
472
+
473
+ // Memoize RecentUploads with custom comparison to prevent unnecessary re-renders
474
+ export default /*#__PURE__*/React.memo(RecentUploads, (prevProps, nextProps) => {
475
+ // Only re-render if these props actually change
476
+ const propsEqual = prevProps.onUploaded === nextProps.onUploaded && prevProps.title === nextProps.title;
477
+
478
+ // Deep compare customProps.services since that's what we actually use
479
+ const customPropsEqual = prevProps.customProps === nextProps.customProps || prevProps.customProps?.services === nextProps.customProps?.services && prevProps.customProps?.translation === nextProps.customProps?.translation;
480
+
481
+ // Return true if props are equal (don't re-render), false if different (re-render)
482
+ return propsEqual && customPropsEqual;
483
+ });
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { Grid } from "@mui/material";
3
+ import UploaderWithProgress from "../../UploaderWithProgress";
3
4
  import Uploader from "../../Uploader";
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  const Upload = props => {
@@ -9,11 +10,31 @@ const Upload = props => {
9
10
  onUploaded,
10
11
  customProps,
11
12
  disableUpload = false,
12
- title
13
+ title,
14
+ setS3UploadProp,
15
+ s3UploadProp,
16
+ disableProgress,
17
+ setUniqueId,
18
+ uniqueId
13
19
  } = props;
14
20
  const onDone = img => {
15
21
  onUploaded(img);
16
22
  };
23
+ const commonProps = {
24
+ classes,
25
+ value,
26
+ data: {
27
+ key: "url"
28
+ },
29
+ customProps,
30
+ onUploaded: onDone,
31
+ disableUpload,
32
+ title,
33
+ setS3UploadProp,
34
+ s3UploadProp,
35
+ setUniqueId,
36
+ uniqueId
37
+ };
17
38
  return /*#__PURE__*/_jsx(Grid, {
18
39
  item: true,
19
40
  xs: 12,
@@ -22,16 +43,10 @@ const Upload = props => {
22
43
  height: '100%'
23
44
  },
24
45
  className: "ims-right",
25
- children: /*#__PURE__*/_jsx(Uploader, {
26
- classes: classes,
27
- value: value,
28
- data: {
29
- key: "url"
30
- },
31
- customProps: customProps,
32
- onUploaded: onDone,
33
- disableUpload: disableUpload,
34
- title: title
46
+ children: disableProgress ? /*#__PURE__*/_jsx(Uploader, {
47
+ ...commonProps
48
+ }) : /*#__PURE__*/_jsx(UploaderWithProgress, {
49
+ ...commonProps
35
50
  })
36
51
  });
37
52
  };
@@ -76,7 +76,7 @@ const ImageSelectorStyles = theme => ({
76
76
  background: theme?.palette?.editor?.deviderBgColor,
77
77
  "@media only screen and (min-width: 899px)": {
78
78
  margin: "0px 24px",
79
- width: 'calc(100% - 48px)'
79
+ width: "calc(100% - 48px)"
80
80
  }
81
81
  },
82
82
  "& .primaryBtn": {
@@ -104,12 +104,6 @@ const ImageSelectorStyles = theme => ({
104
104
  marginRight: "8px !important"
105
105
  },
106
106
  "& .MuiGrid-root": {
107
- "&::-webkit-scrollbar-thumb": {
108
- background: `none !important`
109
- },
110
- "&::-webkit-scrollbar-track": {
111
- visibility: "hidden"
112
- },
113
107
  "&::-webkit-scrollbar-thumb": {
114
108
  background: `${theme?.palette?.editor?.brainPopupScroll} !important`
115
109
  },
@@ -118,10 +112,10 @@ const ImageSelectorStyles = theme => ({
118
112
  }
119
113
  },
120
114
  "& .MuiImageList-root": {
121
- margin: '0px'
115
+ margin: "0px"
122
116
  },
123
117
  "& .MuiDialogContent-root": {
124
- padding: '20px 24px 5px 24px'
118
+ padding: "20px 24px 5px 24px"
125
119
  }
126
120
  },
127
121
  titleTypo: {
@@ -68,7 +68,8 @@ const Settings = props => {
68
68
  editor: editor,
69
69
  path: path,
70
70
  customProps: customProps,
71
- theme: theme
71
+ theme: theme,
72
+ onClose: onClose
72
73
  }) : null
73
74
  })]
74
75
  })
@@ -8,7 +8,8 @@ const AppHeaderSettings = props => {
8
8
  const {
9
9
  editor,
10
10
  path,
11
- customProps
11
+ customProps,
12
+ onClose
12
13
  } = props;
13
14
  const item_path = path?.split("|").map(m => parseInt(m));
14
15
  const element_path = [...item_path, 0];
@@ -27,7 +28,7 @@ const AppHeaderSettings = props => {
27
28
  });
28
29
  };
29
30
  const handleClose = () => {
30
- console.log("close");
31
+ onClose();
31
32
  };
32
33
  return /*#__PURE__*/_jsx(Box, {
33
34
  component: "div",
@@ -8,7 +8,8 @@ const BoxSettings = props => {
8
8
  const {
9
9
  editor,
10
10
  path,
11
- customProps
11
+ customProps,
12
+ onClose
12
13
  } = props;
13
14
  const item_path = path?.split("|").map(m => parseInt(m));
14
15
  const element_path = [...item_path];
@@ -27,7 +28,7 @@ const BoxSettings = props => {
27
28
  });
28
29
  };
29
30
  const handleClose = () => {
30
- console.log("close");
31
+ onClose();
31
32
  };
32
33
  return /*#__PURE__*/_jsx(Box, {
33
34
  component: "div",
@@ -8,7 +8,8 @@ const ButtonSettings = props => {
8
8
  const {
9
9
  editor,
10
10
  path,
11
- customProps
11
+ customProps,
12
+ onClose
12
13
  } = props;
13
14
  const item_path = path?.split("|").map(m => parseInt(m));
14
15
  const element_path = [...item_path, 0];
@@ -28,7 +29,7 @@ const ButtonSettings = props => {
28
29
  });
29
30
  };
30
31
  const handleClose = () => {
31
- console.log("close");
32
+ onClose();
32
33
  };
33
34
  return /*#__PURE__*/_jsx(Box, {
34
35
  component: "div",
@@ -8,7 +8,8 @@ const CodeSettings = props => {
8
8
  const {
9
9
  editor,
10
10
  path,
11
- customProps
11
+ customProps,
12
+ onClose
12
13
  } = props;
13
14
  const item_path = path?.split("|").map(m => parseInt(m));
14
15
  const element_path = [...item_path, 0];
@@ -27,7 +28,7 @@ const CodeSettings = props => {
27
28
  });
28
29
  };
29
30
  const handleClose = () => {
30
- console.log("close");
31
+ onClose();
31
32
  };
32
33
  return /*#__PURE__*/_jsx(Box, {
33
34
  component: "div",
@@ -12,7 +12,8 @@ const FormSettings = props => {
12
12
  const {
13
13
  editor,
14
14
  path,
15
- customProps
15
+ customProps,
16
+ onClose
16
17
  } = props;
17
18
  const item_path = path?.split("|").map(m => parseInt(m));
18
19
  const element_path = [...item_path];
@@ -56,7 +57,7 @@ const FormSettings = props => {
56
57
  }
57
58
  };
58
59
  const handleClose = () => {
59
- console.log("close");
60
+ onClose();
60
61
  };
61
62
  const muiTheme = createTheme({
62
63
  components: {