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:
Diffstat (limited to 'app/assets/javascripts/ide')
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/form.vue21
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/message_field.vue4
-rw-r--r--app/assets/javascripts/ide/components/editor_mode_dropdown.vue71
-rw-r--r--app/assets/javascripts/ide/components/file_templates/dropdown.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide.vue40
-rw-r--r--app/assets/javascripts/ide/components/ide_side_bar.vue6
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue16
-rw-r--r--app/assets/javascripts/ide/components/jobs/detail.vue2
-rw-r--r--app/assets/javascripts/ide/components/nav_dropdown.vue3
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue1
-rw-r--r--app/assets/javascripts/ide/components/pipelines/list.vue11
-rw-r--r--app/assets/javascripts/ide/components/preview/clientside.vue2
-rw-r--r--app/assets/javascripts/ide/components/repo_editor.vue20
-rw-r--r--app/assets/javascripts/ide/components/terminal/session.vue18
-rw-r--r--app/assets/javascripts/ide/components/terminal/view.vue3
-rw-r--r--app/assets/javascripts/ide/ide_router.js16
-rw-r--r--app/assets/javascripts/ide/index.js5
-rw-r--r--app/assets/javascripts/ide/lib/common/model.js3
-rw-r--r--app/assets/javascripts/ide/stores/actions.js21
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js23
-rw-r--r--app/assets/javascripts/ide/stores/actions/tree.js21
-rw-r--r--app/assets/javascripts/ide/utils.js4
22 files changed, 189 insertions, 124 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
index 9d2deb1d4d0..7c3e522a488 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
@@ -134,15 +134,17 @@ export default {
@after-enter="afterEndTransition"
>
<div v-if="isCompact" ref="compactEl" class="commit-form-compact">
- <button
+ <gl-button
:disabled="!someUncommittedChanges"
- type="button"
- class="btn btn-primary btn-sm btn-block qa-begin-commit-button"
+ category="primary"
+ variant="info"
+ block
+ class="qa-begin-commit-button"
data-testid="begin-commit-button"
@click="beginCommit"
>
{{ __('Commit…') }}
- </button>
+ </gl-button>
<p class="text-center bold">{{ overviewText }}</p>
</div>
<form v-else ref="formEl" @submit.prevent.stop="commit">
@@ -158,28 +160,21 @@ export default {
<gl-button
:loading="submitCommitLoading"
class="float-left qa-commit-button"
- size="small"
category="primary"
variant="success"
@click="commit"
>
{{ __('Commit') }}
</gl-button>
- <button
- v-if="!discardDraftButtonDisabled"
- type="button"
- class="btn btn-default btn-sm float-right"
- @click="discardDraft"
- >
+ <gl-button v-if="!discardDraftButtonDisabled" class="float-right" @click="discardDraft">
{{ __('Discard draft') }}
- </button>
+ </gl-button>
<gl-button
v-else
type="button"
class="float-right"
category="secondary"
variant="default"
- size="small"
@click="toggleIsCompact"
>
{{ __('Collapse') }}
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
index 7d08815b033..8f0e5aef456 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
@@ -1,13 +1,9 @@
<script>
import { GlIcon, GlPopover } from '@gitlab/ui';
import { __, sprintf } from '../../../locale';
-import popover from '../../../vue_shared/directives/popover';
import { MAX_TITLE_LENGTH, MAX_BODY_LENGTH } from '../../constants';
export default {
- directives: {
- popover,
- },
components: {
GlIcon,
GlPopover,
diff --git a/app/assets/javascripts/ide/components/editor_mode_dropdown.vue b/app/assets/javascripts/ide/components/editor_mode_dropdown.vue
index dec8aa61838..52593aabfea 100644
--- a/app/assets/javascripts/ide/components/editor_mode_dropdown.vue
+++ b/app/assets/javascripts/ide/components/editor_mode_dropdown.vue
@@ -1,11 +1,12 @@
<script>
-import { GlButton } from '@gitlab/ui';
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { viewerTypes } from '../constants';
export default {
components: {
- GlButton,
+ GlDropdown,
+ GlDropdownItem,
},
props: {
viewer: {
@@ -18,10 +19,21 @@ export default {
},
},
computed: {
- mergeReviewLine() {
- return sprintf(__('Reviewing (merge request !%{mergeRequestId})'), {
- mergeRequestId: this.mergeRequestId,
- });
+ modeDropdownItems() {
+ return [
+ {
+ viewerType: this.$options.viewerTypes.mr,
+ title: sprintf(__('Reviewing (merge request !%{mergeRequestId})'), {
+ mergeRequestId: this.mergeRequestId,
+ }),
+ content: __('Compare changes with the merge request target branch'),
+ },
+ {
+ viewerType: this.$options.viewerTypes.diff,
+ title: __('Reviewing'),
+ content: __('Compare changes with the last commit'),
+ },
+ ];
},
},
methods: {
@@ -34,39 +46,16 @@ export default {
</script>
<template>
- <div class="dropdown">
- <gl-button variant="link" data-toggle="dropdown">{{ __('Edit') }}</gl-button>
- <div class="dropdown-menu dropdown-menu-selectable dropdown-open-left">
- <ul>
- <li>
- <a
- :class="{
- 'is-active': viewer === $options.viewerTypes.mr,
- }"
- href="#"
- @click.prevent="changeMode($options.viewerTypes.mr)"
- >
- <strong class="dropdown-menu-inner-title"> {{ mergeReviewLine }} </strong>
- <span class="dropdown-menu-inner-content">
- {{ __('Compare changes with the merge request target branch') }}
- </span>
- </a>
- </li>
- <li>
- <a
- :class="{
- 'is-active': viewer === $options.viewerTypes.diff,
- }"
- href="#"
- @click.prevent="changeMode($options.viewerTypes.diff)"
- >
- <strong class="dropdown-menu-inner-title">{{ __('Reviewing') }}</strong>
- <span class="dropdown-menu-inner-content">
- {{ __('Compare changes with the last commit') }}
- </span>
- </a>
- </li>
- </ul>
- </div>
- </div>
+ <gl-dropdown :text="__('Edit')" size="small">
+ <gl-dropdown-item
+ v-for="mode in modeDropdownItems"
+ :key="mode.viewerType"
+ :is-check-item="true"
+ :is-checked="viewer === mode.viewerType"
+ @click="changeMode(mode.viewerType)"
+ >
+ <strong class="dropdown-menu-inner-title"> {{ mode.title }} </strong>
+ <span class="dropdown-menu-inner-content"> {{ mode.content }} </span>
+ </gl-dropdown-item>
+ </gl-dropdown>
</template>
diff --git a/app/assets/javascripts/ide/components/file_templates/dropdown.vue b/app/assets/javascripts/ide/components/file_templates/dropdown.vue
index cfd2555b769..5d5b66a6444 100644
--- a/app/assets/javascripts/ide/components/file_templates/dropdown.vue
+++ b/app/assets/javascripts/ide/components/file_templates/dropdown.vue
@@ -86,7 +86,7 @@ export default {
type="search"
class="dropdown-input-field qa-dropdown-filter-input"
/>
- <gl-icon name="search" class="dropdown-input-search" aria-hidden="true" />
+ <gl-icon name="search" class="dropdown-input-search" />
</div>
<div class="dropdown-content">
<gl-loading-icon v-if="showLoading" size="lg" />
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index e1d2895831a..f8568f46cd6 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -1,14 +1,13 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
+import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import {
WEBIDE_MARK_APP_START,
WEBIDE_MARK_FILE_FINISH,
WEBIDE_MARK_FILE_CLICKED,
- WEBIDE_MARK_TREE_FINISH,
- WEBIDE_MEASURE_TREE_FROM_REQUEST,
- WEBIDE_MEASURE_FILE_FROM_REQUEST,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
+ WEBIDE_MEASURE_BEFORE_VUE,
} from '~/performance/constants';
import { performanceMarkAndMeasure } from '~/performance/utils';
import { modalTypes } from '../constants';
@@ -19,12 +18,6 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { measurePerformance } from '../utils';
-eventHub.$on(WEBIDE_MEASURE_TREE_FROM_REQUEST, () =>
- measurePerformance(WEBIDE_MARK_TREE_FINISH, WEBIDE_MEASURE_TREE_FROM_REQUEST),
-);
-eventHub.$on(WEBIDE_MEASURE_FILE_FROM_REQUEST, () =>
- measurePerformance(WEBIDE_MARK_FILE_FINISH, WEBIDE_MEASURE_FILE_FROM_REQUEST),
-);
eventHub.$on(WEBIDE_MEASURE_FILE_AFTER_INTERACTION, () =>
measurePerformance(
WEBIDE_MARK_FILE_FINISH,
@@ -37,15 +30,17 @@ export default {
components: {
IdeSidebar,
RepoEditor,
- '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'),
+ GlButton,
+ GlLoadingIcon,
+ ErrorMessage: () => import(/* webpackChunkName: 'ide_runtime' */ './error_message.vue'),
+ CommitEditorHeader: () =>
+ import(/* webpackChunkName: 'ide_runtime' */ './commit_sidebar/editor_header.vue'),
+ RepoTabs: () => import(/* webpackChunkName: 'ide_runtime' */ './repo_tabs.vue'),
+ IdeStatusBar: () => import(/* webpackChunkName: 'ide_runtime' */ './ide_status_bar.vue'),
+ FindFile: () =>
+ import(/* webpackChunkName: 'ide_runtime' */ '~/vue_shared/components/file_finder/index.vue'),
+ RightPane: () => import(/* webpackChunkName: 'ide_runtime' */ './panes/right.vue'),
+ NewModal: () => import(/* webpackChunkName: 'ide_runtime' */ './new_dropdown/modal.vue'),
},
mixins: [glFeatureFlagsMixin()],
data() {
@@ -84,7 +79,14 @@ export default {
document.querySelector('.navbar-gitlab').classList.add(`theme-${this.themeName}`);
},
beforeCreate() {
- performanceMarkAndMeasure({ mark: WEBIDE_MARK_APP_START });
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_APP_START,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_BEFORE_VUE,
+ },
+ ],
+ });
},
methods: {
...mapActions(['toggleFileFinder']),
diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue
index 99215d6c3f1..135b28685ed 100644
--- a/app/assets/javascripts/ide/components/ide_side_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_side_bar.vue
@@ -14,8 +14,10 @@ export default {
ResizablePanel,
ActivityBar,
IdeTree,
- [leftSidebarViews.review.name]: () => import('./ide_review.vue'),
- [leftSidebarViews.commit.name]: () => import('./repo_commit_section.vue'),
+ [leftSidebarViews.review.name]: () =>
+ import(/* webpackChunkName: 'ide_runtime' */ './ide_review.vue'),
+ [leftSidebarViews.commit.name]: () =>
+ import(/* webpackChunkName: 'ide_runtime' */ './repo_commit_section.vue'),
CommitForm,
IdeProjectHeader,
},
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index e7e94f5b5da..b67881b14f4 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -2,17 +2,13 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import FileTree from '~/vue_shared/components/file_tree.vue';
-import {
- WEBIDE_MARK_TREE_START,
- WEBIDE_MEASURE_TREE_FROM_REQUEST,
- WEBIDE_MARK_FILE_CLICKED,
-} from '~/performance/constants';
+import { WEBIDE_MARK_FILE_CLICKED } 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';
export default {
+ name: 'IdeTreeList',
components: {
GlSkeletonLoading,
NavDropdown,
@@ -39,14 +35,6 @@ export default {
}
},
},
- beforeCreate() {
- performanceMarkAndMeasure({ mark: WEBIDE_MARK_TREE_START });
- },
- updated() {
- if (this.currentTree?.tree?.length) {
- eventHub.$emit(WEBIDE_MEASURE_TREE_FROM_REQUEST);
- }
- },
methods: {
...mapActions(['toggleTreeOpen']),
clickedFile() {
diff --git a/app/assets/javascripts/ide/components/jobs/detail.vue b/app/assets/javascripts/ide/components/jobs/detail.vue
index d65304034c2..7f07a5dbe43 100644
--- a/app/assets/javascripts/ide/components/jobs/detail.vue
+++ b/app/assets/javascripts/ide/components/jobs/detail.vue
@@ -92,7 +92,7 @@ export default {
class="controllers-buttons"
target="_blank"
>
- <gl-icon name="doc-text" aria-hidden="true" />
+ <gl-icon name="doc-text" />
</a>
<scroll-button :disabled="isScrolledToTop" direction="up" @click="scrollUp" />
<scroll-button :disabled="isScrolledToBottom" direction="down" @click="scrollDown" />
diff --git a/app/assets/javascripts/ide/components/nav_dropdown.vue b/app/assets/javascripts/ide/components/nav_dropdown.vue
index 2307efd1d24..8cea8655461 100644
--- a/app/assets/javascripts/ide/components/nav_dropdown.vue
+++ b/app/assets/javascripts/ide/components/nav_dropdown.vue
@@ -30,6 +30,7 @@ export default {
.on('hide.bs.dropdown', () => this.hideDropdown());
},
removeDropdownListeners() {
+ // eslint-disable-next-line @gitlab/no-global-event-off
$(this.$refs.dropdown)
.off('show.bs.dropdown')
.off('hide.bs.dropdown');
@@ -45,7 +46,7 @@ export default {
</script>
<template>
- <div ref="dropdown" class="btn-group ide-nav-dropdown dropdown">
+ <div ref="dropdown" class="btn-group ide-nav-dropdown dropdown" data-testid="ide-nav-dropdown">
<nav-dropdown-button :show-merge-requests="canReadMergeRequests" />
<div class="dropdown-menu dropdown-menu-left p-0">
<nav-form v-if="isVisibleDropdown" :show-merge-requests="canReadMergeRequests" />
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index 5ad836f346a..22eefb6634f 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -137,6 +137,7 @@ export default {
ref="modal"
modal-id="ide-new-entry"
data-qa-selector="new_file_modal"
+ data-testid="ide-new-entry"
:title="modalTitle"
:ok-title="buttonLabel"
ok-variant="success"
diff --git a/app/assets/javascripts/ide/components/pipelines/list.vue b/app/assets/javascripts/ide/components/pipelines/list.vue
index 6f15773c9ab..a4a13389fbf 100644
--- a/app/assets/javascripts/ide/components/pipelines/list.vue
+++ b/app/assets/javascripts/ide/components/pipelines/list.vue
@@ -8,6 +8,7 @@ import {
GlTabs,
GlTab,
GlBadge,
+ GlAlert,
} from '@gitlab/ui';
import { sprintf, __ } from '../../../locale';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
@@ -26,6 +27,7 @@ export default {
GlTabs,
GlTab,
GlBadge,
+ GlAlert,
},
directives: {
SafeHtml,
@@ -89,11 +91,16 @@ export default {
:can-set-ci="true"
class="mb-auto mt-auto"
/>
- <div v-else-if="latestPipeline.yamlError" class="bs-callout bs-callout-danger">
+ <gl-alert
+ v-else-if="latestPipeline.yamlError"
+ variant="danger"
+ :dismissible="false"
+ class="gl-mt-5"
+ >
<p class="gl-mb-0">{{ __('Found errors in your .gitlab-ci.yml:') }}</p>
<p class="gl-mb-0 break-word">{{ latestPipeline.yamlError }}</p>
<p v-safe-html="ciLintText" class="gl-mb-0"></p>
- </div>
+ </gl-alert>
<gl-tabs v-else>
<gl-tab :active="!pipelineFailed">
<template #title>
diff --git a/app/assets/javascripts/ide/components/preview/clientside.vue b/app/assets/javascripts/ide/components/preview/clientside.vue
index 3852f2fdfa4..f65b1201d94 100644
--- a/app/assets/javascripts/ide/components/preview/clientside.vue
+++ b/app/assets/javascripts/ide/components/preview/clientside.vue
@@ -152,7 +152,7 @@ export default {
</script>
<template>
- <div class="preview h-100 w-100 d-flex flex-column">
+ <div class="preview h-100 w-100 d-flex flex-column gl-bg-white">
<template v-if="showPreview">
<navigator :manager="manager" />
<div id="ide-preview"></div>
diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue
index c8a825065f1..1f029612c29 100644
--- a/app/assets/javascripts/ide/components/repo_editor.vue
+++ b/app/assets/javascripts/ide/components/repo_editor.vue
@@ -6,9 +6,10 @@ import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer
import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
import {
WEBIDE_MARK_FILE_CLICKED,
- WEBIDE_MARK_FILE_START,
+ WEBIDE_MARK_REPO_EDITOR_START,
+ WEBIDE_MARK_REPO_EDITOR_FINISH,
+ WEBIDE_MEASURE_REPO_EDITOR,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
- WEBIDE_MEASURE_FILE_FROM_REQUEST,
} from '~/performance/constants';
import { performanceMarkAndMeasure } from '~/performance/utils';
import eventHub from '../eventhub';
@@ -28,6 +29,7 @@ import { getRulesWithTraversal } from '../lib/editorconfig/parser';
import mapRulesToMonaco from '../lib/editorconfig/rules_mapper';
export default {
+ name: 'RepoEditor',
components: {
ContentViewer,
DiffViewer,
@@ -175,9 +177,6 @@ export default {
}
},
},
- beforeCreate() {
- performanceMarkAndMeasure({ mark: WEBIDE_MARK_FILE_START });
- },
beforeDestroy() {
this.editor.dispose();
},
@@ -204,6 +203,7 @@ export default {
]),
...mapActions('editor', ['updateFileEditor']),
initEditor() {
+ performanceMarkAndMeasure({ mark: WEBIDE_MARK_REPO_EDITOR_START });
if (this.shouldHideEditor && (this.file.content || this.file.raw)) {
return;
}
@@ -305,7 +305,15 @@ export default {
if (performance.getEntriesByName(WEBIDE_MARK_FILE_CLICKED).length) {
eventHub.$emit(WEBIDE_MEASURE_FILE_AFTER_INTERACTION);
} else {
- eventHub.$emit(WEBIDE_MEASURE_FILE_FROM_REQUEST);
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_REPO_EDITOR_FINISH,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_REPO_EDITOR,
+ start: WEBIDE_MARK_REPO_EDITOR_START,
+ },
+ ],
+ });
}
},
refreshEditorDimensions() {
diff --git a/app/assets/javascripts/ide/components/terminal/session.vue b/app/assets/javascripts/ide/components/terminal/session.vue
index a8fe9ea6866..0e67a2ab45f 100644
--- a/app/assets/javascripts/ide/components/terminal/session.vue
+++ b/app/assets/javascripts/ide/components/terminal/session.vue
@@ -1,5 +1,6 @@
<script>
import { mapActions, mapState } from 'vuex';
+import { GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import Terminal from './terminal.vue';
import { isEndingStatus } from '../../stores/modules/terminal/utils';
@@ -7,6 +8,7 @@ import { isEndingStatus } from '../../stores/modules/terminal/utils';
export default {
components: {
Terminal,
+ GlButton,
},
computed: {
...mapState('terminal', ['session']),
@@ -14,15 +16,17 @@ export default {
if (isEndingStatus(this.session.status)) {
return {
action: () => this.restartSession(),
+ variant: 'info',
+ category: 'primary',
text: __('Restart Terminal'),
- class: 'btn-primary',
};
}
return {
action: () => this.stopSession(),
+ variant: 'danger',
+ category: 'secondary',
text: __('Stop Terminal'),
- class: 'btn-inverted btn-remove',
};
},
},
@@ -37,15 +41,13 @@ export default {
<header class="ide-job-header d-flex align-items-center">
<h5>{{ __('Web Terminal') }}</h5>
<div class="ml-auto align-self-center">
- <button
+ <gl-button
v-if="actionButton"
- type="button"
- class="btn btn-sm"
- :class="actionButton.class"
+ :variant="actionButton.variant"
+ :category="actionButton.category"
@click="actionButton.action"
+ >{{ actionButton.text }}</gl-button
>
- {{ actionButton.text }}
- </button>
</div>
</header>
<terminal :terminal-path="session.terminalPath" :status="session.status" />
diff --git a/app/assets/javascripts/ide/components/terminal/view.vue b/app/assets/javascripts/ide/components/terminal/view.vue
index db97e95eed9..fcf23eb1f73 100644
--- a/app/assets/javascripts/ide/components/terminal/view.vue
+++ b/app/assets/javascripts/ide/components/terminal/view.vue
@@ -1,12 +1,11 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import EmptyState from './empty_state.vue';
-import TerminalSession from './session.vue';
export default {
components: {
EmptyState,
- TerminalSession,
+ TerminalSession: () => import(/* webpackChunkName: 'ide_terminal' */ './session.vue'),
},
computed: {
...mapState('terminal', ['isShowSplash', 'paths']),
diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js
index 396aedbfa10..b9ebacef7e1 100644
--- a/app/assets/javascripts/ide/ide_router.js
+++ b/app/assets/javascripts/ide/ide_router.js
@@ -3,6 +3,12 @@ import IdeRouter from '~/ide/ide_router_extension';
import { joinPaths } from '~/lib/utils/url_utility';
import { deprecatedCreateFlash as flash } from '~/flash';
import { __ } from '~/locale';
+import { performanceMarkAndMeasure } from '~/performance/utils';
+import {
+ WEBIDE_MARK_FETCH_PROJECT_DATA_START,
+ WEBIDE_MARK_FETCH_PROJECT_DATA_FINISH,
+ WEBIDE_MEASURE_FETCH_PROJECT_DATA,
+} from '~/performance/constants';
import { syncRouterAndStore } from './sync_router_and_store';
Vue.use(IdeRouter);
@@ -69,6 +75,7 @@ export const createRouter = store => {
router.beforeEach((to, from, next) => {
if (to.params.namespace && to.params.project) {
+ performanceMarkAndMeasure({ mark: WEBIDE_MARK_FETCH_PROJECT_DATA_START });
store
.dispatch('getProjectData', {
namespace: to.params.namespace,
@@ -81,6 +88,15 @@ export const createRouter = store => {
const mergeRequestId = to.params.mrid;
if (branchId) {
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_FETCH_PROJECT_DATA_FINISH,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_FETCH_PROJECT_DATA,
+ start: WEBIDE_MARK_FETCH_PROJECT_DATA_START,
+ },
+ ],
+ });
store.dispatch('openBranch', {
projectId,
branchId,
diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js
index 56d48e87c18..62f49ba56b1 100644
--- a/app/assets/javascripts/ide/index.js
+++ b/app/assets/javascripts/ide/index.js
@@ -2,6 +2,7 @@ import Vue from 'vue';
import { mapActions } from 'vuex';
import { identity } from 'lodash';
import Translate from '~/vue_shared/translate';
+import PerformancePlugin from '~/performance/vue_performance_plugin';
import ide from './components/ide.vue';
import { createStore } from './stores';
import { createRouter } from './ide_router';
@@ -11,6 +12,10 @@ import { DEFAULT_THEME } from './lib/themes';
Vue.use(Translate);
+Vue.use(PerformancePlugin, {
+ components: ['FileTree'],
+});
+
/**
* Function that receives the default store and returns an extended one.
* @callback extendStoreCallback
diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js
index c5bb00c3dee..2471b3627ce 100644
--- a/app/assets/javascripts/ide/lib/common/model.js
+++ b/app/assets/javascripts/ide/lib/common/model.js
@@ -1,7 +1,8 @@
import { editor as monacoEditor, Uri } from 'monaco-editor';
import Disposable from './disposable';
import eventHub from '../../eventhub';
-import { trimTrailingWhitespace, insertFinalNewline } from '../../utils';
+import { trimTrailingWhitespace } from '../../utils';
+import { insertFinalNewline } from '~/lib/utils/text_utility';
import { defaultModelOptions } from '../editor_options';
export default class Model {
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index 1496170447d..710256b6377 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -3,6 +3,12 @@ import { escape } from 'lodash';
import { __, sprintf } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
import { deprecatedCreateFlash as flash } from '~/flash';
+import { performanceMarkAndMeasure } from '~/performance/utils';
+import {
+ WEBIDE_MARK_FETCH_BRANCH_DATA_START,
+ WEBIDE_MARK_FETCH_BRANCH_DATA_FINISH,
+ WEBIDE_MEASURE_FETCH_BRANCH_DATA,
+} from '~/performance/constants';
import * as types from './mutation_types';
import { decorateFiles } from '../lib/files';
import { stageKeys, commitActionTypes } from '../constants';
@@ -245,13 +251,23 @@ export const renameEntry = ({ dispatch, commit, state, getters }, { path, name,
dispatch('triggerFilesChange', { type: commitActionTypes.move, path, newPath });
};
-export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) =>
- new Promise((resolve, reject) => {
+export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) => {
+ return new Promise((resolve, reject) => {
+ performanceMarkAndMeasure({ mark: WEBIDE_MARK_FETCH_BRANCH_DATA_START });
const currentProject = state.projects[projectId];
if (!currentProject || !currentProject.branches[branchId] || force) {
service
.getBranchData(projectId, branchId)
.then(({ data }) => {
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_FETCH_BRANCH_DATA_FINISH,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_FETCH_BRANCH_DATA,
+ start: WEBIDE_MARK_FETCH_BRANCH_DATA_START,
+ },
+ ],
+ });
const { id } = data.commit;
commit(types.SET_BRANCH, {
projectPath: projectId,
@@ -291,6 +307,7 @@ export const getBranchData = ({ commit, state }, { projectId, branchId, force =
resolve(currentProject.branches[branchId]);
}
});
+};
export * from './actions/tree';
export * from './actions/file';
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index 4b9b958ddd6..8b43c7238fd 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -1,5 +1,11 @@
import { joinPaths, escapeFileUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
+import { performanceMarkAndMeasure } from '~/performance/utils';
+import {
+ WEBIDE_MARK_FETCH_FILE_DATA_START,
+ WEBIDE_MARK_FETCH_FILE_DATA_FINISH,
+ WEBIDE_MEASURE_FETCH_FILE_DATA,
+} from '~/performance/constants';
import eventHub from '../../eventhub';
import service from '../../services';
import * as types from '../mutation_types';
@@ -61,6 +67,7 @@ export const getFileData = (
{ state, commit, dispatch, getters },
{ path, makeFileActive = true, openFile = makeFileActive, toggleLoading = true },
) => {
+ performanceMarkAndMeasure({ mark: WEBIDE_MARK_FETCH_FILE_DATA_START });
const file = state.entries[path];
const fileDeletedAndReadded = getters.isFileDeletedAndReadded(path);
@@ -81,6 +88,15 @@ export const getFileData = (
return service
.getFileData(url)
.then(({ data }) => {
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_FETCH_FILE_DATA_FINISH,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_FETCH_FILE_DATA,
+ start: WEBIDE_MARK_FETCH_FILE_DATA_START,
+ },
+ ],
+ });
if (data) commit(types.SET_FILE_DATA, { data, file });
if (openFile) commit(types.TOGGLE_FILE_OPEN, path);
@@ -150,6 +166,13 @@ export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) =
export const changeFileContent = ({ commit, state, getters }, { path, content }) => {
const file = state.entries[path];
+
+ // It's possible for monaco to hit a race condition where it tries to update renamed files.
+ // See issue https://gitlab.com/gitlab-org/gitlab/-/issues/284930
+ if (!file) {
+ return;
+ }
+
commit(types.UPDATE_FILE_CONTENT, {
path,
content,
diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js
index 3a7daf30cc4..23a5e26bc1c 100644
--- a/app/assets/javascripts/ide/stores/actions/tree.js
+++ b/app/assets/javascripts/ide/stores/actions/tree.js
@@ -1,4 +1,10 @@
import { defer } from 'lodash';
+import { performanceMarkAndMeasure } from '~/performance/utils';
+import {
+ WEBIDE_MARK_FETCH_FILES_FINISH,
+ WEBIDE_MEASURE_FETCH_FILES,
+ WEBIDE_MARK_FETCH_FILES_START,
+} from '~/performance/constants';
import { __ } from '../../../locale';
import service from '../../services';
import * as types from '../mutation_types';
@@ -46,8 +52,9 @@ export const setDirectoryData = ({ state, commit }, { projectId, branchId, treeL
});
};
-export const getFiles = ({ state, commit, dispatch }, payload = {}) =>
- new Promise((resolve, reject) => {
+export const getFiles = ({ state, commit, dispatch }, payload = {}) => {
+ performanceMarkAndMeasure({ mark: WEBIDE_MARK_FETCH_FILES_START });
+ return new Promise((resolve, reject) => {
const { projectId, branchId, ref = branchId } = payload;
if (
@@ -61,6 +68,15 @@ export const getFiles = ({ state, commit, dispatch }, payload = {}) =>
service
.getFiles(selectedProject.path_with_namespace, ref)
.then(({ data }) => {
+ performanceMarkAndMeasure({
+ mark: WEBIDE_MARK_FETCH_FILES_FINISH,
+ measures: [
+ {
+ name: WEBIDE_MEASURE_FETCH_FILES,
+ start: WEBIDE_MARK_FETCH_FILES_START,
+ },
+ ],
+ });
const { entries, treeList } = decorateFiles({ data });
commit(types.SET_ENTRIES, entries);
@@ -85,6 +101,7 @@ export const getFiles = ({ state, commit, dispatch }, payload = {}) =>
resolve();
}
});
+};
export const restoreTree = ({ dispatch, commit, state }, path) => {
const entry = state.entries[path];
diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js
index 1ca1b971de1..43276f32322 100644
--- a/app/assets/javascripts/ide/utils.js
+++ b/app/assets/javascripts/ide/utils.js
@@ -97,10 +97,6 @@ export function trimTrailingWhitespace(content) {
return content.replace(/[^\S\r\n]+$/gm, '');
}
-export function insertFinalNewline(content, eol = '\n') {
- return content.slice(-eol.length) !== eol ? `${content}${eol}` : content;
-}
-
export function getPathParents(path, maxDepth = Infinity) {
const pathComponents = path.split('/');
const paths = [];