diff options
Diffstat (limited to 'app/assets/javascripts')
8 files changed, 116 insertions, 60 deletions
diff --git a/app/assets/javascripts/analytics/usage_trends/components/usage_counts.vue b/app/assets/javascripts/analytics/usage_trends/components/usage_counts.vue index 0b4fa879b03..1eb4832a2a3 100644 --- a/app/assets/javascripts/analytics/usage_trends/components/usage_counts.vue +++ b/app/assets/javascripts/analytics/usage_trends/components/usage_counts.vue @@ -1,5 +1,6 @@ <script> -import MetricCard from '~/analytics/shared/components/metric_card.vue'; +import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; +import { GlSingleStat } from '@gitlab/ui/dist/charts'; import createFlash from '~/flash'; import { number } from '~/lib/utils/unit_format'; import { s__ } from '~/locale'; @@ -10,7 +11,8 @@ const defaultPrecision = 0; export default { name: 'UsageCounts', components: { - MetricCard, + GlSkeletonLoading, + GlSingleStat, }, data() { return { @@ -56,10 +58,24 @@ export default { </script> <template> - <metric-card - :title="__('Usage Trends')" - :metrics="counts" - :is-loading="$apollo.queries.counts.loading" - class="gl-mt-4" - /> + <div> + <h2> + {{ __('Usage Trends') }} + </h2> + <div + class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-my-6 gl-align-items-flex-start" + > + <gl-skeleton-loading v-if="$apollo.queries.counts.loading" /> + <template v-else> + <gl-single-stat + v-for="count in counts" + :key="count.key" + class="gl-pr-9 gl-my-4 gl-md-mt-0 gl-md-mb-0" + :value="`${count.value}`" + :title="count.label" + :should-animate="true" + /> + </template> + </div> + </div> </template> diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue index 9c0d2dee313..53b071aaed1 100644 --- a/app/assets/javascripts/boards/components/board_content.vue +++ b/app/assets/javascripts/boards/components/board_content.vue @@ -12,10 +12,8 @@ import BoardColumnDeprecated from './board_column_deprecated.vue'; export default { components: { BoardAddNewColumn, - BoardColumn: - gon.features?.graphqlBoardLists || gon.features?.epicBoards - ? BoardColumn - : BoardColumnDeprecated, + BoardColumn, + BoardColumnDeprecated, BoardContentSidebar: () => import('~/boards/components/board_content_sidebar.vue'), EpicBoardContentSidebar: () => import('ee_component/boards/components/epic_board_content_sidebar.vue'), @@ -38,11 +36,14 @@ export default { computed: { ...mapState(['boardLists', 'error', 'addColumnForm']), ...mapGetters(['isSwimlanesOn', 'isEpicBoard']), + useNewBoardColumnComponent() { + return this.glFeatures.graphqlBoardLists || this.isSwimlanesOn || this.isEpicBoard; + }, addColumnFormVisible() { return this.addColumnForm?.visible; }, boardListsToUse() { - return this.glFeatures.graphqlBoardLists || this.isSwimlanesOn || this.isEpicBoard + return this.useNewBoardColumnComponent ? sortBy([...Object.values(this.boardLists)], 'position') : this.lists; }, @@ -65,6 +66,9 @@ export default { return this.canDragColumns ? options : {}; }, + boardColumnComponent() { + return this.useNewBoardColumnComponent ? BoardColumn : BoardColumnDeprecated; + }, }, methods: { ...mapActions(['moveList', 'unsetError']), @@ -102,7 +106,8 @@ export default { class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap" @end="handleDragOnEnd" > - <board-column + <component + :is="boardColumnComponent" v-for="(list, index) in boardListsToUse" :key="index" ref="board" diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js index 55bc91cbcff..21a34182369 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js +++ b/app/assets/javascripts/boards/components/board_sidebar.js @@ -105,7 +105,7 @@ export default Vue.extend({ closeSidebar() { this.detail.issue = {}; }, - setAssignees(assignees) { + setAssignees({ assignees }) { boardsStore.detail.issue.setAssignees(assignees); }, showScopedLabels(label) { diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js index 65adb56f6d4..f9503cb592c 100644 --- a/app/assets/javascripts/boards/stores/actions.js +++ b/app/assets/javascripts/boards/stores/actions.js @@ -472,11 +472,11 @@ export default { } }, - setAssignees: ({ commit, getters }, assigneeUsernames) => { + setAssignees: ({ commit }, { id, assignees }) => { commit('UPDATE_BOARD_ITEM_BY_ID', { - itemId: getters.activeBoardItem.id, + itemId: id, prop: 'assignees', - value: assigneeUsernames, + value: assignees, }); }, diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue index d38a703688a..5cf547c1423 100644 --- a/app/assets/javascripts/diffs/components/diff_file.vue +++ b/app/assets/javascripts/diffs/components/diff_file.vue @@ -2,6 +2,7 @@ import { GlButton, GlLoadingIcon, GlSafeHtmlDirective as SafeHtml, GlSprintf } from '@gitlab/ui'; import { escape } from 'lodash'; import { mapActions, mapGetters, mapState } from 'vuex'; +import { IdState } from 'vendor/vue-virtual-scroller'; import createFlash from '~/flash'; import { hasDiff } from '~/helpers/diffs_helper'; import { diffViewerErrors } from '~/ide/constants'; @@ -34,7 +35,7 @@ export default { directives: { SafeHtml, }, - mixins: [glFeatureFlagsMixin()], + mixins: [glFeatureFlagsMixin(), IdState({ idProp: (vm) => vm.file.file_hash })], props: { file: { type: Object, @@ -79,7 +80,7 @@ export default { default: false, }, }, - data() { + idState() { return { isLoadingCollapsedDiff: false, forkMessageVisible: false, @@ -101,7 +102,9 @@ export default { return getShortShaFromFile(this.file); }, showLoadingIcon() { - return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed); + return ( + this.idState.isLoadingCollapsedDiff || (!this.file.renderIt && !this.idState.isCollapsed) + ); }, hasDiff() { return hasDiff(this.file); @@ -145,13 +148,13 @@ export default { return collapsedType(this.file) === DIFF_FILE_MANUAL_COLLAPSE; }, showBody() { - return !this.isCollapsed || this.automaticallyCollapsed; + return !this.idState.isCollapsed || this.automaticallyCollapsed; }, showWarning() { - return this.isCollapsed && this.automaticallyCollapsed && !this.viewDiffsFileByFile; + return this.idState.isCollapsed && this.automaticallyCollapsed && !this.viewDiffsFileByFile; }, showContent() { - return !this.isCollapsed && !this.isFileTooLarge; + return !this.idState.isCollapsed && !this.isFileTooLarge; }, showLocalFileReviews() { const loggedIn = Boolean(gon.current_user_id); @@ -179,23 +182,16 @@ export default { this.requestDiff(); } }, - immediate: true, }, 'file.viewer.automaticallyCollapsed': { handler: function autoChangeWatch(automaticValue) { - if (collapsedType(this.file) !== DIFF_FILE_MANUAL_COLLAPSE) { - this.isCollapsed = this.viewDiffsFileByFile ? false : automaticValue; - } + this.handleAutomaticallyCollapsed(automaticValue); }, - immediate: true, }, 'file.viewer.manuallyCollapsed': { handler: function manualChangeWatch(manualValue) { - if (manualValue !== null) { - this.isCollapsed = manualValue; - } + this.handleManualChangeWatch(manualValue); }, - immediate: true, }, }, created() { @@ -212,6 +208,8 @@ export default { } this.manageViewedEffects(); + this.handleAutomaticallyCollapsed(this.file.viewer.automaticallyCollapsed); + this.handleManualChangeWatch(this.file.viewer.manuallyCollapsed); }, beforeDestroy() { if (this.preRender) return; @@ -226,12 +224,12 @@ export default { 'setFileCollapsedByUser', ]), manageViewedEffects() { - if (this.reviewed && !this.isCollapsed && this.showLocalFileReviews) { + if (this.reviewed && !this.idState.isCollapsed && this.showLocalFileReviews) { this.handleToggle(); } }, expandAllListener() { - if (this.isCollapsed) { + if (this.idState.isCollapsed) { this.handleToggle(); } }, @@ -253,7 +251,7 @@ export default { }); }, handleToggle({ viaUserInteraction = false } = {}) { - const collapsingNow = !this.isCollapsed; + const collapsingNow = !this.idState.isCollapsed; const contentElement = this.$el.querySelector(`#diff-content-${this.file.file_hash}`); this.setFileCollapsedByUser({ @@ -270,11 +268,11 @@ export default { } }, requestDiff() { - this.isLoadingCollapsedDiff = true; + this.idState.isLoadingCollapsedDiff = true; this.loadCollapsedDiff(this.file) .then(() => { - this.isLoadingCollapsedDiff = false; + this.idState.isLoadingCollapsedDiff = false; this.setRenderIt(this.file); }) .then(() => { @@ -287,17 +285,27 @@ export default { ); }) .catch(() => { - this.isLoadingCollapsedDiff = false; + this.idState.isLoadingCollapsedDiff = false; createFlash({ message: this.$options.i18n.genericError, }); }); }, showForkMessage() { - this.forkMessageVisible = true; + this.idState.forkMessageVisible = true; }, hideForkMessage() { - this.forkMessageVisible = false; + this.idState.forkMessageVisible = false; + }, + handleAutomaticallyCollapsed(automaticValue) { + if (collapsedType(this.file) !== DIFF_FILE_MANUAL_COLLAPSE) { + this.idState.isCollapsed = this.viewDiffsFileByFile ? false : automaticValue; + } + }, + handleManualChangeWatch(manualValue) { + if (manualValue !== null) { + this.idState.isCollapsed = manualValue; + } }, }, }; @@ -320,7 +328,7 @@ export default { :diff-file="file" :collapsible="true" :reviewed="reviewed" - :expanded="!isCollapsed" + :expanded="!idState.isCollapsed" :add-merge-request-buttons="true" :view-diffs-file-by-file="viewDiffsFileByFile" :show-local-file-reviews="showLocalFileReviews" @@ -331,7 +339,10 @@ export default { @showForkMessage="showForkMessage" /> - <div v-if="forkMessageVisible" class="js-file-fork-suggestion-section file-fork-suggestion"> + <div + v-if="idState.forkMessageVisible" + class="js-file-fork-suggestion-section file-fork-suggestion" + > <span v-safe-html="forkMessage" class="file-fork-suggestion-note"></span> <a :href="file.fork_path" diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue index 45c7fe35f03..c83abb95198 100644 --- a/app/assets/javascripts/diffs/components/diff_file_header.vue +++ b/app/assets/javascripts/diffs/components/diff_file_header.vue @@ -13,6 +13,7 @@ import { } from '@gitlab/ui'; import { escape } from 'lodash'; import { mapActions, mapGetters, mapState } from 'vuex'; +import { IdState } from 'vendor/vue-virtual-scroller'; import { diffViewerModes } from '~/ide/constants'; import { scrollToElement } from '~/lib/utils/common_utils'; import { truncateSha } from '~/lib/utils/text_utility'; @@ -47,7 +48,7 @@ export default { GlTooltip: GlTooltipDirective, SafeHtml: GlSafeHtmlDirective, }, - mixins: [glFeatureFlagsMixin()], + mixins: [glFeatureFlagsMixin(), IdState({ idProp: (vm) => vm.diffFile.file_hash })], i18n: { ...DIFF_FILE_HEADER, compareButtonLabel: s__('Compare submodule commit revisions'), @@ -102,7 +103,7 @@ export default { default: () => [], }, }, - data() { + idState() { return { moreActionsShown: false, }; @@ -239,7 +240,7 @@ export default { } }, setMoreActionsShown(val) { - this.moreActionsShown = val; + this.idState.moreActionsShown = val; }, toggleReview(newReviewedStatus) { const autoCollapsed = @@ -268,7 +269,7 @@ export default { <template> <div ref="header" - :class="{ 'gl-z-dropdown-menu!': moreActionsShown }" + :class="{ 'gl-z-dropdown-menu!': idState.moreActionsShown }" class="js-file-title file-title file-title-flex-parent" data-qa-selector="file_title_container" :data-qa-file-name="filePath" diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue index aa3e415b264..485cddd50c0 100644 --- a/app/assets/javascripts/diffs/components/diff_view.vue +++ b/app/assets/javascripts/diffs/components/diff_view.vue @@ -1,5 +1,6 @@ <script> import { mapGetters, mapState, mapActions } from 'vuex'; +import { IdState } from 'vendor/vue-virtual-scroller'; import DraftNote from '~/batch_comments/components/draft_note.vue'; import draftCommentsMixin from '~/diffs/mixins/draft_comments'; import { getCommentedLines } from '~/notes/components/multiline_comment_utils'; @@ -17,7 +18,11 @@ export default { DiffCommentCell, DraftNote, }, - mixins: [draftCommentsMixin, glFeatureFlagsMixin()], + mixins: [ + draftCommentsMixin, + glFeatureFlagsMixin(), + IdState({ idProp: (vm) => vm.diffFile.file_hash }), + ], props: { diffFile: { type: Object, @@ -38,7 +43,7 @@ export default { default: false, }, }, - data() { + idState() { return { dragStart: null, updatedLineRange: null, @@ -80,29 +85,29 @@ export default { if (event.target?.parentNode) { hide(event.target.parentNode); } - this.dragStart = line; + this.idState.dragStart = line; }, onDragOver(line) { - if (line.chunk !== this.dragStart.chunk) return; + if (line.chunk !== this.idState.dragStart.chunk) return; - let start = this.dragStart; + let start = this.idState.dragStart; let end = line; - if (this.dragStart.index >= line.index) { + if (this.idState.dragStart.index >= line.index) { start = line; - end = this.dragStart; + end = this.idState.dragStart; } - this.updatedLineRange = { start, end }; + this.idState.updatedLineRange = { start, end }; - this.setSelectedCommentPosition(this.updatedLineRange); + this.setSelectedCommentPosition(this.idState.updatedLineRange); }, onStopDragging() { this.showCommentForm({ - lineCode: this.updatedLineRange?.end?.line_code, + lineCode: this.idState.updatedLineRange?.end?.line_code, fileHash: this.diffFile.file_hash, }); - this.dragStart = null; + this.idState.dragStart = null; }, isHighlighted(line) { return isHighlighted( diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue index d9a974202a3..1dd05d3886e 100644 --- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue +++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue @@ -3,6 +3,7 @@ import { GlDropdownItem } from '@gitlab/ui'; import { cloneDeep } from 'lodash'; import Vue from 'vue'; import createFlash from '~/flash'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { IssuableType } from '~/issue_show/constants'; import { __, n__ } from '~/locale'; import SidebarAssigneesRealtime from '~/sidebar/components/assignees/assignees_realtime.vue'; @@ -80,6 +81,8 @@ export default { selected: [], isSettingAssignees: false, isDirty: false, + oldIid: null, + oldSelected: null, }; }, apollo: { @@ -142,6 +145,14 @@ export default { return this.currentUser.username !== undefined; }, }, + watch: { + iid(_, oldIid) { + if (this.isDirty) { + this.oldIid = oldIid; + this.oldSelected = this.selected; + } + }, + }, created() { assigneesWidget.updateAssignees = this.updateAssignees; }, @@ -157,10 +168,14 @@ export default { variables: { ...this.queryVariables, assigneeUsernames, + iid: this.oldIid || this.iid, }, }) .then(({ data }) => { - this.$emit('assignees-updated', data.issuableSetAssignees.issuable.assignees.nodes); + this.$emit('assignees-updated', { + id: getIdFromGraphQLId(data.issuableSetAssignees.issuable.id), + assignees: data.issuableSetAssignees.issuable.assignees.nodes, + }); return data; }) .catch(() => { @@ -176,7 +191,10 @@ export default { saveAssignees() { if (this.isDirty) { this.isDirty = false; - this.updateAssignees(this.selected.map(({ username }) => username)); + const usernames = this.oldSelected || this.selected; + this.updateAssignees(usernames.map(({ username }) => username)); + this.oldIid = null; + this.oldSelected = null; } this.$el.dispatchEvent(hideDropdownEvent); }, |