@limetech/lime-crm-building-blocks 1.73.0 → 1.74.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.74.0](https://github.com/Lundalogik/lime-crm-building-blocks/compare/v1.73.0...v1.74.0) (2025-05-06)
2
+
3
+ ### Features
4
+
5
+
6
+ * **text-editor:** add metadata event for notifying about metadata changes (images and links) ([5a4f480](https://github.com/Lundalogik/lime-crm-building-blocks/commit/5a4f480bcdd1152c0197ffeeb37b199b55e917c3))
7
+
1
8
  ## [1.73.0](https://github.com/Lundalogik/lime-crm-building-blocks/compare/v1.72.1...v1.73.0) (2025-04-29)
2
9
 
3
10
  ### Features
@@ -1423,6 +1423,36 @@ class UploadHandler {
1423
1423
  }
1424
1424
  return uploadedFile;
1425
1425
  }
1426
+ /**
1427
+ * Extracts a file ID from a image source string.
1428
+ *
1429
+ * This function parses a URL to find a file ID that appears before
1430
+ * '/contents/' at the end of the URL.
1431
+ *
1432
+ * @param {string} src - The URL string to parse
1433
+ * @returns {string | undefined} The extracted file ID or undefined if no match is found
1434
+ *
1435
+ * @example
1436
+ * // Returns 123
1437
+ * parseFileIdFromSrc('/api/file/123/contents/');
1438
+ *
1439
+ * @example
1440
+ * // Returns 456
1441
+ * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
1442
+ *
1443
+ * @example
1444
+ * // Returns undefined
1445
+ * parseFileIdFromSrc('/invalid/url/format/');
1446
+ */
1447
+ parseFileIdFromSrc(src) {
1448
+ if (src) {
1449
+ const regex = /\/(\d+)\/contents\/?$/;
1450
+ const matches = regex.exec(src);
1451
+ if (matches && matches[1]) {
1452
+ return Number(matches[1]);
1453
+ }
1454
+ }
1455
+ }
1426
1456
  /**
1427
1457
  * Validates that the image file size is within limits
1428
1458
  *
@@ -1448,7 +1478,7 @@ class UploadHandler {
1448
1478
  }
1449
1479
  const imageFile = new FileUpload(fileInfo.fileContent, this.http);
1450
1480
  await imageFile.initialize();
1451
- const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
1481
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, id: fileInfo.id });
1452
1482
  imageFile.onProgress = (progress) => {
1453
1483
  if (imageUpload.progress === 0) {
1454
1484
  imageUpload.state = 'uploading';
@@ -1459,10 +1489,6 @@ class UploadHandler {
1459
1489
  }
1460
1490
  };
1461
1491
  const response = await imageFile.upload();
1462
- // FileWrapper wraps the FileStatus type, which wraps the FileInfo interface
1463
- // 'id' is the file id property on the FileInfo interface
1464
- // 'fileId' is the file id property on the FileStatus type
1465
- imageUpload.id = response.id;
1466
1492
  imageUpload.fileId = response.id;
1467
1493
  imageUpload.filename = response.filename;
1468
1494
  imageUpload.extension = response.extension;
@@ -1500,9 +1526,7 @@ const LimeBBTextEditor = class {
1500
1526
  constructor(hostRef) {
1501
1527
  index.registerInstance(this, hostRef);
1502
1528
  this.change = index.createEvent(this, "change", 7);
1503
- this.imageUploaded = index.createEvent(this, "imageUploaded", 7);
1504
- this.imageRemoved = index.createEvent(this, "imageRemoved", 7);
1505
- this.imagesUploading = index.createEvent(this, "imagesUploading", 7);
1529
+ this.metadataChange = index.createEvent(this, "metadataChange", 7);
1506
1530
  /**
1507
1531
  * Set to true to enable mentioning a coworker or groups of coworkers.
1508
1532
  *
@@ -1576,8 +1600,7 @@ const LimeBBTextEditor = class {
1576
1600
  *
1577
1601
  * :::note
1578
1602
  * This component handles the upload process.
1579
- * The consumer must process the uploaded images by listening to `imageUploaded` and
1580
- * `imageRemoved` events.
1603
+ * The consumer must process the uploaded images by listening to `metadataChange` event.
1581
1604
  * :::
1582
1605
  */
1583
1606
  this.allowInlineImages = false;
@@ -1595,7 +1618,6 @@ const LimeBBTextEditor = class {
1595
1618
  this.registeredTriggerMap = this.triggerMap;
1596
1619
  this.registeredCustomElements = this.customElements;
1597
1620
  this.activeTrigger = undefined;
1598
- this.activeUploads = new Set();
1599
1621
  this.handleMouseClick = (event) => {
1600
1622
  if (!this.textEditorPickerElement) {
1601
1623
  return;
@@ -1653,38 +1675,19 @@ const LimeBBTextEditor = class {
1653
1675
  this.handleEnterOrTabKey = (event) => {
1654
1676
  this.handleItemSelection(event);
1655
1677
  };
1656
- this.handleImagePasted = async (event) => {
1678
+ this.handleMetadataChange = (event) => {
1657
1679
  event.stopPropagation();
1658
- if (!this.allowInlineImages) {
1659
- return;
1660
- }
1661
- const imageInserter = event.detail;
1662
- const fileInfo = imageInserter.fileInfo;
1663
- this.activeUploads.add(fileInfo.id);
1664
- this.imagesUploading.emit(this.activeUploads.size > 0);
1665
- const uploadedFile = await this.uploadHandler.handleImagePasted(imageInserter);
1666
- const uploadedFileInfo = {
1667
- fileId: uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId,
1668
- fileInfoId: fileInfo.id,
1669
- };
1670
- if (uploadedFileInfo.fileId) {
1671
- this.imageUploaded.emit(uploadedFileInfo);
1672
- this.activeUploads.delete(fileInfo.id);
1673
- }
1674
- this.imagesUploading.emit(this.activeUploads.size > 0);
1680
+ const editorMetadata = event.detail;
1681
+ const enhancedImages = this.getEnhancedImages(editorMetadata.images || []);
1682
+ const enhancedMetadata = Object.assign(Object.assign({}, editorMetadata), { images: enhancedImages });
1683
+ this.metadataChange.emit(enhancedMetadata);
1675
1684
  };
1676
- this.handleImageRemoved = (event) => {
1685
+ this.handleImagePasted = (event) => {
1677
1686
  event.stopPropagation();
1678
1687
  if (!this.allowInlineImages) {
1679
1688
  return;
1680
1689
  }
1681
- const imageInfo = event.detail;
1682
- if (!imageInfo) {
1683
- return;
1684
- }
1685
- this.activeUploads.delete(imageInfo.fileInfoId);
1686
- this.imagesUploading.emit(this.activeUploads.size > 0);
1687
- this.imageRemoved.emit(imageInfo);
1690
+ this.uploadHandler.handleImagePasted(event.detail);
1688
1691
  };
1689
1692
  this.handleTriggerStart = (event) => {
1690
1693
  event.stopPropagation();
@@ -1867,7 +1870,7 @@ const LimeBBTextEditor = class {
1867
1870
  }
1868
1871
  render() {
1869
1872
  return [
1870
- index.h("limel-text-editor", { key: 'd1442a13d2b3719f15055abc72b14ff1bcd16f94', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onImageRemoved: this.handleImageRemoved, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1873
+ index.h("limel-text-editor", { key: '2cc0cc870f0f26fe18d8c81ed675ab1ddeea6e3e', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onMetadataChange: this.handleMetadataChange, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1871
1874
  this.renderPicker(),
1872
1875
  ];
1873
1876
  }
@@ -1878,6 +1881,15 @@ const LimeBBTextEditor = class {
1878
1881
  return (index.h("limel-portal", { containerId: this.portalId, visible: this.isPickerOpen, openDirection: "top", inheritParentWidth: true, anchor: this.textEditor }, index.h("limebb-text-editor-picker", { ref: (el) => (this.textEditorPickerElement =
1879
1882
  el), items: getUpdatedItems(this.items, this.highlightedItemIndex), onItemSelected: this.handleItemSelection, emptyMessage: this.pickerMessage, isSearching: this.isSearching })));
1880
1883
  }
1884
+ getEnhancedImages(images) {
1885
+ return images.map((image) => {
1886
+ let fileId;
1887
+ if (image.state === 'success') {
1888
+ fileId = this.uploadHandler.parseFileIdFromSrc(image.src);
1889
+ }
1890
+ return fileId ? Object.assign(Object.assign({}, image), { fileId: fileId }) : image;
1891
+ });
1892
+ }
1881
1893
  loadDraft() {
1882
1894
  if (!this.userDataService || !this.textEditorInnerId) {
1883
1895
  return;
@@ -15,7 +15,7 @@ import { ARROW_DOWN, ARROW_UP, ENTER, ESCAPE, TAB } from "../../util/keycodes";
15
15
  import { createRandomString } from "../../util/random-string";
16
16
  import { getMentionLimetypes, MentionsService } from "./mentions";
17
17
  import { debounce } from "lodash-es";
18
- import { UploadHandler } from "./uploader/building-blocks-upload-handler";
18
+ import { UploadHandler, } from "./uploader/building-blocks-upload-handler";
19
19
  const DEBOUNCE_SEARCH_TIMEOUT = 300;
20
20
  /**
21
21
  * This component is a wrapper on the `limel-text-editor`. It adds support for platform
@@ -121,8 +121,7 @@ export class LimeBBTextEditor {
121
121
  *
122
122
  * :::note
123
123
  * This component handles the upload process.
124
- * The consumer must process the uploaded images by listening to `imageUploaded` and
125
- * `imageRemoved` events.
124
+ * The consumer must process the uploaded images by listening to `metadataChange` event.
126
125
  * :::
127
126
  */
128
127
  this.allowInlineImages = false;
@@ -140,7 +139,6 @@ export class LimeBBTextEditor {
140
139
  this.registeredTriggerMap = this.triggerMap;
141
140
  this.registeredCustomElements = this.customElements;
142
141
  this.activeTrigger = undefined;
143
- this.activeUploads = new Set();
144
142
  this.handleMouseClick = (event) => {
145
143
  if (!this.textEditorPickerElement) {
146
144
  return;
@@ -198,38 +196,19 @@ export class LimeBBTextEditor {
198
196
  this.handleEnterOrTabKey = (event) => {
199
197
  this.handleItemSelection(event);
200
198
  };
201
- this.handleImagePasted = async (event) => {
199
+ this.handleMetadataChange = (event) => {
202
200
  event.stopPropagation();
203
- if (!this.allowInlineImages) {
204
- return;
205
- }
206
- const imageInserter = event.detail;
207
- const fileInfo = imageInserter.fileInfo;
208
- this.activeUploads.add(fileInfo.id);
209
- this.imagesUploading.emit(this.activeUploads.size > 0);
210
- const uploadedFile = await this.uploadHandler.handleImagePasted(imageInserter);
211
- const uploadedFileInfo = {
212
- fileId: uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId,
213
- fileInfoId: fileInfo.id,
214
- };
215
- if (uploadedFileInfo.fileId) {
216
- this.imageUploaded.emit(uploadedFileInfo);
217
- this.activeUploads.delete(fileInfo.id);
218
- }
219
- this.imagesUploading.emit(this.activeUploads.size > 0);
201
+ const editorMetadata = event.detail;
202
+ const enhancedImages = this.getEnhancedImages(editorMetadata.images || []);
203
+ const enhancedMetadata = Object.assign(Object.assign({}, editorMetadata), { images: enhancedImages });
204
+ this.metadataChange.emit(enhancedMetadata);
220
205
  };
221
- this.handleImageRemoved = (event) => {
206
+ this.handleImagePasted = (event) => {
222
207
  event.stopPropagation();
223
208
  if (!this.allowInlineImages) {
224
209
  return;
225
210
  }
226
- const imageInfo = event.detail;
227
- if (!imageInfo) {
228
- return;
229
- }
230
- this.activeUploads.delete(imageInfo.fileInfoId);
231
- this.imagesUploading.emit(this.activeUploads.size > 0);
232
- this.imageRemoved.emit(imageInfo);
211
+ this.uploadHandler.handleImagePasted(event.detail);
233
212
  };
234
213
  this.handleTriggerStart = (event) => {
235
214
  event.stopPropagation();
@@ -412,7 +391,7 @@ export class LimeBBTextEditor {
412
391
  }
413
392
  render() {
414
393
  return [
415
- h("limel-text-editor", { key: 'd1442a13d2b3719f15055abc72b14ff1bcd16f94', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onImageRemoved: this.handleImageRemoved, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
394
+ h("limel-text-editor", { key: '2cc0cc870f0f26fe18d8c81ed675ab1ddeea6e3e', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onMetadataChange: this.handleMetadataChange, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
416
395
  this.renderPicker(),
417
396
  ];
418
397
  }
@@ -423,6 +402,15 @@ export class LimeBBTextEditor {
423
402
  return (h("limel-portal", { containerId: this.portalId, visible: this.isPickerOpen, openDirection: "top", inheritParentWidth: true, anchor: this.textEditor }, h("limebb-text-editor-picker", { ref: (el) => (this.textEditorPickerElement =
424
403
  el), items: getUpdatedItems(this.items, this.highlightedItemIndex), onItemSelected: this.handleItemSelection, emptyMessage: this.pickerMessage, isSearching: this.isSearching })));
425
404
  }
405
+ getEnhancedImages(images) {
406
+ return images.map((image) => {
407
+ let fileId;
408
+ if (image.state === 'success') {
409
+ fileId = this.uploadHandler.parseFileIdFromSrc(image.src);
410
+ }
411
+ return fileId ? Object.assign(Object.assign({}, image), { fileId: fileId }) : image;
412
+ });
413
+ }
426
414
  loadDraft() {
427
415
  if (!this.userDataService || !this.textEditorInnerId) {
428
416
  return;
@@ -883,7 +871,7 @@ export class LimeBBTextEditor {
883
871
  "optional": false,
884
872
  "docs": {
885
873
  "tags": [],
886
- "text": "Enables image pasting in the editor.\nDefault: `false`\n\n:::note\nThis component handles the upload process.\nThe consumer must process the uploaded images by listening to `imageUploaded` and\n`imageRemoved` events.\n:::"
874
+ "text": "Enables image pasting in the editor.\nDefault: `false`\n\n:::note\nThis component handles the upload process.\nThe consumer must process the uploaded images by listening to `metadataChange` event.\n:::"
887
875
  },
888
876
  "getter": false,
889
877
  "setter": false,
@@ -920,62 +908,26 @@ export class LimeBBTextEditor {
920
908
  "references": {}
921
909
  }
922
910
  }, {
923
- "method": "imageUploaded",
924
- "name": "imageUploaded",
911
+ "method": "metadataChange",
912
+ "name": "metadataChange",
925
913
  "bubbles": true,
926
914
  "cancelable": true,
927
915
  "composed": true,
928
916
  "docs": {
929
917
  "tags": [],
930
- "text": "Fires when an image upload completes successfully\n\n:::note\nReturns UploadedFileInfo with:\n- fileId: ID of the uploaded file (use for limeobject creation)\n- fileInfoId: ID to match this upload with any removed images\nwhen handling the imageRemoved event\n:::"
918
+ "text": "Dispatched when the metadata of the editor changes"
931
919
  },
932
920
  "complexType": {
933
- "original": "UploadedFileInfo",
934
- "resolved": "{ fileId: string | number | undefined; fileInfoId: string | number | undefined; }",
921
+ "original": "EnhancedEditorMetadata",
922
+ "resolved": "EnhancedEditorMetadata",
935
923
  "references": {
936
- "UploadedFileInfo": {
924
+ "EnhancedEditorMetadata": {
937
925
  "location": "import",
938
- "path": "./uploader/building-blocks-uploader",
939
- "id": "src/components/text-editor/uploader/building-blocks-uploader.ts::UploadedFileInfo"
926
+ "path": "./uploader/building-blocks-upload-handler",
927
+ "id": "src/components/text-editor/uploader/building-blocks-upload-handler.ts::EnhancedEditorMetadata"
940
928
  }
941
929
  }
942
930
  }
943
- }, {
944
- "method": "imageRemoved",
945
- "name": "imageRemoved",
946
- "bubbles": true,
947
- "cancelable": true,
948
- "composed": true,
949
- "docs": {
950
- "tags": [],
951
- "text": "Dispatched when an image has been removed from the editor\n\nThe ImageInfo object contains the fileInfoId which can be used to match with\npreviously uploaded images (from imageUploaded events)\n\n:::note\nThis event is forwarded from the underlying limel-text-editor component.\n:::"
952
- },
953
- "complexType": {
954
- "original": "ImageInfo",
955
- "resolved": "ImageInfo",
956
- "references": {
957
- "ImageInfo": {
958
- "location": "import",
959
- "path": "@limetech/lime-elements",
960
- "id": "node_modules::ImageInfo"
961
- }
962
- }
963
- }
964
- }, {
965
- "method": "imagesUploading",
966
- "name": "imagesUploading",
967
- "bubbles": true,
968
- "cancelable": true,
969
- "composed": true,
970
- "docs": {
971
- "tags": [],
972
- "text": "Will be `true` while there is an active upload in progress,\nor while there is a failed image upload."
973
- },
974
- "complexType": {
975
- "original": "boolean",
976
- "resolved": "boolean",
977
- "references": {}
978
- }
979
931
  }];
980
932
  }
981
933
  static get elementRef() { return "host"; }
@@ -31,6 +31,36 @@ export class UploadHandler {
31
31
  }
32
32
  return uploadedFile;
33
33
  }
34
+ /**
35
+ * Extracts a file ID from a image source string.
36
+ *
37
+ * This function parses a URL to find a file ID that appears before
38
+ * '/contents/' at the end of the URL.
39
+ *
40
+ * @param {string} src - The URL string to parse
41
+ * @returns {string | undefined} The extracted file ID or undefined if no match is found
42
+ *
43
+ * @example
44
+ * // Returns 123
45
+ * parseFileIdFromSrc('/api/file/123/contents/');
46
+ *
47
+ * @example
48
+ * // Returns 456
49
+ * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
50
+ *
51
+ * @example
52
+ * // Returns undefined
53
+ * parseFileIdFromSrc('/invalid/url/format/');
54
+ */
55
+ parseFileIdFromSrc(src) {
56
+ if (src) {
57
+ const regex = /\/(\d+)\/contents\/?$/;
58
+ const matches = regex.exec(src);
59
+ if (matches && matches[1]) {
60
+ return Number(matches[1]);
61
+ }
62
+ }
63
+ }
34
64
  /**
35
65
  * Validates that the image file size is within limits
36
66
  *
@@ -56,7 +86,7 @@ export class UploadHandler {
56
86
  }
57
87
  const imageFile = new FileUpload(fileInfo.fileContent, this.http);
58
88
  await imageFile.initialize();
59
- const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
89
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, id: fileInfo.id });
60
90
  imageFile.onProgress = (progress) => {
61
91
  if (imageUpload.progress === 0) {
62
92
  imageUpload.state = 'uploading';
@@ -67,10 +97,6 @@ export class UploadHandler {
67
97
  }
68
98
  };
69
99
  const response = await imageFile.upload();
70
- // FileWrapper wraps the FileStatus type, which wraps the FileInfo interface
71
- // 'id' is the file id property on the FileInfo interface
72
- // 'fileId' is the file id property on the FileStatus type
73
- imageUpload.id = response.id;
74
100
  imageUpload.fileId = response.id;
75
101
  imageUpload.filename = response.filename;
76
102
  imageUpload.extension = response.extension;
@@ -1420,6 +1420,36 @@ class UploadHandler {
1420
1420
  }
1421
1421
  return uploadedFile;
1422
1422
  }
1423
+ /**
1424
+ * Extracts a file ID from a image source string.
1425
+ *
1426
+ * This function parses a URL to find a file ID that appears before
1427
+ * '/contents/' at the end of the URL.
1428
+ *
1429
+ * @param {string} src - The URL string to parse
1430
+ * @returns {string | undefined} The extracted file ID or undefined if no match is found
1431
+ *
1432
+ * @example
1433
+ * // Returns 123
1434
+ * parseFileIdFromSrc('/api/file/123/contents/');
1435
+ *
1436
+ * @example
1437
+ * // Returns 456
1438
+ * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
1439
+ *
1440
+ * @example
1441
+ * // Returns undefined
1442
+ * parseFileIdFromSrc('/invalid/url/format/');
1443
+ */
1444
+ parseFileIdFromSrc(src) {
1445
+ if (src) {
1446
+ const regex = /\/(\d+)\/contents\/?$/;
1447
+ const matches = regex.exec(src);
1448
+ if (matches && matches[1]) {
1449
+ return Number(matches[1]);
1450
+ }
1451
+ }
1452
+ }
1423
1453
  /**
1424
1454
  * Validates that the image file size is within limits
1425
1455
  *
@@ -1445,7 +1475,7 @@ class UploadHandler {
1445
1475
  }
1446
1476
  const imageFile = new FileUpload(fileInfo.fileContent, this.http);
1447
1477
  await imageFile.initialize();
1448
- const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
1478
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, id: fileInfo.id });
1449
1479
  imageFile.onProgress = (progress) => {
1450
1480
  if (imageUpload.progress === 0) {
1451
1481
  imageUpload.state = 'uploading';
@@ -1456,10 +1486,6 @@ class UploadHandler {
1456
1486
  }
1457
1487
  };
1458
1488
  const response = await imageFile.upload();
1459
- // FileWrapper wraps the FileStatus type, which wraps the FileInfo interface
1460
- // 'id' is the file id property on the FileInfo interface
1461
- // 'fileId' is the file id property on the FileStatus type
1462
- imageUpload.id = response.id;
1463
1489
  imageUpload.fileId = response.id;
1464
1490
  imageUpload.filename = response.filename;
1465
1491
  imageUpload.extension = response.extension;
@@ -1499,9 +1525,7 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1499
1525
  this.__registerHost();
1500
1526
  this.__attachShadow();
1501
1527
  this.change = createEvent(this, "change", 7);
1502
- this.imageUploaded = createEvent(this, "imageUploaded", 7);
1503
- this.imageRemoved = createEvent(this, "imageRemoved", 7);
1504
- this.imagesUploading = createEvent(this, "imagesUploading", 7);
1528
+ this.metadataChange = createEvent(this, "metadataChange", 7);
1505
1529
  /**
1506
1530
  * Set to true to enable mentioning a coworker or groups of coworkers.
1507
1531
  *
@@ -1575,8 +1599,7 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1575
1599
  *
1576
1600
  * :::note
1577
1601
  * This component handles the upload process.
1578
- * The consumer must process the uploaded images by listening to `imageUploaded` and
1579
- * `imageRemoved` events.
1602
+ * The consumer must process the uploaded images by listening to `metadataChange` event.
1580
1603
  * :::
1581
1604
  */
1582
1605
  this.allowInlineImages = false;
@@ -1594,7 +1617,6 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1594
1617
  this.registeredTriggerMap = this.triggerMap;
1595
1618
  this.registeredCustomElements = this.customElements;
1596
1619
  this.activeTrigger = undefined;
1597
- this.activeUploads = new Set();
1598
1620
  this.handleMouseClick = (event) => {
1599
1621
  if (!this.textEditorPickerElement) {
1600
1622
  return;
@@ -1652,38 +1674,19 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1652
1674
  this.handleEnterOrTabKey = (event) => {
1653
1675
  this.handleItemSelection(event);
1654
1676
  };
1655
- this.handleImagePasted = async (event) => {
1677
+ this.handleMetadataChange = (event) => {
1656
1678
  event.stopPropagation();
1657
- if (!this.allowInlineImages) {
1658
- return;
1659
- }
1660
- const imageInserter = event.detail;
1661
- const fileInfo = imageInserter.fileInfo;
1662
- this.activeUploads.add(fileInfo.id);
1663
- this.imagesUploading.emit(this.activeUploads.size > 0);
1664
- const uploadedFile = await this.uploadHandler.handleImagePasted(imageInserter);
1665
- const uploadedFileInfo = {
1666
- fileId: uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId,
1667
- fileInfoId: fileInfo.id,
1668
- };
1669
- if (uploadedFileInfo.fileId) {
1670
- this.imageUploaded.emit(uploadedFileInfo);
1671
- this.activeUploads.delete(fileInfo.id);
1672
- }
1673
- this.imagesUploading.emit(this.activeUploads.size > 0);
1679
+ const editorMetadata = event.detail;
1680
+ const enhancedImages = this.getEnhancedImages(editorMetadata.images || []);
1681
+ const enhancedMetadata = Object.assign(Object.assign({}, editorMetadata), { images: enhancedImages });
1682
+ this.metadataChange.emit(enhancedMetadata);
1674
1683
  };
1675
- this.handleImageRemoved = (event) => {
1684
+ this.handleImagePasted = (event) => {
1676
1685
  event.stopPropagation();
1677
1686
  if (!this.allowInlineImages) {
1678
1687
  return;
1679
1688
  }
1680
- const imageInfo = event.detail;
1681
- if (!imageInfo) {
1682
- return;
1683
- }
1684
- this.activeUploads.delete(imageInfo.fileInfoId);
1685
- this.imagesUploading.emit(this.activeUploads.size > 0);
1686
- this.imageRemoved.emit(imageInfo);
1689
+ this.uploadHandler.handleImagePasted(event.detail);
1687
1690
  };
1688
1691
  this.handleTriggerStart = (event) => {
1689
1692
  event.stopPropagation();
@@ -1866,7 +1869,7 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1866
1869
  }
1867
1870
  render() {
1868
1871
  return [
1869
- h("limel-text-editor", { key: 'd1442a13d2b3719f15055abc72b14ff1bcd16f94', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onImageRemoved: this.handleImageRemoved, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1872
+ h("limel-text-editor", { key: '2cc0cc870f0f26fe18d8c81ed675ab1ddeea6e3e', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onMetadataChange: this.handleMetadataChange, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1870
1873
  this.renderPicker(),
1871
1874
  ];
1872
1875
  }
@@ -1877,6 +1880,15 @@ const LimeBBTextEditor = /*@__PURE__*/ proxyCustomElement(class LimeBBTextEditor
1877
1880
  return (h("limel-portal", { containerId: this.portalId, visible: this.isPickerOpen, openDirection: "top", inheritParentWidth: true, anchor: this.textEditor }, h("limebb-text-editor-picker", { ref: (el) => (this.textEditorPickerElement =
1878
1881
  el), items: getUpdatedItems(this.items, this.highlightedItemIndex), onItemSelected: this.handleItemSelection, emptyMessage: this.pickerMessage, isSearching: this.isSearching })));
1879
1882
  }
1883
+ getEnhancedImages(images) {
1884
+ return images.map((image) => {
1885
+ let fileId;
1886
+ if (image.state === 'success') {
1887
+ fileId = this.uploadHandler.parseFileIdFromSrc(image.src);
1888
+ }
1889
+ return fileId ? Object.assign(Object.assign({}, image), { fileId: fileId }) : image;
1890
+ });
1891
+ }
1880
1892
  loadDraft() {
1881
1893
  if (!this.userDataService || !this.textEditorInnerId) {
1882
1894
  return;
@@ -1419,6 +1419,36 @@ class UploadHandler {
1419
1419
  }
1420
1420
  return uploadedFile;
1421
1421
  }
1422
+ /**
1423
+ * Extracts a file ID from a image source string.
1424
+ *
1425
+ * This function parses a URL to find a file ID that appears before
1426
+ * '/contents/' at the end of the URL.
1427
+ *
1428
+ * @param {string} src - The URL string to parse
1429
+ * @returns {string | undefined} The extracted file ID or undefined if no match is found
1430
+ *
1431
+ * @example
1432
+ * // Returns 123
1433
+ * parseFileIdFromSrc('/api/file/123/contents/');
1434
+ *
1435
+ * @example
1436
+ * // Returns 456
1437
+ * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
1438
+ *
1439
+ * @example
1440
+ * // Returns undefined
1441
+ * parseFileIdFromSrc('/invalid/url/format/');
1442
+ */
1443
+ parseFileIdFromSrc(src) {
1444
+ if (src) {
1445
+ const regex = /\/(\d+)\/contents\/?$/;
1446
+ const matches = regex.exec(src);
1447
+ if (matches && matches[1]) {
1448
+ return Number(matches[1]);
1449
+ }
1450
+ }
1451
+ }
1422
1452
  /**
1423
1453
  * Validates that the image file size is within limits
1424
1454
  *
@@ -1444,7 +1474,7 @@ class UploadHandler {
1444
1474
  }
1445
1475
  const imageFile = new FileUpload(fileInfo.fileContent, this.http);
1446
1476
  await imageFile.initialize();
1447
- const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
1477
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, id: fileInfo.id });
1448
1478
  imageFile.onProgress = (progress) => {
1449
1479
  if (imageUpload.progress === 0) {
1450
1480
  imageUpload.state = 'uploading';
@@ -1455,10 +1485,6 @@ class UploadHandler {
1455
1485
  }
1456
1486
  };
1457
1487
  const response = await imageFile.upload();
1458
- // FileWrapper wraps the FileStatus type, which wraps the FileInfo interface
1459
- // 'id' is the file id property on the FileInfo interface
1460
- // 'fileId' is the file id property on the FileStatus type
1461
- imageUpload.id = response.id;
1462
1488
  imageUpload.fileId = response.id;
1463
1489
  imageUpload.filename = response.filename;
1464
1490
  imageUpload.extension = response.extension;
@@ -1496,9 +1522,7 @@ const LimeBBTextEditor = class {
1496
1522
  constructor(hostRef) {
1497
1523
  registerInstance(this, hostRef);
1498
1524
  this.change = createEvent(this, "change", 7);
1499
- this.imageUploaded = createEvent(this, "imageUploaded", 7);
1500
- this.imageRemoved = createEvent(this, "imageRemoved", 7);
1501
- this.imagesUploading = createEvent(this, "imagesUploading", 7);
1525
+ this.metadataChange = createEvent(this, "metadataChange", 7);
1502
1526
  /**
1503
1527
  * Set to true to enable mentioning a coworker or groups of coworkers.
1504
1528
  *
@@ -1572,8 +1596,7 @@ const LimeBBTextEditor = class {
1572
1596
  *
1573
1597
  * :::note
1574
1598
  * This component handles the upload process.
1575
- * The consumer must process the uploaded images by listening to `imageUploaded` and
1576
- * `imageRemoved` events.
1599
+ * The consumer must process the uploaded images by listening to `metadataChange` event.
1577
1600
  * :::
1578
1601
  */
1579
1602
  this.allowInlineImages = false;
@@ -1591,7 +1614,6 @@ const LimeBBTextEditor = class {
1591
1614
  this.registeredTriggerMap = this.triggerMap;
1592
1615
  this.registeredCustomElements = this.customElements;
1593
1616
  this.activeTrigger = undefined;
1594
- this.activeUploads = new Set();
1595
1617
  this.handleMouseClick = (event) => {
1596
1618
  if (!this.textEditorPickerElement) {
1597
1619
  return;
@@ -1649,38 +1671,19 @@ const LimeBBTextEditor = class {
1649
1671
  this.handleEnterOrTabKey = (event) => {
1650
1672
  this.handleItemSelection(event);
1651
1673
  };
1652
- this.handleImagePasted = async (event) => {
1674
+ this.handleMetadataChange = (event) => {
1653
1675
  event.stopPropagation();
1654
- if (!this.allowInlineImages) {
1655
- return;
1656
- }
1657
- const imageInserter = event.detail;
1658
- const fileInfo = imageInserter.fileInfo;
1659
- this.activeUploads.add(fileInfo.id);
1660
- this.imagesUploading.emit(this.activeUploads.size > 0);
1661
- const uploadedFile = await this.uploadHandler.handleImagePasted(imageInserter);
1662
- const uploadedFileInfo = {
1663
- fileId: uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId,
1664
- fileInfoId: fileInfo.id,
1665
- };
1666
- if (uploadedFileInfo.fileId) {
1667
- this.imageUploaded.emit(uploadedFileInfo);
1668
- this.activeUploads.delete(fileInfo.id);
1669
- }
1670
- this.imagesUploading.emit(this.activeUploads.size > 0);
1676
+ const editorMetadata = event.detail;
1677
+ const enhancedImages = this.getEnhancedImages(editorMetadata.images || []);
1678
+ const enhancedMetadata = Object.assign(Object.assign({}, editorMetadata), { images: enhancedImages });
1679
+ this.metadataChange.emit(enhancedMetadata);
1671
1680
  };
1672
- this.handleImageRemoved = (event) => {
1681
+ this.handleImagePasted = (event) => {
1673
1682
  event.stopPropagation();
1674
1683
  if (!this.allowInlineImages) {
1675
1684
  return;
1676
1685
  }
1677
- const imageInfo = event.detail;
1678
- if (!imageInfo) {
1679
- return;
1680
- }
1681
- this.activeUploads.delete(imageInfo.fileInfoId);
1682
- this.imagesUploading.emit(this.activeUploads.size > 0);
1683
- this.imageRemoved.emit(imageInfo);
1686
+ this.uploadHandler.handleImagePasted(event.detail);
1684
1687
  };
1685
1688
  this.handleTriggerStart = (event) => {
1686
1689
  event.stopPropagation();
@@ -1863,7 +1866,7 @@ const LimeBBTextEditor = class {
1863
1866
  }
1864
1867
  render() {
1865
1868
  return [
1866
- h("limel-text-editor", { key: 'd1442a13d2b3719f15055abc72b14ff1bcd16f94', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onImageRemoved: this.handleImageRemoved, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1869
+ h("limel-text-editor", { key: '2cc0cc870f0f26fe18d8c81ed675ab1ddeea6e3e', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onMetadataChange: this.handleMetadataChange, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
1867
1870
  this.renderPicker(),
1868
1871
  ];
1869
1872
  }
@@ -1874,6 +1877,15 @@ const LimeBBTextEditor = class {
1874
1877
  return (h("limel-portal", { containerId: this.portalId, visible: this.isPickerOpen, openDirection: "top", inheritParentWidth: true, anchor: this.textEditor }, h("limebb-text-editor-picker", { ref: (el) => (this.textEditorPickerElement =
1875
1878
  el), items: getUpdatedItems(this.items, this.highlightedItemIndex), onItemSelected: this.handleItemSelection, emptyMessage: this.pickerMessage, isSearching: this.isSearching })));
1876
1879
  }
1880
+ getEnhancedImages(images) {
1881
+ return images.map((image) => {
1882
+ let fileId;
1883
+ if (image.state === 'success') {
1884
+ fileId = this.uploadHandler.parseFileIdFromSrc(image.src);
1885
+ }
1886
+ return fileId ? Object.assign(Object.assign({}, image), { fileId: fileId }) : image;
1887
+ });
1888
+ }
1877
1889
  loadDraft() {
1878
1890
  if (!this.userDataService || !this.textEditorInnerId) {
1879
1891
  return;
@@ -1 +1 @@
1
- import{p as e,b as t}from"./p-b11e09b4.js";export{s as setNonce}from"./p-b11e09b4.js";import{g as i}from"./p-e1255160.js";(()=>{const t=import.meta.url,i={};return""!==t&&(i.resourcesUrl=new URL(".",t).href),e(i)})().then((async e=>(await i(),t([["p-16090238",[[1,"limebb-feed",{platform:[16],context:[16],items:[16],emptyStateMessage:[1,"empty-state-message"],heading:[1],loading:[4],minutesOfProximity:[2,"minutes-of-proximity"],totalCount:[2,"total-count"],direction:[1],lastVisitedTimestamp:[1,"last-visited-timestamp"]}]]],["p-974c3022",[[1,"limebb-kanban",{platform:[16],context:[16],groups:[16]}]]],["p-99f72b91",[[1,"limebb-chat-list",{platform:[16],context:[16],items:[16],loading:[516],isTypingIndicatorVisible:[516,"is-typing-indicator-visible"],lastVisitedTimestamp:[513,"last-visited-timestamp"],order:[513]},null,{items:["handleItemsChange"]}]]],["p-ded914fe",[[1,"limebb-text-editor",{platform:[16],context:[16],allowMentioning:[4,"allow-mentioning"],contentType:[1,"content-type"],language:[513],disabled:[516],readonly:[516],helperText:[513,"helper-text"],placeholder:[513],label:[513],invalid:[516],required:[516],selectedContext:[16],ui:[513],allowResize:[4,"allow-resize"],value:[1],draftIdentifier:[1,"draft-identifier"],triggerMap:[16],customElements:[16],allowInlineImages:[4,"allow-inline-images"],items:[32],highlightedItemIndex:[32],editorPickerQuery:[32],searchableLimetypes:[32],isPickerOpen:[32],isSearching:[32]},null,{isPickerOpen:["watchOpen"],editorPickerQuery:["watchQuery"]}]]],["p-f5f5ffad",[[1,"limebb-date-range",{platform:[16],context:[16],startTime:[16],endTime:[16],startTimeLabel:[1,"start-time-label"],endTimeLabel:[1,"end-time-label"],language:[1],timeFormat:[1,"time-format"],type:[1]}]]],["p-bed2fa73",[[1,"limebb-info-tile-currency-format",{platform:[16],context:[16],value:[16]}]]],["p-063681c6",[[1,"limebb-notification-list",{platform:[16],context:[16],items:[16],loading:[4],lastVisitedTimestamp:[1,"last-visited-timestamp"]},null,{items:["handleItemsChange"]}]]],["p-769e6d21",[[17,"limebb-browser",{platform:[16],context:[16],items:[16],layout:[1],filter:[32]}]]],["p-3310a5aa",[[1,"limebb-component-config",{platform:[16],context:[16],value:[16],required:[4],readonly:[4],disabled:[4],label:[1],helperText:[1,"helper-text"],formInfo:[16],type:[1],nameField:[1,"name-field"],configComponent:[32],configViewType:[32]},null,{formInfo:["watchFormInfo"],configComponent:["watchconfigComponent"]}]]],["p-306b2ff4",[[1,"limebb-component-picker",{platform:[16],context:[16],type:[1],tags:[16],value:[1],copyLabel:[1,"copy-label"],hideCopyButton:[4,"hide-copy-button"],required:[4],readonly:[4],disabled:[4],label:[1],helperText:[1,"helper-text"]}]]],["p-f71c5e55",[[1,"limebb-dashboard-widget",{heading:[513],subheading:[513],supportingText:[513,"supporting-text"],icon:[513]}]]],["p-c2277792",[[1,"limebb-icon-picker",{value:[1],required:[4],readonly:[4],invalid:[4],disabled:[4],label:[1],helperText:[1,"helper-text"]}]]],["p-99a06202",[[1,"limebb-info-tile",{platform:[16],context:[16],filterId:[513,"filter-id"],disabled:[4],icon:[513],label:[1],prefix:[1],suffix:[1],propertyName:[1,"property-name"],aggregateOperator:[1,"aggregate-operator"],format:[16],config:[32],filters:[32],value:[32],loading:[32],error:[32]},null,{filterId:["watchFilterId"],propertyName:["watchPropertyName"],aggregateOperator:["watchAggregateOperator"]}]]],["p-29c74b32",[[1,"limebb-info-tile-date-format",{value:[16]}]]],["p-a50a02bd",[[1,"limebb-info-tile-decimal-format",{value:[16]}]]],["p-d95f9f11",[[1,"limebb-info-tile-format",{platform:[16],context:[16],type:[1],value:[16]}]]],["p-fefcc3c1",[[1,"limebb-info-tile-relative-date-format",{value:[16]}]]],["p-95e1d1c3",[[1,"limebb-info-tile-unit-format",{value:[16]}]]],["p-fc97d0d1",[[1,"limebb-limeobject-file-viewer",{platform:[16],context:[16],property:[1],fileTypes:[16],limeobject:[32],limetype:[32]}]]],["p-9c29dc6d",[[1,"limebb-locale-picker",{platform:[16],context:[16],value:[1],required:[4],disabled:[4],label:[1],helperText:[1,"helper-text"],readonly:[4],multipleChoice:[4,"multiple-choice"],allLanguages:[32]}]]],["p-9e2dab17",[[1,"limebb-mention",{limetype:[1],objectid:[2],limeobject:[32]}]]],["p-e366bd49",[[1,"limebb-mention-group-counter",{count:[2],limetype:[16],helperLabel:[1,"helper-label"]}]]],["p-5565c444",[[1,"limebb-trend-indicator",{platform:[16],context:[16],value:[520],formerValue:[514,"former-value"],suffix:[513],label:[513],invalid:[516],helperText:[513,"helper-text"],reducePresence:[516,"reduce-presence"]},null,{value:["valueChanged"]}]]],["p-53990354",[[1,"limebb-summary-popover",{triggerDelay:[514,"trigger-delay"],heading:[513],subheading:[513],image:[16],icon:[513],value:[1],openDirection:[513,"open-direction"],popoverMaxWidth:[513,"popover-max-width"],popoverMaxHeight:[513,"popover-max-height"],actions:[16],isPopoverOpen:[32]}],[17,"limebb-navigation-button",{href:[513],tooltipLabel:[513,"tooltip-label"],tooltipHelperLabel:[513,"tooltip-helper-label"],type:[513]}]]],["p-28cec3ed",[[1,"limebb-kanban-item",{platform:[16],context:[16],item:[16]}]]],["p-1d6bbaf0",[[1,"limebb-kanban-group",{platform:[16],context:[16],identifier:[1],heading:[513],help:[1],items:[16],summary:[1],loading:[516],totalCount:[514,"total-count"]}]]],["p-e68d8446",[[1,"limebb-feed-timeline-item",{platform:[16],context:[16],item:[16],ui:[513],isBundled:[516,"is-bundled"],headingCanExpand:[32],isHeadingExpanded:[32],showMore:[32],isTall:[32]}]]],["p-62343f2e",[[1,"limebb-text-editor-picker",{items:[16],open:[516],isSearching:[4,"is-searching"],emptyMessage:[1,"empty-message"]},null,{open:["watchOpen"]}]]],["p-b36e3e0b",[[1,"limebb-currency-picker",{platform:[16],context:[16],label:[513],currencies:[16],helperText:[513,"helper-text"],required:[516],readonly:[516],invalid:[516],disabled:[516],value:[1]}]]],["p-b42bfff4",[[1,"limebb-date-picker",{platform:[16],context:[16],disabled:[516],readonly:[516],invalid:[516],label:[513],placeholder:[513],helperText:[513,"helper-text"],required:[516],value:[1],type:[513]}]]],["p-47288279",[[1,"limebb-notification-item",{platform:[16],context:[16],item:[16]}]]],["p-fcede56f",[[1,"limebb-chat-item",{platform:[16],context:[16],item:[16]}],[1,"limebb-typing-indicator"]]],["p-1a07c942",[[1,"limebb-empty-state",{heading:[513],value:[513],icon:[16]}]]]],e))));
1
+ import{p as e,b as t}from"./p-b11e09b4.js";export{s as setNonce}from"./p-b11e09b4.js";import{g as i}from"./p-e1255160.js";(()=>{const t=import.meta.url,i={};return""!==t&&(i.resourcesUrl=new URL(".",t).href),e(i)})().then((async e=>(await i(),t([["p-16090238",[[1,"limebb-feed",{platform:[16],context:[16],items:[16],emptyStateMessage:[1,"empty-state-message"],heading:[1],loading:[4],minutesOfProximity:[2,"minutes-of-proximity"],totalCount:[2,"total-count"],direction:[1],lastVisitedTimestamp:[1,"last-visited-timestamp"]}]]],["p-974c3022",[[1,"limebb-kanban",{platform:[16],context:[16],groups:[16]}]]],["p-99f72b91",[[1,"limebb-chat-list",{platform:[16],context:[16],items:[16],loading:[516],isTypingIndicatorVisible:[516,"is-typing-indicator-visible"],lastVisitedTimestamp:[513,"last-visited-timestamp"],order:[513]},null,{items:["handleItemsChange"]}]]],["p-f081d779",[[1,"limebb-text-editor",{platform:[16],context:[16],allowMentioning:[4,"allow-mentioning"],contentType:[1,"content-type"],language:[513],disabled:[516],readonly:[516],helperText:[513,"helper-text"],placeholder:[513],label:[513],invalid:[516],required:[516],selectedContext:[16],ui:[513],allowResize:[4,"allow-resize"],value:[1],draftIdentifier:[1,"draft-identifier"],triggerMap:[16],customElements:[16],allowInlineImages:[4,"allow-inline-images"],items:[32],highlightedItemIndex:[32],editorPickerQuery:[32],searchableLimetypes:[32],isPickerOpen:[32],isSearching:[32]},null,{isPickerOpen:["watchOpen"],editorPickerQuery:["watchQuery"]}]]],["p-f5f5ffad",[[1,"limebb-date-range",{platform:[16],context:[16],startTime:[16],endTime:[16],startTimeLabel:[1,"start-time-label"],endTimeLabel:[1,"end-time-label"],language:[1],timeFormat:[1,"time-format"],type:[1]}]]],["p-bed2fa73",[[1,"limebb-info-tile-currency-format",{platform:[16],context:[16],value:[16]}]]],["p-063681c6",[[1,"limebb-notification-list",{platform:[16],context:[16],items:[16],loading:[4],lastVisitedTimestamp:[1,"last-visited-timestamp"]},null,{items:["handleItemsChange"]}]]],["p-769e6d21",[[17,"limebb-browser",{platform:[16],context:[16],items:[16],layout:[1],filter:[32]}]]],["p-3310a5aa",[[1,"limebb-component-config",{platform:[16],context:[16],value:[16],required:[4],readonly:[4],disabled:[4],label:[1],helperText:[1,"helper-text"],formInfo:[16],type:[1],nameField:[1,"name-field"],configComponent:[32],configViewType:[32]},null,{formInfo:["watchFormInfo"],configComponent:["watchconfigComponent"]}]]],["p-306b2ff4",[[1,"limebb-component-picker",{platform:[16],context:[16],type:[1],tags:[16],value:[1],copyLabel:[1,"copy-label"],hideCopyButton:[4,"hide-copy-button"],required:[4],readonly:[4],disabled:[4],label:[1],helperText:[1,"helper-text"]}]]],["p-f71c5e55",[[1,"limebb-dashboard-widget",{heading:[513],subheading:[513],supportingText:[513,"supporting-text"],icon:[513]}]]],["p-c2277792",[[1,"limebb-icon-picker",{value:[1],required:[4],readonly:[4],invalid:[4],disabled:[4],label:[1],helperText:[1,"helper-text"]}]]],["p-99a06202",[[1,"limebb-info-tile",{platform:[16],context:[16],filterId:[513,"filter-id"],disabled:[4],icon:[513],label:[1],prefix:[1],suffix:[1],propertyName:[1,"property-name"],aggregateOperator:[1,"aggregate-operator"],format:[16],config:[32],filters:[32],value:[32],loading:[32],error:[32]},null,{filterId:["watchFilterId"],propertyName:["watchPropertyName"],aggregateOperator:["watchAggregateOperator"]}]]],["p-29c74b32",[[1,"limebb-info-tile-date-format",{value:[16]}]]],["p-a50a02bd",[[1,"limebb-info-tile-decimal-format",{value:[16]}]]],["p-d95f9f11",[[1,"limebb-info-tile-format",{platform:[16],context:[16],type:[1],value:[16]}]]],["p-fefcc3c1",[[1,"limebb-info-tile-relative-date-format",{value:[16]}]]],["p-95e1d1c3",[[1,"limebb-info-tile-unit-format",{value:[16]}]]],["p-fc97d0d1",[[1,"limebb-limeobject-file-viewer",{platform:[16],context:[16],property:[1],fileTypes:[16],limeobject:[32],limetype:[32]}]]],["p-9c29dc6d",[[1,"limebb-locale-picker",{platform:[16],context:[16],value:[1],required:[4],disabled:[4],label:[1],helperText:[1,"helper-text"],readonly:[4],multipleChoice:[4,"multiple-choice"],allLanguages:[32]}]]],["p-9e2dab17",[[1,"limebb-mention",{limetype:[1],objectid:[2],limeobject:[32]}]]],["p-e366bd49",[[1,"limebb-mention-group-counter",{count:[2],limetype:[16],helperLabel:[1,"helper-label"]}]]],["p-5565c444",[[1,"limebb-trend-indicator",{platform:[16],context:[16],value:[520],formerValue:[514,"former-value"],suffix:[513],label:[513],invalid:[516],helperText:[513,"helper-text"],reducePresence:[516,"reduce-presence"]},null,{value:["valueChanged"]}]]],["p-53990354",[[1,"limebb-summary-popover",{triggerDelay:[514,"trigger-delay"],heading:[513],subheading:[513],image:[16],icon:[513],value:[1],openDirection:[513,"open-direction"],popoverMaxWidth:[513,"popover-max-width"],popoverMaxHeight:[513,"popover-max-height"],actions:[16],isPopoverOpen:[32]}],[17,"limebb-navigation-button",{href:[513],tooltipLabel:[513,"tooltip-label"],tooltipHelperLabel:[513,"tooltip-helper-label"],type:[513]}]]],["p-28cec3ed",[[1,"limebb-kanban-item",{platform:[16],context:[16],item:[16]}]]],["p-1d6bbaf0",[[1,"limebb-kanban-group",{platform:[16],context:[16],identifier:[1],heading:[513],help:[1],items:[16],summary:[1],loading:[516],totalCount:[514,"total-count"]}]]],["p-e68d8446",[[1,"limebb-feed-timeline-item",{platform:[16],context:[16],item:[16],ui:[513],isBundled:[516,"is-bundled"],headingCanExpand:[32],isHeadingExpanded:[32],showMore:[32],isTall:[32]}]]],["p-62343f2e",[[1,"limebb-text-editor-picker",{items:[16],open:[516],isSearching:[4,"is-searching"],emptyMessage:[1,"empty-message"]},null,{open:["watchOpen"]}]]],["p-b36e3e0b",[[1,"limebb-currency-picker",{platform:[16],context:[16],label:[513],currencies:[16],helperText:[513,"helper-text"],required:[516],readonly:[516],invalid:[516],disabled:[516],value:[1]}]]],["p-b42bfff4",[[1,"limebb-date-picker",{platform:[16],context:[16],disabled:[516],readonly:[516],invalid:[516],label:[513],placeholder:[513],helperText:[513,"helper-text"],required:[516],value:[1],type:[513]}]]],["p-47288279",[[1,"limebb-notification-item",{platform:[16],context:[16],item:[16]}]]],["p-fcede56f",[[1,"limebb-chat-item",{platform:[16],context:[16],item:[16]}],[1,"limebb-typing-indicator"]]],["p-1a07c942",[[1,"limebb-empty-state",{heading:[513],value:[513],icon:[16]}]]]],e))));
@@ -0,0 +1 @@
1
+ import{r as t,c as i,h as e,g as r}from"./p-b11e09b4.js";import{P as s,A as n}from"./p-a26d352f.js";import{a as o}from"./p-54d4113a.js";import{A as a,a as h,b as c,E as u,T as f}from"./p-463d3174.js";import{d,b as l,k as v,c as b,s as p,a as m,e as g,U as y,S as j,g as w}from"./p-bcc23575.js";import{i as O,e as S}from"./p-c40a3f4b.js";import{d as k,r as x,S as I,a as A,i as T}from"./p-b31772c8.js";import{d as C,i as M,o as E,g as F,h as P,n as $,a as _}from"./p-5322fd19.js";import{i as N}from"./p-6fd28e32.js";import"./p-22de5a0e.js";var D=/\s/,L=/^\s+/;var R=NaN,U=/^[-+]0x[0-9a-f]+$/i,z=/^0b[01]+$/i,G=/^0o[0-7]+$/i,Q=parseInt;function W(t){if("number"==typeof t)return t;if(O(t))return R;if(k(t)){var i="function"==typeof t.valueOf?t.valueOf():t;t=k(i)?i+"":i}if("string"!=typeof t)return 0===t?t:+t;var e;t=(e=t)?e.slice(0,function(t){for(var i=t.length;i--&&D.test(t.charAt(i)););return i}(e)+1).replace(L,""):e;var r=z.test(t);return r||G.test(t)?Q(t.slice(2),r?2:8):U.test(t)?R:+t}var q=Object.create;const B=function(){function t(){}return function(i){if(!k(i))return{};if(q)return q(i);t.prototype=i;var e=new t;return t.prototype=void 0,e}}();function H(t,i,e){"__proto__"==i&&d?d(t,i,{configurable:!0,enumerable:!0,value:e,writable:!0}):t[i]=e}var K=Object.prototype.hasOwnProperty;function V(t,i,e){var r=t[i];K.call(t,i)&&S(r,e)&&(void 0!==e||i in t)||H(t,i,e)}function J(t,i,e,r){var s=!e;e||(e={});for(var n=-1,o=i.length;++n<o;){var a=i[n],h=r?r(e[a],t[a],a,e,t):void 0;void 0===h&&(h=t[a]),s?H(e,a,h):V(e,a,h)}return e}var X=Object.prototype.hasOwnProperty;function Y(t){return M(t)?l(t,!0):function(t){if(!k(t))return function(t){var i=[];if(null!=t)for(var e in Object(t))i.push(e);return i}(t);var i=C(t),e=[];for(var r in t)("constructor"!=r||!i&&X.call(t,r))&&e.push(r);return e}(t)}const Z=E(Object.getPrototypeOf,Object);var tt="object"==typeof exports&&exports&&!exports.nodeType&&exports,it=tt&&"object"==typeof module&&module&&!module.nodeType&&module,et=it&&it.exports===tt?x.Buffer:void 0,rt=et?et.allocUnsafe:void 0;const st=Object.getOwnPropertySymbols?function(t){for(var i=[];t;)m(i,b(t)),t=Z(t);return i}:p;function nt(t){return g(t,Y,st)}var ot=Object.prototype.hasOwnProperty;function at(t){var i=new t.constructor(t.byteLength);return new y(i).set(new y(t)),i}var ht=/\w*$/,ct=I?I.prototype:void 0,ut=ct?ct.valueOf:void 0,ft="[object Boolean]",dt="[object Date]",lt="[object Map]",vt="[object Number]",bt="[object RegExp]",pt="[object Set]",mt="[object String]",gt="[object Symbol]",yt="[object ArrayBuffer]",jt="[object DataView]",wt="[object Float32Array]",Ot="[object Float64Array]",St="[object Int8Array]",kt="[object Int16Array]",xt="[object Int32Array]",It="[object Uint8Array]",At="[object Uint8ClampedArray]",Tt="[object Uint16Array]",Ct="[object Uint32Array]";var Mt=$&&$.isMap;const Et=Mt?P(Mt):function(t){return A(t)&&"[object Map]"==F(t)};var Ft=$&&$.isSet;const Pt=Ft?P(Ft):function(t){return A(t)&&"[object Set]"==F(t)};var $t=1,_t=2,Nt=4,Dt="[object Arguments]",Lt="[object Function]",Rt="[object GeneratorFunction]",Ut="[object Object]",zt={};function Gt(t,i,e,r,s,n){var o,a=i&$t,h=i&_t,c=i&Nt;if(e&&(o=s?e(t,r,s,n):e(t)),void 0!==o)return o;if(!k(t))return t;var u=T(t);if(u){if(o=function(t){var i=t.length,e=new t.constructor(i);return i&&"string"==typeof t[0]&&ot.call(t,"index")&&(e.index=t.index,e.input=t.input),e}(t),!a)return function(t,i){var e=-1,r=t.length;for(i||(i=Array(r));++e<r;)i[e]=t[e];return i}(t,o)}else{var f=F(t),d=f==Lt||f==Rt;if(_(t))return function(t,i){if(i)return t.slice();var e=t.length,r=rt?rt(e):new t.constructor(e);return t.copy(r),r}(t,a);if(f==Ut||f==Dt||d&&!s){if(o=h||d?{}:function(t){return"function"!=typeof t.constructor||C(t)?{}:B(Z(t))}(t),!a)return h?function(t,i){return J(t,st(t),i)}(t,function(t,i){return t&&J(i,Y(i),t)}(o,t)):function(t,i){return J(t,b(t),i)}(t,function(t,i){return t&&J(i,v(i),t)}(o,t))}else{if(!zt[f])return s?t:{};o=function(t,i,e){var r,s,n=t.constructor;switch(i){case yt:return at(t);case ft:case dt:return new n(+t);case jt:return function(t,i){var e=i?at(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.byteLength)}(t,e);case wt:case Ot:case St:case kt:case xt:case It:case At:case Tt:case Ct:return function(t,i){var e=i?at(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.length)}(t,e);case lt:return new n;case vt:case mt:return new n(t);case bt:return(s=new(r=t).constructor(r.source,ht.exec(r))).lastIndex=r.lastIndex,s;case pt:return new n;case gt:return ut?Object(ut.call(t)):{}}}(t,f,a)}}n||(n=new j);var l=n.get(t);if(l)return l;n.set(t,o),Pt(t)?t.forEach((function(r){o.add(Gt(r,i,e,r,t,n))})):Et(t)&&t.forEach((function(r,s){o.set(s,Gt(r,i,e,s,t,n))}));var p=u?void 0:(c?h?nt:w:h?Y:v)(t);return function(t,i){for(var e=-1,r=null==t?0:t.length;++e<r&&!1!==i(t[e],e););}(p||t,(function(r,s){p&&(r=t[s=r]),V(o,s,Gt(r,i,e,s,t,n))})),o}zt[Dt]=zt["[object Array]"]=zt["[object ArrayBuffer]"]=zt["[object DataView]"]=zt["[object Boolean]"]=zt["[object Date]"]=zt["[object Float32Array]"]=zt["[object Float64Array]"]=zt["[object Int8Array]"]=zt["[object Int16Array]"]=zt["[object Int32Array]"]=zt["[object Map]"]=zt["[object Number]"]=zt[Ut]=zt["[object RegExp]"]=zt["[object Set]"]=zt["[object String]"]=zt["[object Symbol]"]=zt["[object Uint8Array]"]=zt["[object Uint8ClampedArray]"]=zt["[object Uint16Array]"]=zt["[object Uint32Array]"]=!0,zt["[object Error]"]=zt[Lt]=zt["[object WeakMap]"]=!1;const Qt=function(){return x.Date.now()};var Wt=Math.max,qt=Math.min;function Bt(t,i){return t.label===i}function Ht(t,i){return Object.values(t.properties).find((t=>t&&t.relation&&Bt(t.relation.getLimetype(),i)))}function Kt(t,i){const e=Ht(t,i);return!!e&&function(t){return function(t){return t&&["belongsto","hasone","hasmany","hasandbelongstomany"].includes(t.type)}(t)&&!function(t){return t&&["belongsto","hasone"].includes(t.type)}(t)}(e)}class Vt{get limeObjectService(){return this.platform.get(s.LimeObjectRepository)}get queryService(){return this.platform.get(s.Query)}get viewFactoryRegistry(){return this.platform.get(s.ViewFactoryRegistry)}get translator(){var t;return null===(t=this.platform)||void 0===t?void 0:t.get(s.Translate)}get triggerCharacter(){return this._triggerCharacter}get triggerHandler(){return this._triggerHandler}constructor(t,i,e){this.platform=t,this.context=i,this.searchableLimetypes=e,this.groupCounts={},this._triggerCharacter="@",this._triggerHandler={searcher:t=>this.searcher(t),inserter:(t,i)=>this.inserter(t,i),emptySearchMessage:"Start typing a name...",noItemsFoundMessage:"No results for your search...",nodeDefinition:{customElement:{tagName:"limebb-mention",attributes:["limetype","objectid","href"]},mapAttributes:t=>({limetype:t.value.getLimetype().name,objectid:t.value.id,href:`object/${this.context.limetype}/${this.context.id}`})}},this.searcher=async t=>{if(!t)return[];const{objects:i}=await this.limeObjectService.search(t,this.searchableLimetypes,10);return this.createSearchListItems(i)},this.inserter=async(t,i)=>{var e;const r=this.triggerHandler.nodeDefinition;r&&t.insert({node:{tagName:r.customElement.tagName,attributes:r.mapAttributes(i)},children:[null===(e=i.value)||void 0===e?void 0:e.descriptive]})}}async initialize(){await this.loadGroupCounts()}async loadGroupCounts(){const t=this.searchableLimetypes.filter((t=>!Bt(t,"user")&&Kt(t,"user"))).map((t=>this.getGroupCounts(t)));(await Promise.all(t)).forEach((t=>{Object.assign(this.groupCounts,t)}))}async getGroupCounts(t){var i;const e=Ht(t,"user"),r=t.name;try{const t=await this.queryService.execute({limetype:r,responseFormat:{object:{_id:null,[e.name]:{count:{aggregate:{op:n.Count}}}}}});if(!(null===(i=t.objects)||void 0===i?void 0:i.length))return{[r]:{}};const s=this.createGroupCount(t.objects,e.name);return{[r]:s}}catch(i){return console.error(`Error fetching group count for limetype: ${t.name}`,i),{[r]:{}}}}createGroupCount(t,i){const e={};return t.forEach((t=>{const{_id:r,[i]:s}=t;e[r]=s.count})),e}createSearchListItems(t=[]){return t.map((t=>this.createSearchListItem(t))).filter(N)}createSearchListItem(t){const i=this.viewFactoryRegistry.getFactory("search"),e=this.limeObjectService.getObject(t._limetype,t._id);if(!e)return null;const r=i(e,this.context),s=this.getGroupCountComponent(e);return Object.assign(Object.assign({},r),s?{primaryComponent:s}:{})}getGroupCountComponent(t){var i;const e=t.getLimetype(),r=null===(i=this.groupCounts[e.name])||void 0===i?void 0:i[t.id],s=Ht(e,"user");if(void 0!==r&&s)return{name:"limebb-mention-group-counter",props:{count:r,limetype:s.relation.getLimetype(),helperLabel:this.translator.get("webclient.notification-center.members-will-be-notified")}}}}class Jt{constructor(t,i){this.file=t,this.http=i,this.uploadCancelled=!1,this.getUrl=t=>`api/v1/file/${t||""}`}async initialize(){this.uploadService=await this.http.createFileUpload("POST",this.getUrl(),this.file),this.progressCallback&&(this.uploadService.onProgress=this.progressCallback)}async upload(){return this.uploadService.upload()}getFileName(){return this.file.name}cancel(){this.uploadService.cancel(),this.uploadCancelled=!0}set onProgress(t){this.progressCallback=t,this.uploadService&&(this.uploadService.onProgress=t)}}class Xt{constructor(t){this.platform=t}async handleImagePasted(t){const i=null==t?void 0:t.fileInfo;if(!i)return;if(!this.validateImageSize(i))return;t.insertThumbnail();const e=await this.createFileUpload(i),r=null==e?void 0:e.href;return r&&void 0!==(null==e?void 0:e.fileId)?t.insertImage(r):t.insertFailedThumbnail(),e}parseFileIdFromSrc(t){if(t){const i=/\/(\d+)\/contents\/?$/.exec(t);if(i&&i[1])return Number(i[1])}}validateImageSize(t){return!!t.fileContent&&t.fileContent.size<=52428800}async createFileUpload(t){var i;if(!t.fileContent)return;const e=new Jt(t.fileContent,this.http);await e.initialize();const r=Object.assign(Object.assign({},t),{progress:0,file:e,state:"added",fileId:void 0,href:void 0,id:t.id});e.onProgress=t=>{0===r.progress&&(r.state="uploading"),r.progress=t,100===t&&(r.state="finalizing")};const s=await e.upload();return r.fileId=s.id,r.filename=s.filename,r.extension=s.extension,r.contentType=s.contentType,r.size=s.size,r.state="done",r.href=null===(i=s._links)||void 0===i?void 0:i.contents.href,r}get http(){return this.platform.get(s.Http)}}const Yt=class{watchOpen(){this.setupHandlers(),this.setPickerMessage()}watchQuery(){this.setPickerMessage()}constructor(e){var r;t(this,e),this.change=i(this,"change",7),this.metadataChange=i(this,"metadataChange",7),this.allowMentioning=!1,this.contentType="markdown",this.language="en",this.disabled=!1,this.readonly=!1,this.invalid=!1,this.required=!1,this.ui="standard",this.allowResize=!0,this.value="",this.triggerMap={},this.customElements=[],this.allowInlineImages=!1,this.items=[],this.highlightedItemIndex=0,this.isPickerOpen=!1,this.isSearching=!1,this.registeredTriggers=[],this.registeredTriggerMap=this.triggerMap,this.registeredCustomElements=this.customElements,this.activeTrigger=void 0,this.handleMouseClick=t=>{this.textEditorPickerElement&&(t.target===this.textEditorPickerElement||this.resetTriggerAndPicker())},this.handleKeyPress=t=>{if(!this.isPickerOpen||!this.activeTrigger)return;if(![h,c,a,u,f].includes(t.key))return;if(t.stopPropagation(),t.preventDefault(),"keyup"===t.type)return;const i={[h]:this.handleEscapeKey,[u]:this.handleEnterOrTabKey,[f]:this.handleEnterOrTabKey,[a]:this.handleArrowKeyPress,[c]:this.handleArrowKeyPress}[t.key];i&&i(t)},this.handleArrowKeyPress=t=>{this.highlightedItemIndex=this.findNonSeparatorIndex(t.key,this.highlightedItemIndex)},this.findNonSeparatorIndex=(t,i,e=0)=>{if(!this.items.length||e>this.items.length)return i;const r=((t,i,e)=>(i+(t===a?1:-1)+e)%e)(t,i,this.items.length);return this.isListSeparator(this.items[r])?this.findNonSeparatorIndex(t,r,e+1):r},this.handleEscapeKey=()=>{var t;null===(t=this.triggerFunction)||void 0===t||t.stopTrigger(),this.resetTriggerAndPicker()},this.handleEnterOrTabKey=t=>{this.handleItemSelection(t)},this.handleMetadataChange=t=>{t.stopPropagation();const i=t.detail,e=this.getEnhancedImages(i.images||[]),r=Object.assign(Object.assign({},i),{images:e});this.metadataChange.emit(r)},this.handleImagePasted=t=>{t.stopPropagation(),this.allowInlineImages&&this.uploadHandler.handleImagePasted(t.detail)},this.handleTriggerStart=t=>{t.stopPropagation(),this.activeTrigger=t.detail.trigger,this.triggerFunction=t.detail.textEditor,this.isPickerOpen=!0},this.handleTriggerStop=t=>{t.stopPropagation(),this.resetTriggerAndPicker()},this.handleTriggerChange=t=>{var i;t.stopImmediatePropagation(),this.editorPickerQuery=t.detail.value;const e=null===(i=this.registeredTriggerMap[t.detail.trigger])||void 0===i?void 0:i.searcher;e&&(this.isSearching=!0,this.debouncedSearchFn(e,this.editorPickerQuery))},this.resetTriggerAndPicker=()=>{this.isPickerOpen=!1,this.activeTrigger=void 0,this.triggerFunction=void 0,this.isSearching=!1,this.highlightedItemIndex=0,this.items=[]},this.handleItemSelection=t=>{var i;let e;if(t instanceof CustomEvent)e=t.detail;else{if(!(t instanceof KeyboardEvent))return;{const t=this.items[this.highlightedItemIndex];if(this.isListSeparator(t))return;e=t}}if(!this.activeTrigger)return;const r=this.registeredTriggerMap[this.activeTrigger];try{r.inserter(this.triggerFunction,e)}catch(t){console.error("Error inserting",t)}this.resetTriggerAndPicker(),null===(i=this.textEditor)||void 0===i||i.focus()},this.handleVisibilityChange=()=>{"hidden"===document.visibilityState&&this.saveDraft()},this.handleBeforeUnload=()=>{this.saveDraft()},this.portalId="crypto"in window&&"function"==typeof(null===(r=window.crypto)||void 0===r?void 0:r.randomUUID)?"a_"+crypto.randomUUID():String.fromCharCode(97+Math.floor(26*Math.random()))+Math.random().toString(36).substring(2)+Math.random().toString(36).substring(2),this.debouncedSearchFn=function(t,i,e){var r,s,n,o,a,h,c=0,u=!1,f=!1,d=!0;if("function"!=typeof t)throw new TypeError("Expected a function");function l(i){var e=r,n=s;return r=s=void 0,c=i,o=t.apply(n,e)}function v(t){var e=t-h;return void 0===h||e>=i||e<0||f&&t-c>=n}function b(){var t=Qt();if(v(t))return p(t);a=setTimeout(b,function(t){var e=i-(t-h);return f?qt(e,n-(t-c)):e}(t))}function p(t){return a=void 0,d&&r?l(t):(r=s=void 0,o)}function m(){var t=Qt(),e=v(t);if(r=arguments,s=this,h=t,e){if(void 0===a)return function(t){return c=t,a=setTimeout(b,i),u?l(t):o}(h);if(f)return clearTimeout(a),a=setTimeout(b,i),l(h)}return void 0===a&&(a=setTimeout(b,i)),o}return i=W(i)||0,k(e)&&(u=!!e.leading,n=(f="maxWait"in e)?Wt(W(e.maxWait)||0,i):n,d="trailing"in e?!!e.trailing:d),m.cancel=function(){void 0!==a&&clearTimeout(a),c=0,r=h=s=a=void 0},m.flush=function(){return void 0===a?o:p(Qt())},m}((async(t,i)=>{try{const e=await t(i);if(i!==this.editorPickerQuery||!this.activeTrigger)return;this.items=e}catch(t){console.error("Error searching",t)}finally{this.isSearching=!1}}),300)}connectedCallback(){var t,i,e,r;if(this.draftIdentifier){const s=null!==(i=null===(t=this.context)||void 0===t?void 0:t.id)&&void 0!==i?i:"no-limeobject",n=null!==(r=null===(e=this.context)||void 0===e?void 0:e.limetype)&&void 0!==r?r:"no-limetype";this.textEditorInnerId=["text-editor-draft",n,s,this.draftIdentifier].join("-")}this.textEditorInnerId&&(document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("beforeunload",this.handleBeforeUnload)),this.uploadHandler=new Xt(this.platform)}componentWillLoad(){this.allowMentioning&&this.registerMentions(),this.registerTriggers(),this.loadDraft()}disconnectedCallback(){document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("beforeunload",this.handleBeforeUnload),document.removeEventListener("mousedown",this.handleMouseClick),this.saveDraft(),this.host&&(this.host.removeEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.removeEventListener("keydown",this.handleKeyPress,{capture:!0})),this.debouncedSearchFn&&this.debouncedSearchFn.cancel&&this.debouncedSearchFn.cancel()}registerMentions(){const t=new Vt(this.platform,this.context,this.searchableLimetypes),i=t.triggerHandler.nodeDefinition;i&&(this.registeredCustomElements.push(i.customElement),this.registeredTriggerMap[t.triggerCharacter]=t.triggerHandler,t.initialize())}registerTriggers(){this.registeredTriggers=Object.keys(this.registeredTriggerMap)}setPickerMessage(){var t;if(!this.activeTrigger)return;const i=this.registeredTriggerMap[this.activeTrigger];this.pickerMessage=(null===(t=this.editorPickerQuery)||void 0===t?void 0:t.length)>0?i.noItemsFoundMessage:i.emptySearchMessage}setupHandlers(){this.isPickerOpen?(this.host.addEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.addEventListener("keydown",this.handleKeyPress,{capture:!0}),document.addEventListener("mousedown",this.handleMouseClick)):(this.host.removeEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.removeEventListener("keydown",this.handleKeyPress,{capture:!0}),document.removeEventListener("mousedown",this.handleMouseClick))}isListSeparator(t){return"separator"in t&&!0===t.separator}render(){return[e("limel-text-editor",{key:"2cc0cc870f0f26fe18d8c81ed675ab1ddeea6e3e",ref:t=>this.textEditor=t,tabindex:this.disabled?-1:0,value:this.value,contentType:this.contentType,customElements:this.registeredCustomElements,"aria-disabled":this.disabled,language:this.language,triggers:this.registeredTriggers,onTriggerStart:this.handleTriggerStart,onTriggerStop:this.handleTriggerStop,onTriggerChange:this.handleTriggerChange,onImagePasted:this.handleImagePasted,onMetadataChange:this.handleMetadataChange,ui:this.ui,allowResize:this.allowResize,required:this.required,disabled:this.disabled,readonly:this.readonly,helperText:this.helperText,placeholder:this.placeholder,label:this.label,invalid:this.invalid}),this.renderPicker()]}renderPicker(){if(this.isPickerOpen)return e("limel-portal",{containerId:this.portalId,visible:this.isPickerOpen,openDirection:"top",inheritParentWidth:!0,anchor:this.textEditor},e("limebb-text-editor-picker",{ref:t=>this.textEditorPickerElement=t,items:(t=this.items,i=this.highlightedItemIndex,t.map(((t,e)=>{const r=Gt(t,5);return Object.assign(Object.assign({},r),{selected:e===i})}))),onItemSelected:this.handleItemSelection,emptyMessage:this.pickerMessage,isSearching:this.isSearching}));var t,i}getEnhancedImages(t){return t.map((t=>{let i;return"success"===t.state&&(i=this.uploadHandler.parseFileIdFromSrc(t.src)),i?Object.assign(Object.assign({},t),{fileId:i}):t}))}loadDraft(){if(!this.userDataService||!this.textEditorInnerId)return;if(this.value)return;const t=this.userDataService.get(this.textEditorInnerId);t&&this.change.emit(t)}saveDraft(){var t,i,e;this.textEditorInnerId&&((null===(t=this.value)||void 0===t?void 0:t.trim())?null===(i=this.userDataService)||void 0===i||i.set(this.textEditorInnerId,this.value):null===(e=this.userDataService)||void 0===e||e.set(this.textEditorInnerId,void 0))}get userDataService(){return this.platform.get(s.UserDataRepository)}get host(){return r(this)}static get watchers(){return{isPickerOpen:["watchOpen"],editorPickerQuery:["watchQuery"]}}};!function(t,i,e,r){var s,n=arguments.length,o=n<3?i:null===r?r=Object.getOwnPropertyDescriptor(i,e):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,i,e,r);else for(var a=t.length-1;a>=0;a--)(s=t[a])&&(o=(n<3?s(o):n>3?s(i,e,o):s(i,e))||o);n>3&&o&&Object.defineProperty(i,e,o)}([o({map:[function(t){return Object.values(t).filter((t=>Bt(t,"user")||Kt(t,"user")))}]})],Yt.prototype,"searchableLimetypes",void 0);export{Yt as limebb_text_editor}
@@ -1,8 +1,8 @@
1
- import { CustomElementDefinition, EditorUiType, ImageInfo, FormComponent, Languages } from '@limetech/lime-elements';
1
+ import { CustomElementDefinition, EditorUiType, FormComponent, Languages } from '@limetech/lime-elements';
2
2
  import { LimeWebComponentContext, LimeWebComponentPlatform } from '@limetech/lime-web-components';
3
3
  import { EventEmitter } from '../../stencil-public-runtime';
4
4
  import { TriggerMap } from './text-editor.types';
5
- import { UploadedFileInfo } from './uploader/building-blocks-uploader';
5
+ import { EnhancedEditorMetadata } from './uploader/building-blocks-upload-handler';
6
6
  /**
7
7
  * This component is a wrapper on the `limel-text-editor`. It adds support for platform
8
8
  * specific things that can't reside in lime-elements. So this is basically an
@@ -167,8 +167,7 @@ export declare class LimeBBTextEditor implements FormComponent<string> {
167
167
  *
168
168
  * :::note
169
169
  * This component handles the upload process.
170
- * The consumer must process the uploaded images by listening to `imageUploaded` and
171
- * `imageRemoved` events.
170
+ * The consumer must process the uploaded images by listening to `metadataChange` event.
172
171
  * :::
173
172
  */
174
173
  allowInlineImages: boolean;
@@ -190,32 +189,9 @@ export declare class LimeBBTextEditor implements FormComponent<string> {
190
189
  */
191
190
  change: EventEmitter<string>;
192
191
  /**
193
- * Fires when an image upload completes successfully
194
- *
195
- * :::note
196
- * Returns UploadedFileInfo with:
197
- * - fileId: ID of the uploaded file (use for limeobject creation)
198
- * - fileInfoId: ID to match this upload with any removed images
199
- * when handling the imageRemoved event
200
- * :::
201
- */
202
- imageUploaded: EventEmitter<UploadedFileInfo>;
203
- /**
204
- * Dispatched when an image has been removed from the editor
205
- *
206
- * The ImageInfo object contains the fileInfoId which can be used to match with
207
- * previously uploaded images (from imageUploaded events)
208
- *
209
- * :::note
210
- * This event is forwarded from the underlying limel-text-editor component.
211
- * :::
212
- */
213
- imageRemoved: EventEmitter<ImageInfo>;
214
- /**
215
- * Will be `true` while there is an active upload in progress,
216
- * or while there is a failed image upload.
192
+ * Dispatched when the metadata of the editor changes
217
193
  */
218
- imagesUploading: EventEmitter<boolean>;
194
+ metadataChange: EventEmitter<EnhancedEditorMetadata>;
219
195
  private registeredTriggers;
220
196
  private registeredTriggerMap;
221
197
  private registeredCustomElements;
@@ -228,7 +204,6 @@ export declare class LimeBBTextEditor implements FormComponent<string> {
228
204
  private textEditorInnerId;
229
205
  private debouncedSearchFn;
230
206
  private uploadHandler;
231
- private activeUploads;
232
207
  protected watchOpen(): void;
233
208
  protected watchQuery(): void;
234
209
  constructor();
@@ -248,8 +223,9 @@ export declare class LimeBBTextEditor implements FormComponent<string> {
248
223
  private readonly handleEnterOrTabKey;
249
224
  render(): any[];
250
225
  private renderPicker;
226
+ private readonly handleMetadataChange;
227
+ private getEnhancedImages;
251
228
  private readonly handleImagePasted;
252
- private readonly handleImageRemoved;
253
229
  private readonly handleTriggerStart;
254
230
  private readonly handleTriggerStop;
255
231
  private readonly handleTriggerChange;
@@ -1,4 +1,4 @@
1
- import { ImageInserter } from '@limetech/lime-elements';
1
+ import { EditorImage, ImageInserter, EditorMetadata } from '@limetech/lime-elements';
2
2
  import { LimeWebComponentPlatform } from '@limetech/lime-web-components';
3
3
  import { FileWrapper } from './building-blocks-uploader';
4
4
  export declare class UploadHandler {
@@ -11,6 +11,28 @@ export declare class UploadHandler {
11
11
  * @returns {Promise<FileWrapper | undefined>} Promise resolving to the uploaded file wrapper or undefined if upload fails
12
12
  */
13
13
  handleImagePasted(imageInserter: ImageInserter): Promise<FileWrapper | undefined>;
14
+ /**
15
+ * Extracts a file ID from a image source string.
16
+ *
17
+ * This function parses a URL to find a file ID that appears before
18
+ * '/contents/' at the end of the URL.
19
+ *
20
+ * @param {string} src - The URL string to parse
21
+ * @returns {string | undefined} The extracted file ID or undefined if no match is found
22
+ *
23
+ * @example
24
+ * // Returns 123
25
+ * parseFileIdFromSrc('/api/file/123/contents/');
26
+ *
27
+ * @example
28
+ * // Returns 456
29
+ * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
30
+ *
31
+ * @example
32
+ * // Returns undefined
33
+ * parseFileIdFromSrc('/invalid/url/format/');
34
+ */
35
+ parseFileIdFromSrc(src: string): number | undefined;
14
36
  /**
15
37
  * Validates that the image file size is within limits
16
38
  *
@@ -27,4 +49,14 @@ export declare class UploadHandler {
27
49
  private createFileUpload;
28
50
  private get http();
29
51
  }
52
+ export interface EnhancedEditorImage extends EditorImage {
53
+ fileId?: number;
54
+ }
55
+ /**
56
+ * Extends the EditorMetadata interface from lime-elements to replace the images property
57
+ * with our custom EnhancedEditorImage type
58
+ */
59
+ export interface EnhancedEditorMetadata extends Omit<EditorMetadata, 'images'> {
60
+ images: EnhancedEditorImage[];
61
+ }
30
62
  //# sourceMappingURL=building-blocks-upload-handler.d.ts.map
@@ -22,10 +22,5 @@ export type FileStatus = FileInfo & {
22
22
  };
23
23
  export type FileWrapper = FileStatus & {
24
24
  file: FileUpload;
25
- fileInfoId: string | number | undefined;
26
- };
27
- export type UploadedFileInfo = {
28
- fileId: string | number | undefined;
29
- fileInfoId: string | number | undefined;
30
25
  };
31
26
  //# sourceMappingURL=building-blocks-uploader.d.ts.map
@@ -7,7 +7,7 @@
7
7
  import { HTMLStencilElement, JSXBase } from "./stencil-public-runtime";
8
8
  import { AggregateOperator, LimeFileUrlType, LimeType, LimeWebComponentContext, LimeWebComponentPlatform } from "@limetech/lime-web-components";
9
9
  import { BrowserItem } from "./components/browser/browser-item.types";
10
- import { ActionBarItem, CustomElementDefinition, DateType, EditorUiType, FormInfo, Icon, Image, ImageInfo, Languages, ListItem, ListSeparator, OpenDirection } from "@limetech/lime-elements";
10
+ import { ActionBarItem, CustomElementDefinition, DateType, EditorUiType, FormInfo, Icon, Image, Languages, ListItem, ListSeparator, OpenDirection } from "@limetech/lime-elements";
11
11
  import { ChatItem } from "./components/chat-list/chat-item/chat-item.types";
12
12
  import { ComponentPickerType } from "./components/component-command-picker/types";
13
13
  import { FeedItem } from "./components/feed/feed-item/feed-item.types";
@@ -19,10 +19,10 @@ import { LanguagePickerType } from "./components/locale-picker/language-picker.t
19
19
  import { NavigationButtonType } from "./components/navigation-button/navigation-button.types";
20
20
  import { NotificationItem } from "./components/notification-list/notification-item/notification-item.types";
21
21
  import { TriggerMap } from "./components/text-editor/text-editor.types";
22
- import { UploadedFileInfo } from "./components/text-editor/uploader/building-blocks-uploader";
22
+ import { EnhancedEditorMetadata } from "./components/text-editor/uploader/building-blocks-upload-handler";
23
23
  export { AggregateOperator, LimeFileUrlType, LimeType, LimeWebComponentContext, LimeWebComponentPlatform } from "@limetech/lime-web-components";
24
24
  export { BrowserItem } from "./components/browser/browser-item.types";
25
- export { ActionBarItem, CustomElementDefinition, DateType, EditorUiType, FormInfo, Icon, Image, ImageInfo, Languages, ListItem, ListSeparator, OpenDirection } from "@limetech/lime-elements";
25
+ export { ActionBarItem, CustomElementDefinition, DateType, EditorUiType, FormInfo, Icon, Image, Languages, ListItem, ListSeparator, OpenDirection } from "@limetech/lime-elements";
26
26
  export { ChatItem } from "./components/chat-list/chat-item/chat-item.types";
27
27
  export { ComponentPickerType } from "./components/component-command-picker/types";
28
28
  export { FeedItem } from "./components/feed/feed-item/feed-item.types";
@@ -34,7 +34,7 @@ export { LanguagePickerType } from "./components/locale-picker/language-picker.t
34
34
  export { NavigationButtonType } from "./components/navigation-button/navigation-button.types";
35
35
  export { NotificationItem } from "./components/notification-list/notification-item/notification-item.types";
36
36
  export { TriggerMap } from "./components/text-editor/text-editor.types";
37
- export { UploadedFileInfo } from "./components/text-editor/uploader/building-blocks-uploader";
37
+ export { EnhancedEditorMetadata } from "./components/text-editor/uploader/building-blocks-upload-handler";
38
38
  export namespace Components {
39
39
  /**
40
40
  * This component creates a UI that allows the user to easily navigate through a list of items,
@@ -1154,7 +1154,7 @@ export namespace Components {
1154
1154
  */
1155
1155
  interface LimebbTextEditor {
1156
1156
  /**
1157
- * Enables image pasting in the editor. Default: `false` :::note This component handles the upload process. The consumer must process the uploaded images by listening to `imageUploaded` and `imageRemoved` events. :::
1157
+ * Enables image pasting in the editor. Default: `false` :::note This component handles the upload process. The consumer must process the uploaded images by listening to `metadataChange` event. :::
1158
1158
  */
1159
1159
  "allowInlineImages": boolean;
1160
1160
  /**
@@ -2167,9 +2167,7 @@ declare global {
2167
2167
  };
2168
2168
  interface HTMLLimebbTextEditorElementEventMap {
2169
2169
  "change": string;
2170
- "imageUploaded": UploadedFileInfo;
2171
- "imageRemoved": ImageInfo;
2172
- "imagesUploading": boolean;
2170
+ "metadataChange": EnhancedEditorMetadata;
2173
2171
  }
2174
2172
  /**
2175
2173
  * This component is a wrapper on the `limel-text-editor`. It adds support for platform
@@ -3520,7 +3518,7 @@ declare namespace LocalJSX {
3520
3518
  */
3521
3519
  interface LimebbTextEditor {
3522
3520
  /**
3523
- * Enables image pasting in the editor. Default: `false` :::note This component handles the upload process. The consumer must process the uploaded images by listening to `imageUploaded` and `imageRemoved` events. :::
3521
+ * Enables image pasting in the editor. Default: `false` :::note This component handles the upload process. The consumer must process the uploaded images by listening to `metadataChange` event. :::
3524
3522
  */
3525
3523
  "allowInlineImages"?: boolean;
3526
3524
  /**
@@ -3570,17 +3568,9 @@ declare namespace LocalJSX {
3570
3568
  */
3571
3569
  "onChange"?: (event: LimebbTextEditorCustomEvent<string>) => void;
3572
3570
  /**
3573
- * Dispatched when an image has been removed from the editor The ImageInfo object contains the fileInfoId which can be used to match with previously uploaded images (from imageUploaded events) :::note This event is forwarded from the underlying limel-text-editor component. :::
3571
+ * Dispatched when the metadata of the editor changes
3574
3572
  */
3575
- "onImageRemoved"?: (event: LimebbTextEditorCustomEvent<ImageInfo>) => void;
3576
- /**
3577
- * Fires when an image upload completes successfully :::note Returns UploadedFileInfo with: - fileId: ID of the uploaded file (use for limeobject creation) - fileInfoId: ID to match this upload with any removed images when handling the imageRemoved event :::
3578
- */
3579
- "onImageUploaded"?: (event: LimebbTextEditorCustomEvent<UploadedFileInfo>) => void;
3580
- /**
3581
- * Will be `true` while there is an active upload in progress, or while there is a failed image upload.
3582
- */
3583
- "onImagesUploading"?: (event: LimebbTextEditorCustomEvent<boolean>) => void;
3573
+ "onMetadataChange"?: (event: LimebbTextEditorCustomEvent<EnhancedEditorMetadata>) => void;
3584
3574
  /**
3585
3575
  * The placeholder text shown inside the input field, when the field is empty.
3586
3576
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limetech/lime-crm-building-blocks",
3
- "version": "1.73.0",
3
+ "version": "1.74.0",
4
4
  "description": "A home for shared components meant for use with Lime CRM",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -43,11 +43,11 @@
43
43
  "devDependencies": {
44
44
  "@eslint/eslintrc": "^3.3.0",
45
45
  "@eslint/js": "^9.21.0",
46
- "@limetech/lime-elements": "^38.9.6",
46
+ "@limetech/lime-elements": "^38.12.0",
47
47
  "@limetech/lime-web-components": "^5.46.0",
48
48
  "@limetech/lime-web-components-testing": "^1.0.0",
49
49
  "@lundalogik/lime-icons8": "^2.33.0",
50
- "@lundalogik/limeclient.js": "^1.80.1",
50
+ "@lundalogik/limeclient.js": "^1.80.2",
51
51
  "@stencil/core": "^4.27.2",
52
52
  "@stencil/sass": "^3.1.9",
53
53
  "@types/jest": "^29.5.14",
@@ -1 +0,0 @@
1
- import{r as t,c as i,h as e,g as r}from"./p-b11e09b4.js";import{P as s,A as n}from"./p-a26d352f.js";import{a as o}from"./p-54d4113a.js";import{A as a,a as h,b as c,E as u,T as f}from"./p-463d3174.js";import{d as l,b as d,k as v,c as b,s as p,a as m,e as g,U as y,S as j,g as w}from"./p-bcc23575.js";import{i as O,e as S}from"./p-c40a3f4b.js";import{d as I,r as k,S as x,a as A,i as T}from"./p-b31772c8.js";import{d as M,i as C,o as E,g as P,h as F,n as _,a as R}from"./p-5322fd19.js";import{i as U}from"./p-6fd28e32.js";import"./p-22de5a0e.js";var $=/\s/,D=/^\s+/;var N=NaN,L=/^[-+]0x[0-9a-f]+$/i,z=/^0b[01]+$/i,G=/^0o[0-7]+$/i,Q=parseInt;function W(t){if("number"==typeof t)return t;if(O(t))return N;if(I(t)){var i="function"==typeof t.valueOf?t.valueOf():t;t=I(i)?i+"":i}if("string"!=typeof t)return 0===t?t:+t;var e;t=(e=t)?e.slice(0,function(t){for(var i=t.length;i--&&$.test(t.charAt(i)););return i}(e)+1).replace(D,""):e;var r=z.test(t);return r||G.test(t)?Q(t.slice(2),r?2:8):L.test(t)?N:+t}var q=Object.create;const B=function(){function t(){}return function(i){if(!I(i))return{};if(q)return q(i);t.prototype=i;var e=new t;return t.prototype=void 0,e}}();function H(t,i,e){"__proto__"==i&&l?l(t,i,{configurable:!0,enumerable:!0,value:e,writable:!0}):t[i]=e}var K=Object.prototype.hasOwnProperty;function V(t,i,e){var r=t[i];K.call(t,i)&&S(r,e)&&(void 0!==e||i in t)||H(t,i,e)}function J(t,i,e,r){var s=!e;e||(e={});for(var n=-1,o=i.length;++n<o;){var a=i[n],h=r?r(e[a],t[a],a,e,t):void 0;void 0===h&&(h=t[a]),s?H(e,a,h):V(e,a,h)}return e}var X=Object.prototype.hasOwnProperty;function Y(t){return C(t)?d(t,!0):function(t){if(!I(t))return function(t){var i=[];if(null!=t)for(var e in Object(t))i.push(e);return i}(t);var i=M(t),e=[];for(var r in t)("constructor"!=r||!i&&X.call(t,r))&&e.push(r);return e}(t)}const Z=E(Object.getPrototypeOf,Object);var tt="object"==typeof exports&&exports&&!exports.nodeType&&exports,it=tt&&"object"==typeof module&&module&&!module.nodeType&&module,et=it&&it.exports===tt?k.Buffer:void 0,rt=et?et.allocUnsafe:void 0;const st=Object.getOwnPropertySymbols?function(t){for(var i=[];t;)m(i,b(t)),t=Z(t);return i}:p;function nt(t){return g(t,Y,st)}var ot=Object.prototype.hasOwnProperty;function at(t){var i=new t.constructor(t.byteLength);return new y(i).set(new y(t)),i}var ht=/\w*$/,ct=x?x.prototype:void 0,ut=ct?ct.valueOf:void 0,ft="[object Boolean]",lt="[object Date]",dt="[object Map]",vt="[object Number]",bt="[object RegExp]",pt="[object Set]",mt="[object String]",gt="[object Symbol]",yt="[object ArrayBuffer]",jt="[object DataView]",wt="[object Float32Array]",Ot="[object Float64Array]",St="[object Int8Array]",It="[object Int16Array]",kt="[object Int32Array]",xt="[object Uint8Array]",At="[object Uint8ClampedArray]",Tt="[object Uint16Array]",Mt="[object Uint32Array]";var Ct=_&&_.isMap;const Et=Ct?F(Ct):function(t){return A(t)&&"[object Map]"==P(t)};var Pt=_&&_.isSet;const Ft=Pt?F(Pt):function(t){return A(t)&&"[object Set]"==P(t)};var _t=1,Rt=2,Ut=4,$t="[object Arguments]",Dt="[object Function]",Nt="[object GeneratorFunction]",Lt="[object Object]",zt={};function Gt(t,i,e,r,s,n){var o,a=i&_t,h=i&Rt,c=i&Ut;if(e&&(o=s?e(t,r,s,n):e(t)),void 0!==o)return o;if(!I(t))return t;var u=T(t);if(u){if(o=function(t){var i=t.length,e=new t.constructor(i);return i&&"string"==typeof t[0]&&ot.call(t,"index")&&(e.index=t.index,e.input=t.input),e}(t),!a)return function(t,i){var e=-1,r=t.length;for(i||(i=Array(r));++e<r;)i[e]=t[e];return i}(t,o)}else{var f=P(t),l=f==Dt||f==Nt;if(R(t))return function(t,i){if(i)return t.slice();var e=t.length,r=rt?rt(e):new t.constructor(e);return t.copy(r),r}(t,a);if(f==Lt||f==$t||l&&!s){if(o=h||l?{}:function(t){return"function"!=typeof t.constructor||M(t)?{}:B(Z(t))}(t),!a)return h?function(t,i){return J(t,st(t),i)}(t,function(t,i){return t&&J(i,Y(i),t)}(o,t)):function(t,i){return J(t,b(t),i)}(t,function(t,i){return t&&J(i,v(i),t)}(o,t))}else{if(!zt[f])return s?t:{};o=function(t,i,e){var r,s,n=t.constructor;switch(i){case yt:return at(t);case ft:case lt:return new n(+t);case jt:return function(t,i){var e=i?at(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.byteLength)}(t,e);case wt:case Ot:case St:case It:case kt:case xt:case At:case Tt:case Mt:return function(t,i){var e=i?at(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.length)}(t,e);case dt:return new n;case vt:case mt:return new n(t);case bt:return(s=new(r=t).constructor(r.source,ht.exec(r))).lastIndex=r.lastIndex,s;case pt:return new n;case gt:return ut?Object(ut.call(t)):{}}}(t,f,a)}}n||(n=new j);var d=n.get(t);if(d)return d;n.set(t,o),Ft(t)?t.forEach((function(r){o.add(Gt(r,i,e,r,t,n))})):Et(t)&&t.forEach((function(r,s){o.set(s,Gt(r,i,e,s,t,n))}));var p=u?void 0:(c?h?nt:w:h?Y:v)(t);return function(t,i){for(var e=-1,r=null==t?0:t.length;++e<r&&!1!==i(t[e],e););}(p||t,(function(r,s){p&&(r=t[s=r]),V(o,s,Gt(r,i,e,s,t,n))})),o}zt[$t]=zt["[object Array]"]=zt["[object ArrayBuffer]"]=zt["[object DataView]"]=zt["[object Boolean]"]=zt["[object Date]"]=zt["[object Float32Array]"]=zt["[object Float64Array]"]=zt["[object Int8Array]"]=zt["[object Int16Array]"]=zt["[object Int32Array]"]=zt["[object Map]"]=zt["[object Number]"]=zt[Lt]=zt["[object RegExp]"]=zt["[object Set]"]=zt["[object String]"]=zt["[object Symbol]"]=zt["[object Uint8Array]"]=zt["[object Uint8ClampedArray]"]=zt["[object Uint16Array]"]=zt["[object Uint32Array]"]=!0,zt["[object Error]"]=zt[Dt]=zt["[object WeakMap]"]=!1;const Qt=function(){return k.Date.now()};var Wt=Math.max,qt=Math.min;function Bt(t,i){return t.label===i}function Ht(t,i){return Object.values(t.properties).find((t=>t&&t.relation&&Bt(t.relation.getLimetype(),i)))}function Kt(t,i){const e=Ht(t,i);return!!e&&function(t){return function(t){return t&&["belongsto","hasone","hasmany","hasandbelongstomany"].includes(t.type)}(t)&&!function(t){return t&&["belongsto","hasone"].includes(t.type)}(t)}(e)}class Vt{get limeObjectService(){return this.platform.get(s.LimeObjectRepository)}get queryService(){return this.platform.get(s.Query)}get viewFactoryRegistry(){return this.platform.get(s.ViewFactoryRegistry)}get translator(){var t;return null===(t=this.platform)||void 0===t?void 0:t.get(s.Translate)}get triggerCharacter(){return this._triggerCharacter}get triggerHandler(){return this._triggerHandler}constructor(t,i,e){this.platform=t,this.context=i,this.searchableLimetypes=e,this.groupCounts={},this._triggerCharacter="@",this._triggerHandler={searcher:t=>this.searcher(t),inserter:(t,i)=>this.inserter(t,i),emptySearchMessage:"Start typing a name...",noItemsFoundMessage:"No results for your search...",nodeDefinition:{customElement:{tagName:"limebb-mention",attributes:["limetype","objectid","href"]},mapAttributes:t=>({limetype:t.value.getLimetype().name,objectid:t.value.id,href:`object/${this.context.limetype}/${this.context.id}`})}},this.searcher=async t=>{if(!t)return[];const{objects:i}=await this.limeObjectService.search(t,this.searchableLimetypes,10);return this.createSearchListItems(i)},this.inserter=async(t,i)=>{var e;const r=this.triggerHandler.nodeDefinition;r&&t.insert({node:{tagName:r.customElement.tagName,attributes:r.mapAttributes(i)},children:[null===(e=i.value)||void 0===e?void 0:e.descriptive]})}}async initialize(){await this.loadGroupCounts()}async loadGroupCounts(){const t=this.searchableLimetypes.filter((t=>!Bt(t,"user")&&Kt(t,"user"))).map((t=>this.getGroupCounts(t)));(await Promise.all(t)).forEach((t=>{Object.assign(this.groupCounts,t)}))}async getGroupCounts(t){var i;const e=Ht(t,"user"),r=t.name;try{const t=await this.queryService.execute({limetype:r,responseFormat:{object:{_id:null,[e.name]:{count:{aggregate:{op:n.Count}}}}}});if(!(null===(i=t.objects)||void 0===i?void 0:i.length))return{[r]:{}};const s=this.createGroupCount(t.objects,e.name);return{[r]:s}}catch(i){return console.error(`Error fetching group count for limetype: ${t.name}`,i),{[r]:{}}}}createGroupCount(t,i){const e={};return t.forEach((t=>{const{_id:r,[i]:s}=t;e[r]=s.count})),e}createSearchListItems(t=[]){return t.map((t=>this.createSearchListItem(t))).filter(U)}createSearchListItem(t){const i=this.viewFactoryRegistry.getFactory("search"),e=this.limeObjectService.getObject(t._limetype,t._id);if(!e)return null;const r=i(e,this.context),s=this.getGroupCountComponent(e);return Object.assign(Object.assign({},r),s?{primaryComponent:s}:{})}getGroupCountComponent(t){var i;const e=t.getLimetype(),r=null===(i=this.groupCounts[e.name])||void 0===i?void 0:i[t.id],s=Ht(e,"user");if(void 0!==r&&s)return{name:"limebb-mention-group-counter",props:{count:r,limetype:s.relation.getLimetype(),helperLabel:this.translator.get("webclient.notification-center.members-will-be-notified")}}}}class Jt{constructor(t,i){this.file=t,this.http=i,this.uploadCancelled=!1,this.getUrl=t=>`api/v1/file/${t||""}`}async initialize(){this.uploadService=await this.http.createFileUpload("POST",this.getUrl(),this.file),this.progressCallback&&(this.uploadService.onProgress=this.progressCallback)}async upload(){return this.uploadService.upload()}getFileName(){return this.file.name}cancel(){this.uploadService.cancel(),this.uploadCancelled=!0}set onProgress(t){this.progressCallback=t,this.uploadService&&(this.uploadService.onProgress=t)}}class Xt{constructor(t){this.platform=t}async handleImagePasted(t){const i=null==t?void 0:t.fileInfo;if(!i)return;if(!this.validateImageSize(i))return;t.insertThumbnail();const e=await this.createFileUpload(i),r=null==e?void 0:e.href;return r&&void 0!==(null==e?void 0:e.fileId)?t.insertImage(r):t.insertFailedThumbnail(),e}validateImageSize(t){return!!t.fileContent&&t.fileContent.size<=52428800}async createFileUpload(t){var i;if(!t.fileContent)return;const e=new Jt(t.fileContent,this.http);await e.initialize();const r=Object.assign(Object.assign({},t),{progress:0,file:e,state:"added",fileId:void 0,href:void 0,fileInfoId:t.id});e.onProgress=t=>{0===r.progress&&(r.state="uploading"),r.progress=t,100===t&&(r.state="finalizing")};const s=await e.upload();return r.id=s.id,r.fileId=s.id,r.filename=s.filename,r.extension=s.extension,r.contentType=s.contentType,r.size=s.size,r.state="done",r.href=null===(i=s._links)||void 0===i?void 0:i.contents.href,r}get http(){return this.platform.get(s.Http)}}const Yt=class{watchOpen(){this.setupHandlers(),this.setPickerMessage()}watchQuery(){this.setPickerMessage()}constructor(e){var r;t(this,e),this.change=i(this,"change",7),this.imageUploaded=i(this,"imageUploaded",7),this.imageRemoved=i(this,"imageRemoved",7),this.imagesUploading=i(this,"imagesUploading",7),this.allowMentioning=!1,this.contentType="markdown",this.language="en",this.disabled=!1,this.readonly=!1,this.invalid=!1,this.required=!1,this.ui="standard",this.allowResize=!0,this.value="",this.triggerMap={},this.customElements=[],this.allowInlineImages=!1,this.items=[],this.highlightedItemIndex=0,this.isPickerOpen=!1,this.isSearching=!1,this.registeredTriggers=[],this.registeredTriggerMap=this.triggerMap,this.registeredCustomElements=this.customElements,this.activeTrigger=void 0,this.activeUploads=new Set,this.handleMouseClick=t=>{this.textEditorPickerElement&&(t.target===this.textEditorPickerElement||this.resetTriggerAndPicker())},this.handleKeyPress=t=>{if(!this.isPickerOpen||!this.activeTrigger)return;if(![h,c,a,u,f].includes(t.key))return;if(t.stopPropagation(),t.preventDefault(),"keyup"===t.type)return;const i={[h]:this.handleEscapeKey,[u]:this.handleEnterOrTabKey,[f]:this.handleEnterOrTabKey,[a]:this.handleArrowKeyPress,[c]:this.handleArrowKeyPress}[t.key];i&&i(t)},this.handleArrowKeyPress=t=>{this.highlightedItemIndex=this.findNonSeparatorIndex(t.key,this.highlightedItemIndex)},this.findNonSeparatorIndex=(t,i,e=0)=>{if(!this.items.length||e>this.items.length)return i;const r=((t,i,e)=>(i+(t===a?1:-1)+e)%e)(t,i,this.items.length);return this.isListSeparator(this.items[r])?this.findNonSeparatorIndex(t,r,e+1):r},this.handleEscapeKey=()=>{var t;null===(t=this.triggerFunction)||void 0===t||t.stopTrigger(),this.resetTriggerAndPicker()},this.handleEnterOrTabKey=t=>{this.handleItemSelection(t)},this.handleImagePasted=async t=>{if(t.stopPropagation(),!this.allowInlineImages)return;const i=t.detail,e=i.fileInfo;this.activeUploads.add(e.id),this.imagesUploading.emit(this.activeUploads.size>0);const r=await this.uploadHandler.handleImagePasted(i),s={fileId:null==r?void 0:r.fileId,fileInfoId:e.id};s.fileId&&(this.imageUploaded.emit(s),this.activeUploads.delete(e.id)),this.imagesUploading.emit(this.activeUploads.size>0)},this.handleImageRemoved=t=>{if(t.stopPropagation(),!this.allowInlineImages)return;const i=t.detail;i&&(this.activeUploads.delete(i.fileInfoId),this.imagesUploading.emit(this.activeUploads.size>0),this.imageRemoved.emit(i))},this.handleTriggerStart=t=>{t.stopPropagation(),this.activeTrigger=t.detail.trigger,this.triggerFunction=t.detail.textEditor,this.isPickerOpen=!0},this.handleTriggerStop=t=>{t.stopPropagation(),this.resetTriggerAndPicker()},this.handleTriggerChange=t=>{var i;t.stopImmediatePropagation(),this.editorPickerQuery=t.detail.value;const e=null===(i=this.registeredTriggerMap[t.detail.trigger])||void 0===i?void 0:i.searcher;e&&(this.isSearching=!0,this.debouncedSearchFn(e,this.editorPickerQuery))},this.resetTriggerAndPicker=()=>{this.isPickerOpen=!1,this.activeTrigger=void 0,this.triggerFunction=void 0,this.isSearching=!1,this.highlightedItemIndex=0,this.items=[]},this.handleItemSelection=t=>{var i;let e;if(t instanceof CustomEvent)e=t.detail;else{if(!(t instanceof KeyboardEvent))return;{const t=this.items[this.highlightedItemIndex];if(this.isListSeparator(t))return;e=t}}if(!this.activeTrigger)return;const r=this.registeredTriggerMap[this.activeTrigger];try{r.inserter(this.triggerFunction,e)}catch(t){console.error("Error inserting",t)}this.resetTriggerAndPicker(),null===(i=this.textEditor)||void 0===i||i.focus()},this.handleVisibilityChange=()=>{"hidden"===document.visibilityState&&this.saveDraft()},this.handleBeforeUnload=()=>{this.saveDraft()},this.portalId="crypto"in window&&"function"==typeof(null===(r=window.crypto)||void 0===r?void 0:r.randomUUID)?"a_"+crypto.randomUUID():String.fromCharCode(97+Math.floor(26*Math.random()))+Math.random().toString(36).substring(2)+Math.random().toString(36).substring(2),this.debouncedSearchFn=function(t,i,e){var r,s,n,o,a,h,c=0,u=!1,f=!1,l=!0;if("function"!=typeof t)throw new TypeError("Expected a function");function d(i){var e=r,n=s;return r=s=void 0,c=i,o=t.apply(n,e)}function v(t){var e=t-h;return void 0===h||e>=i||e<0||f&&t-c>=n}function b(){var t=Qt();if(v(t))return p(t);a=setTimeout(b,function(t){var e=i-(t-h);return f?qt(e,n-(t-c)):e}(t))}function p(t){return a=void 0,l&&r?d(t):(r=s=void 0,o)}function m(){var t=Qt(),e=v(t);if(r=arguments,s=this,h=t,e){if(void 0===a)return function(t){return c=t,a=setTimeout(b,i),u?d(t):o}(h);if(f)return clearTimeout(a),a=setTimeout(b,i),d(h)}return void 0===a&&(a=setTimeout(b,i)),o}return i=W(i)||0,I(e)&&(u=!!e.leading,n=(f="maxWait"in e)?Wt(W(e.maxWait)||0,i):n,l="trailing"in e?!!e.trailing:l),m.cancel=function(){void 0!==a&&clearTimeout(a),c=0,r=h=s=a=void 0},m.flush=function(){return void 0===a?o:p(Qt())},m}((async(t,i)=>{try{const e=await t(i);if(i!==this.editorPickerQuery||!this.activeTrigger)return;this.items=e}catch(t){console.error("Error searching",t)}finally{this.isSearching=!1}}),300)}connectedCallback(){var t,i,e,r;if(this.draftIdentifier){const s=null!==(i=null===(t=this.context)||void 0===t?void 0:t.id)&&void 0!==i?i:"no-limeobject",n=null!==(r=null===(e=this.context)||void 0===e?void 0:e.limetype)&&void 0!==r?r:"no-limetype";this.textEditorInnerId=["text-editor-draft",n,s,this.draftIdentifier].join("-")}this.textEditorInnerId&&(document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("beforeunload",this.handleBeforeUnload)),this.uploadHandler=new Xt(this.platform)}componentWillLoad(){this.allowMentioning&&this.registerMentions(),this.registerTriggers(),this.loadDraft()}disconnectedCallback(){document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("beforeunload",this.handleBeforeUnload),document.removeEventListener("mousedown",this.handleMouseClick),this.saveDraft(),this.host&&(this.host.removeEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.removeEventListener("keydown",this.handleKeyPress,{capture:!0})),this.debouncedSearchFn&&this.debouncedSearchFn.cancel&&this.debouncedSearchFn.cancel()}registerMentions(){const t=new Vt(this.platform,this.context,this.searchableLimetypes),i=t.triggerHandler.nodeDefinition;i&&(this.registeredCustomElements.push(i.customElement),this.registeredTriggerMap[t.triggerCharacter]=t.triggerHandler,t.initialize())}registerTriggers(){this.registeredTriggers=Object.keys(this.registeredTriggerMap)}setPickerMessage(){var t;if(!this.activeTrigger)return;const i=this.registeredTriggerMap[this.activeTrigger];this.pickerMessage=(null===(t=this.editorPickerQuery)||void 0===t?void 0:t.length)>0?i.noItemsFoundMessage:i.emptySearchMessage}setupHandlers(){this.isPickerOpen?(this.host.addEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.addEventListener("keydown",this.handleKeyPress,{capture:!0}),document.addEventListener("mousedown",this.handleMouseClick)):(this.host.removeEventListener("keyup",this.handleKeyPress,{capture:!0}),this.host.removeEventListener("keydown",this.handleKeyPress,{capture:!0}),document.removeEventListener("mousedown",this.handleMouseClick))}isListSeparator(t){return"separator"in t&&!0===t.separator}render(){return[e("limel-text-editor",{key:"d1442a13d2b3719f15055abc72b14ff1bcd16f94",ref:t=>this.textEditor=t,tabindex:this.disabled?-1:0,value:this.value,contentType:this.contentType,customElements:this.registeredCustomElements,"aria-disabled":this.disabled,language:this.language,triggers:this.registeredTriggers,onTriggerStart:this.handleTriggerStart,onTriggerStop:this.handleTriggerStop,onTriggerChange:this.handleTriggerChange,onImagePasted:this.handleImagePasted,onImageRemoved:this.handleImageRemoved,ui:this.ui,allowResize:this.allowResize,required:this.required,disabled:this.disabled,readonly:this.readonly,helperText:this.helperText,placeholder:this.placeholder,label:this.label,invalid:this.invalid}),this.renderPicker()]}renderPicker(){if(this.isPickerOpen)return e("limel-portal",{containerId:this.portalId,visible:this.isPickerOpen,openDirection:"top",inheritParentWidth:!0,anchor:this.textEditor},e("limebb-text-editor-picker",{ref:t=>this.textEditorPickerElement=t,items:(t=this.items,i=this.highlightedItemIndex,t.map(((t,e)=>{const r=Gt(t,5);return Object.assign(Object.assign({},r),{selected:e===i})}))),onItemSelected:this.handleItemSelection,emptyMessage:this.pickerMessage,isSearching:this.isSearching}));var t,i}loadDraft(){if(!this.userDataService||!this.textEditorInnerId)return;if(this.value)return;const t=this.userDataService.get(this.textEditorInnerId);t&&this.change.emit(t)}saveDraft(){var t,i,e;this.textEditorInnerId&&((null===(t=this.value)||void 0===t?void 0:t.trim())?null===(i=this.userDataService)||void 0===i||i.set(this.textEditorInnerId,this.value):null===(e=this.userDataService)||void 0===e||e.set(this.textEditorInnerId,void 0))}get userDataService(){return this.platform.get(s.UserDataRepository)}get host(){return r(this)}static get watchers(){return{isPickerOpen:["watchOpen"],editorPickerQuery:["watchQuery"]}}};!function(t,i,e,r){var s,n=arguments.length,o=n<3?i:null===r?r=Object.getOwnPropertyDescriptor(i,e):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,i,e,r);else for(var a=t.length-1;a>=0;a--)(s=t[a])&&(o=(n<3?s(o):n>3?s(i,e,o):s(i,e))||o);n>3&&o&&Object.defineProperty(i,e,o)}([o({map:[function(t){return Object.values(t).filter((t=>Bt(t,"user")||Kt(t,"user")))}]})],Yt.prototype,"searchableLimetypes",void 0);export{Yt as limebb_text_editor}