diff options
author | Phil Hughes <me@iamphill.com> | 2018-08-16 12:41:21 +0100 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-09-07 08:23:59 +0100 |
commit | 843467b8c4be9ff1658d18d606f7fd5b149cbec9 (patch) | |
tree | 772ffb9f84b2b530963aa103212769760c999be9 | |
parent | c380d3acebd181f13629a25d2e2acca46ffe1e00 (diff) | |
download | gitlab-ce-843467b8c4be9ff1658d18d606f7fd5b149cbec9.tar.gz |
Added file templates to the Web IDE
Closes #47947
-rw-r--r-- | app/assets/javascripts/ide/components/file_templates/bar.vue | 90 | ||||
-rw-r--r-- | app/assets/javascripts/ide/components/file_templates/dropdown.vue | 120 | ||||
-rw-r--r-- | app/assets/javascripts/ide/components/repo_editor.vue | 8 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/index.js | 2 | ||||
-rw-r--r-- | changelogs/unreleased/ide-file-templates.yml | 5 | ||||
-rw-r--r-- | locale/gitlab.pot | 15 |
6 files changed, 239 insertions, 1 deletions
diff --git a/app/assets/javascripts/ide/components/file_templates/bar.vue b/app/assets/javascripts/ide/components/file_templates/bar.vue new file mode 100644 index 00000000000..8344b5440e9 --- /dev/null +++ b/app/assets/javascripts/ide/components/file_templates/bar.vue @@ -0,0 +1,90 @@ +<script> +import { mapActions, mapGetters, mapState } from 'vuex'; +import Dropdown from './dropdown.vue'; + +export default { + components: { + Dropdown, + }, + computed: { + ...mapGetters(['activeFile']), + ...mapGetters('fileTemplates', ['templateTypes']), + ...mapState('fileTemplates', ['selectedTemplateType', 'updateSuccess']), + showTemplatesDropdown() { + return Object.keys(this.selectedTemplateType).length > 0; + }, + }, + watch: { + activeFile: { + handler: 'setInitialType', + }, + }, + mounted() { + this.setInitialType(); + }, + methods: { + ...mapActions('fileTemplates', ['setTemplateType', 'fetchTemplate']), + setInitialType() { + const type = this.templateTypes.find(t => t.name === this.activeFile.name); + + if (type) { + this.setTemplateType(type); + } + }, + selectTemplateType(type) { + this.setTemplateType(type); + }, + selecteTemplate(template) { + this.fetchTemplate(template); + }, + }, +}; +</script> + +<template> + <div class="d-flex align-items-center ide-file-templates"> + <strong class="mr-2"> + {{ __('File templates') }} + </strong> + <dropdown + :data="templateTypes" + :label="selectedTemplateType.name || __('Choose a type...')" + class="mr-2" + @click="selectTemplateType" + /> + <dropdown + v-if="showTemplatesDropdown" + :label="__('Choose a type...')" + :async="true" + :searchable="true" + :title="__('File templates')" + class="mr-2" + @click="selecteTemplate" + /> + <transition name="fade"> + <div v-show="updateSuccess"> + <strong class="text-success mr-2"> + {{ __('Template applied') }} + </strong> + <button + type="button" + class="btn btn-default" + > + {{ __('Undo') }} + </button> + </div> + </transition> + </div> +</template> + +<style> +.ide-file-templates { + padding: 8px 16px; + background-color: #fafafa; + border-bottom: 1px solid #eaeaea; +} + +.ide-file-templates .dropdown { + min-width: 180px; +} +</style> diff --git a/app/assets/javascripts/ide/components/file_templates/dropdown.vue b/app/assets/javascripts/ide/components/file_templates/dropdown.vue new file mode 100644 index 00000000000..914022d8764 --- /dev/null +++ b/app/assets/javascripts/ide/components/file_templates/dropdown.vue @@ -0,0 +1,120 @@ +<script> +import $ from 'jquery'; +import { mapActions, mapState } from 'vuex'; +import LoadingIcon from '~/vue_shared/components/loading_icon.vue'; +import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; + +export default { + components: { + DropdownButton, + LoadingIcon, + }, + props: { + data: { + type: Array, + required: false, + default: () => [], + }, + label: { + type: String, + required: true, + }, + title: { + type: String, + required: false, + default: null, + }, + async: { + type: Boolean, + required: false, + default: false, + }, + searchable: { + type: Boolean, + required: false, + default: false, + }, + }, + data() { + return { + search: '', + }; + }, + computed: { + ...mapState('fileTemplates', ['templates', 'isLoading']), + outputData() { + return (this.async ? this.templates : this.data).filter(t => { + if (!this.searchable) return true; + + return t.name.toLowerCase().indexOf(this.search.toLowerCase()) >= 0; + }); + }, + showLoading() { + return this.async ? this.isLoading : false; + }, + }, + mounted() { + $(this.$el).on('show.bs.dropdown', this.fetchTemplatesIfAsync); + }, + beforeDestroy() { + $(this.$el).off('show.bs.dropdown', this.fetchTemplatesIfAsync); + }, + methods: { + ...mapActions('fileTemplates', ['fetchTemplateTypes']), + fetchTemplatesIfAsync() { + if (this.async) { + this.fetchTemplateTypes(); + } + }, + clickItem(item) { + this.$emit('click', item); + }, + }, +}; +</script> + +<template> + <div class="dropdown"> + <dropdown-button + :toggle-text="label" + /> + <div class="dropdown-menu"> + <div + v-if="title" + class="dropdown-title" + > + {{ title }} + </div> + <div + v-if="!showLoading && searchable" + class="dropdown-input" + > + <input + v-model="search" + :placeholder="__('Filter...')" + type="search" + class="dropdown-input-field" + /> + </div> + <div class="dropdown-content"> + <loading-icon + v-if="showLoading" + size="2" + /> + <ul v-else> + <li + v-for="(item, index) in outputData" + :key="index" + > + <button + type="button" + @click="clickItem(item)" + > + {{ item.name }} + </button> + </li> + </ul> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue index f55aa843444..d3a73e84cc7 100644 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -6,12 +6,14 @@ import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue'; import { activityBarViews, viewerTypes } from '../constants'; import Editor from '../lib/editor'; import ExternalLink from './external_link.vue'; +import FileTemplatesBar from './file_templates/bar.vue'; export default { components: { ContentViewer, DiffViewer, ExternalLink, + FileTemplatesBar, }, props: { file: { @@ -34,6 +36,7 @@ export default { 'isCommitModeActive', 'isReviewModeActive', ]), + ...mapGetters('fileTemplates', ['showFileTemplatesBar']), shouldHideEditor() { return this.file && this.file.binary && !this.file.content; }, @@ -216,7 +219,7 @@ export default { id="ide" class="blob-viewer-container blob-editor-container" > - <div class="ide-mode-tabs clearfix" > + <div class="ide-mode-tabs clearfix"> <ul v-if="!shouldHideEditor && isEditModeActive" class="nav-links float-left" @@ -249,6 +252,9 @@ export default { :file="file" /> </div> + <file-templates-bar + v-if="showFileTemplatesBar(file.name)" + /> <div v-show="!shouldHideEditor && file.viewMode ==='editor'" ref="editor" diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js index a601dc8f5a0..3af39ce62fd 100644 --- a/app/assets/javascripts/ide/stores/index.js +++ b/app/assets/javascripts/ide/stores/index.js @@ -8,6 +8,7 @@ import commitModule from './modules/commit'; import pipelines from './modules/pipelines'; import mergeRequests from './modules/merge_requests'; import branches from './modules/branches'; +import fileTemplates from './modules/file_templates'; Vue.use(Vuex); @@ -22,6 +23,7 @@ export const createStore = () => pipelines, mergeRequests, branches, + fileTemplates, }, }); diff --git a/changelogs/unreleased/ide-file-templates.yml b/changelogs/unreleased/ide-file-templates.yml new file mode 100644 index 00000000000..68983670b25 --- /dev/null +++ b/changelogs/unreleased/ide-file-templates.yml @@ -0,0 +1,5 @@ +--- +title: Added file templates to the Web IDE +merge_request: +author: +type: added diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 0e89c19066e..f197ee94e7e 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1167,6 +1167,9 @@ msgstr "" msgid "Choose a branch/tag (e.g. %{master}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request." msgstr "" +msgid "Choose a type..." +msgstr "" + msgid "Choose any color." msgstr "" @@ -2691,6 +2694,9 @@ msgstr "" msgid "Fields on this page are now uneditable, you can configure" msgstr "" +msgid "File templates" +msgstr "" + msgid "Files" msgstr "" @@ -2703,6 +2709,9 @@ msgstr "" msgid "Filter by commit message" msgstr "" +msgid "Filter..." +msgstr "" + msgid "Find by path" msgstr "" @@ -5595,6 +5604,9 @@ msgstr "" msgid "Template" msgstr "" +msgid "Template applied" +msgstr "" + msgid "Terms of Service Agreement and Privacy Policy" msgstr "" @@ -6175,6 +6187,9 @@ msgstr "" msgid "Unable to load the diff. %{button_try_again}" msgstr "" +msgid "Undo" +msgstr "" + msgid "Unlock" msgstr "" |