247 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/* eslint-disable class-methods-use-this */
 | 
						|
 | 
						|
import $ from 'jquery';
 | 
						|
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).trigger('change');
 | 
						|
  }
 | 
						|
 | 
						|
  getSelected() {
 | 
						|
    return this.templateSelectors.find(selector => selector.selected);
 | 
						|
  }
 | 
						|
}
 |