diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-02 09:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-02 09:09:00 +0300 |
commit | 03c509e17bfa71a124a69b6cf4897414d3bd1cb5 (patch) | |
tree | 1301bca7b00224dd4f567d7e43344982a135c14f /app/assets/javascripts/ide | |
parent | 455e6650ee300263e78a8142d247f538c59737a6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/ide')
8 files changed, 156 insertions, 2 deletions
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index d589f56dd7c..838debf1ceb 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -47,6 +47,7 @@ export default { data() { return { loadDeferred: false, + skipBeforeUnload: false, }; }, computed: { @@ -78,9 +79,14 @@ export default { mounted() { window.onbeforeunload = (e) => this.onBeforeUnload(e); + eventHub.$on('skip-beforeunload', this.handleSkipBeforeUnload); + if (this.themeName) document.querySelector('.navbar-gitlab').classList.add(`theme-${this.themeName}`); }, + destroyed() { + eventHub.$off('skip-beforeunload', this.handleSkipBeforeUnload); + }, beforeCreate() { performanceMarkAndMeasure({ mark: WEBIDE_MARK_APP_START, @@ -94,6 +100,11 @@ export default { methods: { ...mapActions(['toggleFileFinder']), onBeforeUnload(e = {}) { + if (this.skipBeforeUnload) { + this.skipBeforeUnload = false; + return undefined; + } + const returnValue = __('Are you sure you want to lose unsaved changes?'); if (!this.someUncommittedChanges) return undefined; @@ -103,6 +114,9 @@ export default { }); return returnValue; }, + handleSkipBeforeUnload() { + this.skipBeforeUnload = true; + }, openFile(file) { this.$router.push(this.getUrlForPath(file.path)); }, diff --git a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue index 6f42ae48cc9..bf99538a2ad 100644 --- a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue +++ b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue @@ -13,6 +13,11 @@ export default { required: false, default: () => [], }, + initOpenView: { + type: String, + required: false, + default: '', + }, side: { type: String, required: true, @@ -44,6 +49,9 @@ export default { return this.tabViews.filter((view) => this.isAliveView(view.name)); }, }, + created() { + this.openViewByName(this.initOpenView); + }, methods: { ...mapActions({ toggleOpen(dispatch) { @@ -53,6 +61,13 @@ export default { return dispatch(`${this.namespace}/open`, view); }, }), + openViewByName(viewName) { + const view = viewName && this.tabViews.find((x) => x.name === viewName); + + if (view) { + this.open(view); + } + }, }, }; </script> diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue index da2d4fbe7f0..c74a5052573 100644 --- a/app/assets/javascripts/ide/components/panes/right.vue +++ b/app/assets/javascripts/ide/components/panes/right.vue @@ -7,6 +7,7 @@ import PipelinesList from '../pipelines/list.vue'; import Clientside from '../preview/clientside.vue'; import ResizablePanel from '../resizable_panel.vue'; import TerminalView from '../terminal/view.vue'; +import SwitchEditorsView from '../switch_editors/switch_editors_view.vue'; import CollapsibleSidebar from './collapsible_sidebar.vue'; // Need to add the width of the nav buttons since the resizable container contains those as well @@ -20,7 +21,7 @@ export default { }, computed: { ...mapState('terminal', { isTerminalVisible: 'isVisible' }), - ...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']), + ...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled', 'canUseNewWebIde']), ...mapGetters(['packageJson']), ...mapState('rightPane', ['isOpen']), showLivePreview() { @@ -29,6 +30,12 @@ export default { rightExtensionTabs() { return [ { + show: this.canUseNewWebIde, + title: __('Switch editors'), + views: [{ component: SwitchEditorsView, ...rightSidebarViews.switchEditors }], + icon: 'bullhorn', + }, + { show: true, title: __('Pipelines'), views: [ @@ -53,6 +60,7 @@ export default { }, }, WIDTH, + SWITCH_EDITORS_VIEW_NAME: rightSidebarViews.switchEditors.name, }; </script> @@ -64,6 +72,11 @@ export default { :min-size="$options.WIDTH" :resizable="isOpen" > - <collapsible-sidebar class="gl-w-full" :extension-tabs="rightExtensionTabs" side="right" /> + <collapsible-sidebar + class="gl-w-full" + :extension-tabs="rightExtensionTabs" + :init-open-view="$options.SWITCH_EDITORS_VIEW_NAME" + side="right" + /> </resizable-panel> </template> diff --git a/app/assets/javascripts/ide/components/switch_editors/switch_editors_view.vue b/app/assets/javascripts/ide/components/switch_editors/switch_editors_view.vue new file mode 100644 index 00000000000..00164f65e33 --- /dev/null +++ b/app/assets/javascripts/ide/components/switch_editors/switch_editors_view.vue @@ -0,0 +1,103 @@ +<script> +import { GlButton, GlEmptyState, GlLink } from '@gitlab/ui'; +import { mapState } from 'vuex'; +import { createAlert } from '~/flash'; +import { logError } from '~/lib/logger'; +import axios from '~/lib/utils/axios_utils'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; +import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending'; +import { s__, __ } from '~/locale'; +import eventHub from '../../eventhub'; + +export const MSG_DESCRIPTION = s__('WebIDE|You are invited to experience the new Web IDE.'); +export const MSG_BUTTON_TEXT = s__('WebIDE|Switch to new Web IDE'); +export const MSG_LEARN_MORE = __('Learn more'); +export const MSG_TITLE = s__('WebIDE|Ready for something new?'); + +export const MSG_CONFIRM = s__( + 'WebIDE|Are you sure you want to switch editors? You will lose any unsaved changes.', +); +export const MSG_ERROR_ALERT = s__( + 'WebIDE|Something went wrong while updating the user preferences. Please see developer console for details.', +); + +export default { + components: { + GlButton, + GlEmptyState, + GlLink, + }, + data() { + return { + loading: false, + }; + }, + computed: { + ...mapState(['switchEditorSvgPath', 'links', 'userPreferencesPath']), + }, + methods: { + async submitSwitch() { + const confirmed = await confirmAction(MSG_CONFIRM, { + primaryBtnText: __('Switch editors'), + cancelBtnText: __('Cancel'), + }); + + if (!confirmed) { + return; + } + + try { + await axios.put(this.userPreferencesPath, { + user: { use_legacy_web_ide: false }, + }); + } catch (e) { + // why: We do not want to translate console logs + // eslint-disable-next-line @gitlab/require-i18n-strings + logError('Error while updating user preferences', e); + createAlert({ + message: MSG_ERROR_ALERT, + }); + return; + } + + eventHub.$emit('skip-beforeunload'); + window.location.reload(); + }, + // what: ignoreWhilePending prevents double confirmation boxes + onSwitchClicked: ignoreWhilePending(async function onSwitchClicked() { + this.loading = true; + + try { + await this.submitSwitch(); + } finally { + this.loading = false; + } + }), + }, + MSG_TITLE, + MSG_DESCRIPTION, + MSG_BUTTON_TEXT, + MSG_LEARN_MORE, +}; +</script> + +<template> + <div class="gl-h-full gl-display-flex gl-flex-direction-column gl-justify-content-center"> + <gl-empty-state :svg-path="switchEditorSvgPath" :svg-height="150" :title="$options.MSG_TITLE"> + <template #description> + <span>{{ $options.MSG_DESCRIPTION }}</span> + <gl-link :href="links.newWebIDEHelpPagePath">{{ $options.MSG_LEARN_MORE }}</gl-link + >. + </template> + <template #actions> + <gl-button + category="primary" + variant="confirm" + :loading="loading" + @click="onSwitchClicked" + >{{ $options.MSG_BUTTON_TEXT }}</gl-button + > + </template> + </gl-empty-state> + </div> +</template> diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js index bfe4c3ac271..c8e737fa6f5 100644 --- a/app/assets/javascripts/ide/constants.js +++ b/app/assets/javascripts/ide/constants.js @@ -61,6 +61,7 @@ export const leftSidebarViews = { }; export const rightSidebarViews = { + switchEditors: { name: 'switch-editors', keepAlive: true }, pipelines: { name: 'pipelines-list', keepAlive: true }, jobsDetail: { name: 'jobs-detail', keepAlive: false }, mergeRequestInfo: { name: 'merge-request-info', keepAlive: true }, diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js index 1a191f6f76f..dec282239d9 100644 --- a/app/assets/javascripts/ide/index.js +++ b/app/assets/javascripts/ide/index.js @@ -60,9 +60,11 @@ export const initLegacyWebIDE = (el, options = {}) => { committedStateSvgPath: el.dataset.committedStateSvgPath, pipelinesEmptyStateSvgPath: el.dataset.pipelinesEmptyStateSvgPath, promotionSvgPath: el.dataset.promotionSvgPath, + switchEditorSvgPath: el.dataset.switchEditorSvgPath, }); this.setLinks({ webIDEHelpPagePath: el.dataset.webIdeHelpPagePath, + newWebIDEHelpPagePath: el.dataset.newWebIdeHelpPagePath, forkInfo: el.dataset.forkInfo ? JSON.parse(el.dataset.forkInfo) : null, }); this.init({ @@ -72,6 +74,8 @@ export const initLegacyWebIDE = (el, options = {}) => { codesandboxBundlerUrl: el.dataset.codesandboxBundlerUrl, environmentsGuidanceAlertDismissed: !parseBoolean(el.dataset.enableEnvironmentsGuidance), previewMarkdownPath: el.dataset.previewMarkdownPath, + canUseNewWebIde: parseBoolean(el.dataset.canUseNewWebIde), + userPreferencesPath: el.dataset.userPreferencesPath, }); }, beforeDestroy() { diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index 48648796e66..d11fc388d5e 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -110,6 +110,7 @@ export default { committedStateSvgPath, pipelinesEmptyStateSvgPath, promotionSvgPath, + switchEditorSvgPath, }, ) { Object.assign(state, { @@ -118,6 +119,7 @@ export default { committedStateSvgPath, pipelinesEmptyStateSvgPath, promotionSvgPath, + switchEditorSvgPath, }); }, [types.TOGGLE_FILE_FINDER](state, fileFindVisible) { diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 526987c750a..70efda970bf 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -33,4 +33,6 @@ export default () => ({ environmentsGuidanceAlertDismissed: false, environmentsGuidanceAlertDetected: false, previewMarkdownPath: '', + userPreferencesPath: '', + canUseNewWebIde: false, }); |