fa2af5e0f5
Reduced the technical debt around our JS flash function by making it a module that is imported rather than relying on the global function. The global function still exists mainly for technical debt with how some requests are being completed, but new JS should import the module directly. Also reduces some tech debt in the file by removing the need for jQuery. Instead Flash is now 100% vanilla JS.
244 lines
6.2 KiB
JavaScript
244 lines
6.2 KiB
JavaScript
/* eslint-disable class-methods-use-this */
|
|
import Flash from '../flash';
|
|
import FileTemplateTypeSelector from './template_selectors/type_selector';
|
|
import BlobCiYamlSelector from './template_selectors/ci_yaml_selector';
|
|
import DockerfileSelector from './template_selectors/dockerfile_selector';
|
|
import GitignoreSelector from './template_selectors/gitignore_selector';
|
|
import LicenseSelector from './template_selectors/license_selector';
|
|
|
|
export default class FileTemplateMediator {
|
|
constructor({ editor, currentAction }) {
|
|
this.editor = editor;
|
|
this.currentAction = currentAction;
|
|
|
|
this.initTemplateSelectors();
|
|
this.initTemplateTypeSelector();
|
|
this.initDomElements();
|
|
this.initDropdowns();
|
|
this.initPageEvents();
|
|
}
|
|
|
|
initTemplateSelectors() {
|
|
// Order dictates template type dropdown item order
|
|
this.templateSelectors = [
|
|
GitignoreSelector,
|
|
BlobCiYamlSelector,
|
|
DockerfileSelector,
|
|
LicenseSelector,
|
|
].map(TemplateSelectorClass => new TemplateSelectorClass({ mediator: this }));
|
|
}
|
|
|
|
initTemplateTypeSelector() {
|
|
this.typeSelector = new FileTemplateTypeSelector({
|
|
mediator: this,
|
|
dropdownData: this.templateSelectors
|
|
.map((templateSelector) => {
|
|
const cfg = templateSelector.config;
|
|
|
|
return {
|
|
name: cfg.name,
|
|
key: cfg.key,
|
|
};
|
|
}),
|
|
});
|
|
}
|
|
|
|
initDomElements() {
|
|
const $templatesMenu = $('.template-selectors-menu');
|
|
const $undoMenu = $templatesMenu.find('.template-selectors-undo-menu');
|
|
const $fileEditor = $('.file-editor');
|
|
|
|
this.$templatesMenu = $templatesMenu;
|
|
this.$undoMenu = $undoMenu;
|
|
this.$undoBtn = $undoMenu.find('button');
|
|
this.$templateSelectors = $templatesMenu.find('.template-selector-dropdowns-wrap');
|
|
this.$filenameInput = $fileEditor.find('.js-file-path-name-input');
|
|
this.$fileContent = $fileEditor.find('#file-content');
|
|
this.$commitForm = $fileEditor.find('form');
|
|
this.$navLinks = $fileEditor.find('.nav-links');
|
|
}
|
|
|
|
initDropdowns() {
|
|
if (this.currentAction === 'create') {
|
|
this.typeSelector.show();
|
|
} else {
|
|
this.hideTemplateSelectorMenu();
|
|
}
|
|
|
|
this.displayMatchedTemplateSelector();
|
|
}
|
|
|
|
initPageEvents() {
|
|
this.listenForFilenameInput();
|
|
this.prepFileContentForSubmit();
|
|
this.listenForPreviewMode();
|
|
}
|
|
|
|
listenForFilenameInput() {
|
|
this.$filenameInput.on('keyup blur', () => {
|
|
this.displayMatchedTemplateSelector();
|
|
});
|
|
}
|
|
|
|
prepFileContentForSubmit() {
|
|
this.$commitForm.submit(() => {
|
|
this.$fileContent.val(this.editor.getValue());
|
|
});
|
|
}
|
|
|
|
listenForPreviewMode() {
|
|
this.$navLinks.on('click', 'a', (e) => {
|
|
const urlPieces = e.target.href.split('#');
|
|
const hash = urlPieces[1];
|
|
if (hash === 'preview') {
|
|
this.hideTemplateSelectorMenu();
|
|
} else if (hash === 'editor') {
|
|
this.showTemplateSelectorMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
selectTemplateType(item, e) {
|
|
if (e) {
|
|
e.preventDefault();
|
|
}
|
|
|
|
this.templateSelectors.forEach((selector) => {
|
|
if (selector.config.key === item.key) {
|
|
selector.show();
|
|
} else {
|
|
selector.hide();
|
|
}
|
|
});
|
|
|
|
this.typeSelector.setToggleText(item.name);
|
|
|
|
this.cacheToggleText();
|
|
}
|
|
|
|
selectTemplateTypeOptions(options) {
|
|
this.selectTemplateType(options.selectedObj, options.e);
|
|
}
|
|
|
|
selectTemplateFile(selector, query, data) {
|
|
selector.renderLoading();
|
|
// in case undo menu is already already there
|
|
this.destroyUndoMenu();
|
|
this.fetchFileTemplate(selector.config.endpoint, query, data)
|
|
.then((file) => {
|
|
this.showUndoMenu();
|
|
this.setEditorContent(file);
|
|
this.setFilename(selector.config.name);
|
|
selector.renderLoaded();
|
|
})
|
|
.catch(err => new Flash(`An error occurred while fetching the template: ${err}`));
|
|
}
|
|
|
|
displayMatchedTemplateSelector() {
|
|
const currentInput = this.getFilename();
|
|
this.templateSelectors.forEach((selector) => {
|
|
const match = selector.config.pattern.test(currentInput);
|
|
|
|
if (match) {
|
|
this.typeSelector.show();
|
|
this.selectTemplateType(selector.config);
|
|
this.showTemplateSelectorMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
fetchFileTemplate(apiCall, query, data) {
|
|
return new Promise((resolve) => {
|
|
const resolveFile = file => resolve(file);
|
|
|
|
if (!data) {
|
|
apiCall(query, resolveFile);
|
|
} else {
|
|
apiCall(query, data, resolveFile);
|
|
}
|
|
});
|
|
}
|
|
|
|
setEditorContent(file) {
|
|
if (!file && file !== '') return;
|
|
|
|
const newValue = file.content || file;
|
|
|
|
this.editor.setValue(newValue, 1);
|
|
|
|
this.editor.focus();
|
|
|
|
this.editor.navigateFileStart();
|
|
}
|
|
|
|
findTemplateSelectorByKey(key) {
|
|
return this.templateSelectors.find(selector => selector.config.key === key);
|
|
}
|
|
|
|
showUndoMenu() {
|
|
this.$undoMenu.removeClass('hidden');
|
|
|
|
this.$undoBtn.on('click', () => {
|
|
this.restoreFromCache();
|
|
this.destroyUndoMenu();
|
|
});
|
|
}
|
|
|
|
destroyUndoMenu() {
|
|
this.cacheFileContents();
|
|
this.cacheToggleText();
|
|
this.$undoMenu.addClass('hidden');
|
|
this.$undoBtn.off('click');
|
|
}
|
|
|
|
hideTemplateSelectorMenu() {
|
|
this.$templatesMenu.hide();
|
|
}
|
|
|
|
showTemplateSelectorMenu() {
|
|
this.$templatesMenu.show();
|
|
}
|
|
|
|
cacheToggleText() {
|
|
this.cachedToggleText = this.getTemplateSelectorToggleText();
|
|
}
|
|
|
|
cacheFileContents() {
|
|
this.cachedContent = this.editor.getValue();
|
|
this.cachedFilename = this.getFilename();
|
|
}
|
|
|
|
restoreFromCache() {
|
|
this.setEditorContent(this.cachedContent);
|
|
this.setFilename(this.cachedFilename);
|
|
this.setTemplateSelectorToggleText();
|
|
}
|
|
|
|
getTemplateSelectorToggleText() {
|
|
return this.$templateSelectors
|
|
.find('.js-template-selector-wrap:visible .dropdown-toggle-text')
|
|
.text();
|
|
}
|
|
|
|
setTemplateSelectorToggleText() {
|
|
return this.$templateSelectors
|
|
.find('.js-template-selector-wrap:visible .dropdown-toggle-text')
|
|
.text(this.cachedToggleText);
|
|
}
|
|
|
|
getTypeSelectorToggleText() {
|
|
return this.typeSelector.getToggleText();
|
|
}
|
|
|
|
getFilename() {
|
|
return this.$filenameInput.val();
|
|
}
|
|
|
|
setFilename(name) {
|
|
this.$filenameInput.val(name);
|
|
}
|
|
|
|
getSelected() {
|
|
return this.templateSelectors.find(selector => selector.selected);
|
|
}
|
|
}
|