summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards/components
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 10:00:54 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 10:00:54 +0000
commit3cccd102ba543e02725d247893729e5c73b38295 (patch)
treef36a04ec38517f5deaaacb5acc7d949688d1e187 /app/assets/javascripts/boards/components
parent205943281328046ef7b4528031b90fbda70c75ac (diff)
downloadgitlab-ce-3cccd102ba543e02725d247893729e5c73b38295.tar.gz
Add latest changes from gitlab-org/gitlab@14-10-stable-eev14.10.0-rc42
Diffstat (limited to 'app/assets/javascripts/boards/components')
-rw-r--r--app/assets/javascripts/boards/components/board_app.vue3
-rw-r--r--app/assets/javascripts/boards/components/board_card_inner.vue4
-rw-r--r--app/assets/javascripts/boards/components/board_content.vue4
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue30
-rw-r--r--app/assets/javascripts/boards/components/board_form.vue6
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue8
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue12
-rw-r--r--app/assets/javascripts/boards/components/board_top_bar.vue54
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue47
-rw-r--r--app/assets/javascripts/boards/components/config_toggle.vue11
-rw-r--r--app/assets/javascripts/boards/components/issuable_title.vue21
-rw-r--r--app/assets/javascripts/boards/components/issue_board_filtered_search.vue12
-rw-r--r--app/assets/javascripts/boards/components/issue_time_estimate.vue2
-rw-r--r--app/assets/javascripts/boards/components/item_count.vue2
-rw-r--r--app/assets/javascripts/boards/components/toggle_focus.vue9
15 files changed, 122 insertions, 103 deletions
diff --git a/app/assets/javascripts/boards/components/board_app.vue b/app/assets/javascripts/boards/components/board_app.vue
index 28f4a267077..858aabb0f05 100644
--- a/app/assets/javascripts/boards/components/board_app.vue
+++ b/app/assets/javascripts/boards/components/board_app.vue
@@ -2,11 +2,13 @@
import { mapActions, mapGetters } from 'vuex';
import BoardContent from '~/boards/components/board_content.vue';
import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue';
+import BoardTopBar from '~/boards/components/board_top_bar.vue';
export default {
components: {
BoardContent,
BoardSettingsSidebar,
+ BoardTopBar,
},
inject: ['disabled'],
computed: {
@@ -23,6 +25,7 @@ export default {
<template>
<div class="boards-app gl-relative" :class="{ 'is-compact': isSidebarOpen }">
+ <board-top-bar />
<board-content :disabled="disabled" />
<board-settings-sidebar />
</div>
diff --git a/app/assets/javascripts/boards/components/board_card_inner.vue b/app/assets/javascripts/boards/components/board_card_inner.vue
index aee61a5b2a5..814ff16efec 100644
--- a/app/assets/javascripts/boards/components/board_card_inner.vue
+++ b/app/assets/javascripts/boards/components/board_card_inner.vue
@@ -13,7 +13,7 @@ import boardCardInner from 'ee_else_ce/boards/mixins/board_card_inner';
import { isScopedLabel } from '~/lib/utils/common_utils';
import { sprintf, __, n__ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
-import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { ListType } from '../constants';
import BoardBlockedIcon from './board_blocked_icon.vue';
import IssueDueDate from './issue_due_date.vue';
@@ -240,7 +240,7 @@ export default {
class="board-card-footer gl-display-flex gl-justify-content-space-between gl-align-items-flex-end"
>
<div
- class="gl-display-flex align-items-start flex-wrap-reverse board-card-number-container gl-overflow-hidden js-board-card-number-container"
+ class="gl-display-flex align-items-start flex-wrap-reverse board-card-number-container gl-overflow-hidden"
>
<gl-loading-icon v-if="item.isLoading" size="md" class="mt-3" />
<span
diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue
index 27ea2e7a608..1d6a71aca47 100644
--- a/app/assets/javascripts/boards/components/board_content.vue
+++ b/app/assets/javascripts/boards/components/board_content.vue
@@ -4,7 +4,7 @@ import { sortBy } from 'lodash';
import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex';
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
-import defaultSortableConfig from '~/sortable/sortable_config';
+import { defaultSortableOptions } from '~/sortable/constants';
import { DraggableItemTypes } from '../constants';
import BoardColumn from './board_column.vue';
@@ -43,7 +43,7 @@ export default {
},
draggableOptions() {
const options = {
- ...defaultSortableConfig,
+ ...defaultSortableOptions,
disabled: this.disabled,
draggable: '.is-draggable',
fallbackOnBody: false,
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index 95d4fd5bc0a..aeb2cee590d 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -4,7 +4,10 @@ import { mapActions } from 'vuex';
import { getIdFromGraphQLId, isGid } from '~/graphql_shared/utils';
import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
-import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ FILTERED_SEARCH_TERM,
+ FILTER_ANY,
+} from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import { AssigneeFilterType } from '~/boards/constants';
@@ -42,6 +45,7 @@ export default {
search,
milestoneTitle,
iterationId,
+ iterationCadenceId,
types,
weight,
epicId,
@@ -95,10 +99,20 @@ export default {
});
}
- if (iterationId) {
+ let iterationData = null;
+
+ if (iterationId && iterationCadenceId) {
+ iterationData = `${iterationId}&${iterationCadenceId}`;
+ } else if (iterationCadenceId) {
+ iterationData = `${FILTER_ANY}&${iterationCadenceId}`;
+ } else if (iterationId) {
+ iterationData = iterationId;
+ }
+
+ if (iterationData) {
filteredSearchValue.push({
type: 'iteration',
- value: { data: iterationId, operator: '=' },
+ value: { data: iterationData, operator: '=' },
});
}
@@ -228,9 +242,12 @@ export default {
epicId,
myReactionEmoji,
iterationId,
+ iterationCadenceId,
releaseTag,
confidential,
} = this.filterParams;
+ let iteration = iterationId;
+ let cadence = iterationCadenceId;
let notParams = {};
if (Object.prototype.hasOwnProperty.call(this.filterParams, 'not')) {
@@ -251,6 +268,10 @@ export default {
);
}
+ if (iterationId?.includes('&')) {
+ [iteration, cadence] = iterationId.split('&');
+ }
+
return mapValues(
{
...notParams,
@@ -259,7 +280,8 @@ export default {
assignee_username: assigneeUsername,
assignee_id: assigneeId,
milestone_title: milestoneTitle,
- iteration_id: iterationId,
+ iteration_id: iteration,
+ iteration_cadence_id: cadence,
search,
types,
weight,
diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue
index 5fcf9514708..a874c9e070a 100644
--- a/app/assets/javascripts/boards/components/board_form.vue
+++ b/app/assets/javascripts/boards/components/board_form.vue
@@ -48,7 +48,7 @@ export default {
fullPath: {
default: '',
},
- rootPath: {
+ boardBaseUrl: {
default: '',
},
},
@@ -209,7 +209,7 @@ export default {
if (this.isDeleteForm) {
try {
await this.deleteBoard();
- visitUrl(this.rootPath);
+ visitUrl(this.boardBaseUrl);
} catch {
this.setError({ message: this.$options.i18n.deleteErrorMessage });
} finally {
@@ -289,7 +289,7 @@ export default {
<p v-if="isDeleteForm" data-testid="delete-confirmation-message">
{{ $options.i18n.deleteConfirmationMessage }}
</p>
- <form v-else class="js-board-config-modal" data-testid="board-form-wrapper" @submit.prevent>
+ <form v-else data-testid="board-form-wrapper" @submit.prevent>
<div v-if="!readonly" class="gl-mb-5" data-testid="board-form">
<label class="gl-font-weight-bold gl-font-lg" for="board-new-name">
{{ $options.i18n.titleFieldLabel }}
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 1024be61359..47f25f34d0c 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -2,9 +2,9 @@
import { GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import Draggable from 'vuedraggable';
import { mapActions, mapGetters, mapState } from 'vuex';
-import { sortableStart, sortableEnd } from '~/boards/mixins/sortable_default_options';
import { sprintf, __ } from '~/locale';
-import defaultSortableConfig from '~/sortable/sortable_config';
+import { defaultSortableOptions } from '~/sortable/constants';
+import { sortableStart, sortableEnd } from '~/sortable/utils';
import Tracking from '~/tracking';
import listQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
import { toggleFormEventPrefix, DraggableItemTypes } from '../constants';
@@ -121,7 +121,7 @@ export default {
},
treeRootOptions() {
const options = {
- ...defaultSortableConfig,
+ ...defaultSortableOptions,
fallbackOnBody: false,
group: 'board-list',
tag: 'ul',
@@ -287,7 +287,7 @@ export default {
:data-board-type="list.listType"
:class="{ 'bg-danger-100': boardItemsSizeExceedsMax }"
draggable=".board-card"
- class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2 js-board-list"
+ class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2"
data-testid="tree-root-wrapper"
@start="handleDragOnStart"
@end="handleDragOnEnd"
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 46b28d20da9..9f70c84931f 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -18,7 +18,7 @@ import Tracking from '~/tracking';
import { formatDate } from '~/lib/utils/datetime_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import listQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
-import AccessorUtilities from '../../lib/utils/accessor';
+import AccessorUtilities from '~/lib/utils/accessor';
import { inactiveId, LIST, ListType, toggleFormEventPrefix } from '../constants';
import eventHub from '../eventhub';
import ItemCount from './item_count.vue';
@@ -57,6 +57,9 @@ export default {
currentUserId: {
default: null,
},
+ canCreateEpic: {
+ default: false,
+ },
},
props: {
list: {
@@ -129,7 +132,7 @@ export default {
return (this.listType === ListType.backlog || this.showListHeaderButton) && !this.isEpicBoard;
},
isNewEpicShown() {
- return this.isEpicBoard && this.listType !== ListType.closed;
+ return this.isEpicBoard && this.canCreateEpic && this.listType !== ListType.closed;
},
isSettingsShown() {
return (
@@ -262,7 +265,7 @@ export default {
'gl-py-2': list.collapsed && isSwimlanesHeader,
'gl-flex-direction-column': list.collapsed,
}"
- class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3 js-board-handle"
+ class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3"
>
<gl-button
v-gl-tooltip.hover
@@ -443,12 +446,11 @@ export default {
ref="settingsBtn"
v-gl-tooltip.hover
:aria-label="$options.i18n.listSettings"
- class="no-drag js-board-settings-button"
+ class="no-drag"
:title="$options.i18n.listSettings"
icon="settings"
@click="openSidebarSettings"
/>
- <gl-tooltip :target="() => $refs.settingsBtn">{{ $options.i18n.listSettings }}</gl-tooltip>
</gl-button-group>
</h3>
</header>
diff --git a/app/assets/javascripts/boards/components/board_top_bar.vue b/app/assets/javascripts/boards/components/board_top_bar.vue
new file mode 100644
index 00000000000..f90ac1e9079
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_top_bar.vue
@@ -0,0 +1,54 @@
+<script>
+import { mapGetters } from 'vuex';
+import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
+import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
+import IssueBoardFilteredSearch from 'ee_else_ce/boards/components/issue_board_filtered_search.vue';
+import ConfigToggle from './config_toggle.vue';
+import NewBoardButton from './new_board_button.vue';
+import ToggleFocus from './toggle_focus.vue';
+
+export default {
+ components: {
+ BoardAddNewColumnTrigger,
+ BoardsSelector,
+ IssueBoardFilteredSearch,
+ ConfigToggle,
+ NewBoardButton,
+ ToggleFocus,
+ ToggleLabels: () => import('ee_component/boards/components/toggle_labels.vue'),
+ ToggleEpicsSwimlanes: () => import('ee_component/boards/components/toggle_epics_swimlanes.vue'),
+ EpicBoardFilteredSearch: () =>
+ import('ee_component/boards/components/epic_filtered_search.vue'),
+ },
+ inject: ['swimlanesFeatureAvailable', 'canAdminList', 'isSignedIn'],
+ computed: {
+ ...mapGetters(['isEpicBoard']),
+ },
+};
+</script>
+
+<template>
+ <div class="issues-filters">
+ <div
+ class="issues-details-filters filtered-search-block gl-display-flex gl-flex-direction-column gl-lg-flex-direction-row row-content-block second-block"
+ >
+ <div
+ class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-flex-grow-1 gl-lg-mb-0! mb-md-2 mb-sm-0 gl-w-full"
+ >
+ <boards-selector />
+ <new-board-button />
+ <epic-board-filtered-search v-if="isEpicBoard" />
+ <issue-board-filtered-search v-else />
+ </div>
+ <div
+ class="filter-dropdown-container gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-align-items-flex-start"
+ >
+ <toggle-labels />
+ <toggle-epics-swimlanes v-if="swimlanesFeatureAvailable && isSignedIn" />
+ <config-toggle />
+ <board-add-new-column-trigger v-if="canAdminList" />
+ <toggle-focus />
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index 91fdfd668fc..2951eda1112 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -40,37 +40,21 @@ export default {
directives: {
GlModalDirective,
},
- inject: ['fullPath'],
+ inject: [
+ 'boardBaseUrl',
+ 'fullPath',
+ 'canAdminBoard',
+ 'multipleIssueBoardsAvailable',
+ 'hasMissingBoards',
+ 'scopedIssueBoardFeatureEnabled',
+ 'weights',
+ ],
props: {
throttleDuration: {
type: Number,
default: 200,
required: false,
},
- boardBaseUrl: {
- type: String,
- required: true,
- },
- hasMissingBoards: {
- type: Boolean,
- required: true,
- },
- canAdminBoard: {
- type: Boolean,
- required: true,
- },
- multipleIssueBoardsAvailable: {
- type: Boolean,
- required: true,
- },
- scopedIssueBoardFeatureEnabled: {
- type: Boolean,
- required: true,
- },
- weights: {
- type: Array,
- required: true,
- },
},
data() {
return {
@@ -255,11 +239,12 @@ export default {
</script>
<template>
- <div class="boards-switcher js-boards-selector gl-mr-3">
- <span class="boards-selector-wrapper js-boards-selector-wrapper">
+ <div class="boards-switcher gl-mr-3" data-testid="boards-selector">
+ <span class="boards-selector-wrapper">
<gl-dropdown
+ data-testid="boards-dropdown"
data-qa-selector="boards_dropdown"
- toggle-class="dropdown-menu-toggle js-dropdown-toggle"
+ toggle-class="dropdown-menu-toggle"
menu-class="flex-column dropdown-extended-height"
:loading="isBoardLoading"
:text="board.name"
@@ -292,8 +277,8 @@ export default {
<gl-dropdown-item
v-for="recentBoard in recentBoards"
:key="`recent-${recentBoard.id}`"
- class="js-dropdown-item"
:href="`${boardBaseUrl}/${recentBoard.id}`"
+ data-testid="dropdown-item"
>
{{ recentBoard.name }}
</gl-dropdown-item>
@@ -308,8 +293,8 @@ export default {
<gl-dropdown-item
v-for="otherBoard in filteredBoards"
:key="otherBoard.id"
- class="js-dropdown-item"
:href="`${boardBaseUrl}/${otherBoard.id}`"
+ data-testid="dropdown-item"
>
{{ otherBoard.name }}
</gl-dropdown-item>
@@ -347,7 +332,7 @@ export default {
<gl-dropdown-item
v-if="showDelete"
v-gl-modal-directive="'board-config-modal'"
- class="text-danger js-delete-board"
+ class="text-danger"
@click.prevent="showPage('delete')"
>
{{ s__('IssueBoards|Delete board') }}
diff --git a/app/assets/javascripts/boards/components/config_toggle.vue b/app/assets/javascripts/boards/components/config_toggle.vue
index f39e4d90357..4746f598ab7 100644
--- a/app/assets/javascripts/boards/components/config_toggle.vue
+++ b/app/assets/javascripts/boards/components/config_toggle.vue
@@ -14,16 +14,7 @@ export default {
GlModalDirective,
},
mixins: [Tracking.mixin()],
- props: {
- canAdminList: {
- type: Boolean,
- required: true,
- },
- hasScope: {
- type: Boolean,
- required: true,
- },
- },
+ inject: ['canAdminList', 'hasScope'],
computed: {
buttonText() {
return this.canAdminList ? s__('Boards|Edit board') : s__('Boards|View scope');
diff --git a/app/assets/javascripts/boards/components/issuable_title.vue b/app/assets/javascripts/boards/components/issuable_title.vue
deleted file mode 100644
index 40627a9fab8..00000000000
--- a/app/assets/javascripts/boards/components/issuable_title.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-<script>
-export default {
- props: {
- title: {
- type: String,
- required: true,
- },
- refPath: {
- type: String,
- required: true,
- },
- },
-};
-</script>
-
-<template>
- <div data-testid="issue-title">
- <p class="gl-font-weight-bold">{{ title }}</p>
- <p class="gl-mb-0">{{ refPath }}</p>
- </div>
-</template>
diff --git a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
index 6bfdbb674a2..bab6fe26978 100644
--- a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
@@ -41,17 +41,7 @@ export default {
confidential: __('Confidential'),
},
components: { BoardFilteredSearch },
- inject: ['isSignedIn', 'releasesFetchPath'],
- props: {
- fullPath: {
- type: String,
- required: true,
- },
- boardType: {
- type: String,
- required: true,
- },
- },
+ inject: ['isSignedIn', 'releasesFetchPath', 'fullPath', 'boardType'],
computed: {
isGroupBoard() {
return this.boardType === BoardType.group;
diff --git a/app/assets/javascripts/boards/components/issue_time_estimate.vue b/app/assets/javascripts/boards/components/issue_time_estimate.vue
index 1ab7deebfaf..9312db06efe 100644
--- a/app/assets/javascripts/boards/components/issue_time_estimate.vue
+++ b/app/assets/javascripts/boards/components/issue_time_estimate.vue
@@ -43,7 +43,7 @@ export default {
<gl-tooltip
:target="() => $refs.issueTimeEstimate"
placement="bottom"
- class="js-issue-time-estimate"
+ data-testid="issue-time-estimate"
>
<span class="gl-font-weight-bold gl-display-block">{{ $options.i18n.timeEstimate }}</span>
{{ title }}
diff --git a/app/assets/javascripts/boards/components/item_count.vue b/app/assets/javascripts/boards/components/item_count.vue
index 9b1ff254766..a11c23e5625 100644
--- a/app/assets/javascripts/boards/components/item_count.vue
+++ b/app/assets/javascripts/boards/components/item_count.vue
@@ -29,7 +29,7 @@ export default {
<span :class="{ 'text-danger': issuesExceedMax }" data-testid="board-items-count">
{{ itemsSize }}
</span>
- <span v-if="isMaxLimitSet" class="js-max-issue-size">
+ <span v-if="isMaxLimitSet" class="max-issue-size">
{{ maxIssueCount }}
</span>
</div>
diff --git a/app/assets/javascripts/boards/components/toggle_focus.vue b/app/assets/javascripts/boards/components/toggle_focus.vue
index 49f5e7d20a9..71612e0742f 100644
--- a/app/assets/javascripts/boards/components/toggle_focus.vue
+++ b/app/assets/javascripts/boards/components/toggle_focus.vue
@@ -10,12 +10,6 @@ export default {
directives: {
GlTooltip,
},
- props: {
- issueBoardsContentSelector: {
- type: String,
- required: true,
- },
- },
data() {
return {
isFullscreen: false,
@@ -25,7 +19,7 @@ export default {
toggleFocusMode() {
hide(this.$refs.toggleFocusModeButton);
- const issueBoardsContent = document.querySelector(this.issueBoardsContentSelector);
+ const issueBoardsContent = document.querySelector('.content-wrapper > .js-focus-mode-board');
issueBoardsContent.classList.toggle('is-focused');
this.isFullscreen = !this.isFullscreen;
@@ -44,7 +38,6 @@ export default {
v-gl-tooltip
category="tertiary"
:icon="isFullscreen ? 'minimize' : 'maximize'"
- class="js-focus-mode-btn"
data-qa-selector="focus_mode_button"
:title="$options.i18n.toggleFocusMode"
:aria-label="$options.i18n.toggleFocusMode"