diff options
Diffstat (limited to 'app/assets/javascripts/ide')
40 files changed, 162 insertions, 97 deletions
diff --git a/app/assets/javascripts/ide/components/activity_bar.vue b/app/assets/javascripts/ide/components/activity_bar.vue index 644808cb83a..edb7e373f6f 100644 --- a/app/assets/javascripts/ide/components/activity_bar.vue +++ b/app/assets/javascripts/ide/components/activity_bar.vue @@ -1,6 +1,7 @@ <script> import { mapActions, mapState } from 'vuex'; import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; +import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; import { leftSidebarViews } from '../constants'; export default { @@ -11,7 +12,7 @@ export default { GlTooltip: GlTooltipDirective, }, computed: { - ...mapState(['currentActivityView']), + ...mapState(['currentActivityView', 'stagedFiles']), }, methods: { ...mapActions(['updateActivityBarView']), @@ -20,7 +21,7 @@ export default { this.updateActivityBarView(view); - this.$root.$emit('bv::hide::tooltip'); + this.$root.$emit(BV_HIDE_TOOLTIP); }, }, leftSidebarViews, @@ -81,6 +82,9 @@ export default { @click.prevent="changedActivityView($event, $options.leftSidebarViews.commit.name)" > <gl-icon name="commit" /> + <div v-if="stagedFiles.length > 0" class="ide-commit-badge badge badge-pill"> + {{ stagedFiles.length }} + </div> </button> </li> </ul> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue index b89329c92ec..c7f79b3ace4 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue @@ -3,7 +3,10 @@ import { escape } from 'lodash'; import { mapState, mapGetters, createNamespacedHelpers } from 'vuex'; import { GlSprintf } from '@gitlab/ui'; import { s__ } from '~/locale'; -import consts from '../../stores/modules/commit/constants'; +import { + COMMIT_TO_CURRENT_BRANCH, + COMMIT_TO_NEW_BRANCH, +} from '../../stores/modules/commit/constants'; import RadioGroup from './radio_group.vue'; import NewMergeRequestOption from './new_merge_request_option.vue'; @@ -53,14 +56,14 @@ export default { } if (this.shouldDefaultToCurrentBranch) { - this.updateCommitAction(consts.COMMIT_TO_CURRENT_BRANCH); + this.updateCommitAction(COMMIT_TO_CURRENT_BRANCH); } else { - this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH); + this.updateCommitAction(COMMIT_TO_NEW_BRANCH); } }, }, - commitToCurrentBranch: consts.COMMIT_TO_CURRENT_BRANCH, - commitToNewBranch: consts.COMMIT_TO_NEW_BRANCH, + commitToCurrentBranch: COMMIT_TO_CURRENT_BRANCH, + commitToNewBranch: COMMIT_TO_NEW_BRANCH, currentBranchPermissionsTooltip: s__( "IDE|This option is disabled because you don't have write permissions for the current branch.", ), diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue index 7c3e522a488..dd649c7d46a 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue @@ -1,12 +1,16 @@ <script> import { mapState, mapActions, mapGetters } from 'vuex'; -import { GlModal, GlSafeHtmlDirective, GlButton } from '@gitlab/ui'; -import { n__, __ } from '~/locale'; +import { GlModal, GlSafeHtmlDirective, GlButton, GlTooltipDirective } from '@gitlab/ui'; +import { n__, s__ } from '~/locale'; +import { leftSidebarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants'; +import { createUnexpectedCommitError } from '../../lib/errors'; import CommitMessageField from './message_field.vue'; import Actions from './actions.vue'; import SuccessMessage from './success_message.vue'; -import { leftSidebarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants'; -import { createUnexpectedCommitError } from '../../lib/errors'; + +const MSG_CANNOT_PUSH_CODE = s__( + 'WebIDE|You need permission to edit files directly in this project.', +); export default { components: { @@ -18,6 +22,7 @@ export default { }, directives: { SafeHtml: GlSafeHtmlDirective, + GlTooltip: GlTooltipDirective, }, data() { return { @@ -30,15 +35,21 @@ export default { computed: { ...mapState(['changedFiles', 'stagedFiles', 'currentActivityView', 'lastCommitMsg']), ...mapState('commit', ['commitMessage', 'submitCommitLoading', 'commitError']), - ...mapGetters(['someUncommittedChanges']), + ...mapGetters(['someUncommittedChanges', 'canPushCode']), ...mapGetters('commit', ['discardDraftButtonDisabled', 'preBuiltCommitMessage']), + commitButtonDisabled() { + return !this.canPushCode || !this.someUncommittedChanges; + }, + commitButtonTooltip() { + if (!this.canPushCode) { + return MSG_CANNOT_PUSH_CODE; + } + + return ''; + }, overviewText() { return n__('%d changed file', '%d changed files', this.stagedFiles.length); }, - commitButtonText() { - return this.stagedFiles.length ? __('Commit') : __('Stage & Commit'); - }, - currentViewIsCommitView() { return this.currentActivityView === leftSidebarViews.commit.name; }, @@ -73,6 +84,12 @@ export default { 'updateCommitAction', ]), commit() { + // Even though the submit button will be disabled, we need to disable the submission + // since hitting enter on the branch name text input also submits the form. + if (!this.canPushCode) { + return false; + } + return this.commitChanges(); }, handleCompactState() { @@ -113,6 +130,8 @@ export default { this.componentHeight = null; }, }, + // Expose for tests + MSG_CANNOT_PUSH_CODE, }; </script> @@ -134,17 +153,22 @@ export default { @after-enter="afterEndTransition" > <div v-if="isCompact" ref="compactEl" class="commit-form-compact"> - <gl-button - :disabled="!someUncommittedChanges" - category="primary" - variant="info" - block - class="qa-begin-commit-button" - data-testid="begin-commit-button" - @click="beginCommit" + <div + v-gl-tooltip="{ title: commitButtonTooltip }" + data-testid="begin-commit-button-tooltip" > - {{ __('Commit…') }} - </gl-button> + <gl-button + :disabled="commitButtonDisabled" + category="primary" + variant="info" + block + class="qa-begin-commit-button" + data-testid="begin-commit-button" + @click="beginCommit" + > + {{ __('Commit…') }} + </gl-button> + </div> <p class="text-center bold">{{ overviewText }}</p> </div> <form v-else ref="formEl" @submit.prevent.stop="commit"> @@ -157,16 +181,29 @@ export default { /> <div class="clearfix gl-mt-5"> <actions /> + <div + v-gl-tooltip="{ title: commitButtonTooltip }" + class="float-left" + data-testid="commit-button-tooltip" + > + <gl-button + :disabled="commitButtonDisabled" + :loading="submitCommitLoading" + data-testid="commit-button" + class="qa-commit-button" + category="primary" + variant="success" + @click="commit" + > + {{ __('Commit') }} + </gl-button> + </div> <gl-button - :loading="submitCommitLoading" - class="float-left qa-commit-button" - category="primary" - variant="success" - @click="commit" + v-if="!discardDraftButtonDisabled" + class="float-right" + data-testid="discard-draft" + @click="discardDraft" > - {{ __('Commit') }} - </gl-button> - <gl-button v-if="!discardDraftButtonDisabled" class="float-right" @click="discardDraft"> {{ __('Discard draft') }} </gl-button> <gl-button 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 4192a002486..ab90ab0791a 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -85,7 +85,11 @@ export default { role="button" @click="openFileInEditor" > - <span class="multi-file-commit-list-file-path d-flex align-items-center"> + <span + class="multi-file-commit-list-file-path d-flex align-items-center" + data-qa-selector="file_to_commit_content" + :data-qa-file-name="file.name" + > <file-icon :file-name="file.name" class="gl-mr-3" /> <template v-if="file.prevName && file.prevName !== file.name"> {{ file.prevName }} → diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index aac899fde0d..131a039ef1a 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -1,7 +1,7 @@ <script> import { mapActions, mapGetters, mapState } from 'vuex'; -import { GlButton, GlLoadingIcon } from '@gitlab/ui'; -import { __ } from '~/locale'; +import { GlAlert, GlButton, GlLoadingIcon } from '@gitlab/ui'; +import { __, s__ } from '~/locale'; import { WEBIDE_MARK_APP_START, WEBIDE_MARK_FILE_FINISH, @@ -10,13 +10,12 @@ import { WEBIDE_MEASURE_BEFORE_VUE, } from '~/performance/constants'; import { performanceMarkAndMeasure } from '~/performance/utils'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { modalTypes } from '../constants'; import eventHub from '../eventhub'; +import { measurePerformance } from '../utils'; import IdeSidebar from './ide_side_bar.vue'; import RepoEditor from './repo_editor.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; - -import { measurePerformance } from '../utils'; eventHub.$on(WEBIDE_MEASURE_FILE_AFTER_INTERACTION, () => measurePerformance( @@ -26,10 +25,15 @@ eventHub.$on(WEBIDE_MEASURE_FILE_AFTER_INTERACTION, () => ), ); +const MSG_CANNOT_PUSH_CODE = s__( + 'WebIDE|You need permission to edit files directly in this project. Fork this project to make your changes and submit a merge request.', +); + export default { components: { IdeSidebar, RepoEditor, + GlAlert, GlButton, GlLoadingIcon, ErrorMessage: () => import(/* webpackChunkName: 'ide_runtime' */ './error_message.vue'), @@ -59,12 +63,14 @@ export default { 'loading', ]), ...mapGetters([ + 'canPushCode', 'activeFile', 'someUncommittedChanges', 'isCommitModeActive', 'allBlobs', 'emptyRepo', 'currentTree', + 'hasCurrentProject', 'editorTheme', 'getUrlForPath', ]), @@ -110,6 +116,7 @@ export default { this.loadDeferred = true; }, }, + MSG_CANNOT_PUSH_CODE, }; </script> @@ -118,6 +125,9 @@ export default { class="ide position-relative d-flex flex-column align-items-stretch" :class="{ [`theme-${themeName}`]: themeName }" > + <gl-alert v-if="!canPushCode" :dismissible="false">{{ + $options.MSG_CANNOT_PUSH_CODE + }}</gl-alert> <error-message v-if="errorMessage" :message="errorMessage" /> <div class="ide-view flex-grow d-flex"> <template v-if="loadDeferred"> diff --git a/app/assets/javascripts/ide/components/ide_review.vue b/app/assets/javascripts/ide/components/ide_review.vue index 7d2f0acb08c..d75629e9995 100644 --- a/app/assets/javascripts/ide/components/ide_review.vue +++ b/app/assets/javascripts/ide/components/ide_review.vue @@ -1,8 +1,8 @@ <script> import { mapGetters, mapState, mapActions } from 'vuex'; +import { viewerTypes } from '../constants'; import IdeTreeList from './ide_tree_list.vue'; import EditorModeDropdown from './editor_mode_dropdown.vue'; -import { viewerTypes } from '../constants'; export default { components: { diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue index 135b28685ed..a447dae3f80 100644 --- a/app/assets/javascripts/ide/components/ide_side_bar.vue +++ b/app/assets/javascripts/ide/components/ide_side_bar.vue @@ -1,12 +1,12 @@ <script> import { mapState, mapGetters } from 'vuex'; import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; +import { SIDEBAR_INIT_WIDTH, leftSidebarViews } from '../constants'; import IdeTree from './ide_tree.vue'; import ResizablePanel from './resizable_panel.vue'; import ActivityBar from './activity_bar.vue'; import CommitForm from './commit_sidebar/form.vue'; import IdeProjectHeader from './ide_project_header.vue'; -import { SIDEBAR_INIT_WIDTH, leftSidebarViews } from '../constants'; export default { components: { diff --git a/app/assets/javascripts/ide/components/ide_sidebar_nav.vue b/app/assets/javascripts/ide/components/ide_sidebar_nav.vue index 9dbed0ace40..6bc84eb90c6 100644 --- a/app/assets/javascripts/ide/components/ide_sidebar_nav.vue +++ b/app/assets/javascripts/ide/components/ide_sidebar_nav.vue @@ -1,5 +1,6 @@ <script> import { GlTooltipDirective, GlIcon } from '@gitlab/ui'; +import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; import { otherSide } from '../utils'; import { SIDE_RIGHT } from '../constants'; @@ -50,7 +51,7 @@ export default { }, clickTab(e, tab) { e.currentTarget.blur(); - this.$root.$emit('bv::hide::tooltip'); + this.$root.$emit(BV_HIDE_TOOLTIP); if (this.isActiveTab(tab)) { this.$emit('close'); diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue index ee292190e06..8a47835a252 100644 --- a/app/assets/javascripts/ide/components/ide_status_bar.vue +++ b/app/assets/javascripts/ide/components/ide_status_bar.vue @@ -2,12 +2,12 @@ /* eslint-disable @gitlab/vue-require-i18n-strings */ import { mapActions, mapState, mapGetters } from 'vuex'; import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; -import IdeStatusList from './ide_status_list.vue'; -import IdeStatusMr from './ide_status_mr.vue'; import timeAgoMixin from '~/vue_shared/mixins/timeago'; import CiIcon from '../../vue_shared/components/ci_icon.vue'; import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; import { rightSidebarViews } from '../constants'; +import IdeStatusMr from './ide_status_mr.vue'; +import IdeStatusList from './ide_status_list.vue'; export default { components: { diff --git a/app/assets/javascripts/ide/components/ide_status_list.vue b/app/assets/javascripts/ide/components/ide_status_list.vue index aa61c0d9b5e..9966d109b55 100644 --- a/app/assets/javascripts/ide/components/ide_status_list.vue +++ b/app/assets/javascripts/ide/components/ide_status_list.vue @@ -1,8 +1,8 @@ <script> import { mapGetters } from 'vuex'; import { GlLink, GlTooltipDirective } from '@gitlab/ui'; -import TerminalSyncStatusSafe from './terminal_sync/terminal_sync_status_safe.vue'; import { isTextFile, getFileEOL } from '~/ide/utils'; +import TerminalSyncStatusSafe from './terminal_sync/terminal_sync_status_safe.vue'; export default { components: { diff --git a/app/assets/javascripts/ide/components/ide_tree.vue b/app/assets/javascripts/ide/components/ide_tree.vue index e563de6659a..d10714a687d 100644 --- a/app/assets/javascripts/ide/components/ide_tree.vue +++ b/app/assets/javascripts/ide/components/ide_tree.vue @@ -58,8 +58,9 @@ export default { <new-entry-button :label="__('New file')" :show-label="false" - class="d-flex border-0 p-0 mr-3 qa-new-file" + class="d-flex border-0 p-0 mr-3" icon="doc-new" + data-qa-selector="new_file_button" @click="createNewFile()" /> <upload @@ -73,6 +74,7 @@ export default { :show-label="false" class="d-flex border-0 p-0" icon="folder-new" + data-qa-selector="new_directory_button" @click="createNewFolder()" /> </div> diff --git a/app/assets/javascripts/ide/components/merge_requests/list.vue b/app/assets/javascripts/ide/components/merge_requests/list.vue index 4b3c6e61e11..c6711d1ac10 100644 --- a/app/assets/javascripts/ide/components/merge_requests/list.vue +++ b/app/assets/javascripts/ide/components/merge_requests/list.vue @@ -3,8 +3,8 @@ import { mapActions, mapState } from 'vuex'; import { debounce } from 'lodash'; import { GlLoadingIcon, GlIcon } from '@gitlab/ui'; import { __ } from '~/locale'; -import Item from './item.vue'; import TokenedInput from '../shared/tokened_input.vue'; +import Item from './item.vue'; const SEARCH_TYPES = [ { type: 'created', label: __('Created by me') }, diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue index 692878de5e1..46d21bc14aa 100644 --- a/app/assets/javascripts/ide/components/new_dropdown/index.vue +++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue @@ -1,9 +1,9 @@ <script> import { mapActions } from 'vuex'; import { GlIcon } from '@gitlab/ui'; +import { modalTypes } from '../../constants'; import upload from './upload.vue'; import ItemButton from './button.vue'; -import { modalTypes } from '../../constants'; import NewModal from './modal.vue'; export default { @@ -108,6 +108,7 @@ export default { class="d-flex" icon="remove" icon-classes="mr-2" + data-qa-selector="delete_button" @click="deleteEntry(path)" /> </li> diff --git a/app/assets/javascripts/ide/components/new_dropdown/upload.vue b/app/assets/javascripts/ide/components/new_dropdown/upload.vue index 5704129c10f..76d8a0aff3d 100644 --- a/app/assets/javascripts/ide/components/new_dropdown/upload.vue +++ b/app/assets/javascripts/ide/components/new_dropdown/upload.vue @@ -1,6 +1,6 @@ <script> -import ItemButton from './button.vue'; import { isTextFile } from '~/ide/utils'; +import ItemButton from './button.vue'; export default { components: { diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue index 46ef08a45a9..da484893530 100644 --- a/app/assets/javascripts/ide/components/panes/right.vue +++ b/app/assets/javascripts/ide/components/panes/right.vue @@ -1,13 +1,13 @@ <script> import { mapGetters, mapState } from 'vuex'; import { __ } from '~/locale'; -import CollapsibleSidebar from './collapsible_sidebar.vue'; import ResizablePanel from '../resizable_panel.vue'; import { rightSidebarViews, SIDEBAR_INIT_WIDTH, SIDEBAR_NAV_WIDTH } from '../../constants'; import PipelinesList from '../pipelines/list.vue'; import JobsDetail from '../jobs/detail.vue'; import Clientside from '../preview/clientside.vue'; import TerminalView from '../terminal/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 const WIDTH = SIDEBAR_INIT_WIDTH + SIDEBAR_NAV_WIDTH; diff --git a/app/assets/javascripts/ide/components/pipelines/list.vue b/app/assets/javascripts/ide/components/pipelines/list.vue index a4a13389fbf..4c13dfc7a1d 100644 --- a/app/assets/javascripts/ide/components/pipelines/list.vue +++ b/app/assets/javascripts/ide/components/pipelines/list.vue @@ -10,13 +10,12 @@ import { GlBadge, GlAlert, } from '@gitlab/ui'; +import IDEServices from '~/ide/services'; import { sprintf, __ } from '../../../locale'; import CiIcon from '../../../vue_shared/components/ci_icon.vue'; import EmptyState from '../../../pipelines/components/pipelines_list/empty_state.vue'; import JobsList from '../jobs/list.vue'; -import IDEServices from '~/ide/services'; - export default { components: { GlIcon, diff --git a/app/assets/javascripts/ide/components/preview/clientside.vue b/app/assets/javascripts/ide/components/preview/clientside.vue index 4c2a369226e..3bfb8f918af 100644 --- a/app/assets/javascripts/ide/components/preview/clientside.vue +++ b/app/assets/javascripts/ide/components/preview/clientside.vue @@ -4,10 +4,10 @@ import { isEmpty, debounce } from 'lodash'; import { Manager } from 'smooshpack'; import { listen } from 'codesandbox-api'; import { GlLoadingIcon } from '@gitlab/ui'; -import Navigator from './navigator.vue'; import { packageJsonPath, LIVE_PREVIEW_DEBOUNCE } from '../../constants'; import { createPathWithExt } from '../../utils'; import eventHub from '../../eventhub'; +import Navigator from './navigator.vue'; export default { components: { @@ -165,7 +165,7 @@ export default { </p> <a :href="links.webIDEHelpPagePath" - class="btn btn-primary" + class="btn gl-button btn-confirm" target="_blank" rel="noopener noreferrer" > diff --git a/app/assets/javascripts/ide/components/preview/navigator.vue b/app/assets/javascripts/ide/components/preview/navigator.vue index 8986359427f..ad4e6adf125 100644 --- a/app/assets/javascripts/ide/components/preview/navigator.vue +++ b/app/assets/javascripts/ide/components/preview/navigator.vue @@ -78,6 +78,7 @@ export default { this.visitPath(this.path); }, visitPath(path) { + // eslint-disable-next-line vue/no-mutating-props this.manager.iframe.src = `${this.manager.bundlerURL}${path}`; }, }, diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index 8092ef3bce6..c5ff9fbbc01 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -1,8 +1,8 @@ <script> import { mapState, mapActions, mapGetters } from 'vuex'; +import { stageKeys } from '../constants'; import CommitFilesList from './commit_sidebar/list.vue'; import EmptyState from './commit_sidebar/empty_state.vue'; -import { stageKeys } from '../constants'; export default { components: { diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue index a9c05f2e1ac..9f8bd299d52 100644 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -12,21 +12,21 @@ import { WEBIDE_MEASURE_FILE_AFTER_INTERACTION, } from '~/performance/constants'; import { performanceMarkAndMeasure } from '~/performance/utils'; -import eventHub from '../eventhub'; +import { __ } from '~/locale'; +import Editor from '../lib/editor'; import { leftSidebarViews, viewerTypes, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW, } from '../constants'; -import Editor from '../lib/editor'; -import FileTemplatesBar from './file_templates/bar.vue'; -import { __ } from '~/locale'; +import eventHub from '../eventhub'; 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'; +import FileTemplatesBar from './file_templates/bar.vue'; export default { name: 'RepoEditor', diff --git a/app/assets/javascripts/ide/components/terminal/session.vue b/app/assets/javascripts/ide/components/terminal/session.vue index 0e67a2ab45f..4089d2e4ba9 100644 --- a/app/assets/javascripts/ide/components/terminal/session.vue +++ b/app/assets/javascripts/ide/components/terminal/session.vue @@ -2,8 +2,8 @@ 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'; +import Terminal from './terminal.vue'; export default { components: { diff --git a/app/assets/javascripts/ide/components/terminal/terminal.vue b/app/assets/javascripts/ide/components/terminal/terminal.vue index 0ee4107f9ab..9cfc5504c83 100644 --- a/app/assets/javascripts/ide/components/terminal/terminal.vue +++ b/app/assets/javascripts/ide/components/terminal/terminal.vue @@ -3,9 +3,9 @@ import { mapState } from 'vuex'; import { GlLoadingIcon } from '@gitlab/ui'; import { __ } from '~/locale'; import GLTerminal from '~/terminal/terminal'; -import TerminalControls from './terminal_controls.vue'; import { RUNNING, STOPPING } from '../../stores/modules/terminal/constants'; import { isStartingStatus } from '../../stores/modules/terminal/utils'; +import TerminalControls from './terminal_controls.vue'; export default { components: { diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js index e5618466395..6bd74b143e2 100644 --- a/app/assets/javascripts/ide/constants.js +++ b/app/assets/javascripts/ide/constants.js @@ -16,6 +16,13 @@ export const PERMISSION_CREATE_MR = 'createMergeRequestIn'; export const PERMISSION_READ_MR = 'readMergeRequest'; export const PERMISSION_PUSH_CODE = 'pushCode'; +// The default permission object to use when the project data isn't available yet. +// This helps us encapsulate checks like `canPushCode` without requiring an +// additional check like `currentProject && canPushCode`. +export const DEFAULT_PERMISSIONS = { + [PERMISSION_PUSH_CODE]: true, +}; + export const viewerTypes = { mr: 'mrdiff', edit: 'editor', diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js index af408c06556..bf0d6b32850 100644 --- a/app/assets/javascripts/ide/index.js +++ b/app/assets/javascripts/ide/index.js @@ -3,11 +3,11 @@ import { mapActions } from 'vuex'; import { identity } from 'lodash'; import Translate from '~/vue_shared/translate'; import PerformancePlugin from '~/performance/vue_performance_plugin'; +import { parseBoolean } from '../lib/utils/common_utils'; +import { resetServiceWorkersPublicPath } from '../lib/utils/webpack'; import ide from './components/ide.vue'; import { createStore } from './stores'; import { createRouter } from './ide_router'; -import { parseBoolean } from '../lib/utils/common_utils'; -import { resetServiceWorkersPublicPath } from '../lib/utils/webpack'; import { DEFAULT_THEME } from './lib/themes'; Vue.use(Translate); diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js index 4969875439e..46128651547 100644 --- a/app/assets/javascripts/ide/lib/common/model.js +++ b/app/assets/javascripts/ide/lib/common/model.js @@ -1,9 +1,9 @@ import { editor as monacoEditor, Uri } from 'monaco-editor'; -import Disposable from './disposable'; +import { insertFinalNewline } from '~/lib/utils/text_utility'; import eventHub from '../../eventhub'; import { trimTrailingWhitespace } from '../../utils'; -import { insertFinalNewline } from '~/lib/utils/text_utility'; import { defaultModelOptions } from '../editor_options'; +import Disposable from './disposable'; export default class Model { constructor(file, head = null) { diff --git a/app/assets/javascripts/ide/lib/diff/controller.js b/app/assets/javascripts/ide/lib/diff/controller.js index 3efe692be13..ee4fdd10c97 100644 --- a/app/assets/javascripts/ide/lib/diff/controller.js +++ b/app/assets/javascripts/ide/lib/diff/controller.js @@ -1,7 +1,7 @@ import { Range } from 'monaco-editor'; import { throttle } from 'lodash'; -import DirtyDiffWorker from './diff_worker'; import Disposable from '../common/disposable'; +import DirtyDiffWorker from './diff_worker'; export const getDiffChangeType = (change) => { if (change.modified) { diff --git a/app/assets/javascripts/ide/lib/editor.js b/app/assets/javascripts/ide/lib/editor.js index 4fad0c09ce7..f3c572bfeed 100644 --- a/app/assets/javascripts/ide/lib/editor.js +++ b/app/assets/javascripts/ide/lib/editor.js @@ -1,5 +1,7 @@ import { debounce } from 'lodash'; import { editor as monacoEditor, KeyCode, KeyMod, Range } from 'monaco-editor'; +import { clearDomElement } from '~/editor/utils'; +import { registerLanguages } from '../utils'; import DecorationsController from './decorations/controller'; import DirtyDiffController from './diff/controller'; import Disposable from './common/disposable'; @@ -8,8 +10,6 @@ import { editorOptions, defaultEditorOptions, defaultDiffEditorOptions } from '. import { themes } from './themes'; import languages from './languages'; import keymap from './keymap.json'; -import { clearDomElement } from '~/editor/utils'; -import { registerLanguages } from '../utils'; function setupThemes() { themes.forEach((theme) => { diff --git a/app/assets/javascripts/ide/lib/errors.js b/app/assets/javascripts/ide/lib/errors.js index f975034a872..a8a048e588f 100644 --- a/app/assets/javascripts/ide/lib/errors.js +++ b/app/assets/javascripts/ide/lib/errors.js @@ -1,6 +1,6 @@ import { escape } from 'lodash'; import { __ } from '~/locale'; -import consts from '../stores/modules/commit/constants'; +import { COMMIT_TO_NEW_BRANCH } from '../stores/modules/commit/constants'; const CODEOWNERS_REGEX = /Push.*protected branches.*CODEOWNERS/; const BRANCH_CHANGED_REGEX = /changed.*since.*start.*edit/; @@ -8,7 +8,7 @@ const BRANCH_ALREADY_EXISTS = /branch.*already.*exists/; const createNewBranchAndCommit = (store) => store - .dispatch('commit/updateCommitAction', consts.COMMIT_TO_NEW_BRANCH) + .dispatch('commit/updateCommitAction', COMMIT_TO_NEW_BRANCH) .then(() => store.dispatch('commit/commitChanges')); export const createUnexpectedCommitError = (message) => ({ diff --git a/app/assets/javascripts/ide/lib/mirror.js b/app/assets/javascripts/ide/lib/mirror.js index 6f9cfec9465..78990953beb 100644 --- a/app/assets/javascripts/ide/lib/mirror.js +++ b/app/assets/javascripts/ide/lib/mirror.js @@ -1,6 +1,6 @@ -import createDiff from './create_diff'; import { getWebSocketUrl, mergeUrlParams } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; +import createDiff from './create_diff'; export const SERVICE_NAME = 'webide-file-sync'; export const PROTOCOL = 'webfilesync.gitlab.com'; diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js index d62dfc35d15..d4ae460d78b 100644 --- a/app/assets/javascripts/ide/stores/actions.js +++ b/app/assets/javascripts/ide/stores/actions.js @@ -9,11 +9,11 @@ import { 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'; import service from '../services'; import eventHub from '../eventhub'; +import * as types from './mutation_types'; export const redirectToUrl = (self, url) => visitUrl(url); diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js index 59e8d37a92a..9600c1a1b8c 100644 --- a/app/assets/javascripts/ide/stores/getters.js +++ b/app/assets/javascripts/ide/stores/getters.js @@ -1,13 +1,14 @@ -import { getChangesCountForFiles, filePathMatches } from './utils'; +import { addNumericSuffix } from '~/ide/utils'; +import Api from '~/api'; import { leftSidebarViews, packageJsonPath, + DEFAULT_PERMISSIONS, PERMISSION_READ_MR, PERMISSION_CREATE_MR, PERMISSION_PUSH_CODE, } from '../constants'; -import { addNumericSuffix } from '~/ide/utils'; -import Api from '~/api'; +import { getChangesCountForFiles, filePathMatches } from './utils'; export const activeFile = (state) => state.openFiles.find((file) => file.active) || null; @@ -150,7 +151,7 @@ export const getDiffInfo = (state, getters) => (path) => { }; export const findProjectPermissions = (state, getters) => (projectId) => - getters.findProject(projectId)?.userPermissions || {}; + getters.findProject(projectId)?.userPermissions || DEFAULT_PERMISSIONS; export const canReadMergeRequests = (state, getters) => Boolean(getters.findProjectPermissions(state.currentProjectId)[PERMISSION_READ_MR]); diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index 29b9a8a9521..57a1e4f133a 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -1,14 +1,14 @@ import { sprintf, __ } from '~/locale'; import { deprecatedCreateFlash as flash } from '~/flash'; +import { addNumericSuffix } from '~/ide/utils'; import * as rootTypes from '../../mutation_types'; import { createCommitPayload, createNewMergeRequestUrl } from '../../utils'; import service from '../../../services'; -import * as types from './mutation_types'; -import consts from './constants'; import { leftSidebarViews } from '../../../constants'; import eventHub from '../../../eventhub'; import { parseCommitError } from '../../../lib/errors'; -import { addNumericSuffix } from '~/ide/utils'; +import { COMMIT_TO_CURRENT_BRANCH } from './constants'; +import * as types from './mutation_types'; export const updateCommitMessage = ({ commit }, message) => { commit(types.UPDATE_COMMIT_MESSAGE, message); @@ -112,7 +112,7 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo // Pull commit options out because they could change // During some of the pre and post commit processing const { shouldCreateMR, shouldHideNewMrOption, isCreatingNewBranch, branchName } = getters; - const newBranch = state.commitAction !== consts.COMMIT_TO_CURRENT_BRANCH; + const newBranch = state.commitAction !== COMMIT_TO_CURRENT_BRANCH; const stageFilesPromise = rootState.stagedFiles.length ? Promise.resolve() : dispatch('stageAllChanges', null, { root: true }); @@ -206,7 +206,7 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo dispatch('updateViewer', 'editor', { root: true }); } }) - .then(() => dispatch('updateCommitAction', consts.COMMIT_TO_CURRENT_BRANCH)) + .then(() => dispatch('updateCommitAction', COMMIT_TO_CURRENT_BRANCH)) .then(() => { if (newBranch) { const path = rootGetters.activeFile ? rootGetters.activeFile.path : ''; diff --git a/app/assets/javascripts/ide/stores/modules/commit/constants.js b/app/assets/javascripts/ide/stores/modules/commit/constants.js index c6c3701effe..9f4299e5537 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/constants.js +++ b/app/assets/javascripts/ide/stores/modules/commit/constants.js @@ -1,7 +1,2 @@ -const COMMIT_TO_CURRENT_BRANCH = '1'; -const COMMIT_TO_NEW_BRANCH = '2'; - -export default { - COMMIT_TO_CURRENT_BRANCH, - COMMIT_TO_NEW_BRANCH, -}; +export const COMMIT_TO_CURRENT_BRANCH = '1'; +export const COMMIT_TO_NEW_BRANCH = '2'; diff --git a/app/assets/javascripts/ide/stores/modules/commit/getters.js b/app/assets/javascripts/ide/stores/modules/commit/getters.js index 2301cf23f9f..f5e367e16f5 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/getters.js +++ b/app/assets/javascripts/ide/stores/modules/commit/getters.js @@ -1,5 +1,5 @@ import { sprintf, n__, __ } from '../../../../locale'; -import consts from './constants'; +import { COMMIT_TO_NEW_BRANCH } from './constants'; const BRANCH_SUFFIX_COUNT = 5; const createTranslatedTextForFiles = (files, text) => { @@ -48,7 +48,7 @@ export const preBuiltCommitMessage = (state, _, rootState) => { .join('\n'); }; -export const isCreatingNewBranch = (state) => state.commitAction === consts.COMMIT_TO_NEW_BRANCH; +export const isCreatingNewBranch = (state) => state.commitAction === COMMIT_TO_NEW_BRANCH; export const shouldHideNewMrOption = (_state, getters, _rootState, rootGetters) => !getters.isCreatingNewBranch && diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js index 6800f824da0..ad5b01e7040 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js @@ -1,8 +1,8 @@ import Api from '~/api'; import { __ } from '~/locale'; import { normalizeHeaders } from '~/lib/utils/common_utils'; -import * as types from './mutation_types'; import eventHub from '../../../eventhub'; +import * as types from './mutation_types'; export const requestTemplateTypes = ({ commit }) => commit(types.REQUEST_TEMPLATE_TYPES); export const receiveTemplateTypesError = ({ commit, dispatch }) => { diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js index 0613fe9b12b..9708e5e588c 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js @@ -1,5 +1,5 @@ -import { leftSidebarViews } from '../../../constants'; import { __ } from '~/locale'; +import { leftSidebarViews } from '../../../constants'; export const templateTypes = () => [ { diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js index 006800f58c2..a2cb0666a99 100644 --- a/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js +++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js @@ -1,5 +1,5 @@ -import * as types from './mutation_types'; import mirror, { canConnect } from '../../../lib/mirror'; +import * as types from './mutation_types'; export const upload = ({ rootState, commit }) => { commit(types.START_LOADING); diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js index 4446971d5d6..d678c5e280c 100644 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -1,7 +1,7 @@ +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import * as types from '../mutation_types'; import { sortTree } from '../utils'; import { diffModes } from '../../constants'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; export default { [types.SET_FILE_ACTIVE](state, { path, active }) { diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index 04eacf271b8..4019703b296 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -1,10 +1,10 @@ -import { commitActionTypes } from '../constants'; import { relativePathToAbsolute, isAbsolute, isRootRelative, isBlobUrl, } from '~/lib/utils/url_utility'; +import { commitActionTypes } from '../constants'; export const dataStructure = () => ({ id: '', diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js index 8eb2d17b876..99d6ccde770 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 { SIDE_LEFT, SIDE_RIGHT } from './constants'; const toLowerCase = (x) => x.toLowerCase(); |