@limetech/lime-crm-building-blocks 1.71.1 → 1.72.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,13 @@
1
+ ## [1.72.0](https://github.com/Lundalogik/lime-crm-building-blocks/compare/v1.71.1...v1.72.0) (2025-04-23)
2
+
3
+ ### Features
4
+
5
+
6
+ * **text editor:** add allow images prop and update event doc strings ([d09314a](https://github.com/Lundalogik/lime-crm-building-blocks/commit/d09314a9d829b1a9a97b12495261779d9af4693b))
7
+ * **text editor:** add file upload handler ([c4a6754](https://github.com/Lundalogik/lime-crm-building-blocks/commit/c4a67544defc36464ec34859c7cbdd044982cfb1))
8
+ * **text editor:** add file uploader class ([54d2796](https://github.com/Lundalogik/lime-crm-building-blocks/commit/54d27961ac00f07f1b547c67aef9d7e04d87a140))
9
+ * **text editor:** use file upload in text editor ([34fde63](https://github.com/Lundalogik/lime-crm-building-blocks/commit/34fde6379812354d06fe993e1cd91aff521cc8b0))
10
+
1
11
  ## [1.71.1](https://github.com/Lundalogik/lime-crm-building-blocks/compare/v1.71.0...v1.71.1) (2025-04-23)
2
12
 
3
13
  ### Bug Fixes
@@ -19,7 +19,7 @@ var patchBrowser = () => {
19
19
 
20
20
  patchBrowser().then(async (options) => {
21
21
  await appGlobals.globalScripts();
22
- return index.bootstrapLazy([["limebb-feed.cjs",[[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"]}]]],["limebb-kanban.cjs",[[1,"limebb-kanban",{"platform":[16],"context":[16],"groups":[16]}]]],["limebb-chat-list.cjs",[[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"]}]]],["limebb-text-editor.cjs",[[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],"items":[32],"highlightedItemIndex":[32],"editorPickerQuery":[32],"searchableLimetypes":[32],"isPickerOpen":[32],"isSearching":[32]},null,{"isPickerOpen":["watchOpen"],"editorPickerQuery":["watchQuery"]}]]],["limebb-date-range.cjs",[[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]}]]],["limebb-info-tile-currency-format.cjs",[[1,"limebb-info-tile-currency-format",{"platform":[16],"context":[16],"value":[16]}]]],["limebb-notification-list.cjs",[[1,"limebb-notification-list",{"platform":[16],"context":[16],"items":[16],"loading":[4],"lastVisitedTimestamp":[1,"last-visited-timestamp"]},null,{"items":["handleItemsChange"]}]]],["limebb-browser.cjs",[[17,"limebb-browser",{"platform":[16],"context":[16],"items":[16],"layout":[1],"filter":[32]}]]],["limebb-component-config.cjs",[[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"]}]]],["limebb-component-picker.cjs",[[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"]}]]],["limebb-dashboard-widget.cjs",[[1,"limebb-dashboard-widget",{"heading":[513],"subheading":[513],"supportingText":[513,"supporting-text"],"icon":[513]}]]],["limebb-icon-picker.cjs",[[1,"limebb-icon-picker",{"value":[1],"required":[4],"readonly":[4],"invalid":[4],"disabled":[4],"label":[1],"helperText":[1,"helper-text"]}]]],["limebb-info-tile.cjs",[[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"]}]]],["limebb-info-tile-date-format.cjs",[[1,"limebb-info-tile-date-format",{"value":[16]}]]],["limebb-info-tile-decimal-format.cjs",[[1,"limebb-info-tile-decimal-format",{"value":[16]}]]],["limebb-info-tile-format.cjs",[[1,"limebb-info-tile-format",{"platform":[16],"context":[16],"type":[1],"value":[16]}]]],["limebb-info-tile-relative-date-format.cjs",[[1,"limebb-info-tile-relative-date-format",{"value":[16]}]]],["limebb-info-tile-unit-format.cjs",[[1,"limebb-info-tile-unit-format",{"value":[16]}]]],["limebb-limeobject-file-viewer.cjs",[[1,"limebb-limeobject-file-viewer",{"platform":[16],"context":[16],"property":[1],"fileTypes":[16],"limeobject":[32],"limetype":[32]}]]],["limebb-locale-picker.cjs",[[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]}]]],["limebb-mention.cjs",[[1,"limebb-mention",{"limetype":[1],"objectid":[2],"limeobject":[32]}]]],["limebb-mention-group-counter.cjs",[[1,"limebb-mention-group-counter",{"count":[2],"limetype":[16],"helperLabel":[1,"helper-label"]}]]],["limebb-trend-indicator.cjs",[[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"]}]]],["limebb-navigation-button_2.cjs",[[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]}]]],["limebb-kanban-item.cjs",[[1,"limebb-kanban-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-kanban-group.cjs",[[1,"limebb-kanban-group",{"platform":[16],"context":[16],"identifier":[1],"heading":[513],"help":[1],"items":[16],"summary":[1],"loading":[516],"totalCount":[514,"total-count"]}]]],["limebb-feed-timeline-item.cjs",[[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]}]]],["limebb-text-editor-picker.cjs",[[1,"limebb-text-editor-picker",{"items":[16],"open":[516],"isSearching":[4,"is-searching"],"emptyMessage":[1,"empty-message"]},null,{"open":["watchOpen"]}]]],["limebb-currency-picker.cjs",[[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]}]]],["limebb-date-picker.cjs",[[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]}]]],["limebb-notification-item.cjs",[[1,"limebb-notification-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-chat-item_2.cjs",[[1,"limebb-chat-item",{"platform":[16],"context":[16],"item":[16]}],[1,"limebb-typing-indicator"]]],["limebb-empty-state.cjs",[[1,"limebb-empty-state",{"heading":[513],"value":[513],"icon":[16]}]]]], options);
22
+ return index.bootstrapLazy([["limebb-feed.cjs",[[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"]}]]],["limebb-kanban.cjs",[[1,"limebb-kanban",{"platform":[16],"context":[16],"groups":[16]}]]],["limebb-chat-list.cjs",[[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"]}]]],["limebb-text-editor.cjs",[[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"]}]]],["limebb-date-range.cjs",[[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]}]]],["limebb-info-tile-currency-format.cjs",[[1,"limebb-info-tile-currency-format",{"platform":[16],"context":[16],"value":[16]}]]],["limebb-notification-list.cjs",[[1,"limebb-notification-list",{"platform":[16],"context":[16],"items":[16],"loading":[4],"lastVisitedTimestamp":[1,"last-visited-timestamp"]},null,{"items":["handleItemsChange"]}]]],["limebb-browser.cjs",[[17,"limebb-browser",{"platform":[16],"context":[16],"items":[16],"layout":[1],"filter":[32]}]]],["limebb-component-config.cjs",[[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"]}]]],["limebb-component-picker.cjs",[[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"]}]]],["limebb-dashboard-widget.cjs",[[1,"limebb-dashboard-widget",{"heading":[513],"subheading":[513],"supportingText":[513,"supporting-text"],"icon":[513]}]]],["limebb-icon-picker.cjs",[[1,"limebb-icon-picker",{"value":[1],"required":[4],"readonly":[4],"invalid":[4],"disabled":[4],"label":[1],"helperText":[1,"helper-text"]}]]],["limebb-info-tile.cjs",[[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"]}]]],["limebb-info-tile-date-format.cjs",[[1,"limebb-info-tile-date-format",{"value":[16]}]]],["limebb-info-tile-decimal-format.cjs",[[1,"limebb-info-tile-decimal-format",{"value":[16]}]]],["limebb-info-tile-format.cjs",[[1,"limebb-info-tile-format",{"platform":[16],"context":[16],"type":[1],"value":[16]}]]],["limebb-info-tile-relative-date-format.cjs",[[1,"limebb-info-tile-relative-date-format",{"value":[16]}]]],["limebb-info-tile-unit-format.cjs",[[1,"limebb-info-tile-unit-format",{"value":[16]}]]],["limebb-limeobject-file-viewer.cjs",[[1,"limebb-limeobject-file-viewer",{"platform":[16],"context":[16],"property":[1],"fileTypes":[16],"limeobject":[32],"limetype":[32]}]]],["limebb-locale-picker.cjs",[[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]}]]],["limebb-mention.cjs",[[1,"limebb-mention",{"limetype":[1],"objectid":[2],"limeobject":[32]}]]],["limebb-mention-group-counter.cjs",[[1,"limebb-mention-group-counter",{"count":[2],"limetype":[16],"helperLabel":[1,"helper-label"]}]]],["limebb-trend-indicator.cjs",[[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"]}]]],["limebb-navigation-button_2.cjs",[[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]}]]],["limebb-kanban-item.cjs",[[1,"limebb-kanban-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-kanban-group.cjs",[[1,"limebb-kanban-group",{"platform":[16],"context":[16],"identifier":[1],"heading":[513],"help":[1],"items":[16],"summary":[1],"loading":[516],"totalCount":[514,"total-count"]}]]],["limebb-feed-timeline-item.cjs",[[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]}]]],["limebb-text-editor-picker.cjs",[[1,"limebb-text-editor-picker",{"items":[16],"open":[516],"isSearching":[4,"is-searching"],"emptyMessage":[1,"empty-message"]},null,{"open":["watchOpen"]}]]],["limebb-currency-picker.cjs",[[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]}]]],["limebb-date-picker.cjs",[[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]}]]],["limebb-notification-item.cjs",[[1,"limebb-notification-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-chat-item_2.cjs",[[1,"limebb-chat-item",{"platform":[16],"context":[16],"item":[16]}],[1,"limebb-typing-indicator"]]],["limebb-empty-state.cjs",[[1,"limebb-empty-state",{"heading":[513],"value":[513],"icon":[16]}]]]], options);
23
23
  });
24
24
 
25
25
  exports.setNonce = index.setNonce;
@@ -35,6 +35,20 @@ function isSingleRelation(property) {
35
35
  return property && propTypes.includes(property.type);
36
36
  }
37
37
 
38
+ /**
39
+ * Defines the HTTP methods as constants.
40
+ * Used in the UploadFile class in lime-crm-components
41
+ *
42
+ * @public
43
+ */
44
+ const HttpMethod = {
45
+ Get: 'GET',
46
+ Post: 'POST',
47
+ Put: 'PUT',
48
+ Delete: 'DELETE',
49
+ Patch: 'PATCH',
50
+ };
51
+
38
52
  /** Used to match a single whitespace character. */
39
53
  var reWhitespace = /\s/;
40
54
 
@@ -1340,6 +1354,130 @@ class MentionsService {
1340
1354
  }
1341
1355
  }
