1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
import $ from 'jquery';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
export default class TemplateSelector {
constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) {
this.pattern = pattern;
this.editor = editor;
this.dropdown = dropdown;
this.$dropdownContainer = wrapper;
this.$filenameInput = $input || $('#file_name');
this.dropdownIcon = dropdown[0].querySelector('.dropdown-menu-toggle-icon');
this.loadingIcon = loadingIconForLegacyJS({ classes: ['gl-display-none'] });
this.dropdownIcon.parentNode.insertBefore(this.loadingIcon, this.dropdownIcon.nextSibling);
this.initDropdown(dropdown, data);
this.listenForFilenameInput();
this.renderMatchedDropdown();
this.initAutosizeUpdateEvent();
}
initDropdown(dropdown, data) {
return initDeprecatedJQueryDropdown($(dropdown), {
data,
filterable: true,
selectable: true,
toggleLabel: (item) => item.name,
search: {
fields: ['name'],
},
clicked: (options) => this.onDropdownClicked(options),
text: (item) => item.name,
});
}
// Subclasses can override this method to conditionally prevent fetching file templates
onDropdownClicked(options) {
this.fetchFileTemplate(options);
}
initAutosizeUpdateEvent() {
this.autosizeUpdateEvent = document.createEvent('Event');
this.autosizeUpdateEvent.initEvent('autosize:update', true, false);
}
listenForFilenameInput() {
return this.$filenameInput.on('keyup blur', (e) => this.renderMatchedDropdown(e));
}
renderMatchedDropdown() {
if (!this.$filenameInput.length) {
return null;
}
const filenameMatches = this.pattern.test(this.$filenameInput.val().trim());
if (!filenameMatches) {
return this.$dropdownContainer.addClass('hidden');
}
return this.$dropdownContainer.removeClass('hidden');
}
fetchFileTemplate(options) {
const { e } = options;
const item = options.selectedObj;
e.preventDefault();
return this.requestFile(item);
}
// eslint-disable-next-line class-methods-use-this
requestFile() {
// This `requestFile` method is an abstract method that should
// be added by all subclasses.
}
setEditorContent(file, { skipFocus } = {}) {
if (!file) return;
let newValue = file.content;
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('issue[description]')) {
newValue += `\n${urlParams.get('issue[description]')}`;
}
this.editor.setValue(newValue, 1);
if (!skipFocus) this.editor.focus();
if (this.editor instanceof $) {
this.editor.get(0).dispatchEvent(this.autosizeUpdateEvent);
this.editor.trigger('input');
}
}
getEditorContent() {
return this.editor.getValue();
}
startLoadingSpinner() {
this.loadingIcon.classList.remove('gl-display-none');
this.dropdownIcon.classList.add('gl-display-none');
}
stopLoadingSpinner() {
this.loadingIcon.classList.add('gl-display-none');
this.dropdownIcon.classList.remove('gl-display-none');
}
}
|