diff options
Diffstat (limited to 'app/assets')
15 files changed, 430 insertions, 129 deletions
diff --git a/app/assets/javascripts/ide/components/activity_bar.vue b/app/assets/javascripts/ide/components/activity_bar.vue index e27404a08d3..edea6a9b894 100644 --- a/app/assets/javascripts/ide/components/activity_bar.vue +++ b/app/assets/javascripts/ide/components/activity_bar.vue @@ -8,7 +8,7 @@ export default { Icon, }, computed: { - ...mapGetters(['currentProject']), + ...mapGetters(['currentProject', 'hasChanges']), ...mapState(['currentActivityView']), goBackUrl() { return document.referrer || this.currentProject.web_url; @@ -65,7 +65,7 @@ export default { /> </button> </li> - <li> + <li v-show="hasChanges"> <button type="button" class="ide-sidebar-link js-ide-commit-mode" diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue index 45321df191c..3790c3401f3 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue @@ -9,7 +9,7 @@ export default { RadioGroup, }, computed: { - ...mapState(['currentBranchId']), + ...mapState(['currentBranchId', 'changedFiles', 'stagedFiles']), commitToCurrentBranchText() { return sprintf( __('Commit to %{branchName} branch'), @@ -17,6 +17,9 @@ export default { false, ); }, + disableMergeRequestRadio() { + return this.changedFiles.length > 0 && this.stagedFiles.length > 0; + }, }, commitToCurrentBranch: consts.COMMIT_TO_CURRENT_BRANCH, commitToNewBranch: consts.COMMIT_TO_NEW_BRANCH, @@ -44,6 +47,7 @@ export default { :value="$options.commitToNewBranchMR" :label="__('Create a new branch and merge request')" :show-input="true" + :disabled="disableMergeRequestRadio" /> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue new file mode 100644 index 00000000000..163b21221df --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue @@ -0,0 +1,170 @@ +<script> +import { mapState, mapActions, mapGetters } from 'vuex'; +import { sprintf, __ } from '~/locale'; +import LoadingButton from '~/vue_shared/components/loading_button.vue'; +import CommitMessageField from './message_field.vue'; +import Actions from './actions.vue'; +import SuccessMessage from './success_message.vue'; +import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT, COMMIT_ITEM_PADDING } from '../../constants'; + +export default { + components: { + Actions, + LoadingButton, + CommitMessageField, + SuccessMessage, + }, + data() { + return { + isCompact: true, + componentHeight: null, + }; + }, + computed: { + ...mapState(['changedFiles', 'stagedFiles', 'currentActivityView', 'lastCommitMsg']), + ...mapState('commit', ['commitMessage', 'submitCommitLoading']), + ...mapGetters(['hasChanges']), + ...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled']), + overviewText() { + return sprintf( + __( + '<strong>%{changedFilesLength} unstaged</strong> and <strong>%{stagedFilesLength} staged</strong> changes', + ), + { + stagedFilesLength: this.stagedFiles.length, + changedFilesLength: this.changedFiles.length, + }, + ); + }, + }, + watch: { + currentActivityView() { + if (this.lastCommitMsg) { + this.isCompact = false; + } else { + this.isCompact = !( + this.currentActivityView === activityBarViews.commit && + window.innerHeight >= MAX_WINDOW_HEIGHT_COMPACT + ); + } + }, + lastCommitMsg() { + this.isCompact = this.lastCommitMsg === ''; + }, + }, + methods: { + ...mapActions(['updateActivityBarView']), + ...mapActions('commit', ['updateCommitMessage', 'discardDraft', 'commitChanges']), + toggleIsSmall() { + this.updateActivityBarView(activityBarViews.commit) + .then(() => { + this.isCompact = !this.isCompact; + }) + .catch(e => { + throw e; + }); + }, + beforeEnterTransition() { + const elHeight = this.isCompact + ? this.$refs.formEl && this.$refs.formEl.offsetHeight + : this.$refs.compactEl && this.$refs.compactEl.offsetHeight; + + this.componentHeight = elHeight + COMMIT_ITEM_PADDING; + }, + enterTransition() { + this.$nextTick(() => { + const elHeight = this.isCompact + ? this.$refs.compactEl && this.$refs.compactEl.offsetHeight + : this.$refs.formEl && this.$refs.formEl.offsetHeight; + + this.componentHeight = elHeight + COMMIT_ITEM_PADDING; + }); + }, + afterEndTransition() { + this.componentHeight = null; + }, + }, + activityBarViews, +}; +</script> + +<template> + <div + class="multi-file-commit-form" + :class="{ + 'is-compact': isCompact, + 'is-full': !isCompact + }" + :style="{ + height: componentHeight ? `${componentHeight}px` : null, + }" + > + <transition + name="commit-form-slide-up" + @before-enter="beforeEnterTransition" + @enter="enterTransition" + @after-enter="afterEndTransition" + > + <div + v-if="isCompact" + class="commit-form-compact" + ref="compactEl" + > + <button + type="button" + :disabled="!hasChanges" + class="btn btn-primary btn-sm btn-block" + @click="toggleIsSmall" + > + {{ __('Commit') }} + </button> + <p + class="text-center" + v-html="overviewText" + ></p> + </div> + <form + v-if="!isCompact" + class="form-horizontal" + @submit.prevent.stop="commitChanges" + ref="formEl" + > + <transition name="fade"> + <success-message + v-show="lastCommitMsg" + /> + </transition> + <commit-message-field + :text="commitMessage" + @input="updateCommitMessage" + /> + <div class="clearfix prepend-top-15"> + <actions /> + <loading-button + :loading="submitCommitLoading" + :disabled="commitButtonDisabled" + container-class="btn btn-success btn-sm pull-left" + :label="__('Commit')" + @click="commitChanges" + /> + <button + v-if="!discardDraftButtonDisabled" + type="button" + class="btn btn-default btn-sm pull-right" + @click="discardDraft" + > + {{ __('Discard draft') }} + </button> + <button + v-else + type="button" + class="btn btn-default btn-sm pull-right" + @click="toggleIsSmall" + > + {{ __('Collapse') }} + </button> + </div> + </form> + </transition> + </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 e0de30d935b..f6625fda596 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -44,6 +44,11 @@ export default { default: false, }, }, + data() { + return { + showActionButton: false, + }; + }, computed: { titleText() { return sprintf(__('%{title} changes'), { @@ -56,6 +61,9 @@ export default { actionBtnClicked() { this[this.action](); }, + setShowActionButton(show) { + this.showActionButton = show; + }, }, }; </script> @@ -76,7 +84,16 @@ export default { :size="18" /> {{ titleText }} + <span + v-show="!showActionButton" + @mouseenter="setShowActionButton(true)" + class="ide-commit-file-count" + > + {{ fileList.length }} + </span> <button + v-show="showActionButton" + @mouseleave="setShowActionButton(false)" type="button" class="btn btn-blank btn-link ide-staged-action-btn" @click="actionBtnClicked" diff --git a/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue index b660a2961cb..00f2312ae51 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue @@ -1,5 +1,6 @@ <script> import { mapActions, mapState, mapGetters } from 'vuex'; +import { __ } from '~/locale'; import tooltip from '~/vue_shared/directives/tooltip'; export default { @@ -26,10 +27,20 @@ export default { required: false, default: false, }, + disabled: { + type: Boolean, + required: false, + default: false, + }, }, computed: { ...mapState('commit', ['commitAction']), ...mapGetters('commit', ['newBranchName']), + tooltipTitle() { + return this.disabled + ? __('This option is disabled while you still have unstaged changes') + : ''; + }, }, methods: { ...mapActions('commit', ['updateCommitAction', 'updateBranchName']), @@ -39,19 +50,28 @@ export default { <template> <fieldset> - <label> + <label + v-tooltip + :title="tooltipTitle" + :class="{ + 'is-disabled': disabled + }" + > <input type="radio" name="commit-action" :value="value" @change="updateCommitAction($event.target.value)" - :checked="checked" - v-once + :checked="commitAction === value" + :disabled="disabled" /> <span class="prepend-left-10"> - <template v-if="label"> + <span + v-if="label" + class="ide-radio-label" + > {{ label }} - </template> + </span> <slot v-else></slot> </span> </label> diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue index 3fb9b8b241d..8015b245c2f 100644 --- a/app/assets/javascripts/ide/components/ide_side_bar.vue +++ b/app/assets/javascripts/ide/components/ide_side_bar.vue @@ -9,7 +9,10 @@ import IdeTree from './ide_tree.vue'; import ResizablePanel from './resizable_panel.vue'; import ActivityBar from './activity_bar.vue'; import CommitSection from './repo_commit_section.vue'; +import CommitForm from './commit_sidebar/form.vue'; import IdeReview from './ide_review.vue'; +import SuccessMessage from './commit_sidebar/success_message.vue'; +import { activityBarViews } from '../constants'; export default { components: { @@ -22,11 +25,26 @@ export default { Identicon, CommitSection, IdeTree, + CommitForm, IdeReview, + SuccessMessage, }, computed: { - ...mapState(['loading', 'currentBranchId', 'currentActivityView']), - ...mapGetters(['currentProject']), + ...mapState([ + 'loading', + 'currentBranchId', + 'currentActivityView', + 'changedFiles', + 'stagedFiles', + 'lastCommitMsg', + ]), + ...mapGetters(['currentProject', 'someUncommitedChanges']), + showSuccessMessage() { + return ( + this.currentActivityView === activityBarViews.edit && + (this.lastCommitMsg && !this.someUncommitedChanges) + ); + }, }, }; </script> @@ -93,6 +111,7 @@ export default { :is="currentActivityView" /> </div> + <commit-form /> </template> </div> </resizable-panel> diff --git a/app/assets/javascripts/ide/components/ide_tree.vue b/app/assets/javascripts/ide/components/ide_tree.vue index 569d55d28ac..8fc4ebe6ca6 100644 --- a/app/assets/javascripts/ide/components/ide_tree.vue +++ b/app/assets/javascripts/ide/components/ide_tree.vue @@ -1,5 +1,5 @@ <script> -import { mapState, mapGetters } from 'vuex'; +import { mapState, mapGetters, mapActions } from 'vuex'; import NewDropdown from './new_dropdown/index.vue'; import IdeTreeList from './ide_tree_list.vue'; @@ -10,7 +10,17 @@ export default { }, computed: { ...mapState(['currentBranchId']), - ...mapGetters(['currentProject']), + ...mapGetters(['currentProject', 'currentTree', 'activeFile']), + }, + mounted() { + if (this.activeFile && this.activeFile.pending) { + this.$router.push(`/project${this.activeFile.url}`, () => { + this.updateViewer('editor'); + }); + } + }, + methods: { + ...mapActions(['updateViewer']), }, }; </script> diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index 4c0dab70ab0..c5092d8e04d 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -3,13 +3,10 @@ import { mapState, mapActions, mapGetters } from 'vuex'; import tooltip from '~/vue_shared/directives/tooltip'; import Icon from '~/vue_shared/components/icon.vue'; import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; -import LoadingButton from '~/vue_shared/components/loading_button.vue'; import CommitFilesList from './commit_sidebar/list.vue'; import EmptyState from './commit_sidebar/empty_state.vue'; -import CommitMessageField from './commit_sidebar/message_field.vue'; -import SuccessMessage from './commit_sidebar/success_message.vue'; import * as consts from '../stores/modules/commit/constants'; -import Actions from './commit_sidebar/actions.vue'; +import { activityBarViews } from '../constants'; export default { components: { @@ -17,21 +14,11 @@ export default { Icon, CommitFilesList, EmptyState, - SuccessMessage, - Actions, - LoadingButton, - CommitMessageField, }, directives: { tooltip, }, computed: { - showStageUnstageArea() { - return !!(this.someUncommitedChanges || this.lastCommitMsg || !this.unusedSeal); - }, - someUncommitedChanges() { - return !!(this.changedFiles.length || this.stagedFiles.length); - }, ...mapState([ 'changedFiles', 'stagedFiles', @@ -40,15 +27,37 @@ export default { 'unusedSeal', ]), ...mapState('commit', ['commitMessage', 'submitCommitLoading']), + ...mapGetters(['lastOpenedFile', 'hasChanges', 'someUncommitedChanges']), ...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled']), + showStageUnstageArea() { + return !!(this.someUncommitedChanges || this.lastCommitMsg || !this.unusedSeal); + }, + }, + watch: { + hasChanges() { + if (!this.hasChanges) { + this.updateActivityBarView(activityBarViews.edit); + } + }, + }, + mounted() { + if (this.lastOpenedFile) { + this.openPendingTab({ + file: this.lastOpenedFile, + }) + .then(changeViewer => { + if (changeViewer) { + this.updateViewer('diff'); + } + }) + .catch(e => { + throw e; + }); + } }, methods: { - ...mapActions('commit', [ - 'updateCommitMessage', - 'discardDraft', - 'commitChanges', - 'updateCommitAction', - ]), + ...mapActions(['openPendingTab', 'updateViewer', 'updateActivityBarView']), + ...mapActions('commit', ['commitChanges', 'updateCommitAction']), forceCreateNewBranch() { return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => this.commitChanges()); }, @@ -76,6 +85,7 @@ export default { v-if="showStageUnstageArea" > <commit-files-list + class="is-first" icon-name="unstaged" :title="__('Unstaged')" :file-list="changedFiles" @@ -96,39 +106,5 @@ export default { <empty-state v-if="unusedSeal" /> - <div - class="multi-file-commit-panel-bottom" - > - <form - class="form-horizontal multi-file-commit-form" - @submit.prevent.stop="commitChanges" - > - <success-message - v-if="lastCommitMsg && !someUncommitedChanges" - /> - <commit-message-field - :text="commitMessage" - @input="updateCommitMessage" - /> - <div class="clearfix prepend-top-15"> - <actions /> - <loading-button - :loading="submitCommitLoading" - :disabled="commitButtonDisabled" - container-class="btn btn-success btn-sm pull-left" - :label="__('Commit')" - @click="commitChanges" - /> - <button - v-if="!discardDraftButtonDisabled" - type="button" - class="btn btn-default btn-sm pull-right" - @click="discardDraft" - > - {{ __('Discard draft') }} - </button> - </div> - </form> - </div> </div> </template> diff --git a/app/assets/javascripts/ide/components/repo_tab.vue b/app/assets/javascripts/ide/components/repo_tab.vue index b3221deada0..fb26b973236 100644 --- a/app/assets/javascripts/ide/components/repo_tab.vue +++ b/app/assets/javascripts/ide/components/repo_tab.vue @@ -32,6 +32,8 @@ export default { return `Close ${this.tab.name}`; }, showChangedIcon() { + if (this.tab.pending) return true; + return this.fileHasChanged ? !this.tabMouseOver : false; }, fileHasChanged() { @@ -91,6 +93,7 @@ export default { class="multi-file-tab-close" @click.stop.prevent="closeFile(tab)" :aria-label="closeLabel" + :disabled="tab.pending" > <icon v-if="!showChangedIcon" diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js index 16110b2f5a4..dbaf370a18c 100644 --- a/app/assets/javascripts/ide/constants.js +++ b/app/assets/javascripts/ide/constants.js @@ -3,6 +3,10 @@ export const MAX_FILE_FINDER_RESULTS = 40; export const FILE_FINDER_ROW_HEIGHT = 55; export const FILE_FINDER_EMPTY_ROW_HEIGHT = 33; +export const MAX_WINDOW_HEIGHT_COMPACT = 750; + +export const COMMIT_ITEM_PADDING = 32; + // Commit message textarea export const MAX_TITLE_LENGTH = 50; export const MAX_BODY_LENGTH = 72; diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js index 4fe6f5334e3..885584e77ac 100644 --- a/app/assets/javascripts/ide/stores/actions/file.js +++ b/app/assets/javascripts/ide/stores/actions/file.js @@ -194,9 +194,7 @@ export const unstageChange = ({ commit }, path) => { }; export const openPendingTab = ({ commit, getters, dispatch, state }, { file, keyPrefix }) => { - if (getters.activeFile && getters.activeFile.path === file.path && state.viewer === 'diff') { - return false; - } + state.openFiles.forEach(f => eventHub.$emit(`editor.update.model.dispose.${f.key}`)); commit(types.ADD_PENDING_TAB, { file, keyPrefix }); diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js index 80de60799f2..28e08c2b679 100644 --- a/app/assets/javascripts/ide/stores/getters.js +++ b/app/assets/javascripts/ide/stores/getters.js @@ -60,10 +60,16 @@ export const allBlobs = state => export const getChangedFile = state => path => state.changedFiles.find(f => f.path === path); export const getStagedFile = state => path => state.stagedFiles.find(f => f.path === path); +export const lastOpenedFile = state => + [...state.changedFiles, ...state.stagedFiles].sort((a, b) => b.lastOpenedAt - a.lastOpenedAt)[0]; + export const isEditModeActive = state => state.currentActivityView === activityBarViews.edit; export const isCommitModeActive = state => state.currentActivityView === activityBarViews.commit; export const isReviewModeActive = state => state.currentActivityView === activityBarViews.review; +export const someUncommitedChanges = state => + !!(state.changedFiles.length || state.stagedFiles.length); + export const getChangesInFolder = state => path => { const changedFilesCount = state.changedFiles.filter(f => filePathMatches(f, path)).length; const stagedFilesCount = state.stagedFiles.filter( diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index 4fbc97d053e..ab00d12089d 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -8,6 +8,7 @@ import router from '../../../ide_router'; import service from '../../../services'; import * as types from './mutation_types'; import * as consts from './constants'; +import { activityBarViews } from '../../../constants'; import eventHub from '../../../eventhub'; export const updateCommitMessage = ({ commit }, message) => { @@ -75,7 +76,7 @@ export const checkCommitStatus = ({ rootState }) => export const updateFilesAfterCommit = ( { commit, dispatch, state, rootState, rootGetters }, - { data, branch }, + { data }, ) => { const selectedProject = rootState.projects[rootState.currentProjectId]; const lastCommit = { @@ -126,15 +127,9 @@ export const updateFilesAfterCommit = ( changed: !!changedFile, }); }); - - if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH && rootGetters.activeFile) { - router.push( - `/project/${rootState.currentProjectId}/blob/${branch}/${rootGetters.activeFile.path}`, - ); - } }; -export const commitChanges = ({ commit, state, getters, dispatch, rootState }) => { +export const commitChanges = ({ commit, state, getters, dispatch, rootState, rootGetters }) => { const newBranch = state.commitAction !== consts.COMMIT_TO_CURRENT_BRANCH; const payload = createCommitPayload(getters.branchName, newBranch, state, rootState); const getCommitStatus = newBranch ? Promise.resolve(false) : dispatch('checkCommitStatus'); @@ -187,6 +182,34 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState }) = commit(rootTypes.SET_LAST_COMMIT_MSG, '', { root: true }); }, 5000); }) + .then(() => { + if (rootGetters.lastOpenedFile) { + dispatch( + 'openPendingTab', + { + file: rootGetters.lastOpenedFile, + }, + { root: true }, + ) + .then(changeViewer => { + if (changeViewer) { + dispatch('updateViewer', 'diff', { root: true }); + } + }) + .catch(e => { + throw e; + }); + } else { + dispatch('updateActivityBarView', activityBarViews.edit, { root: true }); + dispatch('updateViewer', 'editor', { root: true }); + + router.push( + `/project/${rootState.currentProjectId}/blob/${getters.branchName}/${ + rootGetters.activeFile.path + }`, + ); + } + }) .then(() => dispatch('updateCommitAction', consts.COMMIT_TO_CURRENT_BRANCH)); }) .catch(err => { diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js index 7f670eb744c..13f123b6630 100644 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -1,3 +1,4 @@ +/* eslint-disable no-param-reassign */ import * as types from '../mutation_types'; export default { @@ -169,36 +170,24 @@ export default { }); }, [types.ADD_PENDING_TAB](state, { file, keyPrefix = 'pending' }) { - const key = `${keyPrefix}-${file.key}`; - const pendingTab = state.openFiles.find(f => f.key === key && f.pending); - let openFiles = state.openFiles.map(f => Object.assign(f, { active: false, opened: false })); - - if (!pendingTab) { - const openFile = openFiles.find(f => f.path === file.path); - - openFiles = openFiles.concat(openFile ? null : file).reduce((acc, f) => { - if (!f) return acc; - - if (f.path === file.path) { - return acc.concat({ - ...f, - content: file.content, - active: true, - pending: true, - opened: true, - key, - }); - } - - return acc.concat(f); - }, []); - } else { - openFiles = state.openFiles.map(f => - Object.assign(f, { active: f.key === key, opened: f.key === key }), - ); - } - - Object.assign(state, { openFiles }); + state.entries[file.path].opened = false; + state.entries[file.path].active = false; + state.entries[file.path].lastOpenedAt = new Date().getTime(); + state.openFiles.forEach(f => + Object.assign(f, { + opened: false, + active: false, + }), + ); + state.openFiles = [ + { + ...file, + key: `${keyPrefix}-${file.key}`, + pending: true, + opened: true, + active: true, + }, + ]; }, [types.REMOVE_PENDING_TAB](state, file) { Object.assign(state, { diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 9c374cda3f3..4170baebffe 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -192,11 +192,11 @@ right: 3px; } - &:hover { + &:not([disabled]):hover { background-color: $theme-gray-200; } - &:focus { + &:not([disabled]):focus { background-color: $blue-500; color: $white-light; outline: 0; @@ -443,6 +443,7 @@ } .multi-file-commit-panel-inner { + position: relative; display: flex; flex-direction: column; height: 100%; @@ -484,14 +485,13 @@ align-items: center; margin-bottom: 0; border-bottom: 1px solid $white-dark; - padding: $gl-btn-padding 0; - min-height: 56px; + padding: $gl-btn-padding $gl-padding; } .multi-file-commit-panel-header-title { display: flex; flex: 1; - padding-left: $grid-size; + align-items: center; svg { margin-right: $gl-btn-padding; @@ -507,7 +507,7 @@ .multi-file-commit-list { flex: 1; overflow: auto; - padding: $gl-padding 0; + padding: $gl-padding; min-height: 60px; } @@ -602,30 +602,24 @@ } .multi-file-commit-form { + position: relative; padding: $gl-padding; + background-color: $white-light; border-top: 1px solid $white-dark; + border-left: 1px solid $white-dark; + transition: all 0.3s ease; .btn { font-size: $gl-font-size; } + + .multi-file-commit-panel-success-message { + top: 0; + } } .multi-file-commit-panel-bottom { position: relative; - - .multi-file-commit-panel-success-message { - position: absolute; - top: 1px; - left: 3px; - bottom: 0; - right: 0; - z-index: 10; - background: $gray-light; - overflow: auto; - display: flex; - flex-direction: column; - justify-content: center; - } } .dirty-diff { @@ -779,17 +773,36 @@ flex-direction: column; width: 100%; min-height: 140px; - padding: 0 16px; + + &.is-first { + border-bottom: 1px solid $white-dark; + } } .ide-staged-action-btn { margin-left: auto; - color: $gl-link-color; + line-height: 22px; +} + +.ide-commit-file-count { + min-width: 22px; + margin-left: auto; + background-color: $gray-light; + border-radius: $border-radius-default; + border: 1px solid $white-dark; + line-height: 20px; + text-align: center; } .ide-commit-radios { label { font-weight: normal; + + &.is-disabled { + .ide-radio-label { + text-decoration: line-through; + } + } } .help-block { @@ -853,6 +866,7 @@ .ide-activity-bar { position: relative; flex: 0 0 60px; + z-index: 1; } .ide-file-finder-overlay { @@ -969,6 +983,40 @@ } } +.commit-form-compact { + .btn { + margin-bottom: 8px; + } + + p { + margin-bottom: 0; + } +} + +.commit-form-slide-up-enter-active, +.commit-form-slide-up-leave-active { + position: absolute; + top: 16px; + left: 16px; + right: 16px; + transition: all 0.3s ease; +} + +.is-full .commit-form-slide-up-enter, +.is-compact .commit-form-slide-up-leave-to { + transform: translateY(100%); +} + +.is-full .commit-form-slide-up-enter-to, +.is-compact .commit-form-slide-up-leave { + transform: translateY(0); +} + +.commit-form-slide-up-enter, +.commit-form-slide-up-leave-to { + opacity: 0; +} + .ide-review-header { flex-direction: column; align-items: flex-start; @@ -987,3 +1035,17 @@ .ide-new-modal-label { line-height: 34px; } + +.multi-file-commit-panel-success-message { + position: absolute; + top: 61px; + left: 1px; + bottom: 0; + right: 0; + z-index: 10; + background: $white-light; + overflow: auto; + display: flex; + flex-direction: column; + justify-content: center; +} |