Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
commit7e9c479f7de77702622631cff2628a9c8dcbc627 (patch)
treec8f718a08e110ad7e1894510980d2155a6549197 /app/assets/javascripts/ide
parente852b0ae16db4052c1c567d9efa4facc81146e88 (diff)
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/ide')
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/form.vue26
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list.vue12
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue103
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list_item.vue7
-rw-r--r--app/assets/javascripts/ide/components/file_row_extra.vue7
-rw-r--r--app/assets/javascripts/ide/components/ide.vue74
-rw-r--r--app/assets/javascripts/ide/components/ide_side_bar.vue10
-rw-r--r--app/assets/javascripts/ide/components/ide_status_list.vue7
-rw-r--r--app/assets/javascripts/ide/components/ide_tree.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue11
-rw-r--r--app/assets/javascripts/ide/components/jobs/detail.vue9
-rw-r--r--app/assets/javascripts/ide/components/jobs/item.vue6
-rw-r--r--app/assets/javascripts/ide/components/mr_file_icon.vue7
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/button.vue7
-rw-r--r--app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue4
-rw-r--r--app/assets/javascripts/ide/components/pipelines/list.vue36
-rw-r--r--app/assets/javascripts/ide/components/repo_commit_section.vue5
-rw-r--r--app/assets/javascripts/ide/components/repo_editor.vue45
-rw-r--r--app/assets/javascripts/ide/components/repo_file_status_icon.vue7
-rw-r--r--app/assets/javascripts/ide/components/repo_tab.vue4
-rw-r--r--app/assets/javascripts/ide/components/terminal/empty_state.vue22
-rw-r--r--app/assets/javascripts/ide/stores/actions.js4
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js24
-rw-r--r--app/assets/javascripts/ide/stores/index.js11
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/getters.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/actions.js19
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/getters.js13
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/index.js12
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/mutation_types.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/mutations.js25
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/setup.js19
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/state.js8
-rw-r--r--app/assets/javascripts/ide/stores/modules/editor/utils.js11
-rw-r--r--app/assets/javascripts/ide/stores/mutation_types.js3
-rw-r--r--app/assets/javascripts/ide/stores/mutations/file.js16
-rw-r--r--app/assets/javascripts/ide/stores/utils.js6
-rw-r--r--app/assets/javascripts/ide/utils.js2
37 files changed, 298 insertions, 291 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
index f36fe87ccfa..9d2deb1d4d0 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
@@ -1,8 +1,7 @@
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
-import { GlModal, GlSafeHtmlDirective } from '@gitlab/ui';
+import { GlModal, GlSafeHtmlDirective, GlButton } from '@gitlab/ui';
import { n__, __ } from '~/locale';
-import LoadingButton from '~/vue_shared/components/loading_button.vue';
import CommitMessageField from './message_field.vue';
import Actions from './actions.vue';
import SuccessMessage from './success_message.vue';
@@ -12,10 +11,10 @@ import { createUnexpectedCommitError } from '../../lib/errors';
export default {
components: {
Actions,
- LoadingButton,
CommitMessageField,
SuccessMessage,
GlModal,
+ GlButton,
},
directives: {
SafeHtml: GlSafeHtmlDirective,
@@ -156,12 +155,16 @@ export default {
/>
<div class="clearfix gl-mt-5">
<actions />
- <loading-button
+ <gl-button
:loading="submitCommitLoading"
- :label="commitButtonText"
- container-class="btn btn-success btn-sm float-left qa-commit-button"
+ class="float-left qa-commit-button"
+ size="small"
+ category="primary"
+ variant="success"
@click="commit"
- />
+ >
+ {{ __('Commit') }}
+ </gl-button>
<button
v-if="!discardDraftButtonDisabled"
type="button"
@@ -170,14 +173,17 @@ export default {
>
{{ __('Discard draft') }}
</button>
- <button
+ <gl-button
v-else
type="button"
- class="btn btn-default btn-sm float-right"
+ class="float-right"
+ category="secondary"
+ variant="default"
+ size="small"
@click="toggleIsCompact"
>
{{ __('Collapse') }}
- </button>
+ </gl-button>
</div>
<gl-modal
ref="commitErrorModal"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
index 609ce287d3f..729ff7c74ec 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
@@ -1,8 +1,7 @@
<script>
import { mapActions } from 'vuex';
-import { GlModal, GlIcon } from '@gitlab/ui';
+import { GlModal, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
import ListItem from './list_item.vue';
export default {
@@ -12,17 +11,13 @@ export default {
GlModal,
},
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
props: {
fileList: {
type: Array,
required: true,
},
- iconName: {
- type: String,
- required: true,
- },
stagedList: {
type: Boolean,
required: false,
@@ -73,12 +68,11 @@ export default {
<div class="ide-commit-list-container">
<header class="multi-file-commit-panel-header d-flex mb-0">
<div class="d-flex align-items-center flex-fill">
- <gl-icon v-once :name="iconName" :size="18" class="gl-mr-3" />
<strong> {{ titleText }} </strong>
<div class="d-flex ml-auto">
<button
v-if="!stagedList"
- v-tooltip
+ v-gl-tooltip
:title="__('Discard all changes')"
:aria-label="__('Discard all changes')"
:disabled="!filesLength"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue
deleted file mode 100644
index 4821b8389ff..00000000000
--- a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script>
-import { GlIcon } from '@gitlab/ui';
-import tooltip from '~/vue_shared/directives/tooltip';
-import { sprintf, n__, __ } from '~/locale';
-
-export default {
- components: {
- GlIcon,
- },
- directives: {
- tooltip,
- },
- props: {
- files: {
- type: Array,
- required: true,
- },
- iconName: {
- type: String,
- required: true,
- },
- title: {
- type: String,
- required: true,
- },
- },
- computed: {
- addedFilesLength() {
- return this.files.filter(f => f.tempFile).length;
- },
- modifiedFilesLength() {
- return this.files.filter(f => !f.tempFile).length;
- },
- addedFilesIconClass() {
- return this.addedFilesLength ? 'multi-file-addition' : '';
- },
- modifiedFilesClass() {
- return this.modifiedFilesLength ? 'multi-file-modified' : '';
- },
- additionsTooltip() {
- return sprintf(
- n__('1 %{type} addition', '%{count} %{type} additions', this.addedFilesLength),
- {
- type: this.title.toLowerCase(),
- count: this.addedFilesLength,
- },
- );
- },
- modifiedTooltip() {
- return sprintf(
- n__('1 %{type} modification', '%{count} %{type} modifications', this.modifiedFilesLength),
- {
- type: this.title.toLowerCase(),
- count: this.modifiedFilesLength,
- },
- );
- },
- titleTooltip() {
- return sprintf(__('%{title} changes'), { title: this.title });
- },
- additionIconName() {
- return this.title.toLowerCase() === 'staged' ? 'file-addition-solid' : 'file-addition';
- },
- modifiedIconName() {
- return this.title.toLowerCase() === 'staged' ? 'file-modified-solid' : 'file-modified';
- },
- },
-};
-</script>
-
-<template>
- <div class="multi-file-commit-list-collapsed text-center">
- <div
- v-tooltip
- :title="titleTooltip"
- data-container="body"
- data-placement="left"
- class="gl-mb-5"
- >
- <gl-icon v-once :name="iconName" :size="18" />
- </div>
- <div
- v-tooltip
- :title="additionsTooltip"
- data-container="body"
- data-placement="left"
- class="gl-mb-3"
- >
- <gl-icon :name="additionIconName" :size="18" :class="addedFilesIconClass" />
- </div>
- {{ addedFilesLength }}
- <div
- v-tooltip
- :title="modifiedTooltip"
- data-container="body"
- data-placement="left"
- class="gl-mt-3 gl-mb-3"
- >
- <gl-icon :name="modifiedIconName" :size="18" :class="modifiedFilesClass" />
- </div>
- {{ modifiedFilesLength }}
- </div>
-</template>
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
index a0d6cf3c42d..123e0aba959 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
@@ -1,7 +1,6 @@
<script>
import { mapActions } from 'vuex';
-import { GlIcon } from '@gitlab/ui';
-import tooltip from '~/vue_shared/directives/tooltip';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import { viewerTypes } from '../../constants';
import getCommitIconMap from '../../commit_icon';
@@ -12,7 +11,7 @@ export default {
FileIcon,
},
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
props: {
file: {
@@ -77,7 +76,7 @@ export default {
<template>
<div class="multi-file-commit-list-item position-relative">
<div
- v-tooltip
+ v-gl-tooltip
:title="tooltipTitle"
:class="{
'is-active': isActive,
diff --git a/app/assets/javascripts/ide/components/file_row_extra.vue b/app/assets/javascripts/ide/components/file_row_extra.vue
index 48ab58e1cb7..fb0d00dc6a1 100644
--- a/app/assets/javascripts/ide/components/file_row_extra.vue
+++ b/app/assets/javascripts/ide/components/file_row_extra.vue
@@ -1,8 +1,7 @@
<script>
import { mapGetters } from 'vuex';
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { n__ } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
import NewDropdown from './new_dropdown/index.vue';
import MrFileIcon from './mr_file_icon.vue';
@@ -10,7 +9,7 @@ import MrFileIcon from './mr_file_icon.vue';
export default {
name: 'FileRowExtra',
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
components: {
GlIcon,
@@ -70,7 +69,7 @@ export default {
<span v-if="showTreeChangesCount" class="ide-tree-changes">
{{ changesCount }}
<gl-icon
- v-tooltip
+ v-gl-tooltip.left.viewport
:title="folderChangesTooltip"
:size="12"
data-container="body"
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index 8f23856fd6c..e1d2895831a 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -1,6 +1,5 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import {
WEBIDE_MARK_APP_START,
@@ -10,19 +9,12 @@ import {
WEBIDE_MEASURE_TREE_FROM_REQUEST,
WEBIDE_MEASURE_FILE_FROM_REQUEST,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
-} from '~/performance_constants';
-import { performanceMarkAndMeasure } from '~/performance_utils';
+} from '~/performance/constants';
+import { performanceMarkAndMeasure } from '~/performance/utils';
import { modalTypes } from '../constants';
import eventHub from '../eventhub';
-import FindFile from '~/vue_shared/components/file_finder/index.vue';
-import NewModal from './new_dropdown/modal.vue';
import IdeSidebar from './ide_side_bar.vue';
-import RepoTabs from './repo_tabs.vue';
-import IdeStatusBar from './ide_status_bar.vue';
import RepoEditor from './repo_editor.vue';
-import RightPane from './panes/right.vue';
-import ErrorMessage from './error_message.vue';
-import CommitEditorHeader from './commit_sidebar/editor_header.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { measurePerformance } from '../utils';
@@ -43,19 +35,24 @@ eventHub.$on(WEBIDE_MEASURE_FILE_AFTER_INTERACTION, () =>
export default {
components: {
- NewModal,
IdeSidebar,
- RepoTabs,
- IdeStatusBar,
RepoEditor,
- FindFile,
- ErrorMessage,
- CommitEditorHeader,
- GlButton,
- GlLoadingIcon,
- RightPane,
+ 'error-message': () => import('./error_message.vue'),
+ 'gl-button': () => import('@gitlab/ui/src/components/base/button/button.vue'),
+ 'gl-loading-icon': () => import('@gitlab/ui/src/components/base/loading_icon/loading_icon.vue'),
+ 'commit-editor-header': () => import('./commit_sidebar/editor_header.vue'),
+ 'repo-tabs': () => import('./repo_tabs.vue'),
+ 'ide-status-bar': () => import('./ide_status_bar.vue'),
+ 'find-file': () => import('~/vue_shared/components/file_finder/index.vue'),
+ 'right-pane': () => import('./panes/right.vue'),
+ 'new-modal': () => import('./new_dropdown/modal.vue'),
},
mixins: [glFeatureFlagsMixin()],
+ data() {
+ return {
+ loadDeferred: false,
+ };
+ },
computed: {
...mapState([
'openFiles',
@@ -107,6 +104,9 @@ export default {
createNewFile() {
this.$refs.newModal.open(modalTypes.blob);
},
+ loadDeferredComponents() {
+ this.loadDeferred = true;
+ },
},
};
</script>
@@ -118,19 +118,23 @@ export default {
>
<error-message v-if="errorMessage" :message="errorMessage" />
<div class="ide-view flex-grow d-flex">
- <find-file
- v-show="fileFindVisible"
- :files="allBlobs"
- :visible="fileFindVisible"
- :loading="loading"
- @toggle="toggleFileFinder"
- @click="openFile"
- />
- <ide-sidebar />
+ <template v-if="loadDeferred">
+ <find-file
+ v-show="fileFindVisible"
+ :files="allBlobs"
+ :visible="fileFindVisible"
+ :loading="loading"
+ @toggle="toggleFileFinder"
+ @click="openFile"
+ />
+ </template>
+ <ide-sidebar @tree-ready="loadDeferredComponents" />
<div class="multi-file-edit-pane">
<template v-if="activeFile">
- <commit-editor-header v-if="isCommitModeActive" :active-file="activeFile" />
- <repo-tabs v-else :active-file="activeFile" :files="openFiles" :viewer="viewer" />
+ <template v-if="loadDeferred">
+ <commit-editor-header v-if="isCommitModeActive" :active-file="activeFile" />
+ <repo-tabs v-else :active-file="activeFile" :files="openFiles" :viewer="viewer" />
+ </template>
<repo-editor :file="activeFile" class="multi-file-edit-pane-content" />
</template>
<template v-else>
@@ -177,9 +181,13 @@ export default {
</div>
</template>
</div>
- <right-pane v-if="currentProjectId" />
+ <template v-if="loadDeferred">
+ <right-pane v-if="currentProjectId" />
+ </template>
</div>
- <ide-status-bar />
- <new-modal ref="newModal" />
+ <template v-if="loadDeferred">
+ <ide-status-bar />
+ <new-modal ref="newModal" />
+ </template>
</article>
</template>
diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue
index 53dfc133fc8..99215d6c3f1 100644
--- a/app/assets/javascripts/ide/components/ide_side_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_side_bar.vue
@@ -4,21 +4,19 @@ import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import IdeTree from './ide_tree.vue';
import ResizablePanel from './resizable_panel.vue';
import ActivityBar from './activity_bar.vue';
-import RepoCommitSection from './repo_commit_section.vue';
import CommitForm from './commit_sidebar/form.vue';
-import IdeReview from './ide_review.vue';
import IdeProjectHeader from './ide_project_header.vue';
-import { SIDEBAR_INIT_WIDTH } from '../constants';
+import { SIDEBAR_INIT_WIDTH, leftSidebarViews } from '../constants';
export default {
components: {
GlSkeletonLoading,
ResizablePanel,
ActivityBar,
- RepoCommitSection,
IdeTree,
+ [leftSidebarViews.review.name]: () => import('./ide_review.vue'),
+ [leftSidebarViews.commit.name]: () => import('./repo_commit_section.vue'),
CommitForm,
- IdeReview,
IdeProjectHeader,
},
computed: {
@@ -49,7 +47,7 @@ export default {
<div class="multi-file-commit-panel-inner" data-testid="ide-side-bar-inner">
<div class="multi-file-commit-panel-inner-content">
<keep-alive>
- <component :is="currentActivityView" />
+ <component :is="currentActivityView" @tree-ready="$emit('tree-ready')" />
</keep-alive>
</div>
<commit-form />
diff --git a/app/assets/javascripts/ide/components/ide_status_list.vue b/app/assets/javascripts/ide/components/ide_status_list.vue
index caa122f6ed2..aa61c0d9b5e 100644
--- a/app/assets/javascripts/ide/components/ide_status_list.vue
+++ b/app/assets/javascripts/ide/components/ide_status_list.vue
@@ -14,6 +14,7 @@ export default {
},
computed: {
...mapGetters(['activeFile']),
+ ...mapGetters('editor', ['activeFileEditor']),
activeFileEOL() {
return getFileEOL(this.activeFile.content);
},
@@ -33,8 +34,10 @@ export default {
</gl-link>
</div>
<div>{{ activeFileEOL }}</div>
- <div v-if="activeFileIsText">{{ activeFile.editorRow }}:{{ activeFile.editorColumn }}</div>
- <div>{{ activeFile.fileLanguage }}</div>
+ <div v-if="activeFileIsText">
+ {{ activeFileEditor.editorRow }}:{{ activeFileEditor.editorColumn }}
+ </div>
+ <div>{{ activeFileEditor.fileLanguage }}</div>
</template>
<terminal-sync-status-safe />
</div>
diff --git a/app/assets/javascripts/ide/components/ide_tree.vue b/app/assets/javascripts/ide/components/ide_tree.vue
index 56fcb6c2600..e563de6659a 100644
--- a/app/assets/javascripts/ide/components/ide_tree.vue
+++ b/app/assets/javascripts/ide/components/ide_tree.vue
@@ -51,7 +51,7 @@ export default {
</script>
<template>
- <ide-tree-list>
+ <ide-tree-list @tree-ready="$emit('tree-ready')">
<template #header>
{{ __('Edit') }}
<div class="ide-tree-actions ml-auto d-flex" data-testid="ide-root-actions">
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index dd226f07fb0..e7e94f5b5da 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -6,8 +6,8 @@ import {
WEBIDE_MARK_TREE_START,
WEBIDE_MEASURE_TREE_FROM_REQUEST,
WEBIDE_MARK_FILE_CLICKED,
-} from '~/performance_constants';
-import { performanceMarkAndMeasure } from '~/performance_utils';
+} from '~/performance/constants';
+import { performanceMarkAndMeasure } from '~/performance/utils';
import eventHub from '../eventhub';
import IdeFileRow from './ide_file_row.vue';
import NavDropdown from './nav_dropdown.vue';
@@ -32,6 +32,13 @@ export default {
return !this.currentTree || this.currentTree.loading;
},
},
+ watch: {
+ showLoading(newVal) {
+ if (!newVal) {
+ this.$emit('tree-ready');
+ }
+ },
+ },
beforeCreate() {
performanceMarkAndMeasure({ mark: WEBIDE_MARK_TREE_START });
},
diff --git a/app/assets/javascripts/ide/components/jobs/detail.vue b/app/assets/javascripts/ide/components/jobs/detail.vue
index a5ae8bbfe9a..d65304034c2 100644
--- a/app/assets/javascripts/ide/components/jobs/detail.vue
+++ b/app/assets/javascripts/ide/components/jobs/detail.vue
@@ -2,7 +2,7 @@
/* eslint-disable vue/no-v-html */
import { mapActions, mapState } from 'vuex';
import { throttle } from 'lodash';
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlTooltipDirective, GlButton, GlIcon } from '@gitlab/ui';
import { __ } from '../../../locale';
import ScrollButton from './detail/scroll_button.vue';
import JobDescription from './detail/description.vue';
@@ -17,6 +17,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
+ GlButton,
GlIcon,
ScrollButton,
JobDescription,
@@ -75,9 +76,9 @@ export default {
<template>
<div class="ide-pipeline build-page d-flex flex-column flex-fill">
<header class="ide-job-header d-flex align-items-center">
- <button class="btn btn-default btn-sm d-flex" @click="setDetailJob(null)">
- <gl-icon name="chevron-left" /> {{ __('View jobs') }}
- </button>
+ <gl-button category="secondary" icon="chevron-left" size="small" @click="setDetailJob(null)">
+ {{ __('View jobs') }}
+ </gl-button>
</header>
<div class="top-bar d-flex border-left-0 mr-3">
<job-description :job="detailJob" />
diff --git a/app/assets/javascripts/ide/components/jobs/item.vue b/app/assets/javascripts/ide/components/jobs/item.vue
index db3630bc1d1..f84315b63d2 100644
--- a/app/assets/javascripts/ide/components/jobs/item.vue
+++ b/app/assets/javascripts/ide/components/jobs/item.vue
@@ -1,9 +1,11 @@
<script>
+import { GlButton } from '@gitlab/ui';
import JobDescription from './detail/description.vue';
export default {
components: {
JobDescription,
+ GlButton,
},
props: {
job: {
@@ -28,9 +30,9 @@ export default {
<div class="ide-job-item">
<job-description :job="job" class="gl-mr-3" />
<div class="ml-auto align-self-center">
- <button v-if="job.started" type="button" class="btn btn-default btn-sm" @click="clickViewLog">
+ <gl-button v-if="job.started" category="secondary" size="small" @click="clickViewLog">
{{ __('View log') }}
- </button>
+ </gl-button>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/mr_file_icon.vue b/app/assets/javascripts/ide/components/mr_file_icon.vue
index c8629a869e0..af297753c28 100644
--- a/app/assets/javascripts/ide/components/mr_file_icon.vue
+++ b/app/assets/javascripts/ide/components/mr_file_icon.vue
@@ -1,20 +1,19 @@
<script>
-import { GlIcon } from '@gitlab/ui';
-import tooltip from '~/vue_shared/directives/tooltip';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
export default {
components: {
GlIcon,
},
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
};
</script>
<template>
<gl-icon
- v-tooltip
+ v-gl-tooltip
:title="__('Part of merge request changes')"
:size="12"
name="git-merge"
diff --git a/app/assets/javascripts/ide/components/new_dropdown/button.vue b/app/assets/javascripts/ide/components/new_dropdown/button.vue
index 8ae8f97f237..ce80fbee2e0 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/button.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/button.vue
@@ -1,10 +1,9 @@
<script>
-import { GlIcon } from '@gitlab/ui';
-import tooltip from '~/vue_shared/directives/tooltip';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
export default {
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
components: {
GlIcon,
@@ -45,7 +44,7 @@ export default {
<template>
<button
- v-tooltip
+ v-gl-tooltip
:aria-label="label"
:title="tooltipTitle"
type="button"
diff --git a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
index f1b882d8f29..87019c3b2a5 100644
--- a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
+++ b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
@@ -1,13 +1,9 @@
<script>
import { mapActions, mapState } from 'vuex';
-import tooltip from '~/vue_shared/directives/tooltip';
import IdeSidebarNav from '../ide_sidebar_nav.vue';
export default {
name: 'CollapsibleSidebar',
- directives: {
- tooltip,
- },
components: {
IdeSidebarNav,
},
diff --git a/app/assets/javascripts/ide/components/pipelines/list.vue b/app/assets/javascripts/ide/components/pipelines/list.vue
index 91bd64a2c9c..6f15773c9ab 100644
--- a/app/assets/javascripts/ide/components/pipelines/list.vue
+++ b/app/assets/javascripts/ide/components/pipelines/list.vue
@@ -1,11 +1,16 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { escape } from 'lodash';
-import { GlLoadingIcon, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+import {
+ GlLoadingIcon,
+ GlIcon,
+ GlSafeHtmlDirective as SafeHtml,
+ GlTabs,
+ GlTab,
+ GlBadge,
+} from '@gitlab/ui';
import { sprintf, __ } from '../../../locale';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
-import Tabs from '../../../vue_shared/components/tabs/tabs';
-import Tab from '../../../vue_shared/components/tabs/tab.vue';
import EmptyState from '../../../pipelines/components/pipelines_list/empty_state.vue';
import JobsList from '../jobs/list.vue';
@@ -15,11 +20,12 @@ export default {
components: {
GlIcon,
CiIcon,
- Tabs,
- Tab,
JobsList,
EmptyState,
GlLoadingIcon,
+ GlTabs,
+ GlTab,
+ GlBadge,
},
directives: {
SafeHtml,
@@ -88,22 +94,26 @@ export default {
<p class="gl-mb-0 break-word">{{ latestPipeline.yamlError }}</p>
<p v-safe-html="ciLintText" class="gl-mb-0"></p>
</div>
- <tabs v-else class="ide-pipeline-list">
- <tab :active="!pipelineFailed">
+ <gl-tabs v-else>
+ <gl-tab :active="!pipelineFailed">
<template #title>
{{ __('Jobs') }}
- <span v-if="jobsCount" class="badge badge-pill"> {{ jobsCount }} </span>
+ <gl-badge v-if="jobsCount" size="sm" class="gl-tab-counter-badge">{{
+ jobsCount
+ }}</gl-badge>
</template>
<jobs-list :loading="isLoadingJobs" :stages="stages" />
- </tab>
- <tab :active="pipelineFailed">
+ </gl-tab>
+ <gl-tab :active="pipelineFailed">
<template #title>
{{ __('Failed Jobs') }}
- <span v-if="failedJobsCount" class="badge badge-pill"> {{ failedJobsCount }} </span>
+ <gl-badge v-if="failedJobsCount" size="sm" class="gl-tab-counter-badge">{{
+ failedJobsCount
+ }}</gl-badge>
</template>
<jobs-list :loading="isLoadingJobs" :stages="failedStages" />
- </tab>
- </tabs>
+ </gl-tab>
+ </gl-tabs>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue
index 92b99b5c731..dfd25feed08 100644
--- a/app/assets/javascripts/ide/components/repo_commit_section.vue
+++ b/app/assets/javascripts/ide/components/repo_commit_section.vue
@@ -1,6 +1,5 @@
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
-import tooltip from '~/vue_shared/directives/tooltip';
import CommitFilesList from './commit_sidebar/list.vue';
import EmptyState from './commit_sidebar/empty_state.vue';
import { stageKeys } from '../constants';
@@ -10,9 +9,6 @@ export default {
CommitFilesList,
EmptyState,
},
- directives: {
- tooltip,
- },
computed: {
...mapState(['changedFiles', 'stagedFiles', 'lastCommitMsg']),
...mapState('commit', ['commitMessage', 'submitCommitLoading']),
@@ -68,7 +64,6 @@ export default {
:active-file-key="activeFileKey"
:empty-state-text="__('There are no changes')"
class="is-first"
- icon-name="unstaged"
/>
</template>
<empty-state v-else />
diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue
index 56bbb6349cd..c8a825065f1 100644
--- a/app/assets/javascripts/ide/components/repo_editor.vue
+++ b/app/assets/javascripts/ide/components/repo_editor.vue
@@ -9,8 +9,8 @@ import {
WEBIDE_MARK_FILE_START,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
WEBIDE_MEASURE_FILE_FROM_REQUEST,
-} from '~/performance_constants';
-import { performanceMarkAndMeasure } from '~/performance_utils';
+} from '~/performance/constants';
+import { performanceMarkAndMeasure } from '~/performance/utils';
import eventHub from '../eventhub';
import {
leftSidebarViews,
@@ -22,6 +22,7 @@ import Editor from '../lib/editor';
import FileTemplatesBar from './file_templates/bar.vue';
import { __ } from '~/locale';
import { extractMarkdownImagesFromEntries } from '../stores/utils';
+import { getFileEditorOrDefault } from '../stores/modules/editor/utils';
import { getPathParent, readFileAsDataURL, registerSchema, isTextFile } from '../utils';
import { getRulesWithTraversal } from '../lib/editorconfig/parser';
import mapRulesToMonaco from '../lib/editorconfig/rules_mapper';
@@ -49,6 +50,7 @@ export default {
...mapState('rightPane', {
rightPaneIsOpen: 'isOpen',
}),
+ ...mapState('editor', ['fileEditors']),
...mapState([
'viewer',
'panelResizing',
@@ -67,6 +69,9 @@ export default {
'getJsonSchemaForPath',
]),
...mapGetters('fileTemplates', ['showFileTemplatesBar']),
+ fileEditor() {
+ return getFileEditorOrDefault(this.fileEditors, this.file.path);
+ },
shouldHideEditor() {
return this.file && !this.file.loading && !isTextFile(this.file);
},
@@ -80,10 +85,10 @@ export default {
return this.shouldHideEditor && this.file.mrChange && this.viewer === viewerTypes.mr;
},
isEditorViewMode() {
- return this.file.viewMode === FILE_VIEW_MODE_EDITOR;
+ return this.fileEditor.viewMode === FILE_VIEW_MODE_EDITOR;
},
isPreviewViewMode() {
- return this.file.viewMode === FILE_VIEW_MODE_PREVIEW;
+ return this.fileEditor.viewMode === FILE_VIEW_MODE_PREVIEW;
},
editTabCSS() {
return {
@@ -125,8 +130,7 @@ export default {
this.initEditor();
if (this.currentActivityView !== leftSidebarViews.edit.name) {
- this.setFileViewMode({
- file: this.file,
+ this.updateEditor({
viewMode: FILE_VIEW_MODE_EDITOR,
});
}
@@ -134,8 +138,7 @@ export default {
},
currentActivityView() {
if (this.currentActivityView !== leftSidebarViews.edit.name) {
- this.setFileViewMode({
- file: this.file,
+ this.updateEditor({
viewMode: FILE_VIEW_MODE_EDITOR,
});
}
@@ -195,13 +198,11 @@ export default {
'getFileData',
'getRawFileData',
'changeFileContent',
- 'setFileLanguage',
- 'setEditorPosition',
- 'setFileViewMode',
'removePendingTab',
'triggerFilesChange',
'addTempImage',
]),
+ ...mapActions('editor', ['updateFileEditor']),
initEditor() {
if (this.shouldHideEditor && (this.file.content || this.file.raw)) {
return;
@@ -284,19 +285,19 @@ export default {
// Handle Cursor Position
this.editor.onPositionChange((instance, e) => {
- this.setEditorPosition({
+ this.updateEditor({
editorRow: e.position.lineNumber,
editorColumn: e.position.column,
});
});
this.editor.setPosition({
- lineNumber: this.file.editorRow,
- column: this.file.editorColumn,
+ lineNumber: this.fileEditor.editorRow,
+ column: this.fileEditor.editorColumn,
});
// Handle File Language
- this.setFileLanguage({
+ this.updateEditor({
fileLanguage: this.model.language,
});
@@ -354,6 +355,16 @@ export default {
const schema = this.getJsonSchemaForPath(this.file.path);
registerSchema(schema);
},
+ updateEditor(data) {
+ // Looks like our model wrapper `.dispose` causes the monaco editor to emit some position changes after
+ // when disposing. We want to ignore these by only capturing editor changes that happen to the currently active
+ // file.
+ if (!this.file.active) {
+ return;
+ }
+
+ this.updateFileEditor({ path: this.file.path, data });
+ },
},
viewerTypes,
FILE_VIEW_MODE_EDITOR,
@@ -369,7 +380,7 @@ export default {
<a
href="javascript:void(0);"
role="button"
- @click.prevent="setFileViewMode({ file, viewMode: $options.FILE_VIEW_MODE_EDITOR })"
+ @click.prevent="updateEditor({ viewMode: $options.FILE_VIEW_MODE_EDITOR })"
>
{{ __('Edit') }}
</a>
@@ -378,7 +389,7 @@ export default {
<a
href="javascript:void(0);"
role="button"
- @click.prevent="setFileViewMode({ file, viewMode: $options.FILE_VIEW_MODE_PREVIEW })"
+ @click.prevent="updateEditor({ viewMode: $options.FILE_VIEW_MODE_PREVIEW })"
>{{ previewMode.previewTitle }}</a
>
</li>
diff --git a/app/assets/javascripts/ide/components/repo_file_status_icon.vue b/app/assets/javascripts/ide/components/repo_file_status_icon.vue
index 1402f7aaf39..72c56daf69c 100644
--- a/app/assets/javascripts/ide/components/repo_file_status_icon.vue
+++ b/app/assets/javascripts/ide/components/repo_file_status_icon.vue
@@ -1,7 +1,6 @@
<script>
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
import '~/lib/utils/datetime_utility';
export default {
@@ -9,7 +8,7 @@ export default {
GlIcon,
},
directives: {
- tooltip,
+ GlTooltip: GlTooltipDirective,
},
props: {
file: {
@@ -28,7 +27,7 @@ export default {
</script>
<template>
- <span v-if="file.file_lock" v-tooltip :title="lockTooltip" data-container="body">
+ <span v-if="file.file_lock" v-gl-tooltip :title="lockTooltip" data-container="body">
<gl-icon name="lock" class="file-status-icon" />
</span>
</template>
diff --git a/app/assets/javascripts/ide/components/repo_tab.vue b/app/assets/javascripts/ide/components/repo_tab.vue
index 60a80a31a8b..e3c41eee15e 100644
--- a/app/assets/javascripts/ide/components/repo_tab.vue
+++ b/app/assets/javascripts/ide/components/repo_tab.vue
@@ -29,9 +29,9 @@ export default {
...mapGetters(['getUrlForPath']),
closeLabel() {
if (this.fileHasChanged) {
- return sprintf(__(`%{tabname} changed`), { tabname: this.tab.name });
+ return sprintf(__('%{tabname} changed'), { tabname: this.tab.name });
}
- return sprintf(__(`Close %{tabname}`, { tabname: this.tab.name }));
+ return sprintf(__('Close %{tabname}'), { tabname: this.tab.name });
},
showChangedIcon() {
if (this.tab.pending) return true;
diff --git a/app/assets/javascripts/ide/components/terminal/empty_state.vue b/app/assets/javascripts/ide/components/terminal/empty_state.vue
index 3668dd24e81..f4dd83b16c7 100644
--- a/app/assets/javascripts/ide/components/terminal/empty_state.vue
+++ b/app/assets/javascripts/ide/components/terminal/empty_state.vue
@@ -1,10 +1,14 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlLoadingIcon } from '@gitlab/ui';
+import { GlLoadingIcon, GlButton, GlAlert, GlSafeHtmlDirective } from '@gitlab/ui';
export default {
components: {
GlLoadingIcon,
+ GlButton,
+ GlAlert,
+ },
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
},
props: {
isLoading: {
@@ -41,24 +45,26 @@ export default {
};
</script>
<template>
- <div class="text-center p-3">
+ <div class="gl-text-center gl-p-5">
<div v-if="illustrationPath" class="svg-content svg-130"><img :src="illustrationPath" /></div>
<h4>{{ __('Web Terminal') }}</h4>
<gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-3" />
<template v-else>
<p>{{ __('Run tests against your code live using the Web Terminal') }}</p>
<p>
- <button
+ <gl-button
:disabled="!isValid"
- class="btn btn-info"
- type="button"
+ category="primary"
+ variant="info"
data-qa-selector="start_web_terminal_button"
@click="onStart"
>
{{ __('Start Web Terminal') }}
- </button>
+ </gl-button>
</p>
- <div v-if="!isValid && message" class="bs-callout text-left" v-html="message"></div>
+ <gl-alert v-if="!isValid && message" variant="tip" :dismissible="false">
+ <span v-safe-html="message"></span>
+ </gl-alert>
<p v-else>
<a
v-if="helpPath"
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index b8d59f8bd36..1496170447d 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -5,7 +5,7 @@ import { visitUrl } from '~/lib/utils/url_utility';
import { deprecatedCreateFlash as flash } from '~/flash';
import * as types from './mutation_types';
import { decorateFiles } from '../lib/files';
-import { stageKeys } from '../constants';
+import { stageKeys, commitActionTypes } from '../constants';
import service from '../services';
import eventHub from '../eventhub';
@@ -242,7 +242,7 @@ export const renameEntry = ({ dispatch, commit, state, getters }, { path, name,
}
}
- dispatch('triggerFilesChange');
+ dispatch('triggerFilesChange', { type: commitActionTypes.move, path, newPath });
};
export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) =>
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index a0df85540f9..4b9b958ddd6 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -164,26 +164,6 @@ export const changeFileContent = ({ commit, state, getters }, { path, content })
}
};
-export const setFileLanguage = ({ getters, commit }, { fileLanguage }) => {
- if (getters.activeFile) {
- commit(types.SET_FILE_LANGUAGE, { file: getters.activeFile, fileLanguage });
- }
-};
-
-export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn }) => {
- if (getters.activeFile) {
- commit(types.SET_FILE_POSITION, {
- file: getters.activeFile,
- editorRow,
- editorColumn,
- });
- }
-};
-
-export const setFileViewMode = ({ commit }, { file, viewMode }) => {
- commit(types.SET_FILE_VIEWMODE, { file, viewMode });
-};
-
export const restoreOriginalFile = ({ dispatch, state, commit }, path) => {
const file = state.entries[path];
const isDestructiveDiscard = file.tempFile || file.prevPath;
@@ -289,7 +269,7 @@ export const removePendingTab = ({ commit }, file) => {
eventHub.$emit(`editor.update.model.dispose.${file.key}`);
};
-export const triggerFilesChange = () => {
+export const triggerFilesChange = (ctx, payload = {}) => {
// Used in EE for file mirroring
- eventHub.$emit('ide.files.change');
+ eventHub.$emit('ide.files.change', payload);
};
diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js
index 324c5b0c6e4..d543209716a 100644
--- a/app/assets/javascripts/ide/stores/index.js
+++ b/app/assets/javascripts/ide/stores/index.js
@@ -12,6 +12,8 @@ import fileTemplates from './modules/file_templates';
import paneModule from './modules/pane';
import clientsideModule from './modules/clientside';
import routerModule from './modules/router';
+import editorModule from './modules/editor';
+import { setupFileEditorsSync } from './modules/editor/setup';
Vue.use(Vuex);
@@ -29,7 +31,14 @@ export const createStoreOptions = () => ({
rightPane: paneModule(),
clientside: clientsideModule(),
router: routerModule,
+ editor: editorModule,
},
});
-export const createStore = () => new Vuex.Store(createStoreOptions());
+export const createStore = () => {
+ const store = new Vuex.Store(createStoreOptions());
+
+ setupFileEditorsSync(store);
+
+ return store;
+};
diff --git a/app/assets/javascripts/ide/stores/modules/commit/getters.js b/app/assets/javascripts/ide/stores/modules/commit/getters.js
index 37f887bcf0a..416ca88d6c9 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/getters.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/getters.js
@@ -14,6 +14,8 @@ const createTranslatedTextForFiles = (files, text) => {
export const discardDraftButtonDisabled = state =>
state.commitMessage === '' || state.submitCommitLoading;
+// Note: If changing the structure of the placeholder branch name, please also
+// update #patch_branch_name in app/helpers/tree_helper.rb
export const placeholderBranchName = (state, _, rootState) =>
`${gon.current_username}-${rootState.currentBranchId}-patch-${`${new Date().getTime()}`.substr(
-BRANCH_SUFFIX_COUNT,
diff --git a/app/assets/javascripts/ide/stores/modules/editor/actions.js b/app/assets/javascripts/ide/stores/modules/editor/actions.js
new file mode 100644
index 00000000000..cc23a655235
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/actions.js
@@ -0,0 +1,19 @@
+import * as types from './mutation_types';
+
+/**
+ * Action to update the current file editor info at the given `path` with the given `data`
+ *
+ * @param {} vuex
+ * @param {{ path: String, data: any }} payload
+ */
+export const updateFileEditor = ({ commit }, payload) => {
+ commit(types.UPDATE_FILE_EDITOR, payload);
+};
+
+export const removeFileEditor = ({ commit }, path) => {
+ commit(types.REMOVE_FILE_EDITOR, path);
+};
+
+export const renameFileEditor = ({ commit }, payload) => {
+ commit(types.RENAME_FILE_EDITOR, payload);
+};
diff --git a/app/assets/javascripts/ide/stores/modules/editor/getters.js b/app/assets/javascripts/ide/stores/modules/editor/getters.js
new file mode 100644
index 00000000000..dabaafa453a
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/getters.js
@@ -0,0 +1,13 @@
+import { getFileEditorOrDefault } from './utils';
+
+export const activeFileEditor = (state, getters, rootState, rootGetters) => {
+ const { activeFile } = rootGetters;
+
+ if (!activeFile) {
+ return null;
+ }
+
+ const { path } = rootGetters.activeFile;
+
+ return getFileEditorOrDefault(state.fileEditors, path);
+};
diff --git a/app/assets/javascripts/ide/stores/modules/editor/index.js b/app/assets/javascripts/ide/stores/modules/editor/index.js
new file mode 100644
index 00000000000..8a7437b427d
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/index.js
@@ -0,0 +1,12 @@
+import * as actions from './actions';
+import * as getters from './getters';
+import state from './state';
+import mutations from './mutations';
+
+export default {
+ namespaced: true,
+ actions,
+ state,
+ mutations,
+ getters,
+};
diff --git a/app/assets/javascripts/ide/stores/modules/editor/mutation_types.js b/app/assets/javascripts/ide/stores/modules/editor/mutation_types.js
new file mode 100644
index 00000000000..89b7e9cbc76
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/mutation_types.js
@@ -0,0 +1,3 @@
+export const UPDATE_FILE_EDITOR = 'UPDATE_FILE_EDITOR';
+export const REMOVE_FILE_EDITOR = 'REMOVE_FILE_EDITOR';
+export const RENAME_FILE_EDITOR = 'RENAME_FILE_EDITOR';
diff --git a/app/assets/javascripts/ide/stores/modules/editor/mutations.js b/app/assets/javascripts/ide/stores/modules/editor/mutations.js
new file mode 100644
index 00000000000..f332fe9dce9
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/mutations.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import * as types from './mutation_types';
+import { getFileEditorOrDefault } from './utils';
+
+export default {
+ [types.UPDATE_FILE_EDITOR](state, { path, data }) {
+ const editor = getFileEditorOrDefault(state.fileEditors, path);
+
+ Vue.set(state.fileEditors, path, Object.assign(editor, data));
+ },
+ [types.REMOVE_FILE_EDITOR](state, path) {
+ Vue.delete(state.fileEditors, path);
+ },
+ [types.RENAME_FILE_EDITOR](state, { path, newPath }) {
+ const existing = state.fileEditors[path];
+
+ // Gracefully do nothing if fileEditor isn't found.
+ if (!existing) {
+ return;
+ }
+
+ Vue.delete(state.fileEditors, path);
+ Vue.set(state.fileEditors, newPath, existing);
+ },
+};
diff --git a/app/assets/javascripts/ide/stores/modules/editor/setup.js b/app/assets/javascripts/ide/stores/modules/editor/setup.js
new file mode 100644
index 00000000000..c5a613c6baa
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/setup.js
@@ -0,0 +1,19 @@
+import eventHub from '~/ide/eventhub';
+import { commitActionTypes } from '~/ide/constants';
+
+const removeUnusedFileEditors = store => {
+ Object.keys(store.state.editor.fileEditors)
+ .filter(path => !store.state.entries[path])
+ .forEach(path => store.dispatch('editor/removeFileEditor', path));
+};
+
+export const setupFileEditorsSync = store => {
+ eventHub.$on('ide.files.change', ({ type, ...payload } = {}) => {
+ if (type === commitActionTypes.move) {
+ store.dispatch('editor/renameFileEditor', payload);
+ } else {
+ // The files have changed, but the specific change is not known.
+ removeUnusedFileEditors(store);
+ }
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/modules/editor/state.js b/app/assets/javascripts/ide/stores/modules/editor/state.js
new file mode 100644
index 00000000000..484aeec5cc3
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/state.js
@@ -0,0 +1,8 @@
+export default () => ({
+ // Object which represents a dictionary of filePath to editor specific properties, including:
+ // - fileLanguage
+ // - editorRow
+ // - editorCol
+ // - viewMode
+ fileEditors: {},
+});
diff --git a/app/assets/javascripts/ide/stores/modules/editor/utils.js b/app/assets/javascripts/ide/stores/modules/editor/utils.js
new file mode 100644
index 00000000000..bef21d04b2b
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/editor/utils.js
@@ -0,0 +1,11 @@
+import { FILE_VIEW_MODE_EDITOR } from '../../../constants';
+
+export const createDefaultFileEditor = () => ({
+ editorRow: 1,
+ editorColumn: 1,
+ fileLanguage: '',
+ viewMode: FILE_VIEW_MODE_EDITOR,
+});
+
+export const getFileEditorOrDefault = (fileEditors, path) =>
+ fileEditors[path] || createDefaultFileEditor();
diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js
index ae119c2b1fd..22ff29e8866 100644
--- a/app/assets/javascripts/ide/stores/mutation_types.js
+++ b/app/assets/javascripts/ide/stores/mutation_types.js
@@ -36,9 +36,6 @@ export const SET_FILE_ACTIVE = 'SET_FILE_ACTIVE';
export const SET_FILE_RAW_DATA = 'SET_FILE_RAW_DATA';
export const SET_FILE_BASE_RAW_DATA = 'SET_FILE_BASE_RAW_DATA';
export const UPDATE_FILE_CONTENT = 'UPDATE_FILE_CONTENT';
-export const SET_FILE_LANGUAGE = 'SET_FILE_LANGUAGE';
-export const SET_FILE_POSITION = 'SET_FILE_POSITION';
-export const SET_FILE_VIEWMODE = 'SET_FILE_VIEWMODE';
export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES';
export const ADD_FILE_TO_CHANGED = 'ADD_FILE_TO_CHANGED';
export const REMOVE_FILE_FROM_CHANGED = 'REMOVE_FILE_FROM_CHANGED';
diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js
index a981f86fa40..61a55d45128 100644
--- a/app/assets/javascripts/ide/stores/mutations/file.js
+++ b/app/assets/javascripts/ide/stores/mutations/file.js
@@ -95,17 +95,6 @@ export default {
changed,
});
},
- [types.SET_FILE_LANGUAGE](state, { file, fileLanguage }) {
- Object.assign(state.entries[file.path], {
- fileLanguage,
- });
- },
- [types.SET_FILE_POSITION](state, { file, editorRow, editorColumn }) {
- Object.assign(state.entries[file.path], {
- editorRow,
- editorColumn,
- });
- },
[types.SET_FILE_MERGE_REQUEST_CHANGE](state, { file, mrChange }) {
let diffMode = diffModes.replaced;
if (mrChange.new_file) {
@@ -122,11 +111,6 @@ export default {
},
});
},
- [types.SET_FILE_VIEWMODE](state, { file, viewMode }) {
- Object.assign(state.entries[file.path], {
- viewMode,
- });
- },
[types.DISCARD_FILE_CHANGES](state, path) {
const stagedFile = state.stagedFiles.find(f => f.path === path);
const entry = state.entries[path];
diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js
index b7ced3a271a..96f3caf1e98 100644
--- a/app/assets/javascripts/ide/stores/utils.js
+++ b/app/assets/javascripts/ide/stores/utils.js
@@ -1,4 +1,4 @@
-import { commitActionTypes, FILE_VIEW_MODE_EDITOR } from '../constants';
+import { commitActionTypes } from '../constants';
import {
relativePathToAbsolute,
isAbsolute,
@@ -25,10 +25,6 @@ export const dataStructure = () => ({
rawPath: '',
raw: '',
content: '',
- editorRow: 1,
- editorColumn: 1,
- fileLanguage: '',
- viewMode: FILE_VIEW_MODE_EDITOR,
size: 0,
parentPath: null,
lastOpenedAt: 0,
diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js
index 4cf4f5e1d81..1ca1b971de1 100644
--- a/app/assets/javascripts/ide/utils.js
+++ b/app/assets/javascripts/ide/utils.js
@@ -1,7 +1,7 @@
import { languages } from 'monaco-editor';
import { flatten, isString } from 'lodash';
import { SIDE_LEFT, SIDE_RIGHT } from './constants';
-import { performanceMarkAndMeasure } from '~/performance_utils';
+import { performanceMarkAndMeasure } from '~/performance/utils';
const toLowerCase = x => x.toLowerCase();