@memberjunction/ng-conversations 2.129.0 → 2.130.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/lib/components/attachment/image-viewer.component.d.ts +95 -0
  2. package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -0
  3. package/dist/lib/components/attachment/image-viewer.component.js +293 -0
  4. package/dist/lib/components/attachment/image-viewer.component.js.map +1 -0
  5. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +76 -7
  6. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  7. package/dist/lib/components/conversation/conversation-chat-area.component.js +433 -193
  8. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +12 -3
  10. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-empty-state.component.js +68 -55
  12. package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
  13. package/dist/lib/components/conversation/conversation-list.component.d.ts +2 -0
  14. package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
  15. package/dist/lib/components/conversation/conversation-list.component.js +157 -145
  16. package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
  17. package/dist/lib/components/mention/mention-editor.component.d.ts +102 -5
  18. package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
  19. package/dist/lib/components/mention/mention-editor.component.js +349 -21
  20. package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
  21. package/dist/lib/components/message/message-input-box.component.d.ts +29 -2
  22. package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
  23. package/dist/lib/components/message/message-input-box.component.js +79 -12
  24. package/dist/lib/components/message/message-input-box.component.js.map +1 -1
  25. package/dist/lib/components/message/message-input.component.d.ts +56 -4
  26. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  27. package/dist/lib/components/message/message-input.component.js +227 -60
  28. package/dist/lib/components/message/message-input.component.js.map +1 -1
  29. package/dist/lib/components/message/message-item.component.d.ts +34 -1
  30. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  31. package/dist/lib/components/message/message-item.component.js +181 -93
  32. package/dist/lib/components/message/message-item.component.js.map +1 -1
  33. package/dist/lib/components/message/message-list.component.d.ts +4 -1
  34. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  35. package/dist/lib/components/message/message-list.component.js +12 -1
  36. package/dist/lib/components/message/message-list.component.js.map +1 -1
  37. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +44 -13
  38. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  39. package/dist/lib/components/workspace/conversation-workspace.component.js +82 -108
  40. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  41. package/dist/lib/conversations.module.d.ts +26 -25
  42. package/dist/lib/conversations.module.d.ts.map +1 -1
  43. package/dist/lib/conversations.module.js +7 -3
  44. package/dist/lib/conversations.module.js.map +1 -1
  45. package/dist/lib/services/active-tasks.service.d.ts +23 -0
  46. package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
  47. package/dist/lib/services/active-tasks.service.js +91 -2
  48. package/dist/lib/services/active-tasks.service.js.map +1 -1
  49. package/dist/lib/services/conversation-agent.service.d.ts +36 -5
  50. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  51. package/dist/lib/services/conversation-agent.service.js +233 -71
  52. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  53. package/dist/lib/services/conversation-attachment.service.d.ts +79 -0
  54. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -0
  55. package/dist/lib/services/conversation-attachment.service.js +327 -0
  56. package/dist/lib/services/conversation-attachment.service.js.map +1 -0
  57. package/dist/lib/services/conversation-data.service.d.ts +15 -1
  58. package/dist/lib/services/conversation-data.service.d.ts.map +1 -1
  59. package/dist/lib/services/conversation-data.service.js +23 -1
  60. package/dist/lib/services/conversation-data.service.js.map +1 -1
  61. package/dist/lib/services/conversation-streaming.service.d.ts +26 -1
  62. package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
  63. package/dist/lib/services/conversation-streaming.service.js +18 -3
  64. package/dist/lib/services/conversation-streaming.service.js.map +1 -1
  65. package/dist/lib/services/mention-parser.service.d.ts +15 -0
  66. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  67. package/dist/lib/services/mention-parser.service.js +30 -0
  68. package/dist/lib/services/mention-parser.service.js.map +1 -1
  69. package/dist/public-api.d.ts +2 -0
  70. package/dist/public-api.d.ts.map +1 -1
  71. package/dist/public-api.js +2 -0
  72. package/dist/public-api.js.map +1 -1
  73. package/package.json +17 -17
@@ -6,14 +6,63 @@ import * as i1 from "../../services/mention-autocomplete.service";
6
6
  import * as i2 from "@angular/common";
7
7
  import * as i3 from "./mention-dropdown.component";
8
8
  const _c0 = ["editor"];
