Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/devextreme-angular/src/core/tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const PROPERTY_TOKEN_series = new InjectionToken<string>('property-token-
export const PROPERTY_TOKEN_strips = new InjectionToken<string>('property-token-strips');
export const PROPERTY_TOKEN_valueAxis = new InjectionToken<string>('property-token-valueAxis');
export const PROPERTY_TOKEN_alerts = new InjectionToken<string>('property-token-alerts');
export const PROPERTY_TOKEN_attachments = new InjectionToken<string>('property-token-attachments');
export const PROPERTY_TOKEN_typingUsers = new InjectionToken<string>('property-token-typingUsers');
export const PROPERTY_TOKEN_ranges = new InjectionToken<string>('property-token-ranges');
export const PROPERTY_TOKEN_groupItems = new InjectionToken<string>('property-token-groupItems');
Expand Down
51 changes: 50 additions & 1 deletion packages/devextreme-angular/src/ui/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ import {

import DataSource from 'devextreme/data/data_source';
import dxChat from 'devextreme/ui/chat';
import { Alert, Message, DisposingEvent, InitializedEvent, MessageDeletedEvent, MessageDeletingEvent, MessageEditCanceledEvent, MessageEditingStartEvent, MessageEnteredEvent, MessageUpdatedEvent, MessageUpdatingEvent, OptionChangedEvent, TypingEndEvent, TypingStartEvent, User } from 'devextreme/ui/chat';
import { Alert, Message, AttachmentDownloadEvent, DisposingEvent, InitializedEvent, MessageDeletedEvent, MessageDeletingEvent, MessageEditCanceledEvent, MessageEditingStartEvent, MessageEnteredEvent, MessageUpdatedEvent, MessageUpdatingEvent, OptionChangedEvent, TypingEndEvent, TypingStartEvent, User } from 'devextreme/ui/chat';
import { DataSourceOptions } from 'devextreme/data/data_source';
import { Store } from 'devextreme/data/store';
import { Format } from 'devextreme/common/core/localization';
import { dxFileUploaderOptions } from 'devextreme/ui/file_uploader';

import DxChat from 'devextreme/ui/chat';

Expand All @@ -46,22 +47,27 @@ import {
import { DxiAlertModule } from 'devextreme-angular/ui/nested';
import { DxoDayHeaderFormatModule } from 'devextreme-angular/ui/nested';
import { DxoEditingModule } from 'devextreme-angular/ui/nested';
import { DxoFileUploaderOptionsModule } from 'devextreme-angular/ui/nested';
import { DxiItemModule } from 'devextreme-angular/ui/nested';
import { DxiAttachmentModule } from 'devextreme-angular/ui/nested';
import { DxoAuthorModule } from 'devextreme-angular/ui/nested';
import { DxoMessageTimestampFormatModule } from 'devextreme-angular/ui/nested';
import { DxiTypingUserModule } from 'devextreme-angular/ui/nested';
import { DxoUserModule } from 'devextreme-angular/ui/nested';

import { DxiChatAlertModule } from 'devextreme-angular/ui/chat/nested';
import { DxiChatAttachmentModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatAuthorModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatDayHeaderFormatModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatEditingModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatFileUploaderOptionsModule } from 'devextreme-angular/ui/chat/nested';
import { DxiChatItemModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatMessageTimestampFormatModule } from 'devextreme-angular/ui/chat/nested';
import { DxiChatTypingUserModule } from 'devextreme-angular/ui/chat/nested';
import { DxoChatUserModule } from 'devextreme-angular/ui/chat/nested';
import {
PROPERTY_TOKEN_alerts,
PROPERTY_TOKEN_attachments,
PROPERTY_TOKEN_items,
PROPERTY_TOKEN_typingUsers,
} from 'devextreme-angular/core/tokens';
Expand Down Expand Up @@ -91,6 +97,11 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
this.setChildren('alerts', value);
}

@ContentChildren(PROPERTY_TOKEN_attachments)
set _attachmentsContentChildren(value: QueryList<CollectionNestedOption>) {
this.setChildren('attachments', value);
}
Comment on lines +98 to +101
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @ContentChildren decorator for PROPERTY_TOKEN_attachments is set at the Chat component level, but attachments are actually nested within Item components according to the nested component structure (see item-dxi.ts lines 45-48). This decorator may not function correctly at this level and could lead to incorrect attachment binding. Consider removing this decorator from the Chat component since attachments are already properly handled within the Item nested component.

Suggested change
@ContentChildren(PROPERTY_TOKEN_attachments)
set _attachmentsContentChildren(value: QueryList<CollectionNestedOption>) {
this.setChildren('attachments', value);
}

Copilot uses AI. Check for mistakes.

@ContentChildren(PROPERTY_TOKEN_items)
set _itemsContentChildren(value: QueryList<CollectionNestedOption>) {
this.setChildren('items', value);
Expand Down Expand Up @@ -220,6 +231,19 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
}


/**
* [descr:dxChatOptions.fileUploaderOptions]

*/
@Input()
get fileUploaderOptions(): dxFileUploaderOptions {
return this._getOption('fileUploaderOptions');
}
set fileUploaderOptions(value: dxFileUploaderOptions) {
this._setOption('fileUploaderOptions', value);
}


/**
* [descr:dxChatOptions.focusStateEnabled]

Expand Down Expand Up @@ -440,6 +464,14 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
this._setOption('width', value);
}

/**

* [descr:dxChatOptions.onAttachmentDownload]


Comment thread
marker-dao marked this conversation as resolved.
Comment on lines +463 to +466
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc comment contains placeholder text [descr:undefined] instead of actual documentation. This property should have proper documentation describing the attachment download event, its usage, and when it fires.

Suggested change
* [descr:undefined]
* Fires when a user attempts to download an attachment from a chat message.
* Use this event to handle or intercept attachment downloads, for example to log downloads,
* implement custom download logic, or restrict access to certain files.
* The event provides information about the attachment and the message it belongs to.

Copilot uses AI. Check for mistakes.
*/
@Output() onAttachmentDownload: EventEmitter<AttachmentDownloadEvent>;

/**

* [descr:dxChatOptions.onDisposing]
Expand Down Expand Up @@ -599,6 +631,13 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
*/
@Output() emptyViewTemplateChange: EventEmitter<any>;

/**

* This member supports the internal infrastructure and is not intended to be used directly from your code.

*/
@Output() fileUploaderOptionsChange: EventEmitter<dxFileUploaderOptions>;

/**

* This member supports the internal infrastructure and is not intended to be used directly from your code.
Expand Down Expand Up @@ -731,6 +770,7 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
super(elementRef, ngZone, templateHost, _watcherHelper, transferState, platformId);

this._createEventEmitters([
{ subscribe: 'attachmentDownload', emit: 'onAttachmentDownload' },
{ subscribe: 'disposing', emit: 'onDisposing' },
{ subscribe: 'initialized', emit: 'onInitialized' },
{ subscribe: 'messageDeleted', emit: 'onMessageDeleted' },
Expand All @@ -752,6 +792,7 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
{ emit: 'editingChange' },
{ emit: 'elementAttrChange' },
{ emit: 'emptyViewTemplateChange' },
{ emit: 'fileUploaderOptionsChange' },
{ emit: 'focusStateEnabledChange' },
{ emit: 'heightChange' },
{ emit: 'hintChange' },
Expand Down Expand Up @@ -825,15 +866,19 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
DxiAlertModule,
DxoDayHeaderFormatModule,
DxoEditingModule,
DxoFileUploaderOptionsModule,
DxiItemModule,
DxiAttachmentModule,
DxoAuthorModule,
DxoMessageTimestampFormatModule,
DxiTypingUserModule,
DxoUserModule,
DxiChatAlertModule,
DxiChatAttachmentModule,
DxoChatAuthorModule,
DxoChatDayHeaderFormatModule,
DxoChatEditingModule,
DxoChatFileUploaderOptionsModule,
DxiChatItemModule,
DxoChatMessageTimestampFormatModule,
DxiChatTypingUserModule,
Expand All @@ -846,15 +891,19 @@ export class DxChatComponent extends DxComponent implements OnDestroy, OnChanges
DxiAlertModule,
DxoDayHeaderFormatModule,
DxoEditingModule,
DxoFileUploaderOptionsModule,
DxiItemModule,
DxiAttachmentModule,
DxoAuthorModule,
DxoMessageTimestampFormatModule,
DxiTypingUserModule,
DxoUserModule,
DxiChatAlertModule,
DxiChatAttachmentModule,
DxoChatAuthorModule,
DxoChatDayHeaderFormatModule,
DxoChatEditingModule,
DxoChatFileUploaderOptionsModule,
DxiChatItemModule,
DxoChatMessageTimestampFormatModule,
DxiChatTypingUserModule,
Expand Down
84 changes: 84 additions & 0 deletions packages/devextreme-angular/src/ui/chat/nested/attachment-dxi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* tslint:disable:max-line-length */


import {
Component,
NgModule,
Host,
SkipSelf,
Input
} from '@angular/core';





import {
DxIntegrationModule,
NestedOptionHost,
} from 'devextreme-angular/core';
import { CollectionNestedOption } from 'devextreme-angular/core';

import { PROPERTY_TOKEN_attachments } from 'devextreme-angular/core/tokens';

@Component({
selector: 'dxi-chat-attachment',
standalone: true,
template: '',
styles: [''],
imports: [ DxIntegrationModule ],
providers: [
NestedOptionHost,
{
provide: PROPERTY_TOKEN_attachments,
useExisting: DxiChatAttachmentComponent,
}
]
})
export class DxiChatAttachmentComponent extends CollectionNestedOption {
@Input()
get name(): string {
return this._getOption('name');
}
set name(value: string) {
this._setOption('name', value);
}

@Input()
get size(): number {
return this._getOption('size');
}
set size(value: number) {
this._setOption('size', value);
}


protected get _optionPath() {
return 'attachments';
}


constructor(@SkipSelf() @Host() parentOptionHost: NestedOptionHost,
@Host() optionHost: NestedOptionHost) {
super();
parentOptionHost.setNestedOption(this);
optionHost.setHost(this, this._fullOptionPath.bind(this));
}



ngOnDestroy() {
this._deleteRemovedOptions(this._fullOptionPath());
}

}

@NgModule({
imports: [
DxiChatAttachmentComponent
],
exports: [
DxiChatAttachmentComponent
],
})
export class DxiChatAttachmentModule { }
Loading
Loading