1342
1356
 
1357
+ const CORE_API_PATH = 'api/v1';
1358
+ const FILE_PATH = 'file';
1359
+ const FIFTY = 50;
1360
+ const THOUSAND_BYTES = 1024;
1361
+ const MAX_FILE_SIZE = FIFTY * THOUSAND_BYTES * THOUSAND_BYTES; // 50 MB
1362
+ class FileUpload {
1363
+ constructor(file, http) {
1364
+ this.file = file;
1365
+ this.http = http;
1366
+ this.uploadCancelled = false;
1367
+ this.getUrl = (fileid) => {
1368
+ return `${CORE_API_PATH}/${FILE_PATH}/${fileid ? fileid : ''}`;
1369
+ };
1370
+ }
1371
+ async initialize() {
1372
+ this.uploadService = await this.http.createFileUpload(HttpMethod.Post, this.getUrl(), this.file);
1373
+ if (this.progressCallback) {
1374
+ this.uploadService.onProgress = this.progressCallback;
1375
+ }
1376
+ }
1377
+ async upload() {
1378
+ return this.uploadService.upload();
1379
+ }
1380
+ getFileName() {
1381
+ return this.file.name;
1382
+ }
1383
+ cancel() {
1384
+ this.uploadService.cancel();
1385
+ this.uploadCancelled = true;
1386
+ }
1387
+ set onProgress(callback) {
1388
+ this.progressCallback = callback;
1389
+ if (this.uploadService) {
1390
+ this.uploadService.onProgress = callback;
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+ const UPLOAD_COMPLETED = 100;
1396
+ class UploadHandler {
1397
+ constructor(platform) {
1398
+ this.platform = platform;
1399
+ }
1400
+ /**
1401
+ * Handles image paste events in the text editor
1402
+ *
1403
+ * @param {ImageInserter} imageInserter - The image inserter with the file info
1404
+ * @returns {Promise<FileWrapper | undefined>} Promise resolving to the uploaded file wrapper or undefined if upload fails
1405
+ */
1406
+ async handleImagePasted(imageInserter) {
1407
+ const fileInfo = imageInserter === null || imageInserter === void 0 ? void 0 : imageInserter.fileInfo;
1408
+ if (!fileInfo) {
1409
+ return;
1410
+ }
1411
+ if (!this.validateImageSize(fileInfo)) {
1412
+ return;
1413
+ }
1414
+ imageInserter.insertThumbnail();
1415
+ const uploadedFile = await this.createFileUpload(fileInfo);
1416
+ const fileUrl = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.href;
1417
+ const fileId = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId;
1418
+ if (fileUrl && fileId !== undefined) {
1419
+ imageInserter.insertImage(fileUrl);
1420
+ }
1421
+ else {
1422
+ imageInserter.insertFailedThumbnail();
1423
+ }
1424
+ return uploadedFile;
1425
+ }
1426
+ /**
1427
+ * Validates that the image file size is within limits
1428
+ *
1429
+ * @param {FileInfo} fileInfo - The file info to validate
1430
+ * @returns {boolean} True if file size is valid, false otherwise
1431
+ */
1432
+ validateImageSize(fileInfo) {
1433
+ if (!fileInfo.fileContent) {
1434
+ return false;
1435
+ }
1436
+ return fileInfo.fileContent.size <= MAX_FILE_SIZE;
1437
+ }
1438
+ /**
1439
+ * Creates and uploads a file
1440
+ *
1441
+ * @param {FileInfo} fileInfo - The file info to upload
1442
+ * @returns {Promise<FileWrapper | undefined>} Promise resolving to the uploaded file wrapper or undefined if upload fails
1443
+ */
1444
+ async createFileUpload(fileInfo) {
1445
+ var _a;
1446
+ if (!fileInfo.fileContent) {
1447
+ return;
1448
+ }
1449
+ const imageFile = new FileUpload(fileInfo.fileContent, this.http);
1450
+ await imageFile.initialize();
1451
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
1452
+ imageFile.onProgress = (progress) => {
1453
+ if (imageUpload.progress === 0) {
1454
+ imageUpload.state = 'uploading';
1455
+ }
1456
+ imageUpload.progress = progress;
1457
+ if (progress === UPLOAD_COMPLETED) {
1458
+ imageUpload.state = 'finalizing';
1459
+ }
1460
+ };
1461
+ 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
+ imageUpload.fileId = response.id;
1467
+ imageUpload.filename = response.filename;
1468
+ imageUpload.extension = response.extension;
1469
+ imageUpload.contentType = response.contentType;
1470
+ imageUpload.size = response.size;
1471
+ imageUpload.state = 'done';
1472
+ // eslint-disable-next-line no-underscore-dangle
1473
+ imageUpload.href = (_a = response._links) === null || _a === void 0 ? void 0 : _a.contents.href;
1474
+ return imageUpload;
1475
+ }
1476
+ get http() {
1477
+ return this.platform.get(types.PlatformServiceName.Http);
1478
+ }
1479
+ }
1480
+
1343
1481
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1344
1482
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1345
1483
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -1362,6 +1500,9 @@ const LimeBBTextEditor = class {
1362
1500
  constructor(hostRef) {
1363
1501
  index.registerInstance(this, hostRef);
1364
1502
  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);
1365
1506
  /**
1366
1507
  * Set to true to enable mentioning a coworker or groups of coworkers.
1367
1508
  *
@@ -1429,6 +1570,17 @@ const LimeBBTextEditor = class {
1429
1570
  this.value = '';
1430
1571
  this.triggerMap = {};
1431
1572
  this.customElements = [];
1573
+ /**
1574
+ * Enables image pasting in the editor.
1575
+ * Default: `false`
1576
+ *
1577
+ * :::note
1578
+ * This component handles the upload process.
1579
+ * The consumer must process the uploaded images by listening to `imageUploaded` and
1580
+ * `imageRemoved` events.
1581
+ * :::
1582
+ */
1583
+ this.allowInlineImages = false;
1432
1584
  this.items = [];
1433
1585
  this.highlightedItemIndex = 0;
1434
1586
  /**
@@ -1443,6 +1595,7 @@ const LimeBBTextEditor = class {
1443
1595
  this.registeredTriggerMap = this.triggerMap;
1444
1596
  this.registeredCustomElements = this.customElements;
1445
1597
  this.activeTrigger = undefined;
1598
+ this.activeUploads = new Set();
1446
1599
  this.handleMouseClick = (event) => {
1447
1600
  if (!this.textEditorPickerElement) {
1448
1601
  return;
@@ -1500,6 +1653,37 @@ const LimeBBTextEditor = class {
1500
1653
  this.handleEnterOrTabKey = (event) => {
1501
1654
  this.handleItemSelection(event);
1502
1655
  };
1656
+ this.handleImagePasted = async (event) => {
1657
+ 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);
1675
+ };
1676
+ this.handleImageRemoved = (event) => {
1677
+ event.stopPropagation();
1678
+ if (!this.allowInlineImages) {
1679
+ return;
1680
+ }
1681
+ const imageInfo = event.detail;
1682
+ if (!imageInfo) {
1683
+ return;
1684
+ }
1685
+ this.imageRemoved.emit(imageInfo);
1686
+ };
1503
1687
  this.handleTriggerStart = (event) => {
1504
1688
  event.stopPropagation();
1505
1689
  this.activeTrigger = event.detail.trigger;
@@ -1602,6 +1786,7 @@ const LimeBBTextEditor = class {
1602
1786
  document.addEventListener('visibilitychange', this.handleVisibilityChange);
1603
1787
  window.addEventListener('beforeunload', this.handleBeforeUnload);
1604
1788
  }
1789
+ this.uploadHandler = new UploadHandler(this.platform);
1605
1790
  }
1606
1791
  componentWillLoad() {
1607
1792
  if (this.allowMentioning) {
@@ -1680,7 +1865,7 @@ const LimeBBTextEditor = class {
1680
1865
  }
1681
1866
  render() {
1682
1867
  return [
1683
- index.h("limel-text-editor", { key: '05d39fcf619a9262ef204030aea0fd2b83495fe3', 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, 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 }),
1868
+ index.h("limel-text-editor", { key: 'f262f63be7e201a835c37921a43f3f8817dc538f', 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 }),
1684
1869
  this.renderPicker(),
1685
1870
  ];
1686
1871
  }
@@ -8,7 +8,7 @@ const appGlobals = require('./app-globals-3a1e7e63.js');
8
8
  const defineCustomElements = async (win, options) => {
9
9
  if (typeof window === 'undefined') return undefined;
10
10
  await appGlobals.globalScripts();
11
- return index.bootstrapLazy([["limebb-feed.cjs",[[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"]}]]],["limebb-kanban.cjs",[[1,"limebb-kanban",{"platform":[16],"context":[16],"groups":[16]}]]],["limebb-chat-list.cjs",[[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"]}]]],["limebb-text-editor.cjs",[[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],"items":[32],"highlightedItemIndex":[32],"editorPickerQuery":[32],"searchableLimetypes":[32],"isPickerOpen":[32],"isSearching":[32]},null,{"isPickerOpen":["watchOpen"],"editorPickerQuery":["watchQuery"]}]]],["limebb-date-range.cjs",[[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]}]]],["limebb-info-tile-currency-format.cjs",[[1,"limebb-info-tile-currency-format",{"platform":[16],"context":[16],"value":[16]}]]],["limebb-notification-list.cjs",[[1,"limebb-notification-list",{"platform":[16],"context":[16],"items":[16],"loading":[4],"lastVisitedTimestamp":[1,"last-visited-timestamp"]},null,{"items":["handleItemsChange"]}]]],["limebb-browser.cjs",[[17,"limebb-browser",{"platform":[16],"context":[16],"items":[16],"layout":[1],"filter":[32]}]]],["limebb-component-config.cjs",[[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"]}]]],["limebb-component-picker.cjs",[[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"]}]]],["limebb-dashboard-widget.cjs",[[1,"limebb-dashboard-widget",{"heading":[513],"subheading":[513],"supportingText":[513,"supporting-text"],"icon":[513]}]]],["limebb-icon-picker.cjs",[[1,"limebb-icon-picker",{"value":[1],"required":[4],"readonly":[4],"invalid":[4],"disabled":[4],"label":[1],"helperText":[1,"helper-text"]}]]],["limebb-info-tile.cjs",[[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"]}]]],["limebb-info-tile-date-format.cjs",[[1,"limebb-info-tile-date-format",{"value":[16]}]]],["limebb-info-tile-decimal-format.cjs",[[1,"limebb-info-tile-decimal-format",{"value":[16]}]]],["limebb-info-tile-format.cjs",[[1,"limebb-info-tile-format",{"platform":[16],"context":[16],"type":[1],"value":[16]}]]],["limebb-info-tile-relative-date-format.cjs",[[1,"limebb-info-tile-relative-date-format",{"value":[16]}]]],["limebb-info-tile-unit-format.cjs",[[1,"limebb-info-tile-unit-format",{"value":[16]}]]],["limebb-limeobject-file-viewer.cjs",[[1,"limebb-limeobject-file-viewer",{"platform":[16],"context":[16],"property":[1],"fileTypes":[16],"limeobject":[32],"limetype":[32]}]]],["limebb-locale-picker.cjs",[[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]}]]],["limebb-mention.cjs",[[1,"limebb-mention",{"limetype":[1],"objectid":[2],"limeobject":[32]}]]],["limebb-mention-group-counter.cjs",[[1,"limebb-mention-group-counter",{"count":[2],"limetype":[16],"helperLabel":[1,"helper-label"]}]]],["limebb-trend-indicator.cjs",[[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"]}]]],["limebb-navigation-button_2.cjs",[[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]}]]],["limebb-kanban-item.cjs",[[1,"limebb-kanban-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-kanban-group.cjs",[[1,"limebb-kanban-group",{"platform":[16],"context":[16],"identifier":[1],"heading":[513],"help":[1],"items":[16],"summary":[1],"loading":[516],"totalCount":[514,"total-count"]}]]],["limebb-feed-timeline-item.cjs",[[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]}]]],["limebb-text-editor-picker.cjs",[[1,"limebb-text-editor-picker",{"items":[16],"open":[516],"isSearching":[4,"is-searching"],"emptyMessage":[1,"empty-message"]},null,{"open":["watchOpen"]}]]],["limebb-currency-picker.cjs",[[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]}]]],["limebb-date-picker.cjs",[[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]}]]],["limebb-notification-item.cjs",[[1,"limebb-notification-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-chat-item_2.cjs",[[1,"limebb-chat-item",{"platform":[16],"context":[16],"item":[16]}],[1,"limebb-typing-indicator"]]],["limebb-empty-state.cjs",[[1,"limebb-empty-state",{"heading":[513],"value":[513],"icon":[16]}]]]], options);
11
+ return index.bootstrapLazy([["limebb-feed.cjs",[[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"]}]]],["limebb-kanban.cjs",[[1,"limebb-kanban",{"platform":[16],"context":[16],"groups":[16]}]]],["limebb-chat-list.cjs",[[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"]}]]],["limebb-text-editor.cjs",[[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"]}]]],["limebb-date-range.cjs",[[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]}]]],["limebb-info-tile-currency-format.cjs",[[1,"limebb-info-tile-currency-format",{"platform":[16],"context":[16],"value":[16]}]]],["limebb-notification-list.cjs",[[1,"limebb-notification-list",{"platform":[16],"context":[16],"items":[16],"loading":[4],"lastVisitedTimestamp":[1,"last-visited-timestamp"]},null,{"items":["handleItemsChange"]}]]],["limebb-browser.cjs",[[17,"limebb-browser",{"platform":[16],"context":[16],"items":[16],"layout":[1],"filter":[32]}]]],["limebb-component-config.cjs",[[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"]}]]],["limebb-component-picker.cjs",[[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"]}]]],["limebb-dashboard-widget.cjs",[[1,"limebb-dashboard-widget",{"heading":[513],"subheading":[513],"supportingText":[513,"supporting-text"],"icon":[513]}]]],["limebb-icon-picker.cjs",[[1,"limebb-icon-picker",{"value":[1],"required":[4],"readonly":[4],"invalid":[4],"disabled":[4],"label":[1],"helperText":[1,"helper-text"]}]]],["limebb-info-tile.cjs",[[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"]}]]],["limebb-info-tile-date-format.cjs",[[1,"limebb-info-tile-date-format",{"value":[16]}]]],["limebb-info-tile-decimal-format.cjs",[[1,"limebb-info-tile-decimal-format",{"value":[16]}]]],["limebb-info-tile-format.cjs",[[1,"limebb-info-tile-format",{"platform":[16],"context":[16],"type":[1],"value":[16]}]]],["limebb-info-tile-relative-date-format.cjs",[[1,"limebb-info-tile-relative-date-format",{"value":[16]}]]],["limebb-info-tile-unit-format.cjs",[[1,"limebb-info-tile-unit-format",{"value":[16]}]]],["limebb-limeobject-file-viewer.cjs",[[1,"limebb-limeobject-file-viewer",{"platform":[16],"context":[16],"property":[1],"fileTypes":[16],"limeobject":[32],"limetype":[32]}]]],["limebb-locale-picker.cjs",[[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]}]]],["limebb-mention.cjs",[[1,"limebb-mention",{"limetype":[1],"objectid":[2],"limeobject":[32]}]]],["limebb-mention-group-counter.cjs",[[1,"limebb-mention-group-counter",{"count":[2],"limetype":[16],"helperLabel":[1,"helper-label"]}]]],["limebb-trend-indicator.cjs",[[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"]}]]],["limebb-navigation-button_2.cjs",[[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]}]]],["limebb-kanban-item.cjs",[[1,"limebb-kanban-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-kanban-group.cjs",[[1,"limebb-kanban-group",{"platform":[16],"context":[16],"identifier":[1],"heading":[513],"help":[1],"items":[16],"summary":[1],"loading":[516],"totalCount":[514,"total-count"]}]]],["limebb-feed-timeline-item.cjs",[[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]}]]],["limebb-text-editor-picker.cjs",[[1,"limebb-text-editor-picker",{"items":[16],"open":[516],"isSearching":[4,"is-searching"],"emptyMessage":[1,"empty-message"]},null,{"open":["watchOpen"]}]]],["limebb-currency-picker.cjs",[[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]}]]],["limebb-date-picker.cjs",[[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]}]]],["limebb-notification-item.cjs",[[1,"limebb-notification-item",{"platform":[16],"context":[16],"item":[16]}]]],["limebb-chat-item_2.cjs",[[1,"limebb-chat-item",{"platform":[16],"context":[16],"item":[16]}],[1,"limebb-typing-indicator"]]],["limebb-empty-state.cjs",[[1,"limebb-empty-state",{"heading":[513],"value":[513],"icon":[16]}]]]], options);
12
12
  };
13
13
 
14
14
  exports.setNonce = index.setNonce;
@@ -15,6 +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
19
  const DEBOUNCE_SEARCH_TIMEOUT = 300;
19
20
  /**
20
21
  * This component is a wrapper on the `limel-text-editor`. It adds support for platform
@@ -114,6 +115,17 @@ export class LimeBBTextEditor {
114
115
  this.value = '';
115
116
  this.triggerMap = {};
116
117
  this.customElements = [];
118
+ /**
119
+ * Enables image pasting in the editor.
120
+ * Default: `false`
121
+ *
122
+ * :::note
123
+ * This component handles the upload process.
124
+ * The consumer must process the uploaded images by listening to `imageUploaded` and
125
+ * `imageRemoved` events.
126
+ * :::
127
+ */
128
+ this.allowInlineImages = false;
117
129
  this.items = [];
118
130
  this.highlightedItemIndex = 0;
119
131
  /**
@@ -128,6 +140,7 @@ export class LimeBBTextEditor {
128
140
  this.registeredTriggerMap = this.triggerMap;
129
141
  this.registeredCustomElements = this.customElements;
130
142
  this.activeTrigger = undefined;
143
+ this.activeUploads = new Set();
131
144
  this.handleMouseClick = (event) => {
132
145
  if (!this.textEditorPickerElement) {
133
146
  return;
@@ -185,6 +198,37 @@ export class LimeBBTextEditor {
185
198
  this.handleEnterOrTabKey = (event) => {
186
199
  this.handleItemSelection(event);
187
200
  };
201
+ this.handleImagePasted = async (event) => {
202
+ 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);
220
+ };
221
+ this.handleImageRemoved = (event) => {
222
+ event.stopPropagation();
223
+ if (!this.allowInlineImages) {
224
+ return;
225
+ }
226
+ const imageInfo = event.detail;
227
+ if (!imageInfo) {
228
+ return;
229
+ }
230
+ this.imageRemoved.emit(imageInfo);
231
+ };
188
232
  this.handleTriggerStart = (event) => {
189
233
  event.stopPropagation();
190
234
  this.activeTrigger = event.detail.trigger;
@@ -287,6 +331,7 @@ export class LimeBBTextEditor {
287
331
  document.addEventListener('visibilitychange', this.handleVisibilityChange);
288
332
  window.addEventListener('beforeunload', this.handleBeforeUnload);
289
333
  }
334
+ this.uploadHandler = new UploadHandler(this.platform);
290
335
  }
291
336
  componentWillLoad() {
292
337
  if (this.allowMentioning) {
@@ -365,7 +410,7 @@ export class LimeBBTextEditor {
365
410
  }
366
411
  render() {
367
412
  return [
368
- h("limel-text-editor", { key: '05d39fcf619a9262ef204030aea0fd2b83495fe3', 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, 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 }),
413
+ h("limel-text-editor", { key: 'f262f63be7e201a835c37921a43f3f8817dc538f', 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 }),
369
414
  this.renderPicker(),
370
415
  ];
371
416
  }
@@ -823,6 +868,26 @@ export class LimeBBTextEditor {
823
868
  "getter": false,
824
869
  "setter": false,
825
870
  "defaultValue": "[]"
871
+ },
872
+ "allowInlineImages": {
873
+ "type": "boolean",
874
+ "mutable": false,
875
+ "complexType": {
876
+ "original": "boolean",
877
+ "resolved": "boolean",
878
+ "references": {}
879
+ },
880
+ "required": false,
881
+ "optional": false,
882
+ "docs": {
883
+ "tags": [],
884
+ "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:::"
885
+ },
886
+ "getter": false,
887
+ "setter": false,
888
+ "attribute": "allow-inline-images",
889
+ "reflect": false,
890
+ "defaultValue": "false"
826
891
  }
827
892
  };
828
893
  }
@@ -852,6 +917,63 @@ export class LimeBBTextEditor {
852
917
  "resolved": "string",
853
918
  "references": {}
854
919
  }
920
+ }, {
921
+ "method": "imageUploaded",
922
+ "name": "imageUploaded",
923
+ "bubbles": true,
924
+ "cancelable": true,
925
+ "composed": true,
926
+ "docs": {
927
+ "tags": [],
928
+ "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:::"
929
+ },
930
+ "complexType": {
931
+ "original": "UploadedFileInfo",
932
+ "resolved": "{ fileId: string | number | undefined; fileInfoId: string | number | undefined; }",
933
+ "references": {
934
+ "UploadedFileInfo": {
935
+ "location": "import",
936
+ "path": "./uploader/building-blocks-uploader",
937
+ "id": "src/components/text-editor/uploader/building-blocks-uploader.ts::UploadedFileInfo"
938
+ }
939
+ }
940
+ }
941
+ }, {
942
+ "method": "imageRemoved",
943
+ "name": "imageRemoved",
944
+ "bubbles": true,
945
+ "cancelable": true,
946
+ "composed": true,
947
+ "docs": {
948
+ "tags": [],
949
+ "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:::"
950
+ },
951
+ "complexType": {
952
+ "original": "ImageInfo",
953
+ "resolved": "ImageInfo",
954
+ "references": {
955
+ "ImageInfo": {
956
+ "location": "import",
957
+ "path": "@limetech/lime-elements",
958
+ "id": "node_modules::ImageInfo"
959
+ }
960
+ }
961
+ }
962
+ }, {
963
+ "method": "imagesUploading",
964
+ "name": "imagesUploading",
965
+ "bubbles": true,
966
+ "cancelable": true,
967
+ "composed": true,
968
+ "docs": {
969
+ "tags": [],
970
+ "text": "Will be `true` while there is an active upload in progress."
971
+ },
972
+ "complexType": {
973
+ "original": "boolean",
974
+ "resolved": "boolean",
975
+ "references": {}
976
+ }
855
977
  }];
856
978
  }
857
979
  static get elementRef() { return "host"; }
@@ -0,0 +1,87 @@
1
+ import { PlatformServiceName, } from "@limetech/lime-web-components";
2
+ import { FileUpload, MAX_FILE_SIZE, } from "./building-blocks-uploader";
3
+ const UPLOAD_COMPLETED = 100;
4
+ export class UploadHandler {
5
+ constructor(platform) {
6
+ this.platform = platform;
7
+ }
8
+ /**
9
+ * Handles image paste events in the text editor
10
+ *
11
+ * @param {ImageInserter} imageInserter - The image inserter with the file info
12
+ * @returns {Promise<FileWrapper | undefined>} Promise resolving to the uploaded file wrapper or undefined if upload fails
13
+ */
14
+ async handleImagePasted(imageInserter) {
15
+ const fileInfo = imageInserter === null || imageInserter === void 0 ? void 0 : imageInserter.fileInfo;
16
+ if (!fileInfo) {
17
+ return;
18
+ }
19
+ if (!this.validateImageSize(fileInfo)) {
20
+ return;
21
+ }
22
+ imageInserter.insertThumbnail();
23
+ const uploadedFile = await this.createFileUpload(fileInfo);
24
+ const fileUrl = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.href;
25
+ const fileId = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId;
26
+ if (fileUrl && fileId !== undefined) {
27
+ imageInserter.insertImage(fileUrl);
28
+ }
29
+ else {
30
+ imageInserter.insertFailedThumbnail();
31
+ }
32
+ return uploadedFile;
33
+ }
34
+ /**
35
+ * Validates that the image file size is within limits
36
+ *
37
+ * @param {FileInfo} fileInfo - The file info to validate
38
+ * @returns {boolean} True if file size is valid, false otherwise
39
+ */
40
+ validateImageSize(fileInfo) {
41
+ if (!fileInfo.fileContent) {
42
+ return false;
43
+ }
44
+ return fileInfo.fileContent.size <= MAX_FILE_SIZE;
45
+ }
46
+ /**
47
+ * Creates and uploads a file
48
+ *
49
+ * @param {FileInfo} fileInfo - The file info to upload
50
+ * @returns {Promise<FileWrapper | undefined>} Promise resolving to the uploaded file wrapper or undefined if upload fails
51
+ */
52
+ async createFileUpload(fileInfo) {
53
+ var _a;
54
+ if (!fileInfo.fileContent) {
55
+ return;
56
+ }
57
+ const imageFile = new FileUpload(fileInfo.fileContent, this.http);
58
+ await imageFile.initialize();
59
+ const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, fileInfoId: fileInfo.id });
60
+ imageFile.onProgress = (progress) => {
61
+ if (imageUpload.progress === 0) {
62
+ imageUpload.state = 'uploading';
63
+ }
64
+ imageUpload.progress = progress;
65
+ if (progress === UPLOAD_COMPLETED) {
66
+ imageUpload.state = 'finalizing';
67
+ }
68
+ };
69
+ 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
+ imageUpload.fileId = response.id;
75
+ imageUpload.filename = response.filename;
76
+ imageUpload.extension = response.extension;
77
+ imageUpload.contentType = response.contentType;
78
+ imageUpload.size = response.size;
79
+ imageUpload.state = 'done';
80
+ // eslint-disable-next-line no-underscore-dangle
81
+ imageUpload.href = (_a = response._links) === null || _a === void 0 ? void 0 : _a.contents.href;
82
+ return imageUpload;
83
+ }
84
+ get http() {
85
+ return this.platform.get(PlatformServiceName.Http);
86
+ }
87
+ }