@flozy/editor 11.2.3 → 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 +32 -44
  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 +5 -15
  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 +10 -19
  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
@@ -1,9 +1,15 @@
1
1
  import React, { useState, useEffect, useRef } from "react";
2
2
  import { useSlateStatic, ReactEditor } from "slate-react";
3
3
  import { Node, Transforms } from "slate";
4
- import { IconButton, Tooltip, Box, useTheme } from "@mui/material";
4
+ import IconButton from "@mui/material/IconButton";
5
+ import Tooltip from "@mui/material/Tooltip";
6
+ import Box from "@mui/material/Box";
7
+ import useTheme from "@mui/material/styles/useTheme";
8
+ import Grid from "@mui/material/Grid";
9
+ import CircularProgress from "@mui/material/CircularProgress";
5
10
  import DeleteIcon from "@mui/icons-material/Delete";
6
11
  import AspectRatioIcon from "@mui/icons-material/AspectRatio";
12
+ import HighlightOffRoundedIcon from "@mui/icons-material/HighlightOffRounded";
7
13
  import Icon from "../../common/Icon";
8
14
  import useResize from "../../utils/customHooks/useResize";
9
15
  import EmbedPopup from "./EmbedPopup";
@@ -13,13 +19,19 @@ import { getEmbedURL } from "../../helper";
13
19
  import { getBreakPointsValue, getTRBLBreakPoints, groupByBreakpoint } from "../../helper/theme";
14
20
  import { useEditorContext } from "../../hooks/useMouseMove";
15
21
  import useCommonStyle from "../../commonStyle";
22
+ import ImageSelector from "../../common/ImageSelector/ImageSelector";
16
23
  import { jsx as _jsx } from "react/jsx-runtime";
17
24
  import { jsxs as _jsxs } from "react/jsx-runtime";
25
+ import { Fragment as _Fragment } from "react/jsx-runtime";
18
26
  const TYPE_LABELS = {
19
27
  calendly: "Embed Calendly or Other",
20
28
  video: "Embed Video or Other",
21
29
  image: "Embed Image or Other"
22
30
  };