9
- function MentionEditorComponent_mj_mention_dropdown_3_Template(rf, ctx) { if (rf & 1) {
9
+ function MentionEditorComponent_div_1_div_1_img_1_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵelement(0, "img", 13);
11
+ } if (rf & 2) {
12
+ const attachment_r3 = i0.ɵɵnextContext().$implicit;
13
+ i0.ɵɵproperty("src", attachment_r3.thumbnailUrl, i0.ɵɵsanitizeUrl)("alt", attachment_r3.fileName);
14
+ } }
15
+ function MentionEditorComponent_div_1_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
16
+ i0.ɵɵelementStart(0, "div", 14);
17
+ i0.ɵɵelement(1, "i", 15);
18
+ i0.ɵɵelementStart(2, "span", 16);
19
+ i0.ɵɵtext(3);
20
+ i0.ɵɵelementEnd()();
21
+ } if (rf & 2) {
22
+ const attachment_r3 = i0.ɵɵnextContext().$implicit;
23
+ i0.ɵɵadvance(3);
24
+ i0.ɵɵtextInterpolate(attachment_r3.fileName);
25
+ } }
26
+ function MentionEditorComponent_div_1_div_1_Template(rf, ctx) { if (rf & 1) {
10
27
  const _r2 = i0.ɵɵgetCurrentView();
11
- i0.ɵɵelementStart(0, "mj-mention-dropdown", 4);
12
- i0.ɵɵlistener("suggestionSelected", function MentionEditorComponent_mj_mention_dropdown_3_Template_mj_mention_dropdown_suggestionSelected_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMentionSelected($event)); })("closed", function MentionEditorComponent_mj_mention_dropdown_3_Template_mj_mention_dropdown_closed_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMentionDropdown()); });
28
+ i0.ɵɵelementStart(0, "div", 8);
29
+ i0.ɵɵlistener("click", function MentionEditorComponent_div_1_div_1_Template_div_click_0_listener() { const attachment_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onAttachmentClick(attachment_r3)); });
30
+ i0.ɵɵtemplate(1, MentionEditorComponent_div_1_div_1_img_1_Template, 1, 2, "img", 9)(2, MentionEditorComponent_div_1_div_1_div_2_Template, 4, 1, "div", 10);
31
+ i0.ɵɵelementStart(3, "button", 11);
32
+ i0.ɵɵlistener("click", function MentionEditorComponent_div_1_div_1_Template_button_click_3_listener($event) { const attachment_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.removeAttachment(attachment_r3.id); return i0.ɵɵresetView($event.stopPropagation()); });
33
+ i0.ɵɵelement(4, "i", 12);
34
+ i0.ɵɵelementEnd()();
35
+ } if (rf & 2) {
36
+ const attachment_r3 = ctx.$implicit;
37
+ i0.ɵɵadvance();
38
+ i0.ɵɵproperty("ngIf", attachment_r3.thumbnailUrl);
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵproperty("ngIf", !attachment_r3.thumbnailUrl);
41
+ } }
42
+ function MentionEditorComponent_div_1_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "div", 6);
44
+ i0.ɵɵtemplate(1, MentionEditorComponent_div_1_div_1_Template, 5, 2, "div", 7);
45
+ i0.ɵɵelementEnd();
46
+ } if (rf & 2) {
47
+ const ctx_r3 = i0.ɵɵnextContext();
48
+ i0.ɵɵadvance();
49
+ i0.ɵɵproperty("ngForOf", ctx_r3.pendingAttachments);
50
+ } }
51
+ function MentionEditorComponent_div_4_Template(rf, ctx) { if (rf & 1) {
52
+ i0.ɵɵelementStart(0, "div", 17)(1, "div", 18);
53
+ i0.ɵɵelement(2, "i", 19);
54
+ i0.ɵɵelementStart(3, "span");
55
+ i0.ɵɵtext(4, "Drop files here");
56
+ i0.ɵɵelementEnd()()();
57
+ } }
58
+ function MentionEditorComponent_mj_mention_dropdown_5_Template(rf, ctx) { if (rf & 1) {
59
+ const _r5 = i0.ɵɵgetCurrentView();
60
+ i0.ɵɵelementStart(0, "mj-mention-dropdown", 20);
61
+ i0.ɵɵlistener("suggestionSelected", function MentionEditorComponent_mj_mention_dropdown_5_Template_mj_mention_dropdown_suggestionSelected_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onMentionSelected($event)); })("closed", function MentionEditorComponent_mj_mention_dropdown_5_Template_mj_mention_dropdown_closed_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMentionDropdown()); });
13
62
  i0.ɵɵelementEnd();
14
63
  } if (rf & 2) {
15
- const ctx_r2 = i0.ɵɵnextContext();
16
- i0.ɵɵproperty("suggestions", ctx_r2.mentionSuggestions)("position", ctx_r2.mentionDropdownPosition)("showAbove", ctx_r2.mentionDropdownShowAbove)("useFixedPositioning", true)("visible", true);
64
+ const ctx_r3 = i0.ɵɵnextContext();
65
+ i0.ɵɵproperty("suggestions", ctx_r3.mentionSuggestions)("position", ctx_r3.mentionDropdownPosition)("showAbove", ctx_r3.mentionDropdownShowAbove)("useFixedPositioning", true)("visible", true);
17
66
  } }
18
67
  /**
19
68
  * ContentEditable-based mention editor with visual chips/pills
@@ -21,14 +70,26 @@ function MentionEditorComponent_mj_mention_dropdown_3_Template(rf, ctx) { if (rf
21
70
  */
