@masterteam/discussion 0.0.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.
@@ -0,0 +1,383 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { ElementRef } from '@angular/core';
3
+ import { HttpContext } from '@angular/common/http';
4
+ import { EntityData } from '@masterteam/components/entities';
5
+ import { Observable } from 'rxjs';
6
+
7
+ interface AppResponseViewModelError {
8
+ code?: string;
9
+ message?: string;
10
+ details?: unknown;
11
+ }
12
+ interface AppResponseViewModel<T> {
13
+ endpoint?: string;
14
+ status?: number;
15
+ code?: number;
16
+ locale?: string;
17
+ message?: string | null;
18
+ errors?: AppResponseViewModelError | null;
19
+ data: T;
20
+ cacheSession?: string;
21
+ }
22
+ interface DiscussionThreadSummaryDto {
23
+ threadKey: string;
24
+ moduleType: string;
25
+ recordId: number;
26
+ totalComments: number;
27
+ lastCommentAt: string | null;
28
+ lastReadCommentId: number | null;
29
+ lastReadCommentCreatedAt: string | null;
30
+ lastReadAt: string | null;
31
+ unreadCount: number;
32
+ hasUnread: boolean;
33
+ }
34
+ interface DiscussionCommentAttachmentDto {
35
+ id: number;
36
+ fileId: string;
37
+ fileName: string;
38
+ contentType: string;
39
+ size: number;
40
+ }
41
+ interface DiscussionMentionDto {
42
+ id?: number;
43
+ userId: string;
44
+ startIndex: number;
45
+ length: number;
46
+ }
47
+ interface DiscussionCommentDto {
48
+ id: number;
49
+ moduleType: string;
50
+ recordId: number;
51
+ parentCommentId: number | null;
52
+ comment: string;
53
+ isSystem: boolean;
54
+ createdAt: string;
55
+ updatedAt: string | null;
56
+ createdBy: string;
57
+ updatedBy: string | null;
58
+ attachments: DiscussionCommentAttachmentDto[];
59
+ mentions: DiscussionMentionDto[];
60
+ }
61
+ interface DiscussionCommentsPageDto {
62
+ items: DiscussionCommentDto[];
63
+ nextCursor: string | null;
64
+ hasMore: boolean;
65
+ lastReadCommentId: number | null;
66
+ lastReadCommentCreatedAt: string | null;
67
+ lastReadAt: string | null;
68
+ unreadCount: number;
69
+ hasUnread: boolean;
70
+ }
71
+ interface DiscussionParticipantDto {
72
+ id: number;
73
+ userId: string;
74
+ user?: DiscussionParticipantUserDto | null;
75
+ addedBy: string;
76
+ addedByUser?: DiscussionParticipantUserDto | null;
77
+ createdAt: string;
78
+ }
79
+ interface DiscussionParticipantUserDto {
80
+ id: string;
81
+ displayName: string;
82
+ userName?: string | null;
83
+ fullName?: string | null;
84
+ photoUrl?: string | null;
85
+ isActive?: boolean;
86
+ isDeleted?: boolean;
87
+ hasContactDetails?: boolean;
88
+ }
89
+ interface DiscussionCommentRevisionDto {
90
+ id: number;
91
+ commentId: number;
92
+ revisionNumber: number;
93
+ comment: string;
94
+ createdAt: string;
95
+ createdBy: string;
96
+ mentions: DiscussionMentionDto[];
97
+ }
98
+ interface DiscussionReadStateDto {
99
+ threadKey: string;
100
+ moduleType: string;
101
+ recordId: number;
102
+ userId: string;
103
+ lastReadCommentId: number | null;
104
+ lastReadCommentCreatedAt: string | null;
105
+ lastReadAt: string | null;
106
+ unreadCount: number;
107
+ hasUnread: boolean;
108
+ }
109
+ interface DiscussionCreateCommentRequest {
110
+ comment: string;
111
+ parentCommentId?: number | null;
112
+ attachmentFileIds?: string[];
113
+ mentions?: DiscussionMentionDto[];
114
+ }
115
+ interface DiscussionUpdateCommentRequest {
116
+ comment: string;
117
+ mentions?: DiscussionMentionDto[];
118
+ }
119
+ interface DiscussionAddParticipantRequest {
120
+ userId: string;
121
+ }
122
+ interface DiscussionUpdateReadStateRequest {
123
+ lastReadCommentId?: number;
124
+ }
125
+ interface DiscussionMentionUser {
126
+ userId: string;
127
+ displayName: string;
128
+ userName?: string | null;
129
+ avatarUrl?: string | null;
130
+ }
131
+ interface DiscussionAttachmentUploadResult {
132
+ fileId: string;
133
+ fileName: string;
134
+ contentType?: string | null;
135
+ size?: number | null;
136
+ }
137
+ interface DiscussionAttachmentUploadProgressEvent {
138
+ progress: number;
139
+ completed: boolean;
140
+ file?: DiscussionAttachmentUploadResult;
141
+ }
142
+ interface DiscussionAttachmentDraft {
143
+ id: string;
144
+ fileId: string | null;
145
+ fileName: string;
146
+ contentType: string;
147
+ size: number;
148
+ progress: number;
149
+ status: 'uploading' | 'ready' | 'failed';
150
+ error?: string | null;
151
+ }
152
+ interface DiscussionCommentSegment {
153
+ text: string;
154
+ isMention: boolean;
155
+ userId?: string;
156
+ }
157
+ interface DiscussionReadStateLike {
158
+ lastReadCommentId: number | null;
159
+ lastReadCommentCreatedAt: string | null;
160
+ unreadCount: number;
161
+ hasUnread: boolean;
162
+ }
163
+
164
+ type MentionMode = 'composer' | 'edit';
165
+ interface MentionSession {
166
+ mode: MentionMode;
167
+ triggerIndex: number;
168
+ caretIndex: number;
169
+ query: string;
170
+ textarea: HTMLTextAreaElement;
171
+ editCommentId: number | null;
172
+ }
173
+ interface MentionMenuPosition {
174
+ left: number;
175
+ top: number;
176
+ width: number;
177
+ maxHeight: number;
178
+ placement: 'above' | 'below';
179
+ }
180
+ declare class DiscussionThread {
181
+ private readonly api;
182
+ private readonly destroyRef;
183
+ readonly moduleType: _angular_core.InputSignal<string>;
184
+ readonly recordId: _angular_core.InputSignal<number>;
185
+ readonly title: _angular_core.InputSignal<string>;
186
+ readonly subtitle: _angular_core.InputSignal<string>;
187
+ readonly placeholder: _angular_core.InputSignal<string>;
188
+ readonly pageSize: _angular_core.InputSignal<number>;
189
+ readonly currentUserId: _angular_core.InputSignal<string>;
190
+ readonly requestContext: _angular_core.InputSignal<HttpContext | undefined>;
191
+ readonly mentionableUsers: _angular_core.InputSignal<DiscussionMentionUser[]>;
192
+ readonly mentionSearchEndpoint: _angular_core.InputSignal<string>;
193
+ readonly mentionSearchParam: _angular_core.InputSignal<string>;
194
+ readonly mentionSearchDataPath: _angular_core.InputSignal<string>;
195
+ readonly allowAttachments: _angular_core.InputSignal<boolean>;
196
+ readonly uploadEndpoint: _angular_core.InputSignal<string>;
197
+ readonly attachmentDownloadEndpoint: _angular_core.InputSignal<string>;
198
+ readonly showParticipants: _angular_core.InputSignal<boolean>;
199
+ readonly autoMarkRead: _angular_core.InputSignal<boolean>;
200
+ readonly refreshIntervalMs: _angular_core.InputSignal<number>;
201
+ readonly styleClass: _angular_core.InputSignal<string>;
202
+ readonly disabled: _angular_core.InputSignal<boolean>;
203
+ readonly loaded: _angular_core.OutputEmitterRef<DiscussionThreadSummaryDto>;
204
+ readonly errored: _angular_core.OutputEmitterRef<string>;
205
+ readonly commentCreated: _angular_core.OutputEmitterRef<DiscussionCommentDto>;
206
+ readonly commentUpdated: _angular_core.OutputEmitterRef<DiscussionCommentDto>;
207
+ readonly commentDeleted: _angular_core.OutputEmitterRef<number>;
208
+ readonly readStateChanged: _angular_core.OutputEmitterRef<DiscussionReadStateDto | null>;
209
+ protected readonly viewportRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
210
+ protected readonly composerInputRef: _angular_core.Signal<ElementRef<HTMLTextAreaElement> | undefined>;
211
+ protected readonly attachmentInputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
212
+ protected readonly loadingInitial: _angular_core.WritableSignal<boolean>;
213
+ protected readonly loadingMore: _angular_core.WritableSignal<boolean>;
214
+ protected readonly posting: _angular_core.WritableSignal<boolean>;
215
+ protected readonly refreshing: _angular_core.WritableSignal<boolean>;
216
+ protected readonly markingRead: _angular_core.WritableSignal<boolean>;
217
+ protected readonly participantsLoading: _angular_core.WritableSignal<boolean>;
218
+ protected readonly savingEdit: _angular_core.WritableSignal<boolean>;
219
+ protected readonly revisionLoading: _angular_core.WritableSignal<boolean>;
220
+ protected readonly errorMessage: _angular_core.WritableSignal<string | null>;
221
+ protected readonly threadSummary: _angular_core.WritableSignal<DiscussionThreadSummaryDto | null>;
222
+ protected readonly commentsDesc: _angular_core.WritableSignal<DiscussionCommentDto[]>;
223
+ protected readonly participants: _angular_core.WritableSignal<DiscussionParticipantDto[]>;
224
+ protected readonly readState: _angular_core.WritableSignal<DiscussionReadStateDto | null>;
225
+ protected readonly nextCursor: _angular_core.WritableSignal<string | null>;
226
+ protected readonly hasMore: _angular_core.WritableSignal<boolean>;
227
+ protected readonly composerText: _angular_core.WritableSignal<string>;
228
+ protected readonly composerMentions: _angular_core.WritableSignal<DiscussionMentionDto[]>;
229
+ protected readonly composerAttachments: _angular_core.WritableSignal<DiscussionAttachmentDraft[]>;
230
+ protected readonly replyToCommentId: _angular_core.WritableSignal<number | null>;
231
+ protected readonly editingCommentId: _angular_core.WritableSignal<number | null>;
232
+ protected readonly editText: _angular_core.WritableSignal<string>;
233
+ protected readonly editMentions: _angular_core.WritableSignal<DiscussionMentionDto[]>;
234
+ protected readonly participantsExpanded: _angular_core.WritableSignal<boolean>;
235
+ protected readonly mentionSession: _angular_core.WritableSignal<MentionSession | null>;
236
+ protected readonly mentionCandidates: _angular_core.WritableSignal<DiscussionMentionUser[]>;
237
+ protected readonly mentionLoading: _angular_core.WritableSignal<boolean>;
238
+ protected readonly mentionActiveIndex: _angular_core.WritableSignal<number>;
239
+ protected readonly mentionMenuPosition: _angular_core.WritableSignal<MentionMenuPosition | null>;
240
+ protected readonly mentionMenuStyle: _angular_core.Signal<{
241
+ left: string;
242
+ top: string;
243
+ width: string;
244
+ maxHeight: string;
245
+ } | null>;
246
+ protected readonly revisionsDialogVisible: _angular_core.WritableSignal<boolean>;
247
+ protected readonly selectedRevisionComment: _angular_core.WritableSignal<DiscussionCommentDto | null>;
248
+ protected readonly revisionsByComment: _angular_core.WritableSignal<Map<number, DiscussionCommentRevisionDto[]>>;
249
+ protected readonly deletingCommentIds: _angular_core.WritableSignal<Set<number>>;
250
+ protected readonly atBottom: _angular_core.WritableSignal<boolean>;
251
+ protected readonly resolvedModuleType: _angular_core.Signal<string>;
252
+ protected readonly resolvedRecordId: _angular_core.Signal<number>;
253
+ protected readonly resolvedPageSize: _angular_core.Signal<number>;
254
+ protected readonly threadKey: _angular_core.Signal<string>;
255
+ protected readonly commentsAsc: _angular_core.Signal<DiscussionCommentDto[]>;
256
+ protected readonly commentsById: _angular_core.Signal<Map<number, DiscussionCommentDto>>;
257
+ protected readonly replyToComment: _angular_core.Signal<DiscussionCommentDto | null>;
258
+ protected readonly readStateLike: _angular_core.Signal<DiscussionReadStateLike | null>;
259
+ protected readonly hasUnread: _angular_core.Signal<boolean>;
260
+ protected readonly unreadCount: _angular_core.Signal<number>;
261
+ protected readonly firstUnreadCommentId: _angular_core.Signal<number | null>;
262
+ protected readonly mentionPool: _angular_core.Signal<DiscussionMentionUser[]>;
263
+ protected readonly participantEntities: _angular_core.Signal<EntityData[]>;
264
+ protected readonly uploadInProgress: _angular_core.Signal<boolean>;
265
+ protected readonly readyAttachmentFileIds: _angular_core.Signal<string[]>;
266
+ protected readonly canSend: _angular_core.Signal<boolean>;
267
+ protected readonly canSaveEdit: _angular_core.Signal<boolean>;
268
+ protected readonly charactersLeft: _angular_core.Signal<number>;
269
+ protected readonly visibleRevisions: _angular_core.Signal<DiscussionCommentRevisionDto[]>;
270
+ private readonly mentionSearchTerms;
271
+ private readonly mentionMenuMaxWidthPx;
272
+ private readonly mentionMenuPreferredHeightPx;
273
+ private readonly mentionMenuViewportPaddingPx;
274
+ private autoReadTimer;
275
+ constructor();
276
+ protected trackComment(_: number, comment: DiscussionCommentDto): number;
277
+ protected isOwnComment(comment: DiscussionCommentDto): boolean;
278
+ protected canEditComment(comment: DiscussionCommentDto): boolean;
279
+ protected canDeleteComment(comment: DiscussionCommentDto): boolean;
280
+ protected isDeleting(commentId: number): boolean;
281
+ protected getAvatarText(comment: DiscussionCommentDto): string;
282
+ protected getMentionAvatarText(user: DiscussionMentionUser): string;
283
+ protected getCommentSegments(comment: DiscussionCommentDto): DiscussionCommentSegment[];
284
+ protected getParentComment(comment: DiscussionCommentDto): DiscussionCommentDto | null;
285
+ protected openReply(comment: DiscussionCommentDto): void;
286
+ protected clearReply(): void;
287
+ protected startEdit(comment: DiscussionCommentDto): void;
288
+ protected cancelEdit(): void;
289
+ protected saveEdit(): Promise<void>;
290
+ protected deleteComment(comment: DiscussionCommentDto): Promise<void>;
291
+ protected sendComment(): Promise<void>;
292
+ protected loadOlder(): Promise<void>;
293
+ protected refreshThread(): Promise<void>;
294
+ protected markRead(): Promise<void>;
295
+ protected markUnread(): Promise<void>;
296
+ protected onViewportScroll(): void;
297
+ protected onComposerInput(event: Event): void;
298
+ protected onComposerCaretEvent(event: Event): void;
299
+ protected onComposerKeydown(event: KeyboardEvent): void;
300
+ protected onEditInput(event: Event): void;
301
+ protected onEditCaretEvent(event: Event): void;
302
+ protected onEditKeydown(event: KeyboardEvent): void;
303
+ protected selectMention(user: DiscussionMentionUser): void;
304
+ protected toggleParticipantsPanel(): void;
305
+ protected openRevisions(comment: DiscussionCommentDto): Promise<void>;
306
+ protected downloadAttachment(comment: DiscussionCommentDto, attachment: {
307
+ fileId: string;
308
+ fileName: string;
309
+ }): Promise<void>;
310
+ protected browseAttachments(): void;
311
+ protected onAttachmentSelected(event: Event): void;
312
+ protected removeAttachment(draftId: string): void;
313
+ private uploadAttachment;
314
+ private loadThread;
315
+ private reloadParticipantsQuiet;
316
+ private refreshReadState;
317
+ private resetData;
318
+ private resetComposer;
319
+ private applyInitialComments;
320
+ private applyCommentsPageMeta;
321
+ private normalizeComments;
322
+ private rebaseMentions;
323
+ private computeTextMutation;
324
+ private normalizePageSize;
325
+ private isCursorError;
326
+ private updateMentionSession;
327
+ private searchMentionCandidates;
328
+ private matchesMentionQuery;
329
+ private bindMentionSearch;
330
+ private handleMentionKeyboard;
331
+ private closeMentionMenu;
332
+ private positionMentionMenuForCurrentSession;
333
+ private positionMentionMenu;
334
+ private measureMentionCaret;
335
+ private resolveMentionLineHeight;
336
+ private getParticipantDisplayName;
337
+ private mapParticipantToEntityUserValue;
338
+ private mergeParticipants;
339
+ private toReadStateFromPage;
340
+ private resolveFirstUnreadCommentId;
341
+ private isCommentAfterPointer;
342
+ private focusComposer;
343
+ private scheduleScrollToBottom;
344
+ private scheduleAutoMarkRead;
345
+ private patchSummaryTotal;
346
+ private patchSummaryRead;
347
+ private handleError;
348
+ private generateDraftId;
349
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DiscussionThread, never>;
350
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DiscussionThread, "mt-discussion-thread", never, { "moduleType": { "alias": "moduleType"; "required": true; "isSignal": true; }; "recordId": { "alias": "recordId"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "currentUserId": { "alias": "currentUserId"; "required": false; "isSignal": true; }; "requestContext": { "alias": "requestContext"; "required": false; "isSignal": true; }; "mentionableUsers": { "alias": "mentionableUsers"; "required": false; "isSignal": true; }; "mentionSearchEndpoint": { "alias": "mentionSearchEndpoint"; "required": false; "isSignal": true; }; "mentionSearchParam": { "alias": "mentionSearchParam"; "required": false; "isSignal": true; }; "mentionSearchDataPath": { "alias": "mentionSearchDataPath"; "required": false; "isSignal": true; }; "allowAttachments": { "alias": "allowAttachments"; "required": false; "isSignal": true; }; "uploadEndpoint": { "alias": "uploadEndpoint"; "required": false; "isSignal": true; }; "attachmentDownloadEndpoint": { "alias": "attachmentDownloadEndpoint"; "required": false; "isSignal": true; }; "showParticipants": { "alias": "showParticipants"; "required": false; "isSignal": true; }; "autoMarkRead": { "alias": "autoMarkRead"; "required": false; "isSignal": true; }; "refreshIntervalMs": { "alias": "refreshIntervalMs"; "required": false; "isSignal": true; }; "styleClass": { "alias": "styleClass"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "errored": "errored"; "commentCreated": "commentCreated"; "commentUpdated": "commentUpdated"; "commentDeleted": "commentDeleted"; "readStateChanged": "readStateChanged"; }, never, never, true, never>;
351
+ }
352
+
353
+ declare class DiscussionApiService {
354
+ private readonly http;
355
+ private readonly defaultContext;
356
+ private readonly baseRoute;
357
+ getThreadSummary(moduleType: string, recordId: number, context?: HttpContext): Observable<DiscussionThreadSummaryDto>;
358
+ getComments(moduleType: string, recordId: number, take?: number, cursor?: string | null, context?: HttpContext): Observable<DiscussionCommentsPageDto>;
359
+ createComment(moduleType: string, recordId: number, request: DiscussionCreateCommentRequest, context?: HttpContext): Observable<DiscussionCommentDto>;
360
+ updateComment(moduleType: string, recordId: number, commentId: number, request: DiscussionUpdateCommentRequest, context?: HttpContext): Observable<DiscussionCommentDto>;
361
+ deleteComment(moduleType: string, recordId: number, commentId: number, context?: HttpContext): Observable<boolean>;
362
+ getCommentRevisions(moduleType: string, recordId: number, commentId: number, context?: HttpContext): Observable<DiscussionCommentRevisionDto[]>;
363
+ getParticipants(moduleType: string, recordId: number, context?: HttpContext): Observable<DiscussionParticipantDto[]>;
364
+ addParticipant(moduleType: string, recordId: number, request: DiscussionAddParticipantRequest, context?: HttpContext): Observable<DiscussionParticipantDto>;
365
+ getReadState(moduleType: string, recordId: number, context?: HttpContext): Observable<DiscussionReadStateDto>;
366
+ markReadState(moduleType: string, recordId: number, request?: DiscussionUpdateReadStateRequest, context?: HttpContext): Observable<DiscussionReadStateDto>;
367
+ clearReadState(moduleType: string, recordId: number, context?: HttpContext): Observable<boolean>;
368
+ uploadAttachment(file: File, uploadEndpoint: string, context?: HttpContext): Observable<DiscussionAttachmentUploadProgressEvent>;
369
+ searchMentionUsers(endpoint: string, query: string, paramName: string, dataPath: string, context?: HttpContext): Observable<DiscussionMentionUser[]>;
370
+ downloadAttachment(endpoint: string, fileId: string, fileName: string, context?: HttpContext): Observable<void>;
371
+ private threadRoute;
372
+ private resolveContext;
373
+ private mutationHeaders;
374
+ private idempotencyKey;
375
+ private unwrapUnknownResponse;
376
+ private mapUploadPayload;
377
+ private resolveDownloadEndpoint;
378
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DiscussionApiService, never>;
379
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DiscussionApiService>;
380
+ }
381
+
382
+ export { DiscussionApiService, DiscussionThread };
383
+ export type { AppResponseViewModel, AppResponseViewModelError, DiscussionAddParticipantRequest, DiscussionAttachmentDraft, DiscussionAttachmentUploadProgressEvent, DiscussionAttachmentUploadResult, DiscussionCommentAttachmentDto, DiscussionCommentDto, DiscussionCommentRevisionDto, DiscussionCommentSegment, DiscussionCommentsPageDto, DiscussionCreateCommentRequest, DiscussionMentionDto, DiscussionMentionUser, DiscussionParticipantDto, DiscussionParticipantUserDto, DiscussionReadStateDto, DiscussionReadStateLike, DiscussionThreadSummaryDto, DiscussionUpdateCommentRequest, DiscussionUpdateReadStateRequest };