diff options
Diffstat (limited to 'app')
18 files changed, 486 insertions, 195 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue new file mode 100644 index 00000000000..e69535335d4 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue @@ -0,0 +1,87 @@ +<script> +import { mapActions, mapState, mapGetters } from 'vuex'; +import Icon from '~/vue_shared/components/icon.vue'; + +export default { + components: { + Icon, + }, + props: { + noChangesStateSvgPath: { + type: String, + required: true, + }, + committedStateSvgPath: { + type: String, + required: true, + }, + }, + computed: { + ...mapState(['lastCommitMsg', 'rightPanelCollapsed']), + ...mapGetters(['collapseButtonIcon']), + statusSvg() { + return this.lastCommitMsg + ? this.committedStateSvgPath + : this.noChangesStateSvgPath; + }, + }, + methods: { + ...mapActions(['toggleRightPanelCollapsed']), + }, +}; +</script> + +<template> + <div + class="multi-file-commit-panel-section ide-commity-empty-state js-empty-state" + > + <header + class="multi-file-commit-panel-header" + :class="{ + 'is-collapsed': rightPanelCollapsed, + }" + > + <button + type="button" + class="btn btn-transparent multi-file-commit-panel-collapse-btn" + :aria-label="__('Toggle sidebar')" + @click.stop="toggleRightPanelCollapsed" + > + <icon + :name="collapseButtonIcon" + :size="18" + /> + </button> + </header> + <div + class="ide-commit-empty-state-container" + v-if="!rightPanelCollapsed" + > + <div class="svg-content svg-80"> + <img :src="statusSvg" /> + </div> + <div class="append-right-default prepend-left-default"> + <div + class="text-content text-center" + v-if="!lastCommitMsg" + > + <h4> + {{ __('No changes') }} + </h4> + <p> + {{ __('Edit files in the editor and commit changes here') }} + </p> + </div> + <div + class="text-content text-center" + v-else + > + <h4> + {{ __('All changes are committed') }} + </h4> + <p v-html="lastCommitMsg"></p> + </div> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index 453208f3f19..e3280bbb204 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -1,5 +1,5 @@ <script> - import { mapState } from 'vuex'; + import { mapActions, mapState, mapGetters } from 'vuex'; import icon from '~/vue_shared/components/icon.vue'; import listItem from './list_item.vue'; import listCollapsed from './list_collapsed.vue'; @@ -19,20 +19,44 @@ type: Array, required: true, }, + showToggle: { + type: Boolean, + required: false, + default: true, + }, + icon: { + type: String, + required: true, + }, + action: { + type: String, + required: true, + }, + actionBtnText: { + type: String, + required: true, + }, + itemActionComponent: { + type: String, + required: true, + }, }, computed: { ...mapState([ - 'currentProjectId', - 'currentBranchId', 'rightPanelCollapsed', ]), - isCommitInfoShown() { - return this.rightPanelCollapsed || this.fileList.length; - }, + ...mapGetters([ + 'collapseButtonIcon', + ]), }, methods: { - toggleCollapsed() { - this.$emit('toggleCollapsed'); + ...mapActions([ + 'toggleRightPanelCollapsed', + 'stageAllChanges', + 'unstageAllChanges', + ]), + actionBtnClicked() { + this[this.action](); }, }, }; @@ -40,17 +64,60 @@ <template> <div + class="ide-commit-list-container" :class="{ - 'multi-file-commit-list': isCommitInfoShown + 'is-collapsed': rightPanelCollapsed, }" > + <header + class="multi-file-commit-panel-header" + :class="{ + 'is-collapsed': rightPanelCollapsed, + }" + > + <div + v-if="!rightPanelCollapsed" + class="multi-file-commit-panel-header-title" + :class="{ + 'append-right-10': showToggle, + }" + > + <icon + v-once + :name="icon" + :size="18" + /> + {{ title }} + <button + type="button" + class="btn btn-blank btn-link ide-staged-action-btn" + @click="actionBtnClicked" + > + {{ actionBtnText }} + </button> + </div> + <button + v-if="showToggle" + type="button" + class="btn btn-transparent multi-file-commit-panel-collapse-btn" + :aria-label="__('Toggle sidebar')" + @click.stop="toggleRightPanelCollapsed" + > + <icon + :name="collapseButtonIcon" + :size="18" + /> + </button> + </header> <list-collapsed v-if="rightPanelCollapsed" + :files="fileList" + :icon="icon" /> <template v-else> <ul v-if="fileList.length" - class="list-unstyled append-bottom-0" + class="multi-file-commit-list list-unstyled append-bottom-0" > <li v-for="file in fileList" @@ -58,9 +125,16 @@ > <list-item :file="file" + :action-component="itemActionComponent" /> </li> </ul> + <p + v-else + class="multi-file-commit-list help-block" + > + {{ __('No changes') }} + </p> </template> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue index 15918ac9631..3ab454c2441 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue @@ -1,18 +1,35 @@ <script> - import { mapGetters } from 'vuex'; - import icon from '~/vue_shared/components/icon.vue'; +import icon from '~/vue_shared/components/icon.vue'; - export default { - components: { - icon, +export default { + components: { + icon, + }, + props: { + files: { + type: Array, + required: true, }, - computed: { - ...mapGetters([ - 'addedFiles', - 'modifiedFiles', - ]), + icon: { + 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' : ''; + }, + }, +}; </script> <template> @@ -20,16 +37,22 @@ class="multi-file-commit-list-collapsed text-center" > <icon + v-once + :name="icon" + :size="18" + css-classes="append-bottom-15" + /> + <icon name="file-addition" :size="18" - css-classes="multi-file-addition append-bottom-10" + :css-classes="addedFilesIconClass + 'append-bottom-10'" /> - {{ addedFiles.length }} + {{ addedFilesLength }} <icon name="file-modified" :size="18" - css-classes="multi-file-modified prepend-top-10 append-bottom-10" + :css-classes="modifiedFilesClass + ' prepend-top-10 append-bottom-10'" /> - {{ modifiedFiles.length }} + {{ 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 18934af004a..93c8fc00f28 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -1,38 +1,44 @@ <script> - import { mapActions } from 'vuex'; - import icon from '~/vue_shared/components/icon.vue'; - import router from '../../ide_router'; +import Icon from '~/vue_shared/components/icon.vue'; +import StageButton from './stage_button.vue'; +import UnstageButton from './unstage_button.vue'; +import router from '../../ide_router'; - export default { - components: { - icon, +export default { + components: { + Icon, + StageButton, + UnstageButton, + }, + props: { + file: { + type: Object, + required: true, }, - props: { - file: { - type: Object, - required: true, - }, + actionComponent: { + type: String, + required: true, }, - computed: { - iconName() { - return this.file.tempFile ? 'file-addition' : 'file-modified'; - }, - iconClass() { - return `multi-file-${this.file.tempFile ? 'addition' : 'modified'} append-right-8`; - }, + }, + computed: { + iconName() { + return this.file.tempFile ? 'file-addition' : 'file-modified'; }, - methods: { - ...mapActions([ - 'discardFileChanges', - 'updateViewer', - ]), - openFileInEditor(file) { - this.updateViewer('diff'); + iconClass() { + return `multi-file-${ + this.file.tempFile ? 'addition' : 'modified' + } append-right-8`; + }, + }, + methods: { + ...mapActions(['updateViewer']), + openFileInEditor(file) { + this.updateViewer('diff'); - router.push(`/project${file.url}`); - }, + router.push(`/project${file.url}`); }, - }; + }, +}; </script> <template> @@ -49,12 +55,9 @@ />{{ file.path }} </span> </button> - <button - type="button" - class="btn btn-blank multi-file-discard-btn" - @click="discardFileChanges(file.path)" - > - Discard - </button> + <component + :is="actionComponent" + :file="file" + /> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue new file mode 100644 index 00000000000..0189358d82f --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -0,0 +1,49 @@ +<script> +import { mapActions } from 'vuex'; +import Icon from '~/vue_shared/components/icon.vue'; + +export default { + components: { + Icon, + }, + props: { + file: { + type: Object, + required: true, + }, + }, + methods: { + ...mapActions(['stageChange', 'discardFileChanges']), + }, +}; +</script> + +<template> + <div + v-once + class="multi-file-discard-btn" + > + <button + type="button" + class="btn btn-blank append-right-5" + :aria-label="__('Stage change')" + @click.stop="stageChange(file)" + > + <icon + name="mobile-issue-close" + :size="12" + /> + </button> + <button + type="button" + class="btn btn-blank" + :aria-label="__('Discard change')" + @click.stop="discardFileChanges(file)" + > + <icon + name="remove" + :size="12" + /> + </button> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue new file mode 100644 index 00000000000..fd7ec0366a2 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue @@ -0,0 +1,38 @@ +<script> +import { mapActions } from 'vuex'; +import Icon from '~/vue_shared/components/icon.vue'; + +export default { + components: { + Icon, + }, + props: { + file: { + type: Object, + required: true, + }, + }, + methods: { + ...mapActions(['unstageChange']), + }, +}; +</script> + +<template> + <div + v-once + class="multi-file-discard-btn" + > + <button + type="button" + class="btn btn-blank" + :aria-label="__('Unstage change')" + @click="unstageChange(file)" + > + <icon + name="history" + :size="12" + /> + </button> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/ide_context_bar.vue b/app/assets/javascripts/ide/components/ide_context_bar.vue index 79a83b47994..627fbeb9adf 100644 --- a/app/assets/javascripts/ide/components/ide_context_bar.vue +++ b/app/assets/javascripts/ide/components/ide_context_bar.vue @@ -1,5 +1,4 @@ <script> -import { mapActions, mapGetters, mapState } from 'vuex'; import icon from '~/vue_shared/components/icon.vue'; import panelResizer from '~/vue_shared/components/panel_resizer.vue'; import repoCommitSection from './repo_commit_section.vue'; @@ -22,13 +21,6 @@ export default { required: true, }, }, - computed: { - ...mapState(['changedFiles', 'rightPanelCollapsed']), - ...mapGetters(['currentIcon']), - }, - methods: { - ...mapActions(['setPanelCollapsedStatus']), - }, }; </script> @@ -41,40 +33,6 @@ export default { <div class="multi-file-commit-panel-section" > - <header - class="multi-file-commit-panel-header" - :class="{ - 'is-collapsed': rightPanelCollapsed, - }" - > - <div - class="multi-file-commit-panel-header-title" - v-if="!rightPanelCollapsed" - > - <div - v-if="changedFiles.length" - > - <icon - name="list-bulleted" - :size="18" - /> - Staged - </div> - </div> - <button - type="button" - class="btn btn-transparent multi-file-commit-panel-collapse-btn" - @click.stop="setPanelCollapsedStatus({ - side: 'right', - collapsed: !rightPanelCollapsed, - })" - > - <icon - :name="currentIcon" - :size="18" - /> - </button> - </header> <repo-commit-section :no-changes-state-svg-path="noChangesStateSvgPath" :committed-state-svg-path="committedStateSvgPath" diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index d772cab2d0e..d8d447b80f3 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -5,14 +5,16 @@ import icon from '~/vue_shared/components/icon.vue'; import modal from '~/vue_shared/components/modal.vue'; import LoadingButton from '~/vue_shared/components/loading_button.vue'; import commitFilesList from './commit_sidebar/list.vue'; -import * as consts from '../stores/modules/commit/constants'; +import EmptyState from './commit_sidebar/empty_state.vue'; import Actions from './commit_sidebar/actions.vue'; +import * as consts from '../stores/modules/commit/constants'; export default { components: { modal, icon, commitFilesList, + EmptyState, Actions, LoadingButton, }, @@ -30,45 +32,26 @@ export default { }, }, computed: { - ...mapState([ - 'currentProjectId', - 'currentBranchId', - 'rightPanelCollapsed', - 'lastCommitMsg', - 'changedFiles', - ]), - ...mapState('commit', [ - 'commitMessage', - 'submitCommitLoading', - ]), + ...mapState(['stagedFiles', 'rightPanelCollapsed']), + ...mapState('commit', ['commitMessage', 'submitCommitLoading']), + ...mapGetters(['unstagedFiles']), ...mapGetters('commit', [ 'commitButtonDisabled', 'discardDraftButtonDisabled', 'branchName', ]), - statusSvg() { - return this.lastCommitMsg ? this.committedStateSvgPath : this.noChangesStateSvgPath; - }, }, methods: { - ...mapActions([ - 'setPanelCollapsedStatus', - ]), ...mapActions('commit', [ 'updateCommitMessage', 'discardDraft', 'commitChanges', 'updateCommitAction', ]), - toggleCollapsed() { - this.setPanelCollapsedStatus({ - side: 'right', - collapsed: !this.rightPanelCollapsed, - }); - }, forceCreateNewBranch() { - return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH) - .then(() => this.commitChanges()); + return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => + this.commitChanges(), + ); }, }, }; @@ -77,9 +60,6 @@ export default { <template> <div class="multi-file-commit-panel-section" - :class="{ - 'multi-file-commit-empty-state-container': !changedFiles.length - }" > <modal id="ide-create-branch-modal" @@ -93,15 +73,26 @@ export default { Would you like to create a new branch?`) }} </template> </modal> - <commit-files-list - title="Staged" - :file-list="changedFiles" - :collapsed="rightPanelCollapsed" - @toggleCollapsed="toggleCollapsed" - /> <template - v-if="changedFiles.length" + v-if="unstagedFiles.length || stagedFiles.length" > + <commit-files-list + icon="unstaged" + :title="__('Unstaged')" + :file-list="unstagedFiles" + action="stageAllChanges" + :action-btn-text="__('Stage all')" + item-action-component="stage-button" + /> + <commit-files-list + icon="staged" + :title="__('Staged')" + :file-list="stagedFiles" + action="unstageAllChanges" + :action-btn-text="__('Unstage all')" + item-action-component="unstage-button" + :show-toggle="false" + /> <form class="form-horizontal multi-file-commit-form" @submit.prevent.stop="commitChanges" @@ -137,38 +128,10 @@ export default { </div> </form> </template> - <div - v-else-if="!rightPanelCollapsed" - class="row js-empty-state" - > - <div class="col-xs-10 col-xs-offset-1"> - <div class="svg-content svg-80"> - <img :src="statusSvg" /> - </div> - </div> - <div class="col-xs-10 col-xs-offset-1"> - <div - class="text-content text-center" - v-if="!lastCommitMsg" - > - <h4> - {{ __('No changes') }} - </h4> - <p> - {{ __('Edit files in the editor and commit changes here') }} - </p> - </div> - <div - class="text-content text-center" - v-else - > - <h4> - {{ __('All changes are committed') }} - </h4> - <p v-html="lastCommitMsg"> - </p> - </div> - </div> - </div> + <empty-state + v-else + :no-changes-state-svg-path="noChangesStateSvgPath" + :committed-state-svg-path="committedStateSvgPath" + /> </div> </template> diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js index 7e920aa9f30..639195308b2 100644 --- a/app/assets/javascripts/ide/stores/actions.js +++ b/app/assets/javascripts/ide/stores/actions.js @@ -33,6 +33,13 @@ export const setPanelCollapsedStatus = ({ commit }, { side, collapsed }) => { } }; +export const toggleRightPanelCollapsed = ({ dispatch, state }) => { + dispatch('setPanelCollapsedStatus', { + side: 'right', + collapsed: !state.rightPanelCollapsed, + }); +}; + export const setResizingStatus = ({ commit }, resizing) => { commit(types.SET_RESIZING_STATUS, resizing); }; @@ -108,6 +115,14 @@ export const scrollToTab = () => { }); }; +export const stageAllChanges = ({ state, commit }) => { + [...state.changedFiles].forEach(file => commit(types.STAGE_CHANGE, file)); +}; + +export const unstageAllChanges = ({ state, commit }) => { + [...state.stagedFiles].forEach(file => commit(types.UNSTAGE_CHANGE, file)); +}; + export const updateViewer = ({ commit }, viewer) => { commit(types.UPDATE_VIEWER, viewer); }; diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js index ddc4b757bf9..61aa0e983fc 100644 --- a/app/assets/javascripts/ide/stores/actions/file.js +++ b/app/assets/javascripts/ide/stores/actions/file.js @@ -144,3 +144,11 @@ export const discardFileChanges = ({ state, commit }, path) => { eventHub.$emit(`editor.update.model.content.${file.path}`, file.raw); }; + +export const stageChange = ({ commit }, file) => { + commit(types.STAGE_CHANGE, file); +}; + +export const unstageChange = ({ commit }, file) => { + commit(types.UNSTAGE_CHANGE, file); +}; diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js index eba325a31df..85f9b75636a 100644 --- a/app/assets/javascripts/ide/stores/getters.js +++ b/app/assets/javascripts/ide/stores/getters.js @@ -28,3 +28,5 @@ export const currentIcon = state => state.rightPanelCollapsed ? 'angle-double-left' : 'angle-double-right'; export const hasChanges = state => !!state.changedFiles.length; + +export const unstagedFiles = state => state.changedFiles.filter(f => !f.staged); diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index f536ce6344b..5346bbcdfd9 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -131,9 +131,10 @@ export const updateFilesAfterCommit = ( ); }); - commit(rootTypes.REMOVE_ALL_CHANGES_FILES, null, { root: true }); - - if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH) { + if ( + state.commitAction === consts.COMMIT_TO_NEW_BRANCH && + rootGetters.activeFile + ) { router.push( `/project/${rootState.currentProjectId}/blob/${branch}/${ rootGetters.activeFile.path @@ -186,7 +187,6 @@ export const commitChanges = ({ } dispatch('setLastCommitMessage', data); - dispatch('updateCommitMessage', ''); if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH_MR) { dispatch( @@ -204,6 +204,10 @@ export const commitChanges = ({ branch: getters.branchName, }); } + + commit(rootTypes.CLEAR_STAGED_CHANGES, null, { root: true }); + + dispatch('discardDraft'); }) .catch(err => { let errMsg = __('Error committing changes. Please try again.'); diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js index e28f190897c..49eb30302c6 100644 --- a/app/assets/javascripts/ide/stores/mutation_types.js +++ b/app/assets/javascripts/ide/stores/mutation_types.js @@ -41,3 +41,7 @@ export const SET_ENTRIES = 'SET_ENTRIES'; export const CREATE_TMP_ENTRY = 'CREATE_TMP_ENTRY'; export const UPDATE_VIEWER = 'UPDATE_VIEWER'; export const UPDATE_DELAY_VIEWER_CHANGE = 'UPDATE_DELAY_VIEWER_CHANGE'; + +export const CLEAR_STAGED_CHANGES = 'CLEAR_STAGED_CHANGES'; +export const STAGE_CHANGE = 'STAGE_CHANGE'; +export const UNSTAGE_CHANGE = 'UNSTAGE_CHANGE'; diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index da41fc9285c..5409ec1ec47 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -51,6 +51,11 @@ export default { lastCommitMsg, }); }, + [types.CLEAR_STAGED_CHANGES](state) { + Object.assign(state, { + stagedFiles: [], + }); + }, [types.SET_ENTRIES](state, entries) { Object.assign(state, { entries, diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js index 2500f13db7c..8e739a83270 100644 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -1,4 +1,5 @@ import * as types from '../mutation_types'; +import { findIndexOfFile, findEntry } from '../utils'; export default { [types.SET_FILE_ACTIVE](state, { path, active }) { @@ -75,6 +76,33 @@ export default { changedFiles: state.changedFiles.filter(f => f.path !== path), }); }, + [types.STAGE_CHANGE](state, file) { + const stagedFile = findEntry(state.stagedFiles, 'blob', file.name); + + Object.assign(file, { + staged: true, + }); + + if (stagedFile) { + Object.assign(stagedFile, { + ...file, + }); + } else { + state.stagedFiles.push({ + ...file, + }); + } + }, + [types.UNSTAGE_CHANGE](state, file) { + const indexOfStagedFile = findIndexOfFile(state.stagedFiles, file); + const changedFile = findEntry(state.changedFiles, 'blob', file.name); + + state.stagedFiles.splice(indexOfStagedFile, 1); + + Object.assign(changedFile, { + staged: false, + }); + }, [types.TOGGLE_FILE_CHANGED](state, { file, changed }) { Object.assign(state.entries[file.path], { changed, diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 6110f54951c..6c09324e4ba 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -2,6 +2,7 @@ export default () => ({ currentProjectId: '', currentBranchId: '', changedFiles: [], + stagedFiles: [], endpoints: {}, lastCommitMsg: '', lastCommitPath: '', diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index 487ea1ead8e..da0069b63a8 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -13,6 +13,7 @@ export const dataStructure = () => ({ opened: false, active: false, changed: false, + staged: false, lastCommitPath: '', lastCommit: { id: '', @@ -38,7 +39,7 @@ export const dataStructure = () => ({ eol: '', }); -export const decorateData = (entity) => { +export const decorateData = entity => { const { id, projectId, @@ -57,7 +58,6 @@ export const decorateData = (entity) => { base64 = false, file_lock, - } = entity; return { @@ -80,24 +80,23 @@ export const decorateData = (entity) => { base64, file_lock, - }; }; -export const findEntry = (tree, type, name, prop = 'name') => tree.find( - f => f.type === type && f[prop] === name, -); +export const findEntry = (tree, type, name, prop = 'name') => + tree.find(f => f.type === type && f[prop] === name); -export const findIndexOfFile = (state, file) => state.findIndex(f => f.path === file.path); +export const findIndexOfFile = (state, file) => + state.findIndex(f => f.path === file.path); -export const setPageTitle = (title) => { +export const setPageTitle = title => { document.title = title; }; export const createCommitPayload = (branch, newBranch, state, rootState) => ({ branch, commit_message: state.commitMessage, - actions: rootState.changedFiles.map(f => ({ + actions: rootState.stagedFiles.map(f => ({ action: f.tempFile ? 'create' : 'update', file_path: f.path, content: f.content, @@ -120,6 +119,11 @@ const sortTreesByTypeAndName = (a, b) => { return 0; }; -export const sortTree = sortedTree => sortedTree.map(entity => Object.assign(entity, { - tree: entity.tree.length ? sortTree(entity.tree) : [], -})).sort(sortTreesByTypeAndName); +export const sortTree = sortedTree => + sortedTree + .map(entity => + Object.assign(entity, { + tree: entity.tree.length ? sortTree(entity.tree) : [], + }), + ) + .sort(sortTreesByTypeAndName); diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 7a8fbfc517d..57393cf65e7 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -449,9 +449,13 @@ flex: 1; } -.multi-file-commit-empty-state-container { - align-items: center; - justify-content: center; +.ide-commity-empty-state { + padding: 0 $gl-padding; +} + +.ide-commit-empty-state-container { + margin-top: auto; + margin-bottom: auto; } .multi-file-commit-panel-header { @@ -462,7 +466,8 @@ padding: $gl-btn-padding 0; &.is-collapsed { - border-bottom: 1px solid $white-dark; + margin-left: -$gl-padding; + margin-right: -$gl-padding; svg { margin-left: auto; @@ -480,7 +485,6 @@ .multi-file-commit-panel-header-title { display: flex; flex: 1; - padding: 0 $gl-btn-padding; svg { margin-right: $gl-btn-padding; @@ -489,6 +493,7 @@ .multi-file-commit-panel-collapse-btn { border-left: 1px solid $white-dark; + margin-left: auto; } .multi-file-commit-list { @@ -502,12 +507,14 @@ display: flex; padding: 0; align-items: center; + border-radius: $border-radius-default; .multi-file-discard-btn { display: none; + margin-top: -2px; margin-left: auto; + margin-right: $grid-size; color: $gl-link-color; - padding: 0 2px; &:focus, &:hover { @@ -519,7 +526,7 @@ background: $white-normal; .multi-file-discard-btn { - display: block; + display: flex; } } } @@ -535,10 +542,12 @@ .multi-file-commit-list-collapsed { display: flex; flex-direction: column; + padding: $gl-padding 0; > svg { margin-left: auto; margin-right: auto; + color: $theme-gray-700; } .file-status-icon { @@ -550,7 +559,7 @@ .multi-file-commit-list-path { padding: $grid-size / 2; - padding-left: $gl-padding; + padding-left: $grid-size; background: none; border: 0; text-align: left; @@ -740,6 +749,22 @@ } } +.ide-commit-list-container { + display: flex; + flex-direction: column; + width: 100%; + padding: 0 16px; + + &:not(.is-collapsed) { + flex: 1; + } +} + +.ide-staged-action-btn { + margin-left: auto; + color: $gl-link-color; +} + .ide-commit-radios { label { font-weight: normal; |