22
71
  export class MentionEditorComponent {
23
72
  mentionAutocomplete;
73
+ cdr;
24
74
  editorRef;
25
75
  placeholder = 'Type @ to mention agents or users...';
26
76
  disabled = false;
27
77
  currentUser;
28
78
  enableMentions = true;
79
+ // Attachment settings
80
+ enableAttachments = true;
81
+ maxAttachments = 10;
82
+ maxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB default
83
+ acceptedFileTypes = 'image/*'; // MIME types to accept
29
84
  valueChange = new EventEmitter();
30
85
  mentionSelected = new EventEmitter();
31
86
  enterPressed = new EventEmitter();
87
+ attachmentsChanged = new EventEmitter();
88
+ attachmentError = new EventEmitter();
89
+ attachmentClicked = new EventEmitter();
90
+ // Pending attachments state
91
+ pendingAttachments = [];
92
+ isDragOver = false;
32
93
  // Mention dropdown state
33
94
  showMentionDropdown = false;
34
95
  mentionSuggestions = [];
@@ -38,8 +99,9 @@ export class MentionEditorComponent {
38
99
  mentionQuery = '';
39
100
  onChange = () => { };
40
101
  onTouched = () => { };
41
- constructor(mentionAutocomplete) {
102
+ constructor(mentionAutocomplete, cdr) {
42
103
  this.mentionAutocomplete = mentionAutocomplete;
104
+ this.cdr = cdr;
43
105
  }
44
106
  async ngOnInit() {
45
107
  if (this.enableMentions && this.currentUser) {
@@ -98,15 +160,31 @@ export class MentionEditorComponent {
98
160
  // Use setTimeout to allow mousedown events on dropdown to fire first
99
161
  setTimeout(() => {
100
162
  if (this.showMentionDropdown) {
101
- console.log('[MentionEditor] Closing dropdown on blur');
102
163
  this.closeMentionDropdown();
103
164
  }
104
165
  }, 200);
105
166
  }
106
167
  /**
107
- * Handle paste event - strip HTML and paste as plain text only
168
+ * Handle paste event - images or plain text
108
169
  */
109
170
  onPaste(event) {
171
+ // Check for image data in clipboard
172
+ if (this.enableAttachments && event.clipboardData?.items) {
173
+ const items = Array.from(event.clipboardData.items);
174
+ const imageItems = items.filter(item => item.type.startsWith('image/'));
175
+ if (imageItems.length > 0) {
176
+ event.preventDefault();
177
+ // Process each image
178
+ for (const item of imageItems) {
179
+ const file = item.getAsFile();
180
+ if (file) {
181
+ this.processFile(file);
182
+ }
183
+ }
184
+ return;
185
+ }
186
+ }
187
+ // No images - handle as plain text
110
188
  event.preventDefault();
111
189
  // Get plain text from clipboard
112
190
  const text = event.clipboardData?.getData('text/plain') || '';
@@ -232,7 +310,6 @@ export class MentionEditorComponent {
232
310
  * Handle mention selection from dropdown
233
311
  */
234
312
  onMentionSelected(suggestion) {
235
- console.log('[MentionEditor] Mention selected:', suggestion);
236
313
  this.insertMentionChip(suggestion);
237
314
  this.closeMentionDropdown();
238
315
  this.mentionSelected.emit(suggestion);
@@ -698,13 +775,14 @@ export class MentionEditorComponent {
698
775
  this.editorRef?.nativeElement?.focus();
699
776
  }
700
777
  /**
701
- * Clear the editor content
778
+ * Clear the editor content and pending attachments
702
779
  */
703
780
  clear() {
704
781
  if (this.editorRef?.nativeElement) {
705
782
  this.editorRef.nativeElement.textContent = '';
706
783
  this.onInput();
707
784
  }
785
+ this.clearPendingAttachments();
708
786
  }
709
787
  /**
710
788
  * Extract mention chips with their configuration data
@@ -788,33 +866,269 @@ export class MentionEditorComponent {
788
866
  }
789
867
  return plainText;
790
868
  }
791
- static ɵfac = function MentionEditorComponent_Factory(t) { return new (t || MentionEditorComponent)(i0.ɵɵdirectiveInject(i1.MentionAutocompleteService)); };
869
+ // ==================== Attachment Handling Methods ====================
870
+ /**
871
+ * Handle drag over event
872
+ */
873
+ onDragOver(event) {
874
+ if (!this.enableAttachments)
875
+ return;
876
+ event.preventDefault();
877
+ event.stopPropagation();
878
+ this.isDragOver = true;
879
+ }
880
+ /**
881
+ * Handle drag leave event
882
+ */
883
+ onDragLeave(event) {
884
+ event.preventDefault();
885
+ event.stopPropagation();
886
+ this.isDragOver = false;
887
+ }
888
+ /**
889
+ * Handle drop event
890
+ */
891
+ onDrop(event) {
892
+ if (!this.enableAttachments)
893
+ return;
894
+ event.preventDefault();
895
+ event.stopPropagation();
896
+ this.isDragOver = false;
897
+ if (event.dataTransfer?.files) {
898
+ const files = Array.from(event.dataTransfer.files);
899
+ for (const file of files) {
900
+ if (this.isAcceptedFile(file)) {
901
+ this.processFile(file);
902
+ }
903
+ }
904
+ }
905
+ }
906
+ /**
907
+ * Handle file input change (from file picker)
908
+ */
909
+ onFileSelected(event) {
910
+ const input = event.target;
911
+ if (input.files) {
912
+ const files = Array.from(input.files);
913
+ for (const file of files) {
914
+ this.processFile(file);
915
+ }
916
+ // Reset input so same file can be selected again
917
+ input.value = '';
918
+ }
919
+ }
920
+ /**
921
+ * Process a file for attachment
922
+ */
923
+ async processFile(file) {
924
+ // Validate file
925
+ const validation = this.validateFile(file);
926
+ if (!validation.valid) {
927
+ this.attachmentError.emit(validation.error);
928
+ return;
929
+ }
930
+ // Read file as data URL
931
+ const dataUrl = await this.readFileAsDataUrl(file);
932
+ if (!dataUrl) {
933
+ this.attachmentError.emit('Failed to read file');
934
+ return;
935
+ }
936
+ // Get image dimensions if applicable
937
+ let width;
938
+ let height;
939
+ if (file.type.startsWith('image/')) {
940
+ const dimensions = await this.getImageDimensions(dataUrl);
941
+ width = dimensions.width;
942
+ height = dimensions.height;
943
+ }
944
+ // Create pending attachment
945
+ const attachment = {
946
+ id: this.generateAttachmentId(),
947
+ file,
948
+ dataUrl,
949
+ mimeType: file.type,
950
+ fileName: file.name,
951
+ sizeBytes: file.size,
952
+ width,
953
+ height,
954
+ thumbnailUrl: file.type.startsWith('image/') ? dataUrl : undefined
955
+ };
956
+ // Add to pending attachments
957
+ this.pendingAttachments.push(attachment);
958
+ this.attachmentsChanged.emit([...this.pendingAttachments]);
959
+ this.cdr.detectChanges();
960
+ }
961
+ /**
962
+ * Validate a file against settings
963
+ */
964
+ validateFile(file) {
965
+ // Check count limit
966
+ if (this.pendingAttachments.length >= this.maxAttachments) {
967
+ return {
968
+ valid: false,
969
+ error: `Maximum ${this.maxAttachments} attachments allowed`
970
+ };
971
+ }
972
+ // Check size limit
973
+ if (file.size > this.maxAttachmentSizeBytes) {
974
+ const maxMB = (this.maxAttachmentSizeBytes / (1024 * 1024)).toFixed(1);
975
+ const fileMB = (file.size / (1024 * 1024)).toFixed(1);
976
+ return {
977
+ valid: false,
978
+ error: `File size (${fileMB}MB) exceeds maximum (${maxMB}MB)`
979
+ };
980
+ }
981
+ // Check file type
982
+ if (!this.isAcceptedFile(file)) {
983
+ return {
984
+ valid: false,
985
+ error: `File type ${file.type || 'unknown'} not accepted`
986
+ };
987
+ }
988
+ return { valid: true };
989
+ }
990
+ /**
991
+ * Check if file type is accepted
992
+ */
993
+ isAcceptedFile(file) {
994
+ if (this.acceptedFileTypes === '*' || this.acceptedFileTypes === '*/*') {
995
+ return true;
996
+ }
997
+ const acceptedTypes = this.acceptedFileTypes.split(',').map(t => t.trim());
998
+ for (const accepted of acceptedTypes) {
999
+ // Handle wildcard MIME types like "image/*"
1000
+ if (accepted.endsWith('/*')) {
1001
+ const category = accepted.slice(0, -2);
1002
+ if (file.type.startsWith(category + '/')) {
1003
+ return true;
1004
+ }
1005
+ }
1006
+ else if (accepted.startsWith('.')) {
1007
+ // Handle file extensions like ".png"
1008
+ if (file.name.toLowerCase().endsWith(accepted.toLowerCase())) {
1009
+ return true;
1010
+ }
1011
+ }
1012
+ else if (file.type === accepted) {
1013
+ // Exact MIME type match
1014
+ return true;
1015
+ }
1016
+ }
1017
+ return false;
1018
+ }
1019
+ /**
1020
+ * Read file as data URL
1021
+ */
1022
+ readFileAsDataUrl(file) {
1023
+ return new Promise((resolve) => {
1024
+ const reader = new FileReader();
1025
+ reader.onload = () => resolve(reader.result);
1026
+ reader.onerror = () => resolve(null);
1027
+ reader.readAsDataURL(file);
1028
+ });
1029
+ }
1030
+ /**
1031
+ * Get image dimensions
1032
+ */
1033
+ getImageDimensions(dataUrl) {
1034
+ return new Promise((resolve) => {
1035
+ const img = new Image();
1036
+ img.onload = () => {
1037
+ resolve({ width: img.naturalWidth, height: img.naturalHeight });
1038
+ };
1039
+ img.onerror = () => {
1040
+ resolve({ width: 0, height: 0 });
1041
+ };
1042
+ img.src = dataUrl;
1043
+ });
1044
+ }
1045
+ /**
1046
+ * Generate unique attachment ID
1047
+ */
1048
+ generateAttachmentId() {
1049
+ return `att_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1050
+ }
1051
+ /**
1052
+ * Remove a pending attachment by ID
1053
+ */
1054
+ removeAttachment(id) {
1055
+ const index = this.pendingAttachments.findIndex(a => a.id === id);
1056
+ if (index !== -1) {
1057
+ this.pendingAttachments.splice(index, 1);
1058
+ this.attachmentsChanged.emit([...this.pendingAttachments]);
1059
+ this.cdr.detectChanges();
1060
+ }
1061
+ }
1062
+ /**
1063
+ * Get all pending attachments
1064
+ */
1065
+ getPendingAttachments() {
1066
+ return [...this.pendingAttachments];
1067
+ }
1068
+ /**
1069
+ * Clear all pending attachments
1070
+ */
1071
+ clearPendingAttachments() {
1072
+ this.pendingAttachments = [];
1073
+ this.attachmentsChanged.emit([]);
1074
+ this.cdr.detectChanges();
1075
+ }
1076
+ /**
1077
+ * Handle click on an attachment thumbnail
1078
+ */
1079
+ onAttachmentClick(attachment) {
1080
+ this.attachmentClicked.emit(attachment);
1081
+ }
1082
+ /**
1083
+ * Check if there are any pending attachments
1084
+ */
1085
+ hasAttachments() {
1086
+ return this.pendingAttachments.length > 0;
1087
+ }
1088
+ /**
1089
+ * Trigger file picker programmatically
1090
+ */
1091
+ openFilePicker() {
1092
+ const input = document.createElement('input');
1093
+ input.type = 'file';
1094
+ input.accept = this.acceptedFileTypes;
1095
+ input.multiple = true;
1096
+ input.onchange = (e) => this.onFileSelected(e);
1097
+ input.click();
1098
+ }
1099
+ static ɵfac = function MentionEditorComponent_Factory(t) { return new (t || MentionEditorComponent)(i0.ɵɵdirectiveInject(i1.MentionAutocompleteService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
792
1100
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MentionEditorComponent, selectors: [["mj-mention-editor"]], viewQuery: function MentionEditorComponent_Query(rf, ctx) { if (rf & 1) {
793
1101
  i0.ɵɵviewQuery(_c0, 5);
794
1102
  } if (rf & 2) {
795
1103
  let _t;
796
1104
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.editorRef = _t.first);
797
- } }, inputs: { placeholder: "placeholder", disabled: "disabled", currentUser: "currentUser", enableMentions: "enableMentions" }, outputs: { valueChange: "valueChange", mentionSelected: "mentionSelected", enterPressed: "enterPressed" }, features: [i0.ɵɵProvidersFeature([
1105
+ } }, inputs: { placeholder: "placeholder", disabled: "disabled", currentUser: "currentUser", enableMentions: "enableMentions", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes" }, outputs: { valueChange: "valueChange", mentionSelected: "mentionSelected", enterPressed: "enterPressed", attachmentsChanged: "attachmentsChanged", attachmentError: "attachmentError", attachmentClicked: "attachmentClicked" }, features: [i0.ɵɵProvidersFeature([
798
1106
  {
799
1107
  provide: NG_VALUE_ACCESSOR,
800
1108
  useExisting: forwardRef(() => MentionEditorComponent),
801
1109
  multi: true
802
1110
  }
803
- ])], decls: 4, vars: 3, consts: [["editor", ""], [1, "mention-editor-container", 3, "click"], ["contenteditable", "true", 1, "mention-editor", 3, "input", "keydown", "blur", "paste"], [3, "suggestions", "position", "showAbove", "useFixedPositioning", "visible", "suggestionSelected", "closed", 4, "ngIf"], [3, "suggestionSelected", "closed", "suggestions", "position", "showAbove", "useFixedPositioning", "visible"]], template: function MentionEditorComponent_Template(rf, ctx) { if (rf & 1) {
1111
+ ])], decls: 6, vars: 7, consts: [["editor", ""], [1, "mention-editor-container", 3, "click", "dragover", "dragleave", "drop"], ["class", "pending-attachments", 4, "ngIf"], ["contenteditable", "true", 1, "mention-editor", 3, "input", "keydown", "blur", "paste"], ["class", "drop-overlay", 4, "ngIf"], [3, "suggestions", "position", "showAbove", "useFixedPositioning", "visible", "suggestionSelected", "closed", 4, "ngIf"], [1, "pending-attachments"], ["class", "attachment-thumbnail", 3, "click", 4, "ngFor", "ngForOf"], [1, "attachment-thumbnail", 3, "click"], ["class", "thumbnail-image", 3, "src", "alt", 4, "ngIf"], ["class", "thumbnail-placeholder", 4, "ngIf"], ["title", "Remove attachment", 1, "remove-attachment", 3, "click"], [1, "fa-solid", "fa-times"], [1, "thumbnail-image", 3, "src", "alt"], [1, "thumbnail-placeholder"], [1, "fa-solid", "fa-file"], [1, "file-name"], [1, "drop-overlay"], [1, "drop-message"], [1, "fa-solid", "fa-cloud-arrow-up"], [3, "suggestionSelected", "closed", "suggestions", "position", "showAbove", "useFixedPositioning", "visible"]], template: function MentionEditorComponent_Template(rf, ctx) { if (rf & 1) {
804
1112
  const _r1 = i0.ɵɵgetCurrentView();
805
1113
  i0.ɵɵelementStart(0, "div", 1);
806
- i0.ɵɵlistener("click", function MentionEditorComponent_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onContainerClick($event)); });
807
- i0.ɵɵelementStart(1, "div", 2, 0);
808
- i0.ɵɵlistener("input", function MentionEditorComponent_Template_div_input_1_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onInput()); })("keydown", function MentionEditorComponent_Template_div_keydown_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onKeyDown($event)); })("blur", function MentionEditorComponent_Template_div_blur_1_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onBlur()); })("paste", function MentionEditorComponent_Template_div_paste_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onPaste($event)); });
1114
+ i0.ɵɵlistener("click", function MentionEditorComponent_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onContainerClick($event)); })("dragover", function MentionEditorComponent_Template_div_dragover_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDragOver($event)); })("dragleave", function MentionEditorComponent_Template_div_dragleave_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDragLeave($event)); })("drop", function MentionEditorComponent_Template_div_drop_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDrop($event)); });
1115
+ i0.ɵɵtemplate(1, MentionEditorComponent_div_1_Template, 2, 1, "div", 2);
1116
+ i0.ɵɵelementStart(2, "div", 3, 0);
1117
+ i0.ɵɵlistener("input", function MentionEditorComponent_Template_div_input_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onInput()); })("keydown", function MentionEditorComponent_Template_div_keydown_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onKeyDown($event)); })("blur", function MentionEditorComponent_Template_div_blur_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onBlur()); })("paste", function MentionEditorComponent_Template_div_paste_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onPaste($event)); });
809
1118
  i0.ɵɵelementEnd();
810
- i0.ɵɵtemplate(3, MentionEditorComponent_mj_mention_dropdown_3_Template, 1, 5, "mj-mention-dropdown", 3);
1119
+ i0.ɵɵtemplate(4, MentionEditorComponent_div_4_Template, 5, 0, "div", 4)(5, MentionEditorComponent_mj_mention_dropdown_5_Template, 1, 5, "mj-mention-dropdown", 5);
811
1120
  i0.ɵɵelementEnd();
812
1121
  } if (rf & 2) {
1122
+ i0.ɵɵclassProp("drag-over", ctx.isDragOver);
1123
+ i0.ɵɵadvance();
1124
+ i0.ɵɵproperty("ngIf", ctx.pendingAttachments.length > 0);
813
1125
  i0.ɵɵadvance();
814
1126
  i0.ɵɵattribute("contenteditable", !ctx.disabled)("data-placeholder", ctx.placeholder);
815
1127
  i0.ɵɵadvance(2);
1128
+ i0.ɵɵproperty("ngIf", ctx.isDragOver);
1129
+ i0.ɵɵadvance();
816
1130
  i0.ɵɵproperty("ngIf", ctx.showMentionDropdown && ctx.enableMentions);
817
- } }, dependencies: [i2.NgIf, i3.MentionDropdownComponent], styles: [".mention-editor-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n display: block;\n}\n\n.mention-editor[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n min-height: 100px;\n max-height: 300px;\n padding: 7px 3.5rem 7px 12px;\n outline: none;\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n white-space: pre-wrap;\n cursor: text;\n user-select: text;\n box-sizing: border-box;\n}\n.mention-editor[_ngcontent-%COMP%]:empty:before {\n content: attr(data-placeholder);\n color: var(--text-tertiary, #999);\n pointer-events: none;\n position: absolute;\n}\n.mention-editor[_ngcontent-%COMP%]:focus {\n outline: none;\n}\n.mention-editor[contenteditable=false][_ngcontent-%COMP%] {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--background-disabled, #f5f5f5);\n}\n@media (max-width: 768px) {\n .mention-editor[_ngcontent-%COMP%] {\n font-size: 16px;\n padding: 5px;\n padding-right: 3rem;\n }\n}\n\n .mention-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n margin: 0 3px;\n border-radius: 16px;\n font-size: 13px;\n font-weight: 600;\n cursor: default;\n user-select: none;\n vertical-align: middle;\n white-space: nowrap;\n pointer-events: all;\n -webkit-user-modify: read-only;\n -moz-user-modify: read-only;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: 2px solid rgba(102, 126, 234, 0.4);\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_chipInsert 0.15s ease-out;\n}\n .mention-chip i {\n font-size: 12px;\n opacity: 0.95;\n}\n .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: 2px solid rgba(240, 147, 251, 0.4);\n}\n .mention-chip:hover {\n transform: translateY(-1px);\n box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n}\n .mention-chip:focus, .mention-chip.selected {\n outline: 2px solid var(--primary-color, #007bff);\n outline-offset: 2px;\n}\n@keyframes _ngcontent-%COMP%_chipInsert {\n 0% {\n transform: scale(0.8);\n opacity: 0;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n .mention-editor[_ngcontent-%COMP%] {\n color: black; \n\n \n \n\n }\n .mention-editor[_ngcontent-%COMP%]:empty:before {\n color: #777;\n }\n .mention-editor[contenteditable=false][_ngcontent-%COMP%] {\n background: #2d2d2d;\n }\n .mention-chip[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #4a148c 0%, #6a1b9a 100%);\n color: #ce93d8;\n border-color: #8e24aa;\n }\n .mention-chip[data-mention-type=user][_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #880e4f 0%, #ad1457 100%);\n color: #f48fb1;\n border-color: #c2185b;\n }\n}\n.mention-editor[_ngcontent-%COMP%] .mention-chip[_ngcontent-%COMP%] + .mention-chip[_ngcontent-%COMP%] {\n margin-left: 4px;\n}\n.mention-editor[_ngcontent-%COMP%] br[_ngcontent-%COMP%] {\n display: block;\n content: \"\";\n margin: 0;\n}\n\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.3);\n}"] });
1131
+ } }, dependencies: [i2.NgForOf, i2.NgIf, i3.MentionDropdownComponent], styles: [".mention-editor-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n display: block;\n}\n\n.mention-editor-container.drag-over[_ngcontent-%COMP%] {\n background: rgba(102, 126, 234, 0.05);\n border-color: #667eea;\n}\n\n.mention-editor[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n min-height: 100px;\n max-height: 300px;\n padding: 7px 3.5rem 7px 12px;\n outline: none;\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n white-space: pre-wrap;\n cursor: text;\n user-select: text;\n box-sizing: border-box;\n}\n.mention-editor[_ngcontent-%COMP%]:empty:before {\n content: attr(data-placeholder);\n color: var(--text-tertiary, #999);\n pointer-events: none;\n position: absolute;\n}\n.mention-editor[_ngcontent-%COMP%]:focus {\n outline: none;\n}\n.mention-editor[contenteditable=false][_ngcontent-%COMP%] {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--background-disabled, #f5f5f5);\n}\n@media (max-width: 768px) {\n .mention-editor[_ngcontent-%COMP%] {\n font-size: 16px;\n padding: 5px;\n padding-right: 3rem;\n }\n}\n\n .mention-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n margin: 0 3px;\n border-radius: 16px;\n font-size: 13px;\n font-weight: 600;\n cursor: default;\n user-select: none;\n vertical-align: middle;\n white-space: nowrap;\n pointer-events: all;\n -webkit-user-modify: read-only;\n -moz-user-modify: read-only;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: 2px solid rgba(102, 126, 234, 0.4);\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_chipInsert 0.15s ease-out;\n}\n .mention-chip i {\n font-size: 12px;\n opacity: 0.95;\n}\n .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: 2px solid rgba(240, 147, 251, 0.4);\n}\n .mention-chip:hover {\n transform: translateY(-1px);\n box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n}\n .mention-chip:focus, .mention-chip.selected {\n outline: 2px solid var(--primary-color, #007bff);\n outline-offset: 2px;\n}\n@keyframes _ngcontent-%COMP%_chipInsert {\n 0% {\n transform: scale(0.8);\n opacity: 0;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n .mention-editor[_ngcontent-%COMP%] {\n color: black; \n\n \n \n\n }\n .mention-editor[_ngcontent-%COMP%]:empty:before {\n color: #777;\n }\n .mention-editor[contenteditable=false][_ngcontent-%COMP%] {\n background: #2d2d2d;\n }\n .mention-chip[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #4a148c 0%, #6a1b9a 100%);\n color: #ce93d8;\n border-color: #8e24aa;\n }\n .mention-chip[data-mention-type=user][_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #880e4f 0%, #ad1457 100%);\n color: #f48fb1;\n border-color: #c2185b;\n }\n}\n.mention-editor[_ngcontent-%COMP%] .mention-chip[_ngcontent-%COMP%] + .mention-chip[_ngcontent-%COMP%] {\n margin-left: 4px;\n}\n.mention-editor[_ngcontent-%COMP%] br[_ngcontent-%COMP%] {\n display: block;\n content: \"\";\n margin: 0;\n}\n\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n}\n.mention-editor[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.3);\n}\n\n\n\n\n.pending-attachments[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n background: rgba(0, 0, 0, 0.02);\n}\n\n.attachment-thumbnail[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n border-radius: 8px;\n overflow: hidden;\n cursor: pointer;\n transition: transform 0.2s, box-shadow 0.2s;\n background: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.attachment-thumbnail[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n}\n\n.thumbnail-image[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.thumbnail-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 8px;\n color: #666;\n}\n\n.thumbnail-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 4px;\n color: #999;\n}\n\n.thumbnail-placeholder[_ngcontent-%COMP%] .file-name[_ngcontent-%COMP%] {\n font-size: 10px;\n text-align: center;\n word-break: break-all;\n line-height: 1.2;\n max-height: 36px;\n overflow: hidden;\n}\n\n.remove-attachment[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s, background 0.2s;\n}\n\n.attachment-thumbnail[_ngcontent-%COMP%]:hover .remove-attachment[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.remove-attachment[_ngcontent-%COMP%]:hover {\n background: rgba(220, 53, 69, 0.9);\n}\n\n.remove-attachment[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.drop-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: rgba(102, 126, 234, 0.15);\n backdrop-filter: blur(2px);\n border: 2px dashed #667eea;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n pointer-events: none;\n}\n\n.drop-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: #667eea;\n font-weight: 600;\n}\n\n.drop-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n}\n\n.drop-message[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n@media (prefers-color-scheme: dark) {\n .pending-attachments[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.05);\n border-bottom-color: rgba(255, 255, 255, 0.1);\n }\n\n .attachment-thumbnail[_ngcontent-%COMP%] {\n background: #333;\n border-color: rgba(255, 255, 255, 0.15);\n }\n\n .thumbnail-placeholder[_ngcontent-%COMP%] {\n color: #aaa;\n }\n\n .thumbnail-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #777;\n }\n\n .drop-overlay[_ngcontent-%COMP%] {\n background: rgba(102, 126, 234, 0.25);\n }\n}"] });
818
1132
  }
819
1133
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MentionEditorComponent, [{
820
1134
  type: Component,
@@ -824,8 +1138,8 @@ export class MentionEditorComponent {
824
1138
  useExisting: forwardRef(() => MentionEditorComponent),
825
1139
  multi: true
826
1140
  }
827
- ], template: "<div class=\"mention-editor-container\" (click)=\"onContainerClick($event)\">\n <div\n #editor\n class=\"mention-editor\"\n contenteditable=\"true\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n (paste)=\"onPaste($event)\"\n ></div>\n\n <!-- Mention Dropdown -->\n <mj-mention-dropdown\n *ngIf=\"showMentionDropdown && enableMentions\"\n [suggestions]=\"mentionSuggestions\"\n [position]=\"mentionDropdownPosition\"\n [showAbove]=\"mentionDropdownShowAbove\"\n [useFixedPositioning]=\"true\"\n [visible]=\"true\"\n (suggestionSelected)=\"onMentionSelected($event)\"\n (closed)=\"closeMentionDropdown()\">\n </mj-mention-dropdown>\n</div>\n", styles: [".mention-editor-container {\n position: relative;\n width: 100%;\n display: block;\n}\n\n.mention-editor {\n display: block;\n width: 100%;\n min-height: 100px;\n max-height: 300px;\n padding: 7px 3.5rem 7px 12px;\n outline: none;\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n white-space: pre-wrap;\n cursor: text;\n user-select: text;\n box-sizing: border-box;\n}\n.mention-editor:empty:before {\n content: attr(data-placeholder);\n color: var(--text-tertiary, #999);\n pointer-events: none;\n position: absolute;\n}\n.mention-editor:focus {\n outline: none;\n}\n.mention-editor[contenteditable=false] {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--background-disabled, #f5f5f5);\n}\n@media (max-width: 768px) {\n .mention-editor {\n font-size: 16px;\n padding: 5px;\n padding-right: 3rem;\n }\n}\n\n::ng-deep .mention-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n margin: 0 3px;\n border-radius: 16px;\n font-size: 13px;\n font-weight: 600;\n cursor: default;\n user-select: none;\n vertical-align: middle;\n white-space: nowrap;\n pointer-events: all;\n -webkit-user-modify: read-only;\n -moz-user-modify: read-only;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: 2px solid rgba(102, 126, 234, 0.4);\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);\n animation: chipInsert 0.15s ease-out;\n}\n::ng-deep .mention-chip i {\n font-size: 12px;\n opacity: 0.95;\n}\n::ng-deep .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: 2px solid rgba(240, 147, 251, 0.4);\n}\n::ng-deep .mention-chip:hover {\n transform: translateY(-1px);\n box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n}\n::ng-deep .mention-chip:focus, ::ng-deep .mention-chip.selected {\n outline: 2px solid var(--primary-color, #007bff);\n outline-offset: 2px;\n}\n@keyframes chipInsert {\n 0% {\n transform: scale(0.8);\n opacity: 0;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n .mention-editor {\n color: black; /*computer preference level not yet supported*/\n /*color: #e0e0e0;*/ /*Matt - please work on this - for some as it didn't work*/\n }\n .mention-editor:empty:before {\n color: #777;\n }\n .mention-editor[contenteditable=false] {\n background: #2d2d2d;\n }\n .mention-chip {\n background: linear-gradient(135deg, #4a148c 0%, #6a1b9a 100%);\n color: #ce93d8;\n border-color: #8e24aa;\n }\n .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #880e4f 0%, #ad1457 100%);\n color: #f48fb1;\n border-color: #c2185b;\n }\n}\n.mention-editor .mention-chip + .mention-chip {\n margin-left: 4px;\n}\n.mention-editor br {\n display: block;\n content: \"\";\n margin: 0;\n}\n\n.mention-editor::-webkit-scrollbar {\n width: 6px;\n}\n.mention-editor::-webkit-scrollbar-track {\n background: transparent;\n}\n.mention-editor::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n}\n.mention-editor::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.3);\n}\n"] }]
828
- }], () => [{ type: i1.MentionAutocompleteService }], { editorRef: [{
1141
+ ], template: "<div class=\"mention-editor-container\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onContainerClick($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n <!-- Pending Attachments Preview -->\n <div class=\"pending-attachments\" *ngIf=\"pendingAttachments.length > 0\">\n <div class=\"attachment-thumbnail\"\n *ngFor=\"let attachment of pendingAttachments\"\n (click)=\"onAttachmentClick(attachment)\">\n <img *ngIf=\"attachment.thumbnailUrl\"\n [src]=\"attachment.thumbnailUrl\"\n [alt]=\"attachment.fileName\"\n class=\"thumbnail-image\">\n <div *ngIf=\"!attachment.thumbnailUrl\" class=\"thumbnail-placeholder\">\n <i class=\"fa-solid fa-file\"></i>\n <span class=\"file-name\">{{ attachment.fileName }}</span>\n </div>\n <button class=\"remove-attachment\"\n (click)=\"removeAttachment(attachment.id); $event.stopPropagation()\"\n title=\"Remove attachment\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n\n <div\n #editor\n class=\"mention-editor\"\n contenteditable=\"true\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n (paste)=\"onPaste($event)\"\n ></div>\n\n <!-- Drag & Drop Overlay -->\n <div class=\"drop-overlay\" *ngIf=\"isDragOver\">\n <div class=\"drop-message\">\n <i class=\"fa-solid fa-cloud-arrow-up\"></i>\n <span>Drop files here</span>\n </div>\n </div>\n\n <!-- Mention Dropdown -->\n <mj-mention-dropdown\n *ngIf=\"showMentionDropdown && enableMentions\"\n [suggestions]=\"mentionSuggestions\"\n [position]=\"mentionDropdownPosition\"\n [showAbove]=\"mentionDropdownShowAbove\"\n [useFixedPositioning]=\"true\"\n [visible]=\"true\"\n (suggestionSelected)=\"onMentionSelected($event)\"\n (closed)=\"closeMentionDropdown()\">\n </mj-mention-dropdown>\n</div>\n", styles: [".mention-editor-container {\n position: relative;\n width: 100%;\n display: block;\n}\n\n.mention-editor-container.drag-over {\n background: rgba(102, 126, 234, 0.05);\n border-color: #667eea;\n}\n\n.mention-editor {\n display: block;\n width: 100%;\n min-height: 100px;\n max-height: 300px;\n padding: 7px 3.5rem 7px 12px;\n outline: none;\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n white-space: pre-wrap;\n cursor: text;\n user-select: text;\n box-sizing: border-box;\n}\n.mention-editor:empty:before {\n content: attr(data-placeholder);\n color: var(--text-tertiary, #999);\n pointer-events: none;\n position: absolute;\n}\n.mention-editor:focus {\n outline: none;\n}\n.mention-editor[contenteditable=false] {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--background-disabled, #f5f5f5);\n}\n@media (max-width: 768px) {\n .mention-editor {\n font-size: 16px;\n padding: 5px;\n padding-right: 3rem;\n }\n}\n\n::ng-deep .mention-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n margin: 0 3px;\n border-radius: 16px;\n font-size: 13px;\n font-weight: 600;\n cursor: default;\n user-select: none;\n vertical-align: middle;\n white-space: nowrap;\n pointer-events: all;\n -webkit-user-modify: read-only;\n -moz-user-modify: read-only;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: 2px solid rgba(102, 126, 234, 0.4);\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);\n animation: chipInsert 0.15s ease-out;\n}\n::ng-deep .mention-chip i {\n font-size: 12px;\n opacity: 0.95;\n}\n::ng-deep .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: 2px solid rgba(240, 147, 251, 0.4);\n}\n::ng-deep .mention-chip:hover {\n transform: translateY(-1px);\n box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n}\n::ng-deep .mention-chip:focus, ::ng-deep .mention-chip.selected {\n outline: 2px solid var(--primary-color, #007bff);\n outline-offset: 2px;\n}\n@keyframes chipInsert {\n 0% {\n transform: scale(0.8);\n opacity: 0;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n .mention-editor {\n color: black; /*computer preference level not yet supported*/\n /*color: #e0e0e0;*/ /*Matt - please work on this - for some as it didn't work*/\n }\n .mention-editor:empty:before {\n color: #777;\n }\n .mention-editor[contenteditable=false] {\n background: #2d2d2d;\n }\n .mention-chip {\n background: linear-gradient(135deg, #4a148c 0%, #6a1b9a 100%);\n color: #ce93d8;\n border-color: #8e24aa;\n }\n .mention-chip[data-mention-type=user] {\n background: linear-gradient(135deg, #880e4f 0%, #ad1457 100%);\n color: #f48fb1;\n border-color: #c2185b;\n }\n}\n.mention-editor .mention-chip + .mention-chip {\n margin-left: 4px;\n}\n.mention-editor br {\n display: block;\n content: \"\";\n margin: 0;\n}\n\n.mention-editor::-webkit-scrollbar {\n width: 6px;\n}\n.mention-editor::-webkit-scrollbar-track {\n background: transparent;\n}\n.mention-editor::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n}\n.mention-editor::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.3);\n}\n\n/* ==================== Attachment Styles ==================== */\n\n.pending-attachments {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n background: rgba(0, 0, 0, 0.02);\n}\n\n.attachment-thumbnail {\n position: relative;\n width: 80px;\n height: 80px;\n border-radius: 8px;\n overflow: hidden;\n cursor: pointer;\n transition: transform 0.2s, box-shadow 0.2s;\n background: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.attachment-thumbnail:hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n}\n\n.thumbnail-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.thumbnail-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 8px;\n color: #666;\n}\n\n.thumbnail-placeholder i {\n font-size: 24px;\n margin-bottom: 4px;\n color: #999;\n}\n\n.thumbnail-placeholder .file-name {\n font-size: 10px;\n text-align: center;\n word-break: break-all;\n line-height: 1.2;\n max-height: 36px;\n overflow: hidden;\n}\n\n.remove-attachment {\n position: absolute;\n top: 4px;\n right: 4px;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s, background 0.2s;\n}\n\n.attachment-thumbnail:hover .remove-attachment {\n opacity: 1;\n}\n\n.remove-attachment:hover {\n background: rgba(220, 53, 69, 0.9);\n}\n\n.remove-attachment i {\n font-size: 10px;\n}\n\n/* Drop Overlay */\n.drop-overlay {\n position: absolute;\n inset: 0;\n background: rgba(102, 126, 234, 0.15);\n backdrop-filter: blur(2px);\n border: 2px dashed #667eea;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n pointer-events: none;\n}\n\n.drop-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: #667eea;\n font-weight: 600;\n}\n\n.drop-message i {\n font-size: 32px;\n}\n\n.drop-message span {\n font-size: 14px;\n}\n\n/* Dark Mode for Attachments */\n@media (prefers-color-scheme: dark) {\n .pending-attachments {\n background: rgba(255, 255, 255, 0.05);\n border-bottom-color: rgba(255, 255, 255, 0.1);\n }\n\n .attachment-thumbnail {\n background: #333;\n border-color: rgba(255, 255, 255, 0.15);\n }\n\n .thumbnail-placeholder {\n color: #aaa;\n }\n\n .thumbnail-placeholder i {\n color: #777;\n }\n\n .drop-overlay {\n background: rgba(102, 126, 234, 0.25);\n }\n}\n"] }]
1142
+ }], () => [{ type: i1.MentionAutocompleteService }, { type: i0.ChangeDetectorRef }], { editorRef: [{
829
1143
  type: ViewChild,
830
1144
  args: ['editor', { static: false }]
831
1145
  }], placeholder: [{
@@ -836,12 +1150,26 @@ export class MentionEditorComponent {
836
1150
  type: Input
837
1151
  }], enableMentions: [{
838
1152
  type: Input
1153
+ }], enableAttachments: [{
1154
+ type: Input
1155
+ }], maxAttachments: [{
1156
+ type: Input
1157
+ }], maxAttachmentSizeBytes: [{
1158
+ type: Input
1159
+ }], acceptedFileTypes: [{
1160
+ type: Input
839
1161
  }], valueChange: [{
840
1162
  type: Output
841
1163
  }], mentionSelected: [{
842
1164
  type: Output
843
1165
  }], enterPressed: [{
844
1166
  type: Output
1167
+ }], attachmentsChanged: [{
1168
+ type: Output
1169
+ }], attachmentError: [{
1170
+ type: Output
1171
+ }], attachmentClicked: [{
1172
+ type: Output
845
1173
  }] }); })();
846
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MentionEditorComponent, { className: "MentionEditorComponent", filePath: "src/lib/components/mention/mention-editor.component.ts", lineNumber: 35 }); })();
1174
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MentionEditorComponent, { className: "MentionEditorComponent", filePath: "src/lib/components/mention/mention-editor.component.ts", lineNumber: 61 }); })();
847
1175
  //# sourceMappingURL=mention-editor.component.js.map