31
+ const detectUrlType = url => {
32
+ if (typeof url !== "string") return "iframe";
33
+ return /\.(mp4|webm|ogg|mov|avi|mkv|flv|wmv)$/i.test(url.trim()) ? "video" : "iframe";
34
+ };
23
35
  const VideoContent = props => {
24
36
  const {
25
37
  resizing,
@@ -32,12 +44,26 @@ const VideoContent = props => {
32
44
  videoSX
33
45
  } = props;
34
46
  const iframeRef = useRef(null);
47
+ const mediaType = detectUrlType(embedURL);
35
48
  useEffect(() => {
36
49
  if (iframeRef.current) {
37
50
  iframeRef.current.src = "about:blank"; // reloading the iframe
38
51
  iframeRef.current.src = embedURL;
39
52
  }
40
53
  }, [embedURL, iframeRef.current]);
54
+ const commonSx = {
55
+ border: "none",
56
+ position: "absolute",
57
+ width: "100%",
58
+ height: "100%",
59
+ maxWidth: "100%",
60
+ left: 0,
61
+ ...(gradientBorder(borderColor) || {}),
62
+ borderWidth: borderWidth || "1px",
63
+ borderStyle: borderStyle || "solid",
64
+ background: bgColor || "transparent",
65
+ ...videoSX
66
+ };
41
67
  return resizing ? /*#__PURE__*/_jsx("div", {
42
68
  style: {
43
69
  width: "100%",
@@ -51,24 +77,14 @@ const VideoContent = props => {
51
77
  icon: "videoPlayer"
52
78
  })
53
79
  }) : /*#__PURE__*/_jsx(Box, {
54
- ref: iframeRef,
55
- component: "iframe",
80
+ component: mediaType,
81
+ ref: mediaType === "iframe" ? iframeRef : undefined,
82
+ src: embedURL,
83
+ controls: mediaType === "video",
84
+ allowFullScreen: mediaType === "iframe",
56
85
  className: "embedd-iframe",
57
- sx: {
58
- border: "none",
59
- position: "absolute",
60
- width: "100%",
61
- height: "100%",
62
- maxWidth: "100%",
63
- left: "0px",
64
- ...(gradientBorder(borderColor) || {}),
65
- borderWidth: borderWidth || "1px",
66
- borderStyle: borderStyle || "solid",
67
- background: bgColor || "transparent",
68
- ...videoSX
69
- },
70
- title: alt,
71
- allowFullScreen: true
86
+ sx: commonSx,
87
+ title: alt
72
88
  });
73
89
  };
74
90
  const VideoPlaceholder = props => {
@@ -78,18 +94,104 @@ const VideoPlaceholder = props => {
78
94
  onSettings,
79
95
  classes,
80
96
  type,
81
- translation
97
+ translation,
98
+ uploadStatus,
99
+ setUploadStatus,
100
+ uploadTerminator,
101
+ uniqueId,
102
+ editor,
103
+ path
104
+ // embedURL, // Unused in VideoPlaceholder component
82
105
  } = props;
83
- return !url ? !readOnly ? /*#__PURE__*/_jsxs(Box, {
106
+ const cancelUpload = e => {
107
+ e.stopPropagation();
108
+ uploadTerminator(uniqueId, setUploadStatus);
109
+ Transforms.setNodes(editor, {
110
+ isUpload: false,
111
+ isUploading: false,
112
+ file: null
113
+ }, {
114
+ at: path
115
+ });
116
+ };
117
+ return !url ? !readOnly ? /*#__PURE__*/_jsx(Box, {
84
118
  component: "button",
85
119
  className: "element-empty-btn",
86
- onClick: onSettings,
120
+ onClick: !uploadStatus?.isUploading ? onSettings : () => {},
87
121
  sx: {
88
122
  ...classes.emptyThumbBtn
89
123
  },
90
- children: [/*#__PURE__*/_jsx(Icon, {
91
- icon: "video"
92
- }), TYPE_LABELS[type] || translation("Embed Video or Other")]
124
+ children: uploadStatus?.isUploading ? /*#__PURE__*/_jsxs(Grid, {
125
+ container: true,
126
+ direction: "row",
127
+ style: {
128
+ display: "flex",
129
+ justifyContent: "space-between"
130
+ },
131
+ children: [/*#__PURE__*/_jsx(Grid, {
132
+ style: {
133
+ width: "80%"
134
+ },
135
+ children: /*#__PURE__*/_jsxs(Grid, {
136
+ container: true,
137
+ direction: "row",
138
+ sx: {
139
+ justifyContent: "flex-start",
140
+ alignItems: "center"
141
+ // gap: 1,
142
+ },
143
+ children: [/*#__PURE__*/_jsx(Grid, {
144
+ children: /*#__PURE__*/_jsx(Icon, {
145
+ icon: "image"
146
+ })
147
+ }), /*#__PURE__*/_jsx(Grid, {
148
+ style: {
149
+ width: "80%"
150
+ },
151
+ children: /*#__PURE__*/_jsxs(Box, {
152
+ display: "flex",
153
+ flexDirection: "column",
154
+ alignItems: "flex-start",
155
+ justifyContent: "flex-start",
156
+ children: [/*#__PURE__*/_jsx(Box, {
157
+ className: "truncateText",
158
+ children: uploadStatus?.fileName
159
+ }), /*#__PURE__*/_jsxs(Box, {
160
+ display: "flex",
161
+ alignItems: "center",
162
+ gap: 1,
163
+ marginTop: 1,
164
+ children: [/*#__PURE__*/_jsx(Box, {
165
+ children: uploadStatus?.fileSize
166
+ }), /*#__PURE__*/_jsx(CircularProgress, {
167
+ variant: "determinate",
168
+ value: uploadStatus?.uploadPercentage ?? 0,
169
+ className: "circularProgress-cls",
170
+ size: 15,
171
+ thickness: 8
172
+ }), /*#__PURE__*/_jsx(Box, {
173
+ children: `${uploadStatus?.uploadPercentage?.toFixed(0) ?? 0}%`
174
+ })]
175
+ })]
176
+ })
177
+ })]
178
+ })
179
+ }), /*#__PURE__*/_jsx(Grid, {
180
+ children: /*#__PURE__*/_jsx(HighlightOffRoundedIcon, {
181
+ className: "uploadCancel",
182
+ sx: {
183
+ cursor: "pointer"
184
+ },
185
+ onClick: e => {
186
+ cancelUpload(e);
187
+ }
188
+ })
189
+ })]
190
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
191
+ children: [/*#__PURE__*/_jsx(Icon, {
192
+ icon: "video"
193
+ }), TYPE_LABELS[type] || translation("Embed Video or Other")]
194
+ })
93
195
  }) : /*#__PURE__*/_jsxs(Box, {
94
196
  sx: {
95
197
  color: "#64748B !important",
@@ -120,14 +222,23 @@ const Video = ({
120
222
  xsHidden,
121
223
  width: oldWidth,
122
224
  bannerSpacing,
123
- aspectRatio
225
+ aspectRatio,
226
+ file,
227
+ isUploading,
228
+ uniqueId,
229
+ fromFreeGrid
124
230
  } = element;
125
231
  const editor = useSlateStatic();
126
232
  const [openSetttings, setOpenSettings] = useState(false);
127
233
  const [parentDOM, setParentDOM] = useState(null);
128
234
  const {
129
235
  readOnly,
130
- translation
236
+ translation,
237
+ services,
238
+ uploadFile,
239
+ resumeUploadState,
240
+ uploadTerminator,
241
+ isUploadInProgress = () => false
131
242
  } = customProps;
132
243
  const {
133
244
  vertical,
@@ -148,6 +259,59 @@ const Video = ({
148
259
  return element?.size || {};
149
260
  }
150
261
  };
262
+ const xhrRef = useRef(null);
263
+ const trackingProcessedRef = useRef(false);
264
+ const [openUploadPopup, setUploadPopupOpen] = useState(false);
265
+ const [uploadStatus, setUploadStatus] = useState({
266
+ isUploading: false,
267
+ uploadPercentage: 0
268
+ });
269
+ const onClickUpload = () => {
270
+ setUploadPopupOpen(true);
271
+ };
272
+ const onSelectVideo = async video => {
273
+ handleClose();
274
+ try {
275
+ // Check if this is a recent upload (has source "recent") or manual URL entry (isUpload === false)
276
+ if (video?.isUpload === false || video?.source === "recent") {
277
+ // Pass the full video object to preserve source information
278
+ onSave(video, false); // Manual URL entry or recent upload, not upload completion
279
+ return;
280
+ } else {
281
+ // Reset tracking flag for new upload
282
+ trackingProcessedRef.current = false;
283
+ const id = !uniqueId ? crypto?.randomUUID() : uniqueId;
284
+ const result = await services("uploadFile", video?.file);
285
+ const uploadUrl = result?.data?.[0];
286
+ const fileEntry = {
287
+ ...video,
288
+ xhrRef,
289
+ presidnedURL: uploadUrl,
290
+ status: "uploading"
291
+ };
292
+ uploadFile(id, fileEntry, setUploadStatus, onSave, "video");
293
+ if (!fromFreeGrid) {
294
+ Transforms.setNodes(editor, {
295
+ uniqueId: id,
296
+ isUploading: true
297
+ }, {
298
+ at: path
299
+ });
300
+ } else {
301
+ Transforms.setNodes(editor, {
302
+ isUploading: true
303
+ }, {
304
+ at: path
305
+ });
306
+ }
307
+ }
308
+ } catch (error) {
309
+ console.log(error);
310
+ }
311
+ };
312
+ const handleClose = () => {
313
+ setUploadPopupOpen(false);
314
+ };
151
315
  const [size, onMouseDown, resizing, onLoad] = useResize({
152
316
  parentDOM,
153
317
  size: getSize(),
@@ -161,12 +325,49 @@ const Video = ({
161
325
  });
162
326
  const arr = Array.from(Node.elements(editor));
163
327
  const ele = arr.find(([elem]) => element === elem);
328
+ const noUploadTracks = () => {
329
+ setUploadStatus({
330
+ isUploading: false,
331
+ uploadPercentage: 0,
332
+ fileName: null,
333
+ fileSize: null
334
+ });
335
+ };
336
+ useEffect(() => {
337
+ const isUploading = isUploadInProgress(uniqueId);
338
+ if (fromFreeGrid) {
339
+ if (isUploading) {
340
+ resumeUploadState(uniqueId, setUploadStatus, onSave, noUploadTracks, "image");
341
+ } else {
342
+ if (!isUploading && file) {
343
+ onSelectVideo({
344
+ file: file
345
+ });
346
+ }
347
+ }
348
+ }
349
+ return () => {
350
+ // Transforms.setNodes(editor, { isUploading: false }, { at: path });
351
+ };
352
+ }, [uniqueId, isUploading, file]);
164
353
  useEffect(() => {
165
354
  if (editor && ele && ele[1] !== undefined) {
166
355
  const dom = ReactEditor.toDOMNode(editor, Node.get(editor, ele[1]));
167
356
  setParentDOM(dom);
168
357
  onLoad(element?.size || {});
169
358
  }
359
+ if (!fromFreeGrid) {
360
+ if (uniqueId && isUploading) {
361
+ resumeUploadState(uniqueId, setUploadStatus, onSave, noUploadTracks, "video");
362
+ } else if (file && isUploading) {
363
+ onSelectVideo({
364
+ file: file
365
+ });
366
+ }
367
+ }
368
+ return () => {
369
+ // xhrRef?.current?.abort();
370
+ };
170
371
  }, []);
171
372
  const ToolBar = () => {
172
373
  return /*#__PURE__*/_jsxs("div", {
@@ -192,15 +393,116 @@ const Video = ({
192
393
  const onSettings = () => {
193
394
  setOpenSettings(true);
194
395
  };
195
- const onSave = data => {
396
+ const onSave = async (data, isUploadCompletion = false) => {
397
+ // Determine if this is from recent uploads or choose assets - check both object and string data
398
+ const isFromRecentUploads = typeof data === 'object' && data?.source === "recent" || typeof data === 'string' && data.includes('recent');
399
+
400
+ // Only track if this is NOT an upload completion AND we haven't processed tracking yet
401
+ // Upload completions will be tracked by the uploadFile function in main app
402
+ // Also skip tracking if the source is "recent" (selected from recent uploads or choose assets)
403
+ if (data && !isUploadCompletion && !trackingProcessedRef.current && !isFromRecentUploads) {
404
+ // Mark tracking as processed
405
+ trackingProcessedRef.current = true;
406
+ try {
407
+ // Import utility functions
408
+ const {
409
+ getVideoMimeTypeFromExtension,
410
+ extractFileInfoFromUrl
411
+ } = await import("../../utils/attachments");
412
+
413
+ // Extract URL from data (could be string or object)
414
+ const urlToTrack = typeof data === 'string' ? data : data?.embedURL || data?.url;
415
+ if (urlToTrack) {
416
+ // Extract filename and extension from URL
417
+ const {
418
+ filename,
419
+ extension
420
+ } = extractFileInfoFromUrl(urlToTrack);
421
+ const mimeType = getVideoMimeTypeFromExtension(extension);
422
+ const trackingData = {
423
+ file_url: urlToTrack,
424
+ name: filename || 'Untitled Video',
425
+ mime_type: mimeType,
426
+ resource_type: "flozy_editor",
427
+ resource_id: customProps?.page_id,
428
+ agency_id: customProps?.agency_id,
429
+ uploaded_by: customProps?.user_id,
430
+ category: "video",
431
+ status: 1,
432
+ created_on: new Date().toISOString()
433
+ };
434
+
435
+ // Try main app service first, fallback to direct implementation
436
+ if (customProps.services && typeof customProps.services === 'function') {
437
+ try {
438
+ // const result = await customProps.services('trackEditorUploads', {
439
+ await customProps.services('trackEditorUploads', {
440
+ fileData: trackingData,
441
+ category: 'video'
442
+ });
443
+ } catch (error) {
444
+ console.warn('Main app service failed, falling back to direct tracking:', error);
445
+ }
446
+ }
447
+ }
448
+ } catch (error) {
449
+ console.error("Failed to track video URL:", error);
450
+ }
451
+ } else {}
452
+
453
+ // Data insertion logic - ALWAYS execute regardless of tracking
196
454
  try {
197
- const updateData = {
198
- ...data
199
- };
455
+ let updateData = {};
456
+
457
+ // Handle different data types more robustly
458
+ if (typeof data === "string") {
459
+ // String URL - could be from recent uploads or manual entry
460
+ updateData = {
461
+ url: data,
462
+ isUploading: false
463
+ };
464
+ } else if (data && typeof data === "object") {
465
+ // Object data - check if it has the expected structure
466
+ if (data.embedURL || data.url) {
467
+ // This is from recent uploads or other sources with proper structure
468
+ updateData = {
469
+ url: data.embedURL || data.url,
470
+ isUploading: false,
471
+ source: data.source // Preserve source information
472
+ };
473
+ } else if (typeof data?.url !== "string") {
474
+ // This is a file upload object
475
+ updateData = {
476
+ ...data,
477
+ url: ""
478
+ };
479
+ onSelectVideo({
480
+ file: data?.url?.file,
481
+ isUpload: true,
482
+ setUploadStatus,
483
+ services: customProps?.services
484
+ });
485
+ } else {
486
+ // Fallback for other object structures
487
+ updateData = data;
488
+ }
489
+ } else {
490
+ // Fallback
491
+ updateData = {
492
+ url: "",
493
+ isUploading: false
494
+ };
495
+ }
200
496
  delete updateData.children;
201
- Transforms.setNodes(editor, {
202
- ...updateData
203
- }, {
497
+ Transforms.select(editor, path);
498
+ ReactEditor.focus(editor);
499
+ const finalUpdateData = {
500
+ ...updateData,
501
+ isUpload: false,
502
+ isUploading: false,
503
+ file: null
504
+ };
505
+ Transforms.setNodes(editor, finalUpdateData, {
204
506
  at: path
205
507
  });
206
508
  onClose();
@@ -281,13 +583,19 @@ const Video = ({
281
583
  children: [!readOnly && url && /*#__PURE__*/_jsx(ToolBar, {}), /*#__PURE__*/_jsx(VideoPlaceholder, {
282
584
  ...element,
283
585
  embedURL: embedURL,
284
- onSettings: onSettings,
586
+ onSettings: onClickUpload,
285
587
  videoSX: videoSX,
286
588
  url: url,
287
589
  readOnly: readOnly,
288
590
  resizing: resizing,
289
591
  classes: classes,
290
- translation: translation
592
+ translation: translation,
593
+ uploadStatus: uploadStatus,
594
+ setUploadStatus: setUploadStatus,
595
+ uploadTerminator: uploadTerminator,
596
+ uniqueId: uniqueId,
597
+ editor: editor,
598
+ path: path
291
599
  }), !readOnly && url ? /*#__PURE__*/_jsx(IconButton, {
292
600
  onPointerDown: onMouseDown,
293
601
  style: {
@@ -295,6 +603,18 @@ const Video = ({
295
603
  },
296
604
  className: "resize-br visible-on-hover",
297
605
  children: /*#__PURE__*/_jsx(AspectRatioIcon, {})
606
+ }) : null, openUploadPopup ? /*#__PURE__*/_jsx(ImageSelector, {
607
+ open: true,
608
+ Add: true,
609
+ commentMore: true,
610
+ actions: true,
611
+ title: "Video",
612
+ onClose: handleClose,
613
+ customProps: customProps,
614
+ onSelectImage: onSelectVideo,
615
+ setUploadPopupOpen: setUploadPopupOpen,
616
+ setUploadStatus: setUploadStatus,
617
+ xhrRef: xhrRef
298
618
  }) : null]
299
619
  }), children]
300
620
  });
@@ -52,6 +52,12 @@ const EmbedScriptPopup = props => {
52
52
  const handleChange = e => {
53
53
  setCode(e.target.value);
54
54
  };
55
+ const handleMouseDown = e => {
56
+ e.stopPropagation();
57
+ };
58
+ const handleMouseUp = e => {
59
+ e.stopPropagation();
60
+ };
55
61
  const onSubmit = async () => {
56
62
  updateApiStatus({
57
63
  loading: true
@@ -135,12 +141,9 @@ const EmbedScriptPopup = props => {
135
141
  children: [/*#__PURE__*/_jsx("textarea", {
136
142
  value: code,
137
143
  onChange: handleChange,
138
- style: {
139
- minHeight: "260px",
140
- width: "100%",
141
- resize: "none",
142
- padding: "4px"
143
- }
144
+ onMouseDown: handleMouseDown,
145
+ onMouseUp: handleMouseUp,
146
+ className: "embed-textarea"
144
147
  }), /*#__PURE__*/_jsx(Box, {
145
148
  component: "div",
146
149
  color: "red",
@@ -6,13 +6,29 @@ const Styles = theme => ({
6
6
  border: `1px solid ${theme?.palette?.editor?.miniToolBarBorder}`,
7
7
  overflow: "hidden"
8
8
  },
9
- "& textarea": {
9
+ "& .embed-textarea": {
10
10
  backgroundColor: theme?.palette?.editor?.inputFieldBgColor,
11
11
  border: `1px solid ${theme?.palette?.editor?.inputFieldBorder}`,
12
12
  borderRadius: "12px",
13
13
  padding: "10px !important",
14
14
  color: theme?.palette?.editor?.textColor,
15
15
  boxShadow: "0px 4px 18px 0px #00000014",
16
+ minHeight: "260px",
17
+ width: "100%",
18
+ resize: "none",
19
+ userSelect: "text !important",
20
+ WebkitUserSelect: "text !important",
21
+ MozUserSelect: "text !important",
22
+ msUserSelect: "text !important",
23
+ pointerEvents: "auto !important",
24
+ "&::selection": {
25
+ background: "rgba(37, 99, 235, 0.2) !important",
26
+ color: "inherit !important"
27
+ },
28
+ "&::-moz-selection": {
29
+ background: "rgba(37, 99, 235, 0.2) !important",
30
+ color: "inherit !important"
31
+ },
16
32
  "&:focus": {
17
33
  border: `1px solid #2563EB`,
18
34
  boxShadow: "0px 4px 18px 0px #2563EB1F",
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from "react";
2
- import { Transforms, Node } from "slate";
2
+ import { Transforms } from "slate";
3
3
  import { useSlateStatic, ReactEditor } from "slate-react";
4
4
  import { IconButton, Tooltip, Grid, useTheme } from "@mui/material";
5
5
  import FormElements from "./FormElements";
@@ -9,20 +9,21 @@ const FormStyles = theme => ({
9
9
  color: "#94A3B8"
10
10
  },
11
11
  bodyTextArea: {
12
- '& .mini-editor-cls': {
13
- padding: '12px',
14
- '&:focus-visible': {
15
- outline: 'none',
16
- border: 'none'
12
+ "& .mini-editor-cls": {
13
+ padding: "12px",
14
+ "&:focus-visible": {
15
+ outline: "none",
16
+ border: "none"
17
17
  }
18
18
  },
19
19
  "& .editorWorkflow": {
20
- minHeight: '130px',
21
- padding: '12px',
20
+ minHeight: "130px",
21
+ padding: "12px",
22
22
  paddingBottom: 0,
23
- '&:focus-visible': {
24
- outline: 'none',
25
- border: 'none'
23
+ color: theme?.palette?.editor?.textColor,
24
+ "&:focus-visible": {
25
+ outline: "none",
26
+ border: "none"
26
27
  }
27
28
  }
28
29
  },
@@ -105,7 +106,7 @@ const FormStyles = theme => ({
105
106
  padding: "4px 22px",
106
107
  textTransform: "none",
107
108
  border: "1px solid #D8DDE1",
108
- minWidth: '126px',
109
+ minWidth: "126px",
109
110
  "& svg": {
110
111
  "& path": {
111
112
  stroke: "#64748B"
@@ -169,17 +170,19 @@ const FormStyles = theme => ({
169
170
  }
170
171
  },
171
172
  colorButtonSingle: {
173
+ border: "1.5px solid #DCE4EC !important",
172
174
  "&.active": {
173
- "&:before": {
174
- content: '" "',
175
- position: "absolute",
176
- top: "-5px",
177
- left: "-5px",
178
- width: "calc(100% + 4px)",
179
- height: "calc(100% + 4px)",
180
- border: "3px solid blue",
181
- borderRadius: "50%"
182
- }
175
+ // "&:before": {
176
+ // content: '" "',
177
+ // position: "absolute",
178
+ // top: "-5px",
179
+ // left: "-5px",
180
+ // width: "calc(100% + 4px)",
181
+ // height: "calc(100% + 4px)",
182
+ // border: "3px solid blue",
183
+ // borderRadius: "50%",
184
+ // },
185
+ outline: "2px solid #2563EB"
183
186
  }
184
187
  },
185
188
  colorButtonsInner: {
@@ -249,7 +252,7 @@ const FormStyles = theme => ({
249
252
  }
250
253
  },
251
254
  root: {
252
- padding: '10px'
255
+ padding: "10px"
253
256
  }
254
257
  });
255
258
  export default FormStyles;
@@ -1,3 +1,27 @@
1
1
  export const minutes = [30, 35, 40, 45, 50, 55];
2
2
  export const hours = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
3
- export const days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31];
3
+ export const days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31];
4
+ export const allowedFormat = {
5
+ Document: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.rtf",
6
+ Image: "image/*",
7
+ Video: ".mp4,.webm,.ogg,.mov,.avi,.mkv",
8
+ Embed: "*"
9
+ };
10
+ export const maxSizeMap = {
11
+ Image: 25 * 1024 * 1024,
12
+ // Test -> 5 * 1024 * 1024 -> 5MB
13
+ Video: 1024 * 1024 * 1024,
14
+ Document: 25 * 1024 * 1024,
15
+ Embed: Infinity
16
+ };
17
+ export const allowedTypes = {
18
+ Document: ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "text/plain", "application/rtf"],
19
+ Image: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
20
+ Video: ["video/mp4", "video/webm", "video/ogg", "video/quicktime", "video/x-msvideo", "video/x-matroska"],
21
+ Embed: ["*"]
22
+ };
23
+ export const extensionMap = {
24
+ Video: ["mp4", "webm", "ogg", "mov", "avi", "mkv"],
25
+ Image: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
26
+ Document: ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "rtf"]
27
+ };