diff options
Diffstat (limited to 'app/assets/javascripts/diffs/components')
11 files changed, 190 insertions, 46 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 1e524882d5f..5062006424e 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -1,9 +1,10 @@ <script> import { mapState, mapGetters, mapActions } from 'vuex'; -import { GlLoadingIcon, GlButtonGroup, GlButton } from '@gitlab/ui'; +import { GlLoadingIcon, GlButtonGroup, GlButton, GlAlert } from '@gitlab/ui'; import Mousetrap from 'mousetrap'; import { __ } from '~/locale'; -import createFlash from '~/flash'; +import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; import PanelResizer from '~/vue_shared/components/panel_resizer.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { isSingleViewStyle } from '~/helpers/diffs_helper'; @@ -38,6 +39,7 @@ export default { PanelResizer, GlButtonGroup, GlButton, + GlAlert, }, mixins: [glFeatureFlagsMixin()], props: { @@ -127,7 +129,16 @@ export default { emailPatchPath: state => state.diffs.emailPatchPath, retrievingBatches: state => state.diffs.retrievingBatches, }), - ...mapState('diffs', ['showTreeList', 'isLoading', 'startVersion', 'currentDiffFileId']), + ...mapState('diffs', [ + 'showTreeList', + 'isLoading', + 'startVersion', + 'currentDiffFileId', + 'isTreeLoaded', + 'conflictResolutionPath', + 'canMerge', + 'hasConflicts', + ]), ...mapGetters('diffs', ['isParallelView', 'currentDiffIndex']), ...mapGetters(['isNotesFetched', 'getNoteableData']), diffs() { @@ -155,6 +166,9 @@ export default { isLimitedContainer() { return !this.showTreeList && !this.isParallelView && !this.isFluidLayout; }, + isDiffHead() { + return parseBoolean(getParameterByName('diff_head')); + }, }, watch: { commit(newCommit, oldCommit) { @@ -400,12 +414,12 @@ export default { <template> <div v-show="shouldShow"> - <div v-if="isLoading" class="loading"><gl-loading-icon size="lg" /></div> + <div v-if="isLoading || !isTreeLoaded" class="loading"><gl-loading-icon size="lg" /></div> <div v-else id="diffs" :class="{ active: shouldShow }" class="diffs tab-pane"> <compare-versions :merge-request-diffs="mergeRequestDiffs" :is-limited-container="isLimitedContainer" - :diff-files-length="diffFilesLength" + :diff-files-count-text="numTotalFiles" /> <hidden-files-warning @@ -417,6 +431,49 @@ export default { /> <div + v-if="isDiffHead && hasConflicts" + :class="{ + [CENTERED_LIMITED_CONTAINER_CLASSES]: isLimitedContainer, + }" + > + <gl-alert + :dismissible="false" + :title="__('There are merge conflicts')" + variant="warning" + class="w-100 mb-3" + > + <p class="mb-1"> + {{ __('The comparison view may be inaccurate due to merge conflicts.') }} + </p> + <p class="mb-0"> + {{ + __( + 'Resolve these conflicts or ask someone with write access to this repository to merge it locally.', + ) + }} + </p> + <template #actions> + <gl-button + v-if="conflictResolutionPath" + :href="conflictResolutionPath" + variant="info" + class="mr-3 gl-alert-action" + > + {{ __('Resolve conflicts') }} + </gl-button> + <gl-button + v-if="canMerge" + class="gl-alert-action" + data-toggle="modal" + data-target="#modal_merge_info" + > + {{ __('Merge locally') }} + </gl-button> + </template> + </gl-alert> + </div> + + <div :data-can-create-note="getNoteableData.current_user.can_create_note" class="files d-flex" > @@ -441,7 +498,7 @@ export default { [CENTERED_LIMITED_CONTAINER_CLASSES]: isLimitedContainer, }" > - <commit-widget v-if="commit" :commit="commit" /> + <commit-widget v-if="commit" :commit="commit" :collapsible="false" /> <div v-if="isBatchLoading" class="loading"><gl-loading-icon size="lg" /></div> <template v-else-if="renderDiffFiles"> <diff-file diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue index 99bc1b5c040..274a4027e62 100644 --- a/app/assets/javascripts/diffs/components/commit_item.vue +++ b/app/assets/javascripts/diffs/components/commit_item.vue @@ -52,10 +52,25 @@ export default { }, mixins: [glFeatureFlagsMixin()], props: { + isSelectable: { + type: Boolean, + required: false, + default: false, + }, commit: { type: Object, required: true, }, + checked: { + type: Boolean, + required: false, + default: false, + }, + collapsible: { + type: Boolean, + required: false, + default: true, + }, }, computed: { author() { @@ -78,6 +93,10 @@ export default { authorAvatar() { return this.author.avatar_url || this.commit.author_gravatar_url; }, + commitDescription() { + // Strip the newline at the beginning + return this.commit.description_html.replace(/^
/, ''); + }, nextCommitUrl() { return this.commit.next_commit_id ? setUrlParams({ commit_id: this.commit.next_commit_id }) @@ -104,14 +123,23 @@ export default { </script> <template> - <li class="commit flex-row js-toggle-container"> - <user-avatar-link - :link-href="authorUrl" - :img-src="authorAvatar" - :img-alt="authorName" - :img-size="40" - class="avatar-cell d-none d-sm-block" - /> + <li :class="{ 'js-toggle-container': collapsible }" class="commit flex-row"> + <div class="d-flex align-items-center align-self-start"> + <input + v-if="isSelectable" + class="mr-2" + type="checkbox" + :checked="checked" + @change="$emit('handleCheckboxChange', $event.target.checked)" + /> + <user-avatar-link + :link-href="authorUrl" + :img-src="authorAvatar" + :img-alt="authorName" + :img-size="40" + class="avatar-cell d-none d-sm-block" + /> + </div> <div class="commit-detail flex-list"> <div class="commit-content qa-commit-content"> <a @@ -123,7 +151,7 @@ export default { <span class="commit-row-message d-block d-sm-none">· {{ commit.short_id }}</span> <button - v-if="commit.description_html" + v-if="commit.description_html && collapsible" class="text-expander js-toggle-button" type="button" :aria-label="__('Toggle commit description')" @@ -144,8 +172,9 @@ export default { <pre v-if="commit.description_html" - class="commit-row-description js-toggle-content gl-mb-3" - v-html="commit.description_html" + :class="{ 'js-toggle-content': collapsible, 'd-block': !collapsible }" + class="commit-row-description gl-mb-3 text-dark" + v-html="commitDescription" ></pre> </div> <div class="commit-actions flex-row d-none d-sm-flex"> diff --git a/app/assets/javascripts/diffs/components/commit_widget.vue b/app/assets/javascripts/diffs/components/commit_widget.vue index 31ed003cc0f..5c7e84bd87c 100644 --- a/app/assets/javascripts/diffs/components/commit_widget.vue +++ b/app/assets/javascripts/diffs/components/commit_widget.vue @@ -23,15 +23,20 @@ export default { type: Object, required: true, }, + collapsible: { + type: Boolean, + required: false, + default: true, + }, }, }; </script> <template> - <div class="info-well w-100"> + <div class="info-well mw-100 mx-0"> <div class="well-segment"> <ul class="blob-commit-info"> - <commit-item :commit="commit" /> + <commit-item :commit="commit" :collapsible="collapsible" /> </ul> </div> </div> diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue index 6f6fa312865..35e4527af69 100644 --- a/app/assets/javascripts/diffs/components/compare_versions.vue +++ b/app/assets/javascripts/diffs/components/compare_versions.vue @@ -32,9 +32,10 @@ export default { required: false, default: false, }, - diffFilesLength: { - type: Number, - required: true, + diffFilesCountText: { + type: String, + required: false, + default: null, }, }, computed: { @@ -119,7 +120,7 @@ export default { </div> <div class="inline-parallel-buttons d-none d-md-flex ml-auto"> <diff-stats - :diff-files-length="diffFilesLength" + :diff-files-count-text="diffFilesCountText" :added-lines="addedLines" :removed-lines="removedLines" /> diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index 741462a849c..087a558efdc 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -147,7 +147,7 @@ export default { slot="image-overlay" :discussions="imageDiscussions" :file-hash="diffFileHash" - :can-comment="getNoteableData.current_user.can_create_note" + :can-comment="getNoteableData.current_user.can_create_note && !diffFile.brokenSymlink" /> <div v-if="showNotesContainer" class="note-container"> <user-avatar-link diff --git a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue index 46ed76450c4..e5e63bdcb43 100644 --- a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue @@ -1,6 +1,6 @@ <script> import { mapState, mapActions } from 'vuex'; -import createFlash from '~/flash'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; import { s__ } from '~/locale'; import Icon from '~/vue_shared/components/icon.vue'; import { UNFOLD_COUNT, INLINE_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE } from '../constants'; diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue index 00d36c0b978..eace673c2d7 100644 --- a/app/assets/javascripts/diffs/components/diff_file.vue +++ b/app/assets/javascripts/diffs/components/diff_file.vue @@ -2,8 +2,9 @@ import { mapActions, mapGetters, mapState } from 'vuex'; import { escape } from 'lodash'; import { GlLoadingIcon } from '@gitlab/ui'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { __, sprintf } from '~/locale'; -import createFlash from '~/flash'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; import { hasDiff } from '~/helpers/diffs_helper'; import eventHub from '../../notes/event_hub'; import DiffFileHeader from './diff_file_header.vue'; @@ -16,6 +17,7 @@ export default { DiffContent, GlLoadingIcon, }, + mixins: [glFeatureFlagsMixin()], props: { file: { type: Object, @@ -89,8 +91,25 @@ export default { this.setFileCollapsed({ filePath: this.file.file_path, collapsed: newVal }); }, + 'file.file_hash': { + handler: function watchFileHash() { + if ( + this.glFeatures.autoExpandCollapsedDiffs && + this.viewDiffsFileByFile && + this.file.viewer.collapsed + ) { + this.isCollapsed = false; + this.handleLoadCollapsedDiff(); + } else { + this.isCollapsed = this.file.viewer.collapsed || false; + } + }, + immediate: true, + }, 'file.viewer.collapsed': function setIsCollapsed(newVal) { - this.isCollapsed = newVal; + if (!this.viewDiffsFileByFile && !this.glFeatures.autoExpandCollapsedDiffs) { + this.isCollapsed = newVal; + } }, }, created() { @@ -148,6 +167,7 @@ export default { :id="file.file_hash" :class="{ 'is-active': currentDiffFileId === file.file_hash, + 'comments-disabled': Boolean(file.brokenSymlink), }" :data-path="file.new_path" class="diff-file file-holder" diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index d2f49bd0020..700e6302102 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -148,7 +148,7 @@ export default { <template> <div class="content discussion-form discussion-form-container discussion-notes"> - <div v-if="glFeatures.multilineComments" class="gl-mb-3 gl-text-gray-700 gl-pb-3"> + <div v-if="glFeatures.multilineComments" class="gl-mb-3 gl-text-gray-500 gl-pb-3"> <multiline-comment-form v-model="commentLineStart" :line="line" @@ -172,7 +172,7 @@ export default { :diff-file="diffFile" :show-suggest-popover="showSuggestPopover" save-button-title="Comment" - class="diff-comment-form prepend-top-10" + class="diff-comment-form gl-mt-3" @handleFormUpdateAddToReview="addToReview" @cancelForm="handleCancelCommentForm" @handleFormUpdate="handleSaveNote" diff --git a/app/assets/javascripts/diffs/components/diff_stats.vue b/app/assets/javascripts/diffs/components/diff_stats.vue index 0234fc4f40e..439d8097e56 100644 --- a/app/assets/javascripts/diffs/components/diff_stats.vue +++ b/app/assets/javascripts/diffs/components/diff_stats.vue @@ -1,7 +1,7 @@ <script> +import { isNumber } from 'lodash'; import Icon from '~/vue_shared/components/icon.vue'; import { n__ } from '~/locale'; -import { isNumber } from 'lodash'; export default { components: { Icon }, @@ -14,18 +14,21 @@ export default { type: Number, required: true, }, - diffFilesLength: { - type: Number, + diffFilesCountText: { + type: String, required: false, default: null, }, }, computed: { + diffFilesLength() { + return parseInt(this.diffFilesCountText, 10); + }, filesText() { return n__('file', 'files', this.diffFilesLength); }, isCompareVersionsHeader() { - return Boolean(this.diffFilesLength); + return Boolean(this.diffFilesCountText); }, hasDiffFiles() { return isNumber(this.diffFilesLength) && this.diffFilesLength >= 0; @@ -44,7 +47,7 @@ export default { > <div v-if="hasDiffFiles" class="diff-stats-group"> <icon name="doc-code" class="diff-stats-icon text-secondary" /> - <span class="text-secondary bold">{{ diffFilesLength }} {{ filesText }}</span> + <span class="text-secondary bold">{{ diffFilesCountText }} {{ filesText }}</span> </div> <div class="diff-stats-group cgreen d-flex align-items-center" diff --git a/app/assets/javascripts/diffs/components/diff_table_cell.vue b/app/assets/javascripts/diffs/components/diff_table_cell.vue index 198113e330a..49982a81372 100644 --- a/app/assets/javascripts/diffs/components/diff_table_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_table_cell.vue @@ -1,8 +1,9 @@ <script> import { mapGetters, mapActions } from 'vuex'; -import { GlIcon } from '@gitlab/ui'; +import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; import DiffGutterAvatars from './diff_gutter_avatars.vue'; +import { __ } from '~/locale'; import { CONTEXT_LINE_TYPE, LINE_POSITION_RIGHT, @@ -18,6 +19,9 @@ export default { DiffGutterAvatars, GlIcon, }, + directives: { + GlTooltip: GlTooltipDirective, + }, props: { line: { type: Object, @@ -123,6 +127,24 @@ export default { lineNumber() { return this.lineType === OLD_LINE_TYPE ? this.line.old_line : this.line.new_line; }, + addCommentTooltip() { + const brokenSymlinks = this.line.commentsDisabled; + let tooltip = __('Add a comment to this line'); + + if (brokenSymlinks) { + if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) { + tooltip = __( + 'Commenting on symbolic links that replace or are replaced by files is currently not supported.', + ); + } else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) { + tooltip = __( + 'Commenting on files that replace or are replaced by symbolic links is currently not supported.', + ); + } + } + + return tooltip; + }, }, mounted() { this.unwatchShouldShowCommentButton = this.$watch('shouldShowCommentButton', newVal => { @@ -146,17 +168,24 @@ export default { <template> <td ref="td" :class="classNameMap"> - <button - v-if="shouldRenderCommentButton" - v-show="shouldShowCommentButton" - ref="addDiffNoteButton" - type="button" - class="add-diff-note js-add-diff-note-button qa-diff-comment" - title="Add a comment to this line" - @click="handleCommentButton" + <span + ref="addNoteTooltip" + v-gl-tooltip + class="add-diff-note tooltip-wrapper" + :title="addCommentTooltip" > - <gl-icon :size="12" name="comment" /> - </button> + <button + v-if="shouldRenderCommentButton" + v-show="shouldShowCommentButton" + ref="addDiffNoteButton" + type="button" + class="add-diff-note note-button js-add-diff-note-button qa-diff-comment" + :disabled="line.commentsDisabled" + @click="handleCommentButton" + > + <gl-icon :size="12" name="comment" /> + </button> + </span> <a v-if="lineNumber" ref="lineNumberRef" diff --git a/app/assets/javascripts/diffs/components/hidden_files_warning.vue b/app/assets/javascripts/diffs/components/hidden_files_warning.vue index ad0ca4fa402..baf7471582a 100644 --- a/app/assets/javascripts/diffs/components/hidden_files_warning.vue +++ b/app/assets/javascripts/diffs/components/hidden_files_warning.vue @@ -26,7 +26,7 @@ export default { <div class="alert alert-warning"> <h4> {{ __('Too many changes to show.') }} - <div class="pull-right"> + <div class="float-right"> <a :href="plainDiffPath" class="btn btn-sm"> {{ __('Plain diff') }} </a> <a :href="emailPatchPath" class="btn btn-sm"> {{ __('Email patch') }} </a> </div> |