Skip to content

Commit 8cc48ff

Browse files
r-farkhutdinovRuslan Farkhutdinov
andauthored
Chat FU: Hide download button of File when onDownload is not passed (#31538)
Co-authored-by: Ruslan Farkhutdinov <[email protected]>
1 parent 1ea6be0 commit 8cc48ff

File tree

9 files changed

+99
-60
lines changed

9 files changed

+99
-60
lines changed

packages/devextreme/js/__internal/ui/chat/chat.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class Chat extends Widget<Properties> {
108108
onMessageEntered: undefined,
109109
onTypingEnd: undefined,
110110
onTypingStart: undefined,
111+
onAttachmentDownload: undefined,
111112
};
112113
}
113114

@@ -200,6 +201,7 @@ class Chat extends Widget<Properties> {
200201
// @ts-expect-error
201202
const isLoading = this._dataController.isLoading();
202203
const currentUserId = user?.id;
204+
const onAttachmentDownload = this._getAttachmentDownloadHandler();
203205

204206
const options: MessageListProperties = {
205207
items,
@@ -228,14 +230,23 @@ class Chat extends Widget<Properties> {
228230
onEscapeKeyPressed: () => {
229231
this.focus();
230232
},
231-
onAttachmentDownload: (e) => {
232-
this._attachmentDownloadAction?.(e);
233-
},
233+
onAttachmentDownload,
234234
};
235235

236236
return options;
237237
}
238238

239+
_getAttachmentDownloadHandler(): ((e: AttachmentDownloadEvent) => void) | undefined {
240+
const { onAttachmentDownload } = this.option();
241+
242+
if (!onAttachmentDownload) {
243+
return;
244+
}
245+
246+
// eslint-disable-next-line consistent-return
247+
return (e: AttachmentDownloadEvent): void => { this._attachmentDownloadAction?.(e); };
248+
}
249+
239250
protected _allowEditAction(message: Message): boolean {
240251
const { editing } = this.option();
241252
if (!editing) {
@@ -644,6 +655,7 @@ class Chat extends Widget<Properties> {
644655
break;
645656
case 'onAttachmentDownload':
646657
this._createAttachmentDownloadAction();
658+
this._messageList.option({ onAttachmentDownload: this._getAttachmentDownloadHandler() });
647659
break;
648660
case 'showDayHeaders':
649661
case 'showAvatar':

packages/devextreme/js/__internal/ui/chat/file_view/file.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ class File extends DOMComponent<File, Properties> {
120120
}
121121

122122
private _renderButton(): void {
123+
const { onDownload } = this.option();
124+
125+
if (!onDownload) {
126+
return;
127+
}
128+
123129
const $button = $('<div>').addClass(CHAT_FILE_DOWNLOAD_BUTTON_CLASS);
124130

125131
this._downloadButton = this._createComponent<Button, ButtonProperties>(
@@ -151,18 +157,40 @@ class File extends DOMComponent<File, Properties> {
151157
icon: 'download',
152158
stylingMode: 'text' as const,
153159
onClick: (e: ClickEvent): void => {
154-
const event = {
155-
event: e.event,
156-
attachment: data,
157-
};
158-
159-
this._downloadAction?.(event);
160+
this._downloadHandler(e);
160161
},
161162
};
162163

163164
return configuration;
164165
}
165166

167+
_downloadHandler(e: ClickEvent): void {
168+
const { data } = this.option();
169+
170+
const event = {
171+
event: e.event,
172+
attachment: data,
173+
};
174+
175+
this._downloadAction?.(event);
176+
}
177+
178+
_handleOnDownloadOptionChange(): void {
179+
const { onDownload } = this.option();
180+
181+
if (!onDownload) {
182+
this._cleanDownloadButton();
183+
184+
return;
185+
}
186+
187+
if (this._downloadButton) {
188+
this._downloadButton?.option({ onClick: (e) => this._downloadHandler(e) });
189+
} else {
190+
this._renderButton();
191+
}
192+
}
193+
166194
_optionChanged(args: OptionChanged<Properties>): void {
167195
const { name, value } = args;
168196

@@ -179,6 +207,7 @@ class File extends DOMComponent<File, Properties> {
179207

180208
case 'onDownload':
181209
this._createDownloadAction();
210+
this._handleOnDownloadOptionChange();
182211
break;
183212

184213
default:

packages/devextreme/js/__internal/ui/chat/file_view/file_view.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ export const CHAT_FILE_VIEW_CLASS = 'dx-chat-file-view';
2424
class FileView extends DOMComponent<FileView, FileViewProperties> {
2525
private _fileInstances: File[] = [];
2626

27-
private _downloadAction?: (e: Partial<AttachmentDownloadEvent>) => void;
28-
2927
_getDefaultOptions(): FileViewProperties {
3028
return {
3129
...super._getDefaultOptions(),
@@ -36,19 +34,6 @@ class FileView extends DOMComponent<FileView, FileViewProperties> {
3634
};
3735
}
3836

39-
_init(): void {
40-
super._init();
41-
42-
this._createDownloadAction();
43-
}
44-
45-
_createDownloadAction(): void {
46-
this._downloadAction = this._createActionByOption(
47-
'onDownload',
48-
{ excludeValidators: ['disabled'] },
49-
);
50-
}
51-
5237
_initMarkup(): void {
5338
this.$element().addClass(CHAT_FILE_VIEW_CLASS);
5439

@@ -79,16 +64,16 @@ class FileView extends DOMComponent<FileView, FileViewProperties> {
7964
}
8065

8166
_getFileConfig(data: Attachment): FileProperties {
82-
const { activeStateEnabled, focusStateEnabled, hoverStateEnabled } = this.option();
67+
const {
68+
activeStateEnabled, focusStateEnabled, hoverStateEnabled, onDownload,
69+
} = this.option();
8370

8471
const configuration: FileProperties = {
8572
data,
8673
activeStateEnabled,
8774
focusStateEnabled,
8875
hoverStateEnabled,
89-
onDownload: (event) => {
90-
this._downloadAction?.(event);
91-
},
76+
onDownload,
9277
};
9378

9479
return configuration;
@@ -128,6 +113,7 @@ class FileView extends DOMComponent<FileView, FileViewProperties> {
128113
case 'activeStateEnabled':
129114
case 'focusStateEnabled':
130115
case 'hoverStateEnabled':
116+
case 'onDownload':
131117
this._renderItems();
132118
break;
133119

@@ -136,10 +122,6 @@ class FileView extends DOMComponent<FileView, FileViewProperties> {
136122
this._toggleAria();
137123
break;
138124

139-
case 'onDownload':
140-
this._createDownloadAction();
141-
break;
142-
143125
default:
144126
super._optionChanged(args);
145127
}

packages/devextreme/js/__internal/ui/chat/messagegroup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ class MessageGroup extends Widget<Properties> {
313313
case 'showMessageTimestamp':
314314
case 'messageTemplate':
315315
case 'messageTimestampFormat':
316+
case 'onAttachmentDownload':
316317
this._invalidate();
317318
break;
318319
default:

packages/devextreme/js/__internal/ui/chat/messagelist.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ class MessageList extends Widget<Properties> {
837837
case 'emptyViewTemplate':
838838
case 'dayHeaderFormat':
839839
case 'messageTimestampFormat':
840+
case 'onAttachmentDownload':
840841
this._invalidate();
841842
break;
842843
case 'items':

packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.tests.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,12 @@ QUnit.module('Chat', () => {
22922292

22932293
assert.strictEqual(onAttachmentDownload.callCount, 1);
22942294
});
2295+
2296+
QUnit.test('should hide download button if not passed', function(assert) {
2297+
this.instance.option({ onAttachmentDownload: undefined, dataSource: this.dataSourceWithAttachments });
2298+
2299+
assert.strictEqual(this.getDownloadButton().length, 0, 'button is hidden');
2300+
});
22952301
});
22962302
});
22972303

packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/file.markup.tests.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ QUnit.module('File', moduleConfig, () => {
6565
});
6666

6767
QUnit.test('download button should be rendered', function(assert) {
68+
this.reinit({ onDownload: () => {} });
6869
const $button = this.$element.find(`.${CHAT_FILE_DOWNLOAD_BUTTON_CLASS}`);
6970

7071
assert.strictEqual($button.length, 1, 'download button exists');
@@ -146,4 +147,24 @@ QUnit.module('File', moduleConfig, () => {
146147
assert.strictEqual($size.text(), '10 KB', 'size is updated');
147148
});
148149
});
150+
151+
QUnit.module('onDownload option', () => {
152+
QUnit.test('download button should not be rendered if onDownload is undefined', function(assert) {
153+
const $button = this.$element.find(`.${CHAT_FILE_DOWNLOAD_BUTTON_CLASS}`);
154+
155+
assert.strictEqual($button.length, 0, 'download button is not rendered');
156+
});
157+
158+
QUnit.test('should re-render button on onDownload runtime changes', function(assert) {
159+
let $button = this.$element.find(`.${CHAT_FILE_DOWNLOAD_BUTTON_CLASS}`);
160+
161+
assert.strictEqual($button.length, 0, 'download button is not rendered initially');
162+
163+
this.instance.option('onDownload', () => {});
164+
165+
$button = this.$element.find(`.${CHAT_FILE_DOWNLOAD_BUTTON_CLASS}`);
166+
167+
assert.strictEqual($button.length, 1, 'download button is rendered');
168+
});
169+
});
149170
});

packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/file.tests.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@ const moduleConfig = {
1717
name: 'test-file.txt',
1818
size: 1024,
1919
},
20+
onDownload: () => {},
2021
...options,
2122
};
2223

2324
this.instance = new File($('#component'), defaultOptions);
2425
this.$element = $(this.instance.$element());
2526

2627
const $buttons = this.$element.find(`.${BUTTON_CLASS}`);
27-
this.$downloadButton = $($buttons[0]);
28-
this.downloadButton = Button.getInstance(this.$downloadButton);
28+
29+
if($buttons.length) {
30+
this.$downloadButton = $($buttons[0]);
31+
this.downloadButton = Button.getInstance(this.$downloadButton);
32+
}
2933
};
3034

3135
this.reinit = (options) => {
@@ -55,7 +59,7 @@ QUnit.module('File', moduleConfig, () => {
5559
});
5660

5761
QUnit.test('should have correct default options', function(assert) {
58-
this.reinit({ data: {} });
62+
this.reinit({ data: {}, onDownload: undefined });
5963

6064
const expectedData = {
6165
name: '',

packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/fileView.tests.js

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ const moduleConfig = {
1818
this.instance = new FileView($('#component'), defaultOptions);
1919
this.$element = $(this.instance.$element());
2020

21-
const $buttons = this.$element.find(`.${BUTTON_CLASS}`);
22-
this.$downloadButton = $($buttons[0]);
21+
const getButtons = () => this.$element.find(`.${BUTTON_CLASS}`);
22+
this.$downloadButton = () => $(getButtons()[0]);
2323
};
2424

2525
this.reinit = (options) => {
@@ -53,48 +53,31 @@ QUnit.module('FileView', moduleConfig, () => {
5353

5454
QUnit.module('onDownload option', () => {
5555
QUnit.test('should pass correct event arguments to onDownload', function(assert) {
56-
assert.expect(4);
56+
assert.expect(3);
5757

5858
this.reinit({
5959
onDownload: (e) => {
60-
assert.ok(e.component instanceof FileView, 'component is correct');
61-
assert.strictEqual(e.element, this.instance.element(), 'element is provided correctly');
60+
assert.ok(e.component instanceof File, 'component is correct');
6261
assert.ok(e.event, 'original event is provided');
6362
assert.strictEqual(typeof e.event, 'object', 'event is an object');
6463
},
6564
});
6665

67-
this.$downloadButton.trigger('dxclick');
68-
});
69-
70-
QUnit.test('should pass correct event arguments to onDownload via on()', function(assert) {
71-
assert.expect(4);
72-
73-
const onDownload = (e) => {
74-
assert.ok(e.component instanceof FileView, 'component is correct');
75-
assert.strictEqual(e.element, this.instance.element(), 'element is provided correctly');
76-
assert.ok(e.event, 'original event is provided');
77-
assert.strictEqual(typeof e.event, 'object', 'event is an object');
78-
};
79-
80-
this.instance.on('download', onDownload);
81-
82-
this.$downloadButton.trigger('dxclick');
66+
this.$downloadButton().trigger('dxclick');
8367
});
8468

8569
QUnit.test('should set onDownload via option()', function(assert) {
86-
assert.expect(4);
70+
assert.expect(3);
8771

8872
const onDownload = (e) => {
89-
assert.ok(e.component instanceof FileView, 'component is correct');
90-
assert.strictEqual(e.element, this.instance.element(), 'element is provided correctly');
73+
assert.ok(e.component instanceof File, 'component is correct');
9174
assert.ok(e.event, 'original event is provided');
9275
assert.strictEqual(typeof e.event, 'object', 'event is an object');
9376
};
9477

9578
this.instance.option('onDownload', onDownload);
9679

97-
this.$downloadButton.trigger('dxclick');
80+
this.$downloadButton().trigger('dxclick');
9881
});
9982
});
10083

0 commit comments

Comments
 (0)