@contentstack/live-preview-utils 3.2.0 → 3.2.2
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.
- package/README.md +2 -2
- package/dist/legacy/index.cjs +2 -2
- package/dist/legacy/index.cjs.map +1 -1
- package/dist/legacy/index.js +2 -2
- package/dist/legacy/index.js.map +1 -1
- package/dist/legacy/livePreview/eventManager/postMessageEvent.hooks.cjs +1 -1
- package/dist/legacy/livePreview/eventManager/postMessageEvent.hooks.js +1 -1
- package/dist/legacy/logger/logger.cjs +1 -1
- package/dist/legacy/logger/logger.cjs.map +1 -1
- package/dist/legacy/logger/logger.js +1 -1
- package/dist/legacy/logger/logger.js.map +1 -1
- package/dist/legacy/preview/contentstack-live-preview-HOC.cjs +1 -1
- package/dist/legacy/preview/contentstack-live-preview-HOC.js +1 -1
- package/dist/legacy/visualBuilder/components/FieldRevert/FieldRevertComponent.cjs +4 -1
- package/dist/legacy/visualBuilder/components/FieldRevert/FieldRevertComponent.cjs.map +1 -1
- package/dist/legacy/visualBuilder/components/FieldRevert/FieldRevertComponent.js +4 -1
- package/dist/legacy/visualBuilder/components/FieldRevert/FieldRevertComponent.js.map +1 -1
- package/dist/legacy/visualBuilder/components/FieldToolbar.cjs +24 -13
- package/dist/legacy/visualBuilder/components/FieldToolbar.cjs.map +1 -1
- package/dist/legacy/visualBuilder/components/FieldToolbar.d.cts +2 -0
- package/dist/legacy/visualBuilder/components/FieldToolbar.d.ts +2 -0
- package/dist/legacy/visualBuilder/components/FieldToolbar.js +24 -13
- package/dist/legacy/visualBuilder/components/FieldToolbar.js.map +1 -1
- package/dist/legacy/visualBuilder/components/fieldLabelWrapper.cjs +8 -1
- package/dist/legacy/visualBuilder/components/fieldLabelWrapper.cjs.map +1 -1
- package/dist/legacy/visualBuilder/components/fieldLabelWrapper.js +8 -1
- package/dist/legacy/visualBuilder/components/fieldLabelWrapper.js.map +1 -1
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.cjs +12 -0
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.cjs.map +1 -1
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.d.cts +6 -1
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.d.ts +6 -1
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.js +7 -0
- package/dist/legacy/visualBuilder/eventManager/useVariantsPostMessageEvent.js.map +1 -1
- package/dist/legacy/visualBuilder/generators/generateOverlay.cjs +4 -2
- package/dist/legacy/visualBuilder/generators/generateOverlay.cjs.map +1 -1
- package/dist/legacy/visualBuilder/generators/generateOverlay.js +4 -2
- package/dist/legacy/visualBuilder/generators/generateOverlay.js.map +1 -1
- package/dist/legacy/visualBuilder/generators/generateToolbar.cjs +9 -2
- package/dist/legacy/visualBuilder/generators/generateToolbar.cjs.map +1 -1
- package/dist/legacy/visualBuilder/generators/generateToolbar.d.cts +1 -1
- package/dist/legacy/visualBuilder/generators/generateToolbar.d.ts +1 -1
- package/dist/legacy/visualBuilder/generators/generateToolbar.js +9 -2
- package/dist/legacy/visualBuilder/generators/generateToolbar.js.map +1 -1
- package/dist/legacy/visualBuilder/index.cjs +3 -3
- package/dist/legacy/visualBuilder/index.cjs.map +1 -1
- package/dist/legacy/visualBuilder/index.d.cts +1 -0
- package/dist/legacy/visualBuilder/index.d.ts +1 -0
- package/dist/legacy/visualBuilder/index.js +3 -3
- package/dist/legacy/visualBuilder/index.js.map +1 -1
- package/dist/legacy/visualBuilder/listeners/mouseClick.cjs +33 -2
- package/dist/legacy/visualBuilder/listeners/mouseClick.cjs.map +1 -1
- package/dist/legacy/visualBuilder/listeners/mouseClick.js +33 -2
- package/dist/legacy/visualBuilder/listeners/mouseClick.js.map +1 -1
- package/dist/legacy/visualBuilder/listeners/mouseHover.cjs +46 -12
- package/dist/legacy/visualBuilder/listeners/mouseHover.cjs.map +1 -1
- package/dist/legacy/visualBuilder/listeners/mouseHover.js +46 -12
- package/dist/legacy/visualBuilder/listeners/mouseHover.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/collabUtils.cjs +3 -2
- package/dist/legacy/visualBuilder/utils/collabUtils.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/collabUtils.js +3 -2
- package/dist/legacy/visualBuilder/utils/collabUtils.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/createCachedFetch.cjs +58 -0
- package/dist/legacy/visualBuilder/utils/createCachedFetch.cjs.map +1 -0
- package/dist/legacy/visualBuilder/utils/createCachedFetch.d.cts +12 -0
- package/dist/legacy/visualBuilder/utils/createCachedFetch.d.ts +12 -0
- package/dist/legacy/visualBuilder/utils/createCachedFetch.js +35 -0
- package/dist/legacy/visualBuilder/utils/createCachedFetch.js.map +1 -0
- package/dist/legacy/visualBuilder/utils/fieldSchemaMap.cjs +1 -0
- package/dist/legacy/visualBuilder/utils/fieldSchemaMap.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/fieldSchemaMap.js +1 -0
- package/dist/legacy/visualBuilder/utils/fieldSchemaMap.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.cjs +71 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.cjs.map +1 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.d.cts +14 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.d.ts +14 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.js +38 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissions.js.map +1 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.cjs +36 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.cjs.map +1 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.d.cts +12 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.d.ts +12 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.js +13 -0
- package/dist/legacy/visualBuilder/utils/getEntryPermissionsCached.js.map +1 -0
- package/dist/legacy/visualBuilder/utils/handleFieldMouseDown.cjs +8 -1
- package/dist/legacy/visualBuilder/utils/handleFieldMouseDown.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/handleFieldMouseDown.js +8 -1
- package/dist/legacy/visualBuilder/utils/handleFieldMouseDown.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/handleIndividualFields.cjs +11 -1
- package/dist/legacy/visualBuilder/utils/handleIndividualFields.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/handleIndividualFields.js +11 -1
- package/dist/legacy/visualBuilder/utils/handleIndividualFields.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.cjs +7 -1
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.d.cts +4 -2
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.d.ts +4 -2
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.js +7 -1
- package/dist/legacy/visualBuilder/utils/isFieldDisabled.js.map +1 -1
- package/dist/legacy/visualBuilder/utils/updateFocussedState.cjs +30 -9
- package/dist/legacy/visualBuilder/utils/updateFocussedState.cjs.map +1 -1
- package/dist/legacy/visualBuilder/utils/updateFocussedState.d.cts +1 -1
- package/dist/legacy/visualBuilder/utils/updateFocussedState.d.ts +1 -1
- package/dist/legacy/visualBuilder/utils/updateFocussedState.js +30 -9
- package/dist/legacy/visualBuilder/utils/updateFocussedState.js.map +1 -1
- package/dist/legacy/visualBuilder/visualBuilder.style.cjs +10 -1
- package/dist/legacy/visualBuilder/visualBuilder.style.cjs.map +1 -1
- package/dist/legacy/visualBuilder/visualBuilder.style.js +10 -1
- package/dist/legacy/visualBuilder/visualBuilder.style.js.map +1 -1
- package/dist/modern/index.cjs +2 -2
- package/dist/modern/index.cjs.map +1 -1
- package/dist/modern/index.js +2 -2
- package/dist/modern/index.js.map +1 -1
- package/dist/modern/livePreview/eventManager/postMessageEvent.hooks.cjs +1 -1
- package/dist/modern/livePreview/eventManager/postMessageEvent.hooks.js +1 -1
- package/dist/modern/logger/logger.cjs +1 -1
- package/dist/modern/logger/logger.cjs.map +1 -1
- package/dist/modern/logger/logger.js +1 -1
- package/dist/modern/logger/logger.js.map +1 -1
- package/dist/modern/preview/contentstack-live-preview-HOC.cjs +1 -1
- package/dist/modern/preview/contentstack-live-preview-HOC.js +1 -1
- package/dist/modern/visualBuilder/components/FieldRevert/FieldRevertComponent.cjs +4 -1
- package/dist/modern/visualBuilder/components/FieldRevert/FieldRevertComponent.cjs.map +1 -1
- package/dist/modern/visualBuilder/components/FieldRevert/FieldRevertComponent.js +4 -1
- package/dist/modern/visualBuilder/components/FieldRevert/FieldRevertComponent.js.map +1 -1
- package/dist/modern/visualBuilder/components/FieldToolbar.cjs +24 -13
- package/dist/modern/visualBuilder/components/FieldToolbar.cjs.map +1 -1
- package/dist/modern/visualBuilder/components/FieldToolbar.d.cts +2 -0
- package/dist/modern/visualBuilder/components/FieldToolbar.d.ts +2 -0
- package/dist/modern/visualBuilder/components/FieldToolbar.js +24 -13
- package/dist/modern/visualBuilder/components/FieldToolbar.js.map +1 -1
- package/dist/modern/visualBuilder/components/fieldLabelWrapper.cjs +8 -1
- package/dist/modern/visualBuilder/components/fieldLabelWrapper.cjs.map +1 -1
- package/dist/modern/visualBuilder/components/fieldLabelWrapper.js +8 -1
- package/dist/modern/visualBuilder/components/fieldLabelWrapper.js.map +1 -1
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.cjs +12 -0
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.cjs.map +1 -1
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.d.cts +6 -1
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.d.ts +6 -1
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.js +7 -0
- package/dist/modern/visualBuilder/eventManager/useVariantsPostMessageEvent.js.map +1 -1
- package/dist/modern/visualBuilder/generators/generateOverlay.cjs +4 -2
- package/dist/modern/visualBuilder/generators/generateOverlay.cjs.map +1 -1
- package/dist/modern/visualBuilder/generators/generateOverlay.js +4 -2
- package/dist/modern/visualBuilder/generators/generateOverlay.js.map +1 -1
- package/dist/modern/visualBuilder/generators/generateToolbar.cjs +9 -2
- package/dist/modern/visualBuilder/generators/generateToolbar.cjs.map +1 -1
- package/dist/modern/visualBuilder/generators/generateToolbar.d.cts +1 -1
- package/dist/modern/visualBuilder/generators/generateToolbar.d.ts +1 -1
- package/dist/modern/visualBuilder/generators/generateToolbar.js +9 -2
- package/dist/modern/visualBuilder/generators/generateToolbar.js.map +1 -1
- package/dist/modern/visualBuilder/index.cjs +3 -3
- package/dist/modern/visualBuilder/index.cjs.map +1 -1
- package/dist/modern/visualBuilder/index.d.cts +1 -0
- package/dist/modern/visualBuilder/index.d.ts +1 -0
- package/dist/modern/visualBuilder/index.js +3 -3
- package/dist/modern/visualBuilder/index.js.map +1 -1
- package/dist/modern/visualBuilder/listeners/mouseClick.cjs +33 -2
- package/dist/modern/visualBuilder/listeners/mouseClick.cjs.map +1 -1
- package/dist/modern/visualBuilder/listeners/mouseClick.js +33 -2
- package/dist/modern/visualBuilder/listeners/mouseClick.js.map +1 -1
- package/dist/modern/visualBuilder/listeners/mouseHover.cjs +46 -12
- package/dist/modern/visualBuilder/listeners/mouseHover.cjs.map +1 -1
- package/dist/modern/visualBuilder/listeners/mouseHover.js +46 -12
- package/dist/modern/visualBuilder/listeners/mouseHover.js.map +1 -1
- package/dist/modern/visualBuilder/utils/collabUtils.cjs +3 -2
- package/dist/modern/visualBuilder/utils/collabUtils.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/collabUtils.js +3 -2
- package/dist/modern/visualBuilder/utils/collabUtils.js.map +1 -1
- package/dist/modern/visualBuilder/utils/createCachedFetch.cjs +58 -0
- package/dist/modern/visualBuilder/utils/createCachedFetch.cjs.map +1 -0
- package/dist/modern/visualBuilder/utils/createCachedFetch.d.cts +12 -0
- package/dist/modern/visualBuilder/utils/createCachedFetch.d.ts +12 -0
- package/dist/modern/visualBuilder/utils/createCachedFetch.js +35 -0
- package/dist/modern/visualBuilder/utils/createCachedFetch.js.map +1 -0
- package/dist/modern/visualBuilder/utils/fieldSchemaMap.cjs +1 -0
- package/dist/modern/visualBuilder/utils/fieldSchemaMap.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/fieldSchemaMap.js +1 -0
- package/dist/modern/visualBuilder/utils/fieldSchemaMap.js.map +1 -1
- package/dist/modern/visualBuilder/utils/getEntryPermissions.cjs +70 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissions.cjs.map +1 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissions.d.cts +14 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissions.d.ts +14 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissions.js +37 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissions.js.map +1 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.cjs +36 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.cjs.map +1 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.d.cts +12 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.d.ts +12 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.js +13 -0
- package/dist/modern/visualBuilder/utils/getEntryPermissionsCached.js.map +1 -0
- package/dist/modern/visualBuilder/utils/handleFieldMouseDown.cjs +8 -1
- package/dist/modern/visualBuilder/utils/handleFieldMouseDown.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/handleFieldMouseDown.js +8 -1
- package/dist/modern/visualBuilder/utils/handleFieldMouseDown.js.map +1 -1
- package/dist/modern/visualBuilder/utils/handleIndividualFields.cjs +11 -1
- package/dist/modern/visualBuilder/utils/handleIndividualFields.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/handleIndividualFields.js +11 -1
- package/dist/modern/visualBuilder/utils/handleIndividualFields.js.map +1 -1
- package/dist/modern/visualBuilder/utils/isFieldDisabled.cjs +7 -1
- package/dist/modern/visualBuilder/utils/isFieldDisabled.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/isFieldDisabled.d.cts +4 -2
- package/dist/modern/visualBuilder/utils/isFieldDisabled.d.ts +4 -2
- package/dist/modern/visualBuilder/utils/isFieldDisabled.js +7 -1
- package/dist/modern/visualBuilder/utils/isFieldDisabled.js.map +1 -1
- package/dist/modern/visualBuilder/utils/updateFocussedState.cjs +30 -9
- package/dist/modern/visualBuilder/utils/updateFocussedState.cjs.map +1 -1
- package/dist/modern/visualBuilder/utils/updateFocussedState.d.cts +1 -1
- package/dist/modern/visualBuilder/utils/updateFocussedState.d.ts +1 -1
- package/dist/modern/visualBuilder/utils/updateFocussedState.js +30 -9
- package/dist/modern/visualBuilder/utils/updateFocussedState.js.map +1 -1
- package/dist/modern/visualBuilder/visualBuilder.style.cjs +10 -1
- package/dist/modern/visualBuilder/visualBuilder.style.cjs.map +1 -1
- package/dist/modern/visualBuilder/visualBuilder.style.js +10 -1
- package/dist/modern/visualBuilder/visualBuilder.style.js.map +1 -1
- package/package.json +1 -1
|
@@ -49,6 +49,7 @@ var import_visualBuilder = require("../visualBuilder.style.cjs");
|
|
|
49
49
|
var import__2 = require("../../index.cjs");
|
|
50
50
|
var import_configManager = __toESM(require("../../configManager/configManager.cjs"), 1);
|
|
51
51
|
var import_generateThread = require("../generators/generateThread.cjs");
|
|
52
|
+
var import_getEntryPermissionsCached = require("../utils/getEntryPermissionsCached.cjs");
|
|
52
53
|
var config = import_configManager.default.get();
|
|
53
54
|
function resetCustomCursor(customCursor) {
|
|
54
55
|
if (customCursor) {
|
|
@@ -200,16 +201,31 @@ async function handleMouseHover(params) {
|
|
|
200
201
|
import_fieldSchemaMap.FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(
|
|
201
202
|
(fieldSchema) => {
|
|
202
203
|
if (!fieldSchema) return;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
204
|
+
let entryAcl;
|
|
205
|
+
(0, import_getEntryPermissionsCached.getEntryPermissionsCached)({
|
|
206
|
+
entryUid: fieldMetadata.entry_uid,
|
|
207
|
+
contentTypeUid: fieldMetadata.content_type_uid,
|
|
208
|
+
locale: fieldMetadata.locale
|
|
209
|
+
}).then((data) => {
|
|
210
|
+
entryAcl = data;
|
|
211
|
+
}).catch((error) => {
|
|
212
|
+
console.error(
|
|
213
|
+
"[Visual Builder] Error retrieving entry permissions:",
|
|
214
|
+
error
|
|
215
|
+
);
|
|
216
|
+
}).finally(() => {
|
|
217
|
+
if (!params2.customCursor) return;
|
|
218
|
+
const { isDisabled: fieldDisabled } = (0, import_isFieldDisabled.isFieldDisabled)(
|
|
219
|
+
fieldSchema,
|
|
220
|
+
eventDetails,
|
|
221
|
+
entryAcl
|
|
222
|
+
);
|
|
223
|
+
const fieldType = (0, import_getFieldType.getFieldType)(fieldSchema);
|
|
224
|
+
(0, import_generateCustomCursor.generateCustomCursor)({
|
|
225
|
+
fieldType,
|
|
226
|
+
customCursor: params2.customCursor,
|
|
227
|
+
fieldDisabled
|
|
228
|
+
});
|
|
213
229
|
});
|
|
214
230
|
}
|
|
215
231
|
);
|
|
@@ -220,9 +236,27 @@ async function handleMouseHover(params) {
|
|
|
220
236
|
addOutline(editableElement);
|
|
221
237
|
import_fieldSchemaMap.FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(
|
|
222
238
|
(fieldSchema) => {
|
|
239
|
+
let entryAcl;
|
|
223
240
|
if (!fieldSchema) return;
|
|
224
|
-
|
|
225
|
-
|
|
241
|
+
(0, import_getEntryPermissionsCached.getEntryPermissionsCached)({
|
|
242
|
+
entryUid: fieldMetadata.entry_uid,
|
|
243
|
+
contentTypeUid: fieldMetadata.content_type_uid,
|
|
244
|
+
locale: fieldMetadata.locale
|
|
245
|
+
}).then((data) => {
|
|
246
|
+
entryAcl = data;
|
|
247
|
+
}).catch((error) => {
|
|
248
|
+
console.error(
|
|
249
|
+
"[Visual Builder] Error retrieving entry permissions:",
|
|
250
|
+
error
|
|
251
|
+
);
|
|
252
|
+
}).finally(() => {
|
|
253
|
+
const { isDisabled: fieldDisabled } = (0, import_isFieldDisabled.isFieldDisabled)(
|
|
254
|
+
fieldSchema,
|
|
255
|
+
eventDetails,
|
|
256
|
+
entryAcl
|
|
257
|
+
);
|
|
258
|
+
addOutline(editableElement, fieldDisabled);
|
|
259
|
+
});
|
|
226
260
|
}
|
|
227
261
|
);
|
|
228
262
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/visualBuilder/listeners/mouseHover.ts"],"sourcesContent":["import { throttle } from \"lodash-es\";\nimport { getCsDataOfElement } from \"../utils/getCsDataOfElement\";\nimport { removeAddInstanceButtons } from \"../utils/multipleElementAddButton\";\nimport { generateCustomCursor } from \"../generators/generateCustomCursor\";\nimport { FieldSchemaMap } from \"../utils/fieldSchemaMap\";\nimport { isFieldDisabled } from \"../utils/isFieldDisabled\";\nimport { getFieldType } from \"../utils/getFieldType\";\n\nimport EventListenerHandlerParams from \"./types\";\nimport { VisualBuilder } from \"..\";\nimport { addHoverOutline } from \"../generators/generateHoverOutline\";\nimport { visualBuilderStyles } from \"../visualBuilder.style\";\nimport { VB_EmptyBlockParentClass } from \"../..\";\nimport Config from \"../../configManager/configManager\";\nimport { isCollabThread } from \"../generators/generateThread\";\n\nconst config = Config.get();\nexport interface HandleMouseHoverParams\n extends Pick<\n EventListenerHandlerParams,\n \"event\" | \"overlayWrapper\" | \"visualBuilderContainer\"\n > {\n customCursor: HTMLDivElement | null;\n}\n\nfunction resetCustomCursor(customCursor: HTMLDivElement | null): void {\n if (customCursor) {\n generateCustomCursor({\n fieldType: \"empty\",\n customCursor: customCursor,\n });\n }\n}\n\nfunction collabCustomCursor(customCursor: HTMLDivElement | null): void {\n if (!customCursor) return;\n\n generateCustomCursor({\n fieldType: \"discussion\",\n customCursor: customCursor,\n });\n}\n\nfunction handleCursorPosition(\n event: MouseEvent,\n customCursor: HTMLDivElement | null\n): void {\n if (customCursor) {\n const mouseY = event.clientY;\n const mouseX = event.clientX;\n\n customCursor.style.left = `${mouseX}px`;\n customCursor.style.top = `${mouseY}px`;\n }\n}\n\nfunction addOutline(editableElement: Element, isFieldDisabled?: boolean): void {\n if (!editableElement) return;\n\n addHoverOutline(editableElement as HTMLElement, isFieldDisabled);\n}\n\nfunction hideDefaultCursor(): void {\n if (\n document?.body &&\n !document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.add(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nfunction showDefaultCursor(): void {\n if (\n document?.body &&\n document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.remove(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nexport function hideHoverOutline(\n visualBuilderContainer: HTMLDivElement | null\n): void {\n if (!visualBuilderContainer) {\n return;\n }\n const hoverOutline = visualBuilderContainer.querySelector(\n \".visual-builder__hover-outline\"\n );\n if (!hoverOutline) {\n return;\n }\n hoverOutline.classList.add(\n visualBuilderStyles()[\"visual-builder__hover-outline--hidden\"]\n );\n}\n\nexport function hideCustomCursor(customCursor: HTMLDivElement | null): void {\n showDefaultCursor();\n customCursor?.classList.remove(\"visible\");\n}\n\nexport function showCustomCursor(customCursor: HTMLDivElement | null): void {\n hideDefaultCursor();\n if (\n config.collab.enable &&\n (!config.collab.isFeedbackMode || config.collab.pauseFeedback)\n )\n return;\n customCursor?.classList.add(\"visible\");\n}\n\nfunction isOverlay(target: HTMLElement): boolean {\n return target.classList.contains(\"visual-builder__overlay\");\n}\n\nfunction isContentEditable(target: HTMLElement): boolean {\n if (target.hasAttribute(\"contenteditable\"))\n return target.getAttribute(\"contenteditable\") === \"true\";\n return false;\n}\n\nasync function handleMouseHover(params: HandleMouseHoverParams): Promise<void> {\n throttle(async (params: HandleMouseHoverParams) => {\n const eventDetails = getCsDataOfElement(params.event);\n const eventTarget = params.event.target as HTMLElement | null;\n\n if (config?.collab.enable && config?.collab.pauseFeedback) {\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!eventDetails) {\n if (\n eventTarget &&\n (isOverlay(eventTarget) ||\n isContentEditable(eventTarget) ||\n isCollabThread(eventTarget))\n ) {\n handleCursorPosition(params.event, params.customCursor);\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!config?.collab.enable) {\n resetCustomCursor(params.customCursor);\n }\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n handleCursorPosition(params.event, params.customCursor);\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n showCustomCursor(params.customCursor);\n collabCustomCursor(params.customCursor);\n }\n return;\n }\n\n const { editableElement, fieldMetadata } = eventDetails;\n const { content_type_uid, fieldPath } = fieldMetadata;\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousSelectedEditableDOM &&\n VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.isSameNode(\n editableElement\n )\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (params.customCursor) {\n const elementUnderCursor = document.elementFromPoint(\n params.event.clientX,\n params.event.clientY\n );\n if (elementUnderCursor) {\n if (\n elementUnderCursor.nodeName === \"A\" ||\n elementUnderCursor.nodeName === \"BUTTON\"\n ) {\n elementUnderCursor.classList.add(\n visualBuilderStyles()[\"visual-builder__no-cursor-style\"]\n );\n }\n }\n\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n collabCustomCursor(params.customCursor);\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n return;\n } else if (\n config?.collab.enable &&\n !config?.collab.isFeedbackMode\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM !== editableElement\n ) {\n resetCustomCursor(params.customCursor);\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n }\n\n if (!FieldSchemaMap.hasFieldSchema(content_type_uid, fieldPath)) {\n generateCustomCursor({\n fieldType: \"loading\",\n customCursor: params.customCursor,\n });\n }\n\n /**\n * We called it seperately inside the code block to ensure that\n * the code will not wait for the promise to resolve.\n * If we get a cache miss, we will send a message to the iframe\n * without blocking the code.\n */\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n if (!params.customCursor) return;\n const { isDisabled: fieldDisabled } = isFieldDisabled(\n fieldSchema,\n eventDetails\n );\n const fieldType = getFieldType(fieldSchema);\n generateCustomCursor({\n fieldType,\n customCursor: params.customCursor,\n fieldDisabled,\n });\n }\n );\n\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n }\n\n if (\n !editableElement.classList.contains(VB_EmptyBlockParentClass) &&\n !editableElement.classList.contains(\"visual-builder__empty-block\")\n ) {\n addOutline(editableElement);\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n const { isDisabled: fieldDisabled, reason } =\n isFieldDisabled(fieldSchema, eventDetails);\n addOutline(editableElement, fieldDisabled);\n }\n );\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM === editableElement\n ) {\n return;\n }\n\n VisualBuilder.VisualBuilderGlobalState.value.previousHoveredTargetDOM =\n editableElement;\n }, 10)(params);\n}\n\nexport default handleMouseHover;\n"],"mappings":"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","names":["import__","Config","isFieldDisabled","params"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/visualBuilder/listeners/mouseHover.ts"],"sourcesContent":["import { throttle } from \"lodash-es\";\nimport { getCsDataOfElement } from \"../utils/getCsDataOfElement\";\nimport { removeAddInstanceButtons } from \"../utils/multipleElementAddButton\";\nimport { generateCustomCursor } from \"../generators/generateCustomCursor\";\nimport { FieldSchemaMap } from \"../utils/fieldSchemaMap\";\nimport { isFieldDisabled } from \"../utils/isFieldDisabled\";\nimport { getFieldType } from \"../utils/getFieldType\";\n\nimport EventListenerHandlerParams from \"./types\";\nimport { VisualBuilder } from \"..\";\nimport { addHoverOutline } from \"../generators/generateHoverOutline\";\nimport { visualBuilderStyles } from \"../visualBuilder.style\";\nimport { VB_EmptyBlockParentClass } from \"../..\";\nimport Config from \"../../configManager/configManager\";\nimport { isCollabThread } from \"../generators/generateThread\";\nimport { getEntryPermissionsCached } from \"../utils/getEntryPermissionsCached\";\nimport { EntryPermissions } from \"../utils/getEntryPermissions\";\n\nconst config = Config.get();\nexport interface HandleMouseHoverParams\n extends Pick<\n EventListenerHandlerParams,\n \"event\" | \"overlayWrapper\" | \"visualBuilderContainer\"\n > {\n customCursor: HTMLDivElement | null;\n}\n\nfunction resetCustomCursor(customCursor: HTMLDivElement | null): void {\n if (customCursor) {\n generateCustomCursor({\n fieldType: \"empty\",\n customCursor: customCursor,\n });\n }\n}\n\nfunction collabCustomCursor(customCursor: HTMLDivElement | null): void {\n if (!customCursor) return;\n\n generateCustomCursor({\n fieldType: \"discussion\",\n customCursor: customCursor,\n });\n}\n\nfunction handleCursorPosition(\n event: MouseEvent,\n customCursor: HTMLDivElement | null\n): void {\n if (customCursor) {\n const mouseY = event.clientY;\n const mouseX = event.clientX;\n\n customCursor.style.left = `${mouseX}px`;\n customCursor.style.top = `${mouseY}px`;\n }\n}\n\nfunction addOutline(editableElement: Element, isFieldDisabled?: boolean): void {\n if (!editableElement) return;\n\n addHoverOutline(editableElement as HTMLElement, isFieldDisabled);\n}\n\nfunction hideDefaultCursor(): void {\n if (\n document?.body &&\n !document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.add(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nfunction showDefaultCursor(): void {\n if (\n document?.body &&\n document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.remove(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nexport function hideHoverOutline(\n visualBuilderContainer: HTMLDivElement | null\n): void {\n if (!visualBuilderContainer) {\n return;\n }\n const hoverOutline = visualBuilderContainer.querySelector(\n \".visual-builder__hover-outline\"\n );\n if (!hoverOutline) {\n return;\n }\n hoverOutline.classList.add(\n visualBuilderStyles()[\"visual-builder__hover-outline--hidden\"]\n );\n}\n\nexport function hideCustomCursor(customCursor: HTMLDivElement | null): void {\n showDefaultCursor();\n customCursor?.classList.remove(\"visible\");\n}\n\nexport function showCustomCursor(customCursor: HTMLDivElement | null): void {\n hideDefaultCursor();\n if (\n config.collab.enable &&\n (!config.collab.isFeedbackMode || config.collab.pauseFeedback)\n )\n return;\n customCursor?.classList.add(\"visible\");\n}\n\nfunction isOverlay(target: HTMLElement): boolean {\n return target.classList.contains(\"visual-builder__overlay\");\n}\n\nfunction isContentEditable(target: HTMLElement): boolean {\n if (target.hasAttribute(\"contenteditable\"))\n return target.getAttribute(\"contenteditable\") === \"true\";\n return false;\n}\n\nasync function handleMouseHover(params: HandleMouseHoverParams): Promise<void> {\n throttle(async (params: HandleMouseHoverParams) => {\n const eventDetails = getCsDataOfElement(params.event);\n const eventTarget = params.event.target as HTMLElement | null;\n\n if (config?.collab.enable && config?.collab.pauseFeedback) {\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!eventDetails) {\n if (\n eventTarget &&\n (isOverlay(eventTarget) ||\n isContentEditable(eventTarget) ||\n isCollabThread(eventTarget))\n ) {\n handleCursorPosition(params.event, params.customCursor);\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!config?.collab.enable) {\n resetCustomCursor(params.customCursor);\n }\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n handleCursorPosition(params.event, params.customCursor);\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n showCustomCursor(params.customCursor);\n collabCustomCursor(params.customCursor);\n }\n return;\n }\n\n const { editableElement, fieldMetadata } = eventDetails;\n const { content_type_uid, fieldPath } = fieldMetadata;\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousSelectedEditableDOM &&\n VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.isSameNode(\n editableElement\n )\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (params.customCursor) {\n const elementUnderCursor = document.elementFromPoint(\n params.event.clientX,\n params.event.clientY\n );\n if (elementUnderCursor) {\n if (\n elementUnderCursor.nodeName === \"A\" ||\n elementUnderCursor.nodeName === \"BUTTON\"\n ) {\n elementUnderCursor.classList.add(\n visualBuilderStyles()[\"visual-builder__no-cursor-style\"]\n );\n }\n }\n\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n collabCustomCursor(params.customCursor);\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n return;\n } else if (\n config?.collab.enable &&\n !config?.collab.isFeedbackMode\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM !== editableElement\n ) {\n resetCustomCursor(params.customCursor);\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n }\n\n if (!FieldSchemaMap.hasFieldSchema(content_type_uid, fieldPath)) {\n generateCustomCursor({\n fieldType: \"loading\",\n customCursor: params.customCursor,\n });\n }\n\n /**\n * We called it seperately inside the code block to ensure that\n * the code will not wait for the promise to resolve.\n * If we get a cache miss, we will send a message to the iframe\n * without blocking the code.\n */\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n\n let entryAcl: EntryPermissions | undefined;\n getEntryPermissionsCached({\n entryUid: fieldMetadata.entry_uid,\n contentTypeUid: fieldMetadata.content_type_uid,\n locale: fieldMetadata.locale,\n })\n .then((data) => {\n entryAcl = data;\n })\n .catch((error) => {\n console.error(\n \"[Visual Builder] Error retrieving entry permissions:\",\n error\n );\n })\n .finally(() => {\n if (!params.customCursor) return;\n const { isDisabled: fieldDisabled } =\n isFieldDisabled(\n fieldSchema,\n eventDetails,\n entryAcl\n );\n const fieldType = getFieldType(fieldSchema);\n generateCustomCursor({\n fieldType,\n customCursor: params.customCursor,\n fieldDisabled,\n });\n });\n }\n );\n\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n }\n\n if (\n !editableElement.classList.contains(VB_EmptyBlockParentClass) &&\n !editableElement.classList.contains(\"visual-builder__empty-block\")\n ) {\n addOutline(editableElement);\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n let entryAcl: EntryPermissions | undefined;\n if (!fieldSchema) return;\n getEntryPermissionsCached({\n entryUid: fieldMetadata.entry_uid,\n contentTypeUid: fieldMetadata.content_type_uid,\n locale: fieldMetadata.locale,\n })\n .then((data) => {\n entryAcl = data;\n })\n .catch((error) => {\n console.error(\n \"[Visual Builder] Error retrieving entry permissions:\",\n error\n );\n })\n .finally(() => {\n const { isDisabled: fieldDisabled } =\n isFieldDisabled(\n fieldSchema,\n eventDetails,\n entryAcl\n );\n addOutline(editableElement, fieldDisabled);\n });\n }\n );\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM === editableElement\n ) {\n return;\n }\n\n VisualBuilder.VisualBuilderGlobalState.value.previousHoveredTargetDOM =\n editableElement;\n }, 10)(params);\n}\n\nexport default handleMouseHover;\n"],"mappings":"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","names":["import__","Config","isFieldDisabled","params"]}
|
|
@@ -14,6 +14,7 @@ import { visualBuilderStyles } from "../visualBuilder.style.js";
|
|
|
14
14
|
import { VB_EmptyBlockParentClass } from "../../index.js";
|
|
15
15
|
import Config from "../../configManager/configManager.js";
|
|
16
16
|
import { isCollabThread } from "../generators/generateThread.js";
|
|
17
|
+
import { getEntryPermissionsCached } from "../utils/getEntryPermissionsCached.js";
|
|
17
18
|
var config = Config.get();
|
|
18
19
|
function resetCustomCursor(customCursor) {
|
|
19
20
|
if (customCursor) {
|
|
@@ -165,16 +166,31 @@ async function handleMouseHover(params) {
|
|
|
165
166
|
FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(
|
|
166
167
|
(fieldSchema) => {
|
|
167
168
|
if (!fieldSchema) return;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
169
|
+
let entryAcl;
|
|
170
|
+
getEntryPermissionsCached({
|
|
171
|
+
entryUid: fieldMetadata.entry_uid,
|
|
172
|
+
contentTypeUid: fieldMetadata.content_type_uid,
|
|
173
|
+
locale: fieldMetadata.locale
|
|
174
|
+
}).then((data) => {
|
|
175
|
+
entryAcl = data;
|
|
176
|
+
}).catch((error) => {
|
|
177
|
+
console.error(
|
|
178
|
+
"[Visual Builder] Error retrieving entry permissions:",
|
|
179
|
+
error
|
|
180
|
+
);
|
|
181
|
+
}).finally(() => {
|
|
182
|
+
if (!params2.customCursor) return;
|
|
183
|
+
const { isDisabled: fieldDisabled } = isFieldDisabled(
|
|
184
|
+
fieldSchema,
|
|
185
|
+
eventDetails,
|
|
186
|
+
entryAcl
|
|
187
|
+
);
|
|
188
|
+
const fieldType = getFieldType(fieldSchema);
|
|
189
|
+
generateCustomCursor({
|
|
190
|
+
fieldType,
|
|
191
|
+
customCursor: params2.customCursor,
|
|
192
|
+
fieldDisabled
|
|
193
|
+
});
|
|
178
194
|
});
|
|
179
195
|
}
|
|
180
196
|
);
|
|
@@ -185,9 +201,27 @@ async function handleMouseHover(params) {
|
|
|
185
201
|
addOutline(editableElement);
|
|
186
202
|
FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(
|
|
187
203
|
(fieldSchema) => {
|
|
204
|
+
let entryAcl;
|
|
188
205
|
if (!fieldSchema) return;
|
|
189
|
-
|
|
190
|
-
|
|
206
|
+
getEntryPermissionsCached({
|
|
207
|
+
entryUid: fieldMetadata.entry_uid,
|
|
208
|
+
contentTypeUid: fieldMetadata.content_type_uid,
|
|
209
|
+
locale: fieldMetadata.locale
|
|
210
|
+
}).then((data) => {
|
|
211
|
+
entryAcl = data;
|
|
212
|
+
}).catch((error) => {
|
|
213
|
+
console.error(
|
|
214
|
+
"[Visual Builder] Error retrieving entry permissions:",
|
|
215
|
+
error
|
|
216
|
+
);
|
|
217
|
+
}).finally(() => {
|
|
218
|
+
const { isDisabled: fieldDisabled } = isFieldDisabled(
|
|
219
|
+
fieldSchema,
|
|
220
|
+
eventDetails,
|
|
221
|
+
entryAcl
|
|
222
|
+
);
|
|
223
|
+
addOutline(editableElement, fieldDisabled);
|
|
224
|
+
});
|
|
191
225
|
}
|
|
192
226
|
);
|
|
193
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/visualBuilder/listeners/mouseHover.ts"],"sourcesContent":["import { throttle } from \"lodash-es\";\nimport { getCsDataOfElement } from \"../utils/getCsDataOfElement\";\nimport { removeAddInstanceButtons } from \"../utils/multipleElementAddButton\";\nimport { generateCustomCursor } from \"../generators/generateCustomCursor\";\nimport { FieldSchemaMap } from \"../utils/fieldSchemaMap\";\nimport { isFieldDisabled } from \"../utils/isFieldDisabled\";\nimport { getFieldType } from \"../utils/getFieldType\";\n\nimport EventListenerHandlerParams from \"./types\";\nimport { VisualBuilder } from \"..\";\nimport { addHoverOutline } from \"../generators/generateHoverOutline\";\nimport { visualBuilderStyles } from \"../visualBuilder.style\";\nimport { VB_EmptyBlockParentClass } from \"../..\";\nimport Config from \"../../configManager/configManager\";\nimport { isCollabThread } from \"../generators/generateThread\";\n\nconst config = Config.get();\nexport interface HandleMouseHoverParams\n extends Pick<\n EventListenerHandlerParams,\n \"event\" | \"overlayWrapper\" | \"visualBuilderContainer\"\n > {\n customCursor: HTMLDivElement | null;\n}\n\nfunction resetCustomCursor(customCursor: HTMLDivElement | null): void {\n if (customCursor) {\n generateCustomCursor({\n fieldType: \"empty\",\n customCursor: customCursor,\n });\n }\n}\n\nfunction collabCustomCursor(customCursor: HTMLDivElement | null): void {\n if (!customCursor) return;\n\n generateCustomCursor({\n fieldType: \"discussion\",\n customCursor: customCursor,\n });\n}\n\nfunction handleCursorPosition(\n event: MouseEvent,\n customCursor: HTMLDivElement | null\n): void {\n if (customCursor) {\n const mouseY = event.clientY;\n const mouseX = event.clientX;\n\n customCursor.style.left = `${mouseX}px`;\n customCursor.style.top = `${mouseY}px`;\n }\n}\n\nfunction addOutline(editableElement: Element, isFieldDisabled?: boolean): void {\n if (!editableElement) return;\n\n addHoverOutline(editableElement as HTMLElement, isFieldDisabled);\n}\n\nfunction hideDefaultCursor(): void {\n if (\n document?.body &&\n !document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.add(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nfunction showDefaultCursor(): void {\n if (\n document?.body &&\n document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.remove(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nexport function hideHoverOutline(\n visualBuilderContainer: HTMLDivElement | null\n): void {\n if (!visualBuilderContainer) {\n return;\n }\n const hoverOutline = visualBuilderContainer.querySelector(\n \".visual-builder__hover-outline\"\n );\n if (!hoverOutline) {\n return;\n }\n hoverOutline.classList.add(\n visualBuilderStyles()[\"visual-builder__hover-outline--hidden\"]\n );\n}\n\nexport function hideCustomCursor(customCursor: HTMLDivElement | null): void {\n showDefaultCursor();\n customCursor?.classList.remove(\"visible\");\n}\n\nexport function showCustomCursor(customCursor: HTMLDivElement | null): void {\n hideDefaultCursor();\n if (\n config.collab.enable &&\n (!config.collab.isFeedbackMode || config.collab.pauseFeedback)\n )\n return;\n customCursor?.classList.add(\"visible\");\n}\n\nfunction isOverlay(target: HTMLElement): boolean {\n return target.classList.contains(\"visual-builder__overlay\");\n}\n\nfunction isContentEditable(target: HTMLElement): boolean {\n if (target.hasAttribute(\"contenteditable\"))\n return target.getAttribute(\"contenteditable\") === \"true\";\n return false;\n}\n\nasync function handleMouseHover(params: HandleMouseHoverParams): Promise<void> {\n throttle(async (params: HandleMouseHoverParams) => {\n const eventDetails = getCsDataOfElement(params.event);\n const eventTarget = params.event.target as HTMLElement | null;\n\n if (config?.collab.enable && config?.collab.pauseFeedback) {\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!eventDetails) {\n if (\n eventTarget &&\n (isOverlay(eventTarget) ||\n isContentEditable(eventTarget) ||\n isCollabThread(eventTarget))\n ) {\n handleCursorPosition(params.event, params.customCursor);\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!config?.collab.enable) {\n resetCustomCursor(params.customCursor);\n }\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n handleCursorPosition(params.event, params.customCursor);\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n showCustomCursor(params.customCursor);\n collabCustomCursor(params.customCursor);\n }\n return;\n }\n\n const { editableElement, fieldMetadata } = eventDetails;\n const { content_type_uid, fieldPath } = fieldMetadata;\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousSelectedEditableDOM &&\n VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.isSameNode(\n editableElement\n )\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (params.customCursor) {\n const elementUnderCursor = document.elementFromPoint(\n params.event.clientX,\n params.event.clientY\n );\n if (elementUnderCursor) {\n if (\n elementUnderCursor.nodeName === \"A\" ||\n elementUnderCursor.nodeName === \"BUTTON\"\n ) {\n elementUnderCursor.classList.add(\n visualBuilderStyles()[\"visual-builder__no-cursor-style\"]\n );\n }\n }\n\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n collabCustomCursor(params.customCursor);\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n return;\n } else if (\n config?.collab.enable &&\n !config?.collab.isFeedbackMode\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM !== editableElement\n ) {\n resetCustomCursor(params.customCursor);\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n }\n\n if (!FieldSchemaMap.hasFieldSchema(content_type_uid, fieldPath)) {\n generateCustomCursor({\n fieldType: \"loading\",\n customCursor: params.customCursor,\n });\n }\n\n /**\n * We called it seperately inside the code block to ensure that\n * the code will not wait for the promise to resolve.\n * If we get a cache miss, we will send a message to the iframe\n * without blocking the code.\n */\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n if (!params.customCursor) return;\n const { isDisabled: fieldDisabled } = isFieldDisabled(\n fieldSchema,\n eventDetails\n );\n const fieldType = getFieldType(fieldSchema);\n generateCustomCursor({\n fieldType,\n customCursor: params.customCursor,\n fieldDisabled,\n });\n }\n );\n\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n }\n\n if (\n !editableElement.classList.contains(VB_EmptyBlockParentClass) &&\n !editableElement.classList.contains(\"visual-builder__empty-block\")\n ) {\n addOutline(editableElement);\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n const { isDisabled: fieldDisabled, reason } =\n isFieldDisabled(fieldSchema, eventDetails);\n addOutline(editableElement, fieldDisabled);\n }\n );\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM === editableElement\n ) {\n return;\n }\n\n VisualBuilder.VisualBuilderGlobalState.value.previousHoveredTargetDOM =\n editableElement;\n }, 10)(params);\n}\n\nexport default handleMouseHover;\n"],"mappings":"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","names":["isFieldDisabled","params"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/visualBuilder/listeners/mouseHover.ts"],"sourcesContent":["import { throttle } from \"lodash-es\";\nimport { getCsDataOfElement } from \"../utils/getCsDataOfElement\";\nimport { removeAddInstanceButtons } from \"../utils/multipleElementAddButton\";\nimport { generateCustomCursor } from \"../generators/generateCustomCursor\";\nimport { FieldSchemaMap } from \"../utils/fieldSchemaMap\";\nimport { isFieldDisabled } from \"../utils/isFieldDisabled\";\nimport { getFieldType } from \"../utils/getFieldType\";\n\nimport EventListenerHandlerParams from \"./types\";\nimport { VisualBuilder } from \"..\";\nimport { addHoverOutline } from \"../generators/generateHoverOutline\";\nimport { visualBuilderStyles } from \"../visualBuilder.style\";\nimport { VB_EmptyBlockParentClass } from \"../..\";\nimport Config from \"../../configManager/configManager\";\nimport { isCollabThread } from \"../generators/generateThread\";\nimport { getEntryPermissionsCached } from \"../utils/getEntryPermissionsCached\";\nimport { EntryPermissions } from \"../utils/getEntryPermissions\";\n\nconst config = Config.get();\nexport interface HandleMouseHoverParams\n extends Pick<\n EventListenerHandlerParams,\n \"event\" | \"overlayWrapper\" | \"visualBuilderContainer\"\n > {\n customCursor: HTMLDivElement | null;\n}\n\nfunction resetCustomCursor(customCursor: HTMLDivElement | null): void {\n if (customCursor) {\n generateCustomCursor({\n fieldType: \"empty\",\n customCursor: customCursor,\n });\n }\n}\n\nfunction collabCustomCursor(customCursor: HTMLDivElement | null): void {\n if (!customCursor) return;\n\n generateCustomCursor({\n fieldType: \"discussion\",\n customCursor: customCursor,\n });\n}\n\nfunction handleCursorPosition(\n event: MouseEvent,\n customCursor: HTMLDivElement | null\n): void {\n if (customCursor) {\n const mouseY = event.clientY;\n const mouseX = event.clientX;\n\n customCursor.style.left = `${mouseX}px`;\n customCursor.style.top = `${mouseY}px`;\n }\n}\n\nfunction addOutline(editableElement: Element, isFieldDisabled?: boolean): void {\n if (!editableElement) return;\n\n addHoverOutline(editableElement as HTMLElement, isFieldDisabled);\n}\n\nfunction hideDefaultCursor(): void {\n if (\n document?.body &&\n !document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.add(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nfunction showDefaultCursor(): void {\n if (\n document?.body &&\n document.body.classList.contains(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n )\n )\n document.body.classList.remove(\n visualBuilderStyles()[\"visual-builder__default-cursor--disabled\"]\n );\n}\n\nexport function hideHoverOutline(\n visualBuilderContainer: HTMLDivElement | null\n): void {\n if (!visualBuilderContainer) {\n return;\n }\n const hoverOutline = visualBuilderContainer.querySelector(\n \".visual-builder__hover-outline\"\n );\n if (!hoverOutline) {\n return;\n }\n hoverOutline.classList.add(\n visualBuilderStyles()[\"visual-builder__hover-outline--hidden\"]\n );\n}\n\nexport function hideCustomCursor(customCursor: HTMLDivElement | null): void {\n showDefaultCursor();\n customCursor?.classList.remove(\"visible\");\n}\n\nexport function showCustomCursor(customCursor: HTMLDivElement | null): void {\n hideDefaultCursor();\n if (\n config.collab.enable &&\n (!config.collab.isFeedbackMode || config.collab.pauseFeedback)\n )\n return;\n customCursor?.classList.add(\"visible\");\n}\n\nfunction isOverlay(target: HTMLElement): boolean {\n return target.classList.contains(\"visual-builder__overlay\");\n}\n\nfunction isContentEditable(target: HTMLElement): boolean {\n if (target.hasAttribute(\"contenteditable\"))\n return target.getAttribute(\"contenteditable\") === \"true\";\n return false;\n}\n\nasync function handleMouseHover(params: HandleMouseHoverParams): Promise<void> {\n throttle(async (params: HandleMouseHoverParams) => {\n const eventDetails = getCsDataOfElement(params.event);\n const eventTarget = params.event.target as HTMLElement | null;\n\n if (config?.collab.enable && config?.collab.pauseFeedback) {\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!eventDetails) {\n if (\n eventTarget &&\n (isOverlay(eventTarget) ||\n isContentEditable(eventTarget) ||\n isCollabThread(eventTarget))\n ) {\n handleCursorPosition(params.event, params.customCursor);\n hideCustomCursor(params.customCursor);\n return;\n }\n if (!config?.collab.enable) {\n resetCustomCursor(params.customCursor);\n }\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n handleCursorPosition(params.event, params.customCursor);\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n showCustomCursor(params.customCursor);\n collabCustomCursor(params.customCursor);\n }\n return;\n }\n\n const { editableElement, fieldMetadata } = eventDetails;\n const { content_type_uid, fieldPath } = fieldMetadata;\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousSelectedEditableDOM &&\n VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.isSameNode(\n editableElement\n )\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (params.customCursor) {\n const elementUnderCursor = document.elementFromPoint(\n params.event.clientX,\n params.event.clientY\n );\n if (elementUnderCursor) {\n if (\n elementUnderCursor.nodeName === \"A\" ||\n elementUnderCursor.nodeName === \"BUTTON\"\n ) {\n elementUnderCursor.classList.add(\n visualBuilderStyles()[\"visual-builder__no-cursor-style\"]\n );\n }\n }\n\n if (config?.collab.enable && config?.collab.isFeedbackMode) {\n collabCustomCursor(params.customCursor);\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n return;\n } else if (\n config?.collab.enable &&\n !config?.collab.isFeedbackMode\n ) {\n hideCustomCursor(params.customCursor);\n return;\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM !== editableElement\n ) {\n resetCustomCursor(params.customCursor);\n removeAddInstanceButtons({\n eventTarget: params.event.target,\n visualBuilderContainer: params.visualBuilderContainer,\n overlayWrapper: params.overlayWrapper,\n });\n }\n\n if (!FieldSchemaMap.hasFieldSchema(content_type_uid, fieldPath)) {\n generateCustomCursor({\n fieldType: \"loading\",\n customCursor: params.customCursor,\n });\n }\n\n /**\n * We called it seperately inside the code block to ensure that\n * the code will not wait for the promise to resolve.\n * If we get a cache miss, we will send a message to the iframe\n * without blocking the code.\n */\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n if (!fieldSchema) return;\n\n let entryAcl: EntryPermissions | undefined;\n getEntryPermissionsCached({\n entryUid: fieldMetadata.entry_uid,\n contentTypeUid: fieldMetadata.content_type_uid,\n locale: fieldMetadata.locale,\n })\n .then((data) => {\n entryAcl = data;\n })\n .catch((error) => {\n console.error(\n \"[Visual Builder] Error retrieving entry permissions:\",\n error\n );\n })\n .finally(() => {\n if (!params.customCursor) return;\n const { isDisabled: fieldDisabled } =\n isFieldDisabled(\n fieldSchema,\n eventDetails,\n entryAcl\n );\n const fieldType = getFieldType(fieldSchema);\n generateCustomCursor({\n fieldType,\n customCursor: params.customCursor,\n fieldDisabled,\n });\n });\n }\n );\n\n handleCursorPosition(params.event, params.customCursor);\n showCustomCursor(params.customCursor);\n }\n\n if (\n !editableElement.classList.contains(VB_EmptyBlockParentClass) &&\n !editableElement.classList.contains(\"visual-builder__empty-block\")\n ) {\n addOutline(editableElement);\n FieldSchemaMap.getFieldSchema(content_type_uid, fieldPath).then(\n (fieldSchema) => {\n let entryAcl: EntryPermissions | undefined;\n if (!fieldSchema) return;\n getEntryPermissionsCached({\n entryUid: fieldMetadata.entry_uid,\n contentTypeUid: fieldMetadata.content_type_uid,\n locale: fieldMetadata.locale,\n })\n .then((data) => {\n entryAcl = data;\n })\n .catch((error) => {\n console.error(\n \"[Visual Builder] Error retrieving entry permissions:\",\n error\n );\n })\n .finally(() => {\n const { isDisabled: fieldDisabled } =\n isFieldDisabled(\n fieldSchema,\n eventDetails,\n entryAcl\n );\n addOutline(editableElement, fieldDisabled);\n });\n }\n );\n }\n\n if (\n VisualBuilder.VisualBuilderGlobalState.value\n .previousHoveredTargetDOM === editableElement\n ) {\n return;\n }\n\n VisualBuilder.VisualBuilderGlobalState.value.previousHoveredTargetDOM =\n editableElement;\n }, 10)(params);\n}\n\nexport default handleMouseHover;\n"],"mappings":"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","names":["isFieldDisabled","params"]}
|
|
@@ -78,10 +78,11 @@ var filterOutInvalidMentions = (message, toUsers) => {
|
|
|
78
78
|
var getMessageWithDisplayName = (comment, userState, profile) => {
|
|
79
79
|
if (!comment) return void 0;
|
|
80
80
|
let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, "");
|
|
81
|
-
comment
|
|
81
|
+
comment.toUsers?.forEach((user) => {
|
|
82
82
|
const userPattern = new RegExp(`{{${user}}}`, "g");
|
|
83
83
|
const userData = userState.userMap[user];
|
|
84
|
-
const
|
|
84
|
+
const displayName = userData ? userData.display || getUserName(userData) : `unknown user`;
|
|
85
|
+
const replacement = profile === "html" ? `<b class="collab-thread-comment--message">@${displayName}</b>` : `@${displayName}`;
|
|
85
86
|
tempText = tempText.replace(userPattern, replacement);
|
|
86
87
|
});
|
|
87
88
|
return tempText;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/visualBuilder/utils/collabUtils.ts"],"sourcesContent":["import {\n ICommentState,\n IMentionedList,\n IMentionItem,\n IMessageDTO,\n IUserDTO,\n IUserState,\n} from \"../types/collab.types\";\nimport { maxMessageLength, mentionLimit } from \"./constants\";\nimport { uniqBy } from \"lodash-es\";\nimport DOMPurify from \"dompurify\";\nimport dayjs from \"dayjs\";\n\nconst escapeRegExp = (string: string): string => {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\n/**\n * Generates the title for the thread based on the number of comments.\n * @param {number} commentCount - The number of comments.\n * @returns {string} The title for the thread.\n */\nexport const getThreadTitle = (commentCount: number): string => {\n if (commentCount === 0) return \"Add New Comment\";\n return commentCount === 1 ? \"1 Comment\" : `${commentCount} Comments`;\n};\n\n/**\n * returns the available email.\n * @param {IUserDTO} user - The user object.\n * @returns {string} The user's email.\n */\nexport const getUserName = (user: IUserDTO): string => {\n return user.firstName && user.lastName\n ? `${user.firstName} ${user.lastName}`\n : user.firstName || user.lastName || user.email;\n};\n\n/**\n * Validates the comment length and the number of mentions.\n * @param {string} comment - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {string} The error message if validation fails, otherwise an empty string.\n */\nexport const validateCommentAndMentions = (\n comment: string,\n toUsers: IMentionedList\n): string => {\n if (comment.length > maxMessageLength) {\n return `Limit exceeded. You can have a maximum length of ${maxMessageLength} characters.`;\n }\n if (toUsers.length > mentionLimit) {\n return `Limit exceeded. You can tag a maximum of ${mentionLimit} users.`;\n }\n return \"\";\n};\n\n/**\n * Removes mentions that no longer exist in the message.\n * @param {string} message - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {Object} The updated lists of mentioned users.\n */\nexport const filterOutInvalidMentions = (\n message: string,\n toUsers: IMentionedList\n) => {\n const to_users_temp = toUsers.filter((user) =>\n message.includes(user.display)\n );\n\n return {\n toUsers: uniqBy(to_users_temp, \"id\"),\n };\n};\n\n/**\n * Replaces mention placeholders with display names in the comment message.\n * @param {IMessageDTO | undefined} comment - The comment object.\n * @param {IUserState} userState - The user state containing user and role maps.\n * @param {\"text\" | \"html\"} profile - The format for the output message, either plain text or HTML.\n * @returns {string | undefined} The formatted message or undefined if the comment is not provided.\n */\nexport const getMessageWithDisplayName = (\n comment: IMessageDTO | undefined | null,\n userState: IUserState,\n profile: \"text\" | \"html\"\n): string | undefined => {\n if (!comment) return undefined;\n\n let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, \"\");\n\n comment?.toUsers?.forEach((user) => {\n const userPattern = new RegExp(`{{${user}}}`, \"g\");\n const userData = userState.userMap[user];\n const replacement =\n profile === \"html\"\n ? `<b class=\"collab-thread-comment--message\">@${userData.display || getUserName(userData)}</b>`\n : `@${userData.display || getUserName(userData)}`;\n tempText = tempText.replace(userPattern, replacement);\n });\n\n return tempText;\n};\n\n/**\n * Sanitizes HTML content to prevent XSS attacks.\n * @param {any} dirty - The unsanitized HTML content.\n * @returns {string} The sanitized HTML content.\n */\nexport const sanitizeData = (dirty: any): string => {\n return DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });\n};\n\n/**\n * Constructs the comment body with mentions replaced by their unique identifiers.\n * @param {ICommentState} state - The state containing the comment and mentions.\n * @returns {Object} The comment body containing the sanitized message and mentioned users.\n */\nexport const getCommentBody = (state: ICommentState): ICommentState => {\n let finalMessage = sanitizeData(state.message)\n .replace(/[^\\S\\r\\n]+/g, \" \")\n .replace(/ *\\n */g, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .trim();\n\n const comment = {\n message: finalMessage,\n toUsers: [],\n images: [],\n createdBy: state.createdBy,\n author: state.author,\n };\n\n const updateMentionToUID = (\n entity: IMentionItem,\n result: Array<string>\n ) => {\n const displayName = entity.display;\n\n const escapedDisplayName = escapeRegExp(`@${displayName}`);\n const regexUser = new RegExp(escapedDisplayName, \"g\");\n finalMessage = finalMessage.replace(regexUser, `{{${entity.id}}}`);\n result.push(entity.id);\n };\n\n state.toUsers?.forEach((user) => updateMentionToUID(user, comment.toUsers));\n\n comment.message = finalMessage;\n return comment;\n};\n\nexport function normalizePath(path: string): string {\n if (path === \"/\") return path;\n return path.endsWith(\"/\") ? path.slice(0, -1) : path;\n}\n\nexport function fixSvgXPath(xpath: string | null): string {\n if (!xpath) return \"\";\n return xpath.replace(/\\/svg/g, \"/*[name()='svg']\");\n}\n\n/**\n * populate the position of the thread based on edges of the screen.\n * @param position\n * @param options\n * @returns\n */\nexport function adjustPositionToViewport(\n position: { top: number; left: number },\n options: {\n threadWidth?: number;\n safeMargin?: number;\n topSafeMargin?: number;\n } = {}\n): { top: number; left: number } {\n const { top, left } = position;\n const viewportWidth = window.innerWidth;\n const safeMargin = options.safeMargin ?? 16;\n const topSafeMargin = options.topSafeMargin ?? 42;\n const threadWidth = options.threadWidth ?? 16;\n\n let adjustedLeft = left;\n let adjustedTop = top;\n\n // Adjust position if too close to right edge\n if (adjustedLeft + threadWidth > viewportWidth - safeMargin) {\n adjustedLeft = viewportWidth - safeMargin - threadWidth;\n }\n\n // Adjust position if too close to top edge\n if (adjustedTop - window.scrollY < topSafeMargin) {\n adjustedTop = window.scrollY + topSafeMargin;\n }\n\n return { top: adjustedTop, left: adjustedLeft };\n}\n\nexport function formatDate(dateString: string): string {\n if (!dateString) return \"\";\n return dayjs(dateString).format(\"MMM DD, YYYY, hh:mm A\");\n}\n\ninterface PositionCoords {\n top: number;\n left: number;\n}\n\ninterface Positions {\n bottom: PositionCoords;\n top: PositionCoords;\n left: PositionCoords;\n right: PositionCoords;\n}\n\n/**\n * Calculates and updates tooltip position based on available viewport space.\n */\nexport const positionTooltip = (\n tooltipRef: React.RefObject<HTMLDivElement>,\n targetRef: React.RefObject<HTMLDivElement>,\n position: \"top\" | \"bottom\" | \"left\" | \"right\",\n setActualPosition: (position: \"top\" | \"bottom\" | \"left\" | \"right\") => void\n) => {\n if (!tooltipRef.current || !targetRef.current) return;\n\n const targetRect = targetRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n\n const positions: Positions = {\n bottom: {\n top: targetRect.bottom + margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n top: {\n top: targetRect.top - tooltipRect.height - margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n left: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.left - tooltipRect.width - margin,\n },\n right: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.right + margin,\n },\n };\n\n let bestPosition = position;\n let coords = positions[position];\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const wouldBeOutsideViewport = {\n bottom: coords.top + tooltipRect.height > viewportHeight,\n top: coords.top < 0,\n left: coords.left < 0,\n right: coords.left + tooltipRect.width > viewportWidth,\n };\n\n const horizontalOutOfBounds =\n coords.left < 0 || coords.left + tooltipRect.width > viewportWidth;\n\n if (wouldBeOutsideViewport[position] || horizontalOutOfBounds) {\n const positionPriority = [\"bottom\", \"top\", \"right\", \"left\"];\n\n positionPriority.splice(positionPriority.indexOf(position), 1);\n positionPriority.push(position);\n\n for (const pos of positionPriority) {\n const testCoords = positions[pos as keyof Positions];\n\n const isVisible =\n testCoords.top >= 0 &&\n testCoords.top + tooltipRect.height <= viewportHeight &&\n testCoords.left >= 0 &&\n testCoords.left + tooltipRect.width <= viewportWidth;\n\n if (isVisible) {\n bestPosition = pos as \"top\" | \"bottom\" | \"left\" | \"right\";\n coords = testCoords;\n break;\n }\n }\n }\n\n if (coords.left < 0) {\n coords.left = margin;\n } else if (coords.left + tooltipRect.width > viewportWidth) {\n coords.left = viewportWidth - tooltipRect.width - margin;\n }\n\n if (coords.top < 0) {\n coords.top = margin;\n } else if (coords.top + tooltipRect.height > viewportHeight) {\n coords.top = viewportHeight - tooltipRect.height - margin;\n }\n\n setActualPosition(bestPosition);\n\n Object.assign(tooltipRef.current.style, {\n top: `${coords.top}px`,\n left: `${coords.left}px`,\n });\n};\n"],"mappings":"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","names":["DOMPurify","dayjs"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/visualBuilder/utils/collabUtils.ts"],"sourcesContent":["import {\n ICommentState,\n IMentionedList,\n IMentionItem,\n IMessageDTO,\n IUserDTO,\n IUserState,\n} from \"../types/collab.types\";\nimport { maxMessageLength, mentionLimit } from \"./constants\";\nimport { uniqBy } from \"lodash-es\";\nimport DOMPurify from \"dompurify\";\nimport dayjs from \"dayjs\";\n\nconst escapeRegExp = (string: string): string => {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\n/**\n * Generates the title for the thread based on the number of comments.\n * @param {number} commentCount - The number of comments.\n * @returns {string} The title for the thread.\n */\nexport const getThreadTitle = (commentCount: number): string => {\n if (commentCount === 0) return \"Add New Comment\";\n return commentCount === 1 ? \"1 Comment\" : `${commentCount} Comments`;\n};\n\n/**\n * returns the available email.\n * @param {IUserDTO} user - The user object.\n * @returns {string} The user's email.\n */\nexport const getUserName = (user: IUserDTO): string => {\n return user.firstName && user.lastName\n ? `${user.firstName} ${user.lastName}`\n : user.firstName || user.lastName || user.email;\n};\n\n/**\n * Validates the comment length and the number of mentions.\n * @param {string} comment - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {string} The error message if validation fails, otherwise an empty string.\n */\nexport const validateCommentAndMentions = (\n comment: string,\n toUsers: IMentionedList\n): string => {\n if (comment.length > maxMessageLength) {\n return `Limit exceeded. You can have a maximum length of ${maxMessageLength} characters.`;\n }\n if (toUsers.length > mentionLimit) {\n return `Limit exceeded. You can tag a maximum of ${mentionLimit} users.`;\n }\n return \"\";\n};\n\n/**\n * Removes mentions that no longer exist in the message.\n * @param {string} message - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {Object} The updated lists of mentioned users.\n */\nexport const filterOutInvalidMentions = (\n message: string,\n toUsers: IMentionedList\n) => {\n const to_users_temp = toUsers.filter((user) =>\n message.includes(user.display)\n );\n\n return {\n toUsers: uniqBy(to_users_temp, \"id\"),\n };\n};\n\n/**\n * Replaces mention placeholders with display names in the comment message.\n * @param {IMessageDTO | undefined} comment - The comment object.\n * @param {IUserState} userState - The user state containing user and role maps.\n * @param {\"text\" | \"html\"} profile - The format for the output message, either plain text or HTML.\n * @returns {string | undefined} The formatted message or undefined if the comment is not provided.\n */\nexport const getMessageWithDisplayName = (\n comment: IMessageDTO | undefined | null,\n userState: IUserState,\n profile: \"text\" | \"html\"\n): string | undefined => {\n if (!comment) return undefined;\n\n let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, \"\");\n\n comment.toUsers?.forEach((user) => {\n const userPattern = new RegExp(`{{${user}}}`, \"g\");\n const userData = userState.userMap[user];\n const displayName = userData\n ? userData.display || getUserName(userData)\n : `unknown user`;\n\n const replacement =\n profile === \"html\"\n ? `<b class=\"collab-thread-comment--message\">@${displayName}</b>`\n : `@${displayName}`;\n tempText = tempText.replace(userPattern, replacement);\n });\n\n return tempText;\n};\n\n/**\n * Sanitizes HTML content to prevent XSS attacks.\n * @param {any} dirty - The unsanitized HTML content.\n * @returns {string} The sanitized HTML content.\n */\nexport const sanitizeData = (dirty: any): string => {\n return DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });\n};\n\n/**\n * Constructs the comment body with mentions replaced by their unique identifiers.\n * @param {ICommentState} state - The state containing the comment and mentions.\n * @returns {Object} The comment body containing the sanitized message and mentioned users.\n */\nexport const getCommentBody = (state: ICommentState): ICommentState => {\n let finalMessage = sanitizeData(state.message)\n .replace(/[^\\S\\r\\n]+/g, \" \")\n .replace(/ *\\n */g, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .trim();\n\n const comment = {\n message: finalMessage,\n toUsers: [],\n images: [],\n createdBy: state.createdBy,\n author: state.author,\n };\n\n const updateMentionToUID = (\n entity: IMentionItem,\n result: Array<string>\n ) => {\n const displayName = entity.display;\n\n const escapedDisplayName = escapeRegExp(`@${displayName}`);\n const regexUser = new RegExp(escapedDisplayName, \"g\");\n finalMessage = finalMessage.replace(regexUser, `{{${entity.id}}}`);\n result.push(entity.id);\n };\n\n state.toUsers?.forEach((user) => updateMentionToUID(user, comment.toUsers));\n\n comment.message = finalMessage;\n return comment;\n};\n\nexport function normalizePath(path: string): string {\n if (path === \"/\") return path;\n return path.endsWith(\"/\") ? path.slice(0, -1) : path;\n}\n\nexport function fixSvgXPath(xpath: string | null): string {\n if (!xpath) return \"\";\n return xpath.replace(/\\/svg/g, \"/*[name()='svg']\");\n}\n\n/**\n * populate the position of the thread based on edges of the screen.\n * @param position\n * @param options\n * @returns\n */\nexport function adjustPositionToViewport(\n position: { top: number; left: number },\n options: {\n threadWidth?: number;\n safeMargin?: number;\n topSafeMargin?: number;\n } = {}\n): { top: number; left: number } {\n const { top, left } = position;\n const viewportWidth = window.innerWidth;\n const safeMargin = options.safeMargin ?? 16;\n const topSafeMargin = options.topSafeMargin ?? 42;\n const threadWidth = options.threadWidth ?? 16;\n\n let adjustedLeft = left;\n let adjustedTop = top;\n\n // Adjust position if too close to right edge\n if (adjustedLeft + threadWidth > viewportWidth - safeMargin) {\n adjustedLeft = viewportWidth - safeMargin - threadWidth;\n }\n\n // Adjust position if too close to top edge\n if (adjustedTop - window.scrollY < topSafeMargin) {\n adjustedTop = window.scrollY + topSafeMargin;\n }\n\n return { top: adjustedTop, left: adjustedLeft };\n}\n\nexport function formatDate(dateString: string): string {\n if (!dateString) return \"\";\n return dayjs(dateString).format(\"MMM DD, YYYY, hh:mm A\");\n}\n\ninterface PositionCoords {\n top: number;\n left: number;\n}\n\ninterface Positions {\n bottom: PositionCoords;\n top: PositionCoords;\n left: PositionCoords;\n right: PositionCoords;\n}\n\n/**\n * Calculates and updates tooltip position based on available viewport space.\n */\nexport const positionTooltip = (\n tooltipRef: React.RefObject<HTMLDivElement>,\n targetRef: React.RefObject<HTMLDivElement>,\n position: \"top\" | \"bottom\" | \"left\" | \"right\",\n setActualPosition: (position: \"top\" | \"bottom\" | \"left\" | \"right\") => void\n) => {\n if (!tooltipRef.current || !targetRef.current) return;\n\n const targetRect = targetRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n\n const positions: Positions = {\n bottom: {\n top: targetRect.bottom + margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n top: {\n top: targetRect.top - tooltipRect.height - margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n left: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.left - tooltipRect.width - margin,\n },\n right: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.right + margin,\n },\n };\n\n let bestPosition = position;\n let coords = positions[position];\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const wouldBeOutsideViewport = {\n bottom: coords.top + tooltipRect.height > viewportHeight,\n top: coords.top < 0,\n left: coords.left < 0,\n right: coords.left + tooltipRect.width > viewportWidth,\n };\n\n const horizontalOutOfBounds =\n coords.left < 0 || coords.left + tooltipRect.width > viewportWidth;\n\n if (wouldBeOutsideViewport[position] || horizontalOutOfBounds) {\n const positionPriority = [\"bottom\", \"top\", \"right\", \"left\"];\n\n positionPriority.splice(positionPriority.indexOf(position), 1);\n positionPriority.push(position);\n\n for (const pos of positionPriority) {\n const testCoords = positions[pos as keyof Positions];\n\n const isVisible =\n testCoords.top >= 0 &&\n testCoords.top + tooltipRect.height <= viewportHeight &&\n testCoords.left >= 0 &&\n testCoords.left + tooltipRect.width <= viewportWidth;\n\n if (isVisible) {\n bestPosition = pos as \"top\" | \"bottom\" | \"left\" | \"right\";\n coords = testCoords;\n break;\n }\n }\n }\n\n if (coords.left < 0) {\n coords.left = margin;\n } else if (coords.left + tooltipRect.width > viewportWidth) {\n coords.left = viewportWidth - tooltipRect.width - margin;\n }\n\n if (coords.top < 0) {\n coords.top = margin;\n } else if (coords.top + tooltipRect.height > viewportHeight) {\n coords.top = viewportHeight - tooltipRect.height - margin;\n }\n\n setActualPosition(bestPosition);\n\n Object.assign(tooltipRef.current.style, {\n top: `${coords.top}px`,\n left: `${coords.left}px`,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,uBAA+C;AAC/C,uBAAuB;AACvB,uBAAsB;AACtB,mBAAkB;AAElB,IAAM,eAAe,CAAC,WAA2B;AAC7C,SAAO,OAAO,QAAQ,uBAAuB,MAAM;AACvD;AAOO,IAAM,iBAAiB,CAAC,iBAAiC;AAC5D,MAAI,iBAAiB,EAAG,QAAO;AAC/B,SAAO,iBAAiB,IAAI,cAAc,GAAG,YAAY;AAC7D;AAOO,IAAM,cAAc,CAAC,SAA2B;AACnD,SAAO,KAAK,aAAa,KAAK,WACxB,GAAG,KAAK,SAAS,IAAI,KAAK,QAAQ,KAClC,KAAK,aAAa,KAAK,YAAY,KAAK;AAClD;AAQO,IAAM,6BAA6B,CACtC,SACA,YACS;AACT,MAAI,QAAQ,SAAS,mCAAkB;AACnC,WAAO,oDAAoD,iCAAgB;AAAA,EAC/E;AACA,MAAI,QAAQ,SAAS,+BAAc;AAC/B,WAAO,4CAA4C,6BAAY;AAAA,EACnE;AACA,SAAO;AACX;AAQO,IAAM,2BAA2B,CACpC,SACA,YACC;AACD,QAAM,gBAAgB,QAAQ;AAAA,IAAO,CAAC,SAClC,QAAQ,SAAS,KAAK,OAAO;AAAA,EACjC;AAEA,SAAO;AAAA,IACH,aAAS,yBAAO,eAAe,IAAI;AAAA,EACvC;AACJ;AASO,IAAM,4BAA4B,CACrC,SACA,WACA,YACqB;AACrB,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,WAAW,aAAa,QAAQ,OAAO,EAAE,QAAQ,YAAY,EAAE;AAEnE,UAAQ,SAAS,QAAQ,CAAC,SAAS;AAC/B,UAAM,cAAc,IAAI,OAAO,KAAK,IAAI,MAAM,GAAG;AACjD,UAAM,WAAW,UAAU,QAAQ,IAAI;AACvC,UAAM,cAAc,WACd,SAAS,WAAW,YAAY,QAAQ,IACxC;AAEN,UAAM,cACF,YAAY,SACN,8CAA8C,WAAW,SACzD,IAAI,WAAW;AACzB,eAAW,SAAS,QAAQ,aAAa,WAAW;AAAA,EACxD,CAAC;AAED,SAAO;AACX;AAOO,IAAM,eAAe,CAAC,UAAuB;AAChD,SAAO,iBAAAA,QAAU,SAAS,OAAO,EAAE,cAAc,EAAE,MAAM,KAAK,EAAE,CAAC;AACrE;AAOO,IAAM,iBAAiB,CAAC,UAAwC;AACnE,MAAI,eAAe,aAAa,MAAM,OAAO,EACxC,QAAQ,eAAe,GAAG,EAC1B,QAAQ,WAAW,IAAI,EACvB,QAAQ,YAAY,EAAE,EACtB,KAAK;AAEV,QAAM,UAAU;AAAA,IACZ,SAAS;AAAA,IACT,SAAS,CAAC;AAAA,IACV,QAAQ,CAAC;AAAA,IACT,WAAW,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,EAClB;AAEA,QAAM,qBAAqB,CACvB,QACA,WACC;AACD,UAAM,cAAc,OAAO;AAE3B,UAAM,qBAAqB,aAAa,IAAI,WAAW,EAAE;AACzD,UAAM,YAAY,IAAI,OAAO,oBAAoB,GAAG;AACpD,mBAAe,aAAa,QAAQ,WAAW,KAAK,OAAO,EAAE,IAAI;AACjE,WAAO,KAAK,OAAO,EAAE;AAAA,EACzB;AAEA,QAAM,SAAS,QAAQ,CAAC,SAAS,mBAAmB,MAAM,QAAQ,OAAO,CAAC;AAE1E,UAAQ,UAAU;AAClB,SAAO;AACX;AAEO,SAAS,cAAc,MAAsB;AAChD,MAAI,SAAS,IAAK,QAAO;AACzB,SAAO,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACpD;AAEO,SAAS,YAAY,OAA8B;AACtD,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,QAAQ,UAAU,kBAAkB;AACrD;AAQO,SAAS,yBACZ,UACA,UAII,CAAC,GACwB;AAC7B,QAAM,EAAE,KAAK,KAAK,IAAI;AACtB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,cAAc,QAAQ,eAAe;AAE3C,MAAI,eAAe;AACnB,MAAI,cAAc;AAGlB,MAAI,eAAe,cAAc,gBAAgB,YAAY;AACzD,mBAAe,gBAAgB,aAAa;AAAA,EAChD;AAGA,MAAI,cAAc,OAAO,UAAU,eAAe;AAC9C,kBAAc,OAAO,UAAU;AAAA,EACnC;AAEA,SAAO,EAAE,KAAK,aAAa,MAAM,aAAa;AAClD;AAEO,SAAS,WAAW,YAA4B;AACnD,MAAI,CAAC,WAAY,QAAO;AACxB,aAAO,aAAAC,SAAM,UAAU,EAAE,OAAO,uBAAuB;AAC3D;AAiBO,IAAM,kBAAkB,CAC3B,YACA,WACA,UACA,sBACC;AACD,MAAI,CAAC,WAAW,WAAW,CAAC,UAAU,QAAS;AAE/C,QAAM,aAAa,UAAU,QAAQ,sBAAsB;AAC3D,QAAM,cAAc,WAAW,QAAQ,sBAAsB;AAC7D,QAAM,SAAS;AAEf,QAAM,YAAuB;AAAA,IACzB,QAAQ;AAAA,MACJ,KAAK,WAAW,SAAS;AAAA,MACzB,MAAM,WAAW,QAAQ,WAAW,QAAQ,YAAY,SAAS;AAAA,IACrE;AAAA,IACA,KAAK;AAAA,MACD,KAAK,WAAW,MAAM,YAAY,SAAS;AAAA,MAC3C,MAAM,WAAW,QAAQ,WAAW,QAAQ,YAAY,SAAS;AAAA,IACrE;AAAA,IACA,MAAM;AAAA,MACF,KAAK,WAAW,OAAO,WAAW,SAAS,YAAY,UAAU;AAAA,MACjE,MAAM,WAAW,OAAO,YAAY,QAAQ;AAAA,IAChD;AAAA,IACA,OAAO;AAAA,MACH,KAAK,WAAW,OAAO,WAAW,SAAS,YAAY,UAAU;AAAA,MACjE,MAAM,WAAW,QAAQ;AAAA,IAC7B;AAAA,EACJ;AAEA,MAAI,eAAe;AACnB,MAAI,SAAS,UAAU,QAAQ;AAE/B,QAAM,gBAAgB,OAAO;AAC7B,QAAM,iBAAiB,OAAO;AAE9B,QAAM,yBAAyB;AAAA,IAC3B,QAAQ,OAAO,MAAM,YAAY,SAAS;AAAA,IAC1C,KAAK,OAAO,MAAM;AAAA,IAClB,MAAM,OAAO,OAAO;AAAA,IACpB,OAAO,OAAO,OAAO,YAAY,QAAQ;AAAA,EAC7C;AAEA,QAAM,wBACF,OAAO,OAAO,KAAK,OAAO,OAAO,YAAY,QAAQ;AAEzD,MAAI,uBAAuB,QAAQ,KAAK,uBAAuB;AAC3D,UAAM,mBAAmB,CAAC,UAAU,OAAO,SAAS,MAAM;AAE1D,qBAAiB,OAAO,iBAAiB,QAAQ,QAAQ,GAAG,CAAC;AAC7D,qBAAiB,KAAK,QAAQ;AAE9B,eAAW,OAAO,kBAAkB;AAChC,YAAM,aAAa,UAAU,GAAsB;AAEnD,YAAM,YACF,WAAW,OAAO,KAClB,WAAW,MAAM,YAAY,UAAU,kBACvC,WAAW,QAAQ,KACnB,WAAW,OAAO,YAAY,SAAS;AAE3C,UAAI,WAAW;AACX,uBAAe;AACf,iBAAS;AACT;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,OAAO,OAAO,GAAG;AACjB,WAAO,OAAO;AAAA,EAClB,WAAW,OAAO,OAAO,YAAY,QAAQ,eAAe;AACxD,WAAO,OAAO,gBAAgB,YAAY,QAAQ;AAAA,EACtD;AAEA,MAAI,OAAO,MAAM,GAAG;AAChB,WAAO,MAAM;AAAA,EACjB,WAAW,OAAO,MAAM,YAAY,SAAS,gBAAgB;AACzD,WAAO,MAAM,iBAAiB,YAAY,SAAS;AAAA,EACvD;AAEA,oBAAkB,YAAY;AAE9B,SAAO,OAAO,WAAW,QAAQ,OAAO;AAAA,IACpC,KAAK,GAAG,OAAO,GAAG;AAAA,IAClB,MAAM,GAAG,OAAO,IAAI;AAAA,EACxB,CAAC;AACL;","names":["DOMPurify","dayjs"]}
|
|
@@ -35,10 +35,11 @@ var filterOutInvalidMentions = (message, toUsers) => {
|
|
|
35
35
|
var getMessageWithDisplayName = (comment, userState, profile) => {
|
|
36
36
|
if (!comment) return void 0;
|
|
37
37
|
let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, "");
|
|
38
|
-
comment
|
|
38
|
+
comment.toUsers?.forEach((user) => {
|
|
39
39
|
const userPattern = new RegExp(`{{${user}}}`, "g");
|
|
40
40
|
const userData = userState.userMap[user];
|
|
41
|
-
const
|
|
41
|
+
const displayName = userData ? userData.display || getUserName(userData) : `unknown user`;
|
|
42
|
+
const replacement = profile === "html" ? `<b class="collab-thread-comment--message">@${displayName}</b>` : `@${displayName}`;
|
|
42
43
|
tempText = tempText.replace(userPattern, replacement);
|
|
43
44
|
});
|
|
44
45
|
return tempText;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/visualBuilder/utils/collabUtils.ts"],"sourcesContent":["import {\n ICommentState,\n IMentionedList,\n IMentionItem,\n IMessageDTO,\n IUserDTO,\n IUserState,\n} from \"../types/collab.types\";\nimport { maxMessageLength, mentionLimit } from \"./constants\";\nimport { uniqBy } from \"lodash-es\";\nimport DOMPurify from \"dompurify\";\nimport dayjs from \"dayjs\";\n\nconst escapeRegExp = (string: string): string => {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\n/**\n * Generates the title for the thread based on the number of comments.\n * @param {number} commentCount - The number of comments.\n * @returns {string} The title for the thread.\n */\nexport const getThreadTitle = (commentCount: number): string => {\n if (commentCount === 0) return \"Add New Comment\";\n return commentCount === 1 ? \"1 Comment\" : `${commentCount} Comments`;\n};\n\n/**\n * returns the available email.\n * @param {IUserDTO} user - The user object.\n * @returns {string} The user's email.\n */\nexport const getUserName = (user: IUserDTO): string => {\n return user.firstName && user.lastName\n ? `${user.firstName} ${user.lastName}`\n : user.firstName || user.lastName || user.email;\n};\n\n/**\n * Validates the comment length and the number of mentions.\n * @param {string} comment - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {string} The error message if validation fails, otherwise an empty string.\n */\nexport const validateCommentAndMentions = (\n comment: string,\n toUsers: IMentionedList\n): string => {\n if (comment.length > maxMessageLength) {\n return `Limit exceeded. You can have a maximum length of ${maxMessageLength} characters.`;\n }\n if (toUsers.length > mentionLimit) {\n return `Limit exceeded. You can tag a maximum of ${mentionLimit} users.`;\n }\n return \"\";\n};\n\n/**\n * Removes mentions that no longer exist in the message.\n * @param {string} message - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {Object} The updated lists of mentioned users.\n */\nexport const filterOutInvalidMentions = (\n message: string,\n toUsers: IMentionedList\n) => {\n const to_users_temp = toUsers.filter((user) =>\n message.includes(user.display)\n );\n\n return {\n toUsers: uniqBy(to_users_temp, \"id\"),\n };\n};\n\n/**\n * Replaces mention placeholders with display names in the comment message.\n * @param {IMessageDTO | undefined} comment - The comment object.\n * @param {IUserState} userState - The user state containing user and role maps.\n * @param {\"text\" | \"html\"} profile - The format for the output message, either plain text or HTML.\n * @returns {string | undefined} The formatted message or undefined if the comment is not provided.\n */\nexport const getMessageWithDisplayName = (\n comment: IMessageDTO | undefined | null,\n userState: IUserState,\n profile: \"text\" | \"html\"\n): string | undefined => {\n if (!comment) return undefined;\n\n let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, \"\");\n\n comment?.toUsers?.forEach((user) => {\n const userPattern = new RegExp(`{{${user}}}`, \"g\");\n const userData = userState.userMap[user];\n const replacement =\n profile === \"html\"\n ? `<b class=\"collab-thread-comment--message\">@${userData.display || getUserName(userData)}</b>`\n : `@${userData.display || getUserName(userData)}`;\n tempText = tempText.replace(userPattern, replacement);\n });\n\n return tempText;\n};\n\n/**\n * Sanitizes HTML content to prevent XSS attacks.\n * @param {any} dirty - The unsanitized HTML content.\n * @returns {string} The sanitized HTML content.\n */\nexport const sanitizeData = (dirty: any): string => {\n return DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });\n};\n\n/**\n * Constructs the comment body with mentions replaced by their unique identifiers.\n * @param {ICommentState} state - The state containing the comment and mentions.\n * @returns {Object} The comment body containing the sanitized message and mentioned users.\n */\nexport const getCommentBody = (state: ICommentState): ICommentState => {\n let finalMessage = sanitizeData(state.message)\n .replace(/[^\\S\\r\\n]+/g, \" \")\n .replace(/ *\\n */g, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .trim();\n\n const comment = {\n message: finalMessage,\n toUsers: [],\n images: [],\n createdBy: state.createdBy,\n author: state.author,\n };\n\n const updateMentionToUID = (\n entity: IMentionItem,\n result: Array<string>\n ) => {\n const displayName = entity.display;\n\n const escapedDisplayName = escapeRegExp(`@${displayName}`);\n const regexUser = new RegExp(escapedDisplayName, \"g\");\n finalMessage = finalMessage.replace(regexUser, `{{${entity.id}}}`);\n result.push(entity.id);\n };\n\n state.toUsers?.forEach((user) => updateMentionToUID(user, comment.toUsers));\n\n comment.message = finalMessage;\n return comment;\n};\n\nexport function normalizePath(path: string): string {\n if (path === \"/\") return path;\n return path.endsWith(\"/\") ? path.slice(0, -1) : path;\n}\n\nexport function fixSvgXPath(xpath: string | null): string {\n if (!xpath) return \"\";\n return xpath.replace(/\\/svg/g, \"/*[name()='svg']\");\n}\n\n/**\n * populate the position of the thread based on edges of the screen.\n * @param position\n * @param options\n * @returns\n */\nexport function adjustPositionToViewport(\n position: { top: number; left: number },\n options: {\n threadWidth?: number;\n safeMargin?: number;\n topSafeMargin?: number;\n } = {}\n): { top: number; left: number } {\n const { top, left } = position;\n const viewportWidth = window.innerWidth;\n const safeMargin = options.safeMargin ?? 16;\n const topSafeMargin = options.topSafeMargin ?? 42;\n const threadWidth = options.threadWidth ?? 16;\n\n let adjustedLeft = left;\n let adjustedTop = top;\n\n // Adjust position if too close to right edge\n if (adjustedLeft + threadWidth > viewportWidth - safeMargin) {\n adjustedLeft = viewportWidth - safeMargin - threadWidth;\n }\n\n // Adjust position if too close to top edge\n if (adjustedTop - window.scrollY < topSafeMargin) {\n adjustedTop = window.scrollY + topSafeMargin;\n }\n\n return { top: adjustedTop, left: adjustedLeft };\n}\n\nexport function formatDate(dateString: string): string {\n if (!dateString) return \"\";\n return dayjs(dateString).format(\"MMM DD, YYYY, hh:mm A\");\n}\n\ninterface PositionCoords {\n top: number;\n left: number;\n}\n\ninterface Positions {\n bottom: PositionCoords;\n top: PositionCoords;\n left: PositionCoords;\n right: PositionCoords;\n}\n\n/**\n * Calculates and updates tooltip position based on available viewport space.\n */\nexport const positionTooltip = (\n tooltipRef: React.RefObject<HTMLDivElement>,\n targetRef: React.RefObject<HTMLDivElement>,\n position: \"top\" | \"bottom\" | \"left\" | \"right\",\n setActualPosition: (position: \"top\" | \"bottom\" | \"left\" | \"right\") => void\n) => {\n if (!tooltipRef.current || !targetRef.current) return;\n\n const targetRect = targetRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n\n const positions: Positions = {\n bottom: {\n top: targetRect.bottom + margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n top: {\n top: targetRect.top - tooltipRect.height - margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n left: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.left - tooltipRect.width - margin,\n },\n right: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.right + margin,\n },\n };\n\n let bestPosition = position;\n let coords = positions[position];\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const wouldBeOutsideViewport = {\n bottom: coords.top + tooltipRect.height > viewportHeight,\n top: coords.top < 0,\n left: coords.left < 0,\n right: coords.left + tooltipRect.width > viewportWidth,\n };\n\n const horizontalOutOfBounds =\n coords.left < 0 || coords.left + tooltipRect.width > viewportWidth;\n\n if (wouldBeOutsideViewport[position] || horizontalOutOfBounds) {\n const positionPriority = [\"bottom\", \"top\", \"right\", \"left\"];\n\n positionPriority.splice(positionPriority.indexOf(position), 1);\n positionPriority.push(position);\n\n for (const pos of positionPriority) {\n const testCoords = positions[pos as keyof Positions];\n\n const isVisible =\n testCoords.top >= 0 &&\n testCoords.top + tooltipRect.height <= viewportHeight &&\n testCoords.left >= 0 &&\n testCoords.left + tooltipRect.width <= viewportWidth;\n\n if (isVisible) {\n bestPosition = pos as \"top\" | \"bottom\" | \"left\" | \"right\";\n coords = testCoords;\n break;\n }\n }\n }\n\n if (coords.left < 0) {\n coords.left = margin;\n } else if (coords.left + tooltipRect.width > viewportWidth) {\n coords.left = viewportWidth - tooltipRect.width - margin;\n }\n\n if (coords.top < 0) {\n coords.top = margin;\n } else if (coords.top + tooltipRect.height > viewportHeight) {\n coords.top = viewportHeight - tooltipRect.height - margin;\n }\n\n setActualPosition(bestPosition);\n\n Object.assign(tooltipRef.current.style, {\n top: `${coords.top}px`,\n left: `${coords.left}px`,\n });\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/visualBuilder/utils/collabUtils.ts"],"sourcesContent":["import {\n ICommentState,\n IMentionedList,\n IMentionItem,\n IMessageDTO,\n IUserDTO,\n IUserState,\n} from \"../types/collab.types\";\nimport { maxMessageLength, mentionLimit } from \"./constants\";\nimport { uniqBy } from \"lodash-es\";\nimport DOMPurify from \"dompurify\";\nimport dayjs from \"dayjs\";\n\nconst escapeRegExp = (string: string): string => {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\n/**\n * Generates the title for the thread based on the number of comments.\n * @param {number} commentCount - The number of comments.\n * @returns {string} The title for the thread.\n */\nexport const getThreadTitle = (commentCount: number): string => {\n if (commentCount === 0) return \"Add New Comment\";\n return commentCount === 1 ? \"1 Comment\" : `${commentCount} Comments`;\n};\n\n/**\n * returns the available email.\n * @param {IUserDTO} user - The user object.\n * @returns {string} The user's email.\n */\nexport const getUserName = (user: IUserDTO): string => {\n return user.firstName && user.lastName\n ? `${user.firstName} ${user.lastName}`\n : user.firstName || user.lastName || user.email;\n};\n\n/**\n * Validates the comment length and the number of mentions.\n * @param {string} comment - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {string} The error message if validation fails, otherwise an empty string.\n */\nexport const validateCommentAndMentions = (\n comment: string,\n toUsers: IMentionedList\n): string => {\n if (comment.length > maxMessageLength) {\n return `Limit exceeded. You can have a maximum length of ${maxMessageLength} characters.`;\n }\n if (toUsers.length > mentionLimit) {\n return `Limit exceeded. You can tag a maximum of ${mentionLimit} users.`;\n }\n return \"\";\n};\n\n/**\n * Removes mentions that no longer exist in the message.\n * @param {string} message - The comment message.\n * @param {IMentionedList} toUsers - The list of mentioned users.\n * @returns {Object} The updated lists of mentioned users.\n */\nexport const filterOutInvalidMentions = (\n message: string,\n toUsers: IMentionedList\n) => {\n const to_users_temp = toUsers.filter((user) =>\n message.includes(user.display)\n );\n\n return {\n toUsers: uniqBy(to_users_temp, \"id\"),\n };\n};\n\n/**\n * Replaces mention placeholders with display names in the comment message.\n * @param {IMessageDTO | undefined} comment - The comment object.\n * @param {IUserState} userState - The user state containing user and role maps.\n * @param {\"text\" | \"html\"} profile - The format for the output message, either plain text or HTML.\n * @returns {string | undefined} The formatted message or undefined if the comment is not provided.\n */\nexport const getMessageWithDisplayName = (\n comment: IMessageDTO | undefined | null,\n userState: IUserState,\n profile: \"text\" | \"html\"\n): string | undefined => {\n if (!comment) return undefined;\n\n let tempText = sanitizeData(comment.message).replace(/<[^>]*>/g, \"\");\n\n comment.toUsers?.forEach((user) => {\n const userPattern = new RegExp(`{{${user}}}`, \"g\");\n const userData = userState.userMap[user];\n const displayName = userData\n ? userData.display || getUserName(userData)\n : `unknown user`;\n\n const replacement =\n profile === \"html\"\n ? `<b class=\"collab-thread-comment--message\">@${displayName}</b>`\n : `@${displayName}`;\n tempText = tempText.replace(userPattern, replacement);\n });\n\n return tempText;\n};\n\n/**\n * Sanitizes HTML content to prevent XSS attacks.\n * @param {any} dirty - The unsanitized HTML content.\n * @returns {string} The sanitized HTML content.\n */\nexport const sanitizeData = (dirty: any): string => {\n return DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });\n};\n\n/**\n * Constructs the comment body with mentions replaced by their unique identifiers.\n * @param {ICommentState} state - The state containing the comment and mentions.\n * @returns {Object} The comment body containing the sanitized message and mentioned users.\n */\nexport const getCommentBody = (state: ICommentState): ICommentState => {\n let finalMessage = sanitizeData(state.message)\n .replace(/[^\\S\\r\\n]+/g, \" \")\n .replace(/ *\\n */g, \"\\n\")\n .replace(/<[^>]*>/g, \"\")\n .trim();\n\n const comment = {\n message: finalMessage,\n toUsers: [],\n images: [],\n createdBy: state.createdBy,\n author: state.author,\n };\n\n const updateMentionToUID = (\n entity: IMentionItem,\n result: Array<string>\n ) => {\n const displayName = entity.display;\n\n const escapedDisplayName = escapeRegExp(`@${displayName}`);\n const regexUser = new RegExp(escapedDisplayName, \"g\");\n finalMessage = finalMessage.replace(regexUser, `{{${entity.id}}}`);\n result.push(entity.id);\n };\n\n state.toUsers?.forEach((user) => updateMentionToUID(user, comment.toUsers));\n\n comment.message = finalMessage;\n return comment;\n};\n\nexport function normalizePath(path: string): string {\n if (path === \"/\") return path;\n return path.endsWith(\"/\") ? path.slice(0, -1) : path;\n}\n\nexport function fixSvgXPath(xpath: string | null): string {\n if (!xpath) return \"\";\n return xpath.replace(/\\/svg/g, \"/*[name()='svg']\");\n}\n\n/**\n * populate the position of the thread based on edges of the screen.\n * @param position\n * @param options\n * @returns\n */\nexport function adjustPositionToViewport(\n position: { top: number; left: number },\n options: {\n threadWidth?: number;\n safeMargin?: number;\n topSafeMargin?: number;\n } = {}\n): { top: number; left: number } {\n const { top, left } = position;\n const viewportWidth = window.innerWidth;\n const safeMargin = options.safeMargin ?? 16;\n const topSafeMargin = options.topSafeMargin ?? 42;\n const threadWidth = options.threadWidth ?? 16;\n\n let adjustedLeft = left;\n let adjustedTop = top;\n\n // Adjust position if too close to right edge\n if (adjustedLeft + threadWidth > viewportWidth - safeMargin) {\n adjustedLeft = viewportWidth - safeMargin - threadWidth;\n }\n\n // Adjust position if too close to top edge\n if (adjustedTop - window.scrollY < topSafeMargin) {\n adjustedTop = window.scrollY + topSafeMargin;\n }\n\n return { top: adjustedTop, left: adjustedLeft };\n}\n\nexport function formatDate(dateString: string): string {\n if (!dateString) return \"\";\n return dayjs(dateString).format(\"MMM DD, YYYY, hh:mm A\");\n}\n\ninterface PositionCoords {\n top: number;\n left: number;\n}\n\ninterface Positions {\n bottom: PositionCoords;\n top: PositionCoords;\n left: PositionCoords;\n right: PositionCoords;\n}\n\n/**\n * Calculates and updates tooltip position based on available viewport space.\n */\nexport const positionTooltip = (\n tooltipRef: React.RefObject<HTMLDivElement>,\n targetRef: React.RefObject<HTMLDivElement>,\n position: \"top\" | \"bottom\" | \"left\" | \"right\",\n setActualPosition: (position: \"top\" | \"bottom\" | \"left\" | \"right\") => void\n) => {\n if (!tooltipRef.current || !targetRef.current) return;\n\n const targetRect = targetRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n\n const positions: Positions = {\n bottom: {\n top: targetRect.bottom + margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n top: {\n top: targetRect.top - tooltipRect.height - margin,\n left: targetRect.left + (targetRect.width - tooltipRect.width) / 2,\n },\n left: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.left - tooltipRect.width - margin,\n },\n right: {\n top: targetRect.top + (targetRect.height - tooltipRect.height) / 2,\n left: targetRect.right + margin,\n },\n };\n\n let bestPosition = position;\n let coords = positions[position];\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const wouldBeOutsideViewport = {\n bottom: coords.top + tooltipRect.height > viewportHeight,\n top: coords.top < 0,\n left: coords.left < 0,\n right: coords.left + tooltipRect.width > viewportWidth,\n };\n\n const horizontalOutOfBounds =\n coords.left < 0 || coords.left + tooltipRect.width > viewportWidth;\n\n if (wouldBeOutsideViewport[position] || horizontalOutOfBounds) {\n const positionPriority = [\"bottom\", \"top\", \"right\", \"left\"];\n\n positionPriority.splice(positionPriority.indexOf(position), 1);\n positionPriority.push(position);\n\n for (const pos of positionPriority) {\n const testCoords = positions[pos as keyof Positions];\n\n const isVisible =\n testCoords.top >= 0 &&\n testCoords.top + tooltipRect.height <= viewportHeight &&\n testCoords.left >= 0 &&\n testCoords.left + tooltipRect.width <= viewportWidth;\n\n if (isVisible) {\n bestPosition = pos as \"top\" | \"bottom\" | \"left\" | \"right\";\n coords = testCoords;\n break;\n }\n }\n }\n\n if (coords.left < 0) {\n coords.left = margin;\n } else if (coords.left + tooltipRect.width > viewportWidth) {\n coords.left = viewportWidth - tooltipRect.width - margin;\n }\n\n if (coords.top < 0) {\n coords.top = margin;\n } else if (coords.top + tooltipRect.height > viewportHeight) {\n coords.top = viewportHeight - tooltipRect.height - margin;\n }\n\n setActualPosition(bestPosition);\n\n Object.assign(tooltipRef.current.style, {\n top: `${coords.top}px`,\n left: `${coords.left}px`,\n });\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/visualBuilder/utils/createCachedFetch.ts
|
|
21
|
+
var createCachedFetch_exports = {};
|
|
22
|
+
__export(createCachedFetch_exports, {
|
|
23
|
+
createCachedFetch: () => createCachedFetch
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(createCachedFetch_exports);
|
|
26
|
+
function createCachedFetch(fetchFn, uidResolver = (...args) => JSON.stringify(args)) {
|
|
27
|
+
const cache = /* @__PURE__ */ new Map();
|
|
28
|
+
const pendingPromises = /* @__PURE__ */ new Map();
|
|
29
|
+
async function cachedFetch(...args) {
|
|
30
|
+
const uid = uidResolver(...args);
|
|
31
|
+
if (cache.has(uid)) {
|
|
32
|
+
return cache.get(uid);
|
|
33
|
+
}
|
|
34
|
+
if (pendingPromises.has(uid)) {
|
|
35
|
+
return pendingPromises.get(uid);
|
|
36
|
+
}
|
|
37
|
+
const promise = fetchFn(...args).then((data) => {
|
|
38
|
+
cache.set(uid, data);
|
|
39
|
+
pendingPromises.delete(uid);
|
|
40
|
+
return data;
|
|
41
|
+
}).catch((error) => {
|
|
42
|
+
pendingPromises.delete(uid);
|
|
43
|
+
throw error;
|
|
44
|
+
});
|
|
45
|
+
pendingPromises.set(uid, promise);
|
|
46
|
+
return promise;
|
|
47
|
+
}
|
|
48
|
+
cachedFetch.clearCache = () => {
|
|
49
|
+
cache.clear();
|
|
50
|
+
pendingPromises.clear();
|
|
51
|
+
};
|
|
52
|
+
return cachedFetch;
|
|
53
|
+
}
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
createCachedFetch
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=createCachedFetch.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/visualBuilder/utils/createCachedFetch.ts"],"sourcesContent":["/**\n * Creates a cached async fetch function with support for any number of arguments\n * @param fetchFn - The async function to cache\n * @param uidResolver - Function that generates a unique ID from the arguments passed to fetchFn\n * @returns A cached version of the fetch function with the same signature\n */\nexport function createCachedFetch<TArgs extends any[], TResult>(\n fetchFn: (...args: TArgs) => Promise<TResult>,\n uidResolver: (...args: TArgs) => string = (...args) => JSON.stringify(args)\n): {\n (...args: TArgs): Promise<TResult>;\n clearCache: () => void;\n} {\n // Cache storage\n const cache = new Map<string, TResult>();\n // Track in-flight requests\n const pendingPromises = new Map<string, Promise<TResult>>();\n\n /**\n * The cached fetch function\n * @param args - Arguments to pass to the original fetch function\n * @returns Promise that resolves with the data\n */\n async function cachedFetch(...args: TArgs): Promise<TResult> {\n // Generate unique ID for these arguments\n const uid = uidResolver(...args);\n\n // Return cached value if available\n if (cache.has(uid)) {\n return cache.get(uid)!;\n }\n\n // Return existing promise if request is already in progress\n if (pendingPromises.has(uid)) {\n return pendingPromises.get(uid)!;\n }\n\n // Create new promise for this request\n const promise = fetchFn(...args)\n .then((data) => {\n // Store result in cache\n cache.set(uid, data);\n // Remove from pending\n pendingPromises.delete(uid);\n return data;\n })\n .catch((error) => {\n // Clean up on error\n pendingPromises.delete(uid);\n throw error;\n });\n\n // Store the promise\n pendingPromises.set(uid, promise);\n return promise;\n }\n\n // Add clearCache method to the function\n cachedFetch.clearCache = () => {\n cache.clear();\n pendingPromises.clear();\n };\n\n return cachedFetch;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,SAAS,kBACZ,SACA,cAA0C,IAAI,SAAS,KAAK,UAAU,IAAI,GAI5E;AAEE,QAAM,QAAQ,oBAAI,IAAqB;AAEvC,QAAM,kBAAkB,oBAAI,IAA8B;AAO1D,iBAAe,eAAe,MAA+B;AAEzD,UAAM,MAAM,YAAY,GAAG,IAAI;AAG/B,QAAI,MAAM,IAAI,GAAG,GAAG;AAChB,aAAO,MAAM,IAAI,GAAG;AAAA,IACxB;AAGA,QAAI,gBAAgB,IAAI,GAAG,GAAG;AAC1B,aAAO,gBAAgB,IAAI,GAAG;AAAA,IAClC;AAGA,UAAM,UAAU,QAAQ,GAAG,IAAI,EAC1B,KAAK,CAAC,SAAS;AAEZ,YAAM,IAAI,KAAK,IAAI;AAEnB,sBAAgB,OAAO,GAAG;AAC1B,aAAO;AAAA,IACX,CAAC,EACA,MAAM,CAAC,UAAU;AAEd,sBAAgB,OAAO,GAAG;AAC1B,YAAM;AAAA,IACV,CAAC;AAGL,oBAAgB,IAAI,KAAK,OAAO;AAChC,WAAO;AAAA,EACX;AAGA,cAAY,aAAa,MAAM;AAC3B,UAAM,MAAM;AACZ,oBAAgB,MAAM;AAAA,EAC1B;AAEA,SAAO;AACX;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a cached async fetch function with support for any number of arguments
|
|
3
|
+
* @param fetchFn - The async function to cache
|
|
4
|
+
* @param uidResolver - Function that generates a unique ID from the arguments passed to fetchFn
|
|
5
|
+
* @returns A cached version of the fetch function with the same signature
|
|
6
|
+
*/
|
|
7
|
+
declare function createCachedFetch<TArgs extends any[], TResult>(fetchFn: (...args: TArgs) => Promise<TResult>, uidResolver?: (...args: TArgs) => string): {
|
|
8
|
+
(...args: TArgs): Promise<TResult>;
|
|
9
|
+
clearCache: () => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { createCachedFetch };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a cached async fetch function with support for any number of arguments
|
|
3
|
+
* @param fetchFn - The async function to cache
|
|
4
|
+
* @param uidResolver - Function that generates a unique ID from the arguments passed to fetchFn
|
|
5
|
+
* @returns A cached version of the fetch function with the same signature
|
|
6
|
+
*/
|
|
7
|
+
declare function createCachedFetch<TArgs extends any[], TResult>(fetchFn: (...args: TArgs) => Promise<TResult>, uidResolver?: (...args: TArgs) => string): {
|
|
8
|
+
(...args: TArgs): Promise<TResult>;
|
|
9
|
+
clearCache: () => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { createCachedFetch };
|