summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/boards')
-rw-r--r--app/assets/javascripts/boards/boards_util.js3
-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
-rw-r--r--app/assets/javascripts/boards/config_toggle.js25
-rw-r--r--app/assets/javascripts/boards/graphql/group_projects.query.graphql2
-rw-r--r--app/assets/javascripts/boards/index.js94
-rw-r--r--app/assets/javascripts/boards/mixins/sortable_default_options.js31
-rw-r--r--app/assets/javascripts/boards/mount_filtered_search_issue_boards.js42
-rw-r--r--app/assets/javascripts/boards/mount_multiple_boards_switcher.js50
-rw-r--r--app/assets/javascripts/boards/new_board.js29
-rw-r--r--app/assets/javascripts/boards/toggle_epics_swimlanes.js1
-rw-r--r--app/assets/javascripts/boards/toggle_focus.js18
-rw-r--r--app/assets/javascripts/boards/toggle_labels.js1
26 files changed, 160 insertions, 361 deletions
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js
index 96cc774a280..9fca9860282 100644
--- a/app/assets/javascripts/boards/boards_util.js
+++ b/app/assets/javascripts/boards/boards_util.js
@@ -111,7 +111,7 @@ export function fullLabelId(label) {
export function formatIssueInput(issueInput, boardConfig) {
const { labelIds = [], assigneeIds = [] } = issueInput;
- const { labels, assigneeId, milestoneId } = boardConfig;
+ const { labels, assigneeId, milestoneId, weight } = boardConfig;
return {
...issueInput,
@@ -121,6 +121,7 @@ export function formatIssueInput(issueInput, boardConfig) {
: issueInput?.milestoneId,
labelIds: [...labelIds, ...(labels?.map((l) => fullLabelId(l)) || [])],
assigneeIds: [...assigneeIds, ...(assigneeId ? [fullUserId(assigneeId)] : [])],
+ weight: weight > -1 ? weight : undefined,
};
}
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"
diff --git a/app/assets/javascripts/boards/config_toggle.js b/app/assets/javascripts/boards/config_toggle.js
deleted file mode 100644
index 1e54c2511b8..00000000000
--- a/app/assets/javascripts/boards/config_toggle.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import Vue from 'vue';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import ConfigToggle from './components/config_toggle.vue';
-
-export default () => {
- const el = document.querySelector('.js-board-config');
-
- if (!el) {
- return;
- }
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- name: 'ConfigToggleRoot',
- render(h) {
- return h(ConfigToggle, {
- props: {
- canAdminList: parseBoolean(el.dataset.canAdminList),
- hasScope: parseBoolean(el.dataset.hasScope),
- },
- });
- },
- });
-};
diff --git a/app/assets/javascripts/boards/graphql/group_projects.query.graphql b/app/assets/javascripts/boards/graphql/group_projects.query.graphql
index 0da14d0b872..e0a3cb0ee21 100644
--- a/app/assets/javascripts/boards/graphql/group_projects.query.graphql
+++ b/app/assets/javascripts/boards/graphql/group_projects.query.graphql
@@ -1,4 +1,4 @@
-#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+#import "~/graphql_shared/fragments/page_info.fragment.graphql"
query boardsGetGroupProjects($fullPath: ID!, $search: String, $after: String) {
group(fullPath: $fullPath) {
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index b31b56e6839..77c5994b5a1 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -1,22 +1,19 @@
import PortalVue from 'portal-vue';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-
-import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes';
-import toggleLabels from 'ee_else_ce/boards/toggle_labels';
-import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
import BoardApp from '~/boards/components/board_app.vue';
import '~/boards/filters/due_date_filters';
import { issuableTypes } from '~/boards/constants';
-import initBoardsFilteredSearch from '~/boards/mount_filtered_search_issue_boards';
import store from '~/boards/stores';
-import toggleFocusMode from '~/boards/toggle_focus';
-import { NavigationType, isLoggedIn, parseBoolean } from '~/lib/utils/common_utils';
+import {
+ NavigationType,
+ isLoggedIn,
+ parseBoolean,
+ convertObjectPropsToCamelCase,
+} from '~/lib/utils/common_utils';
+import { queryToObject } from '~/lib/utils/url_utility';
import { fullBoardId } from './boards_util';
-import boardConfigToggle from './config_toggle';
-import initNewBoard from './new_board';
import { gqlClient } from './graphql';
-import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
Vue.use(VueApollo);
Vue.use(PortalVue);
@@ -28,6 +25,12 @@ const apolloProvider = new VueApollo({
function mountBoardApp(el) {
const { boardId, groupId, fullPath, rootPath } = el.dataset;
+ const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
+
+ const initialFilterParams = {
+ ...convertObjectPropsToCamelCase(rawFilterParams),
+ };
+
store.dispatch('fetchBoard', {
fullPath,
fullBoardId: fullBoardId(boardId),
@@ -54,26 +57,41 @@ function mountBoardApp(el) {
boardId,
groupId: Number(groupId),
rootPath,
+ fullPath,
+ initialFilterParams,
+ boardBaseUrl: el.dataset.boardBaseUrl,
+ boardType: el.dataset.parent,
currentUserId: gon.current_user_id || null,
- canUpdate: parseBoolean(el.dataset.canUpdate),
- canAdminList: parseBoolean(el.dataset.canAdminList),
+ boardWeight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null,
labelsManagePath: el.dataset.labelsManagePath,
labelsFilterBasePath: el.dataset.labelsFilterBasePath,
+ releasesFetchPath: el.dataset.releasesFetchPath,
timeTrackingLimitToHours: parseBoolean(el.dataset.timeTrackingLimitToHours),
+ issuableType: issuableTypes.issue,
+ emailsDisabled: parseBoolean(el.dataset.emailsDisabled),
+ hasScope: parseBoolean(el.dataset.hasScope),
+ hasMissingBoards: parseBoolean(el.dataset.hasMissingBoards),
+ weights: el.dataset.weights ? JSON.parse(el.dataset.weights) : [],
+ // Permissions
+ canUpdate: parseBoolean(el.dataset.canUpdate),
+ canAdminList: parseBoolean(el.dataset.canAdminList),
+ canAdminBoard: parseBoolean(el.dataset.canAdminBoard),
+ allowLabelCreate: parseBoolean(el.dataset.canUpdate),
+ allowLabelEdit: parseBoolean(el.dataset.canUpdate),
+ isSignedIn: isLoggedIn(),
+ // Features
multipleAssigneesFeatureAvailable: parseBoolean(el.dataset.multipleAssigneesFeatureAvailable),
epicFeatureAvailable: parseBoolean(el.dataset.epicFeatureAvailable),
iterationFeatureAvailable: parseBoolean(el.dataset.iterationFeatureAvailable),
weightFeatureAvailable: parseBoolean(el.dataset.weightFeatureAvailable),
- boardWeight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null,
scopedLabelsAvailable: parseBoolean(el.dataset.scopedLabels),
milestoneListsAvailable: parseBoolean(el.dataset.milestoneListsAvailable),
assigneeListsAvailable: parseBoolean(el.dataset.assigneeListsAvailable),
iterationListsAvailable: parseBoolean(el.dataset.iterationListsAvailable),
- issuableType: issuableTypes.issue,
- emailsDisabled: parseBoolean(el.dataset.emailsDisabled),
- allowLabelCreate: parseBoolean(el.dataset.canUpdate),
- allowLabelEdit: parseBoolean(el.dataset.canUpdate),
allowScopedLabels: parseBoolean(el.dataset.scopedLabels),
+ swimlanesFeatureAvailable: gon.licensed_features?.swimlanes,
+ multipleIssueBoardsAvailable: parseBoolean(el.dataset.multipleBoardsAvailable),
+ scopedIssueBoardFeatureEnabled: parseBoolean(el.dataset.scopedIssueBoardFeatureEnabled),
},
render: (createComponent) => createComponent(BoardApp),
});
@@ -92,47 +110,5 @@ export default () => {
}
});
- const { releasesFetchPath, epicFeatureAvailable, iterationFeatureAvailable } = $boardApp.dataset;
- initBoardsFilteredSearch(
- apolloProvider,
- isLoggedIn(),
- releasesFetchPath,
- parseBoolean(epicFeatureAvailable),
- parseBoolean(iterationFeatureAvailable),
- );
-
mountBoardApp($boardApp);
-
- const createColumnTriggerEl = document.querySelector('.js-create-column-trigger');
- if (createColumnTriggerEl) {
- // eslint-disable-next-line no-new
- new Vue({
- el: createColumnTriggerEl,
- name: 'BoardAddNewColumnTriggerRoot',
- components: {
- BoardAddNewColumnTrigger,
- },
- store,
- render(createElement) {
- return createElement('board-add-new-column-trigger');
- },
- });
- }
-
- boardConfigToggle();
- initNewBoard();
-
- toggleFocusMode();
- toggleLabels();
-
- if (gon.licensed_features?.swimlanes) {
- toggleEpicsSwimlanes();
- }
-
- mountMultipleBoardsSwitcher({
- fullPath: $boardApp.dataset.fullPath,
- rootPath: $boardApp.dataset.boardsEndpoint,
- allowScopedLabels: $boardApp.dataset.scopedLabels,
- labelsManagePath: $boardApp.dataset.labelsManagePath,
- });
};
diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js b/app/assets/javascripts/boards/mixins/sortable_default_options.js
deleted file mode 100644
index 1bb0ee5b7e3..00000000000
--- a/app/assets/javascripts/boards/mixins/sortable_default_options.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* global DocumentTouch */
-
-import sortableConfig from '~/sortable/sortable_config';
-
-export function sortableStart() {
- document.body.classList.add('is-dragging');
-}
-
-export function sortableEnd() {
- document.body.classList.remove('is-dragging');
-}
-
-export function getBoardSortableDefaultOptions(obj) {
- const touchEnabled =
- 'ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch);
-
- const defaultSortOptions = {
- ...sortableConfig,
- filter: '.no-drag',
- delay: touchEnabled ? 100 : 0,
- scrollSensitivity: touchEnabled ? 60 : 100,
- scrollSpeed: 20,
- onStart: sortableStart,
- onEnd: sortableEnd,
- };
-
- Object.keys(obj).forEach((key) => {
- defaultSortOptions[key] = obj[key];
- });
- return defaultSortOptions;
-}
diff --git a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js b/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
deleted file mode 100644
index bb659eb075a..00000000000
--- a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import Vue from 'vue';
-import IssueBoardFilteredSearch from 'ee_else_ce/boards/components/issue_board_filtered_search.vue';
-import store from '~/boards/stores';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import { queryToObject } from '~/lib/utils/url_utility';
-
-export default (
- apolloProvider,
- isSignedIn,
- releasesFetchPath,
- epicFeatureAvailable,
- iterationFeatureAvailable,
-) => {
- const el = document.getElementById('js-issue-board-filtered-search');
- const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
-
- const initialFilterParams = {
- ...convertObjectPropsToCamelCase(rawFilterParams, {}),
- };
-
- if (!el) {
- return null;
- }
-
- return new Vue({
- el,
- name: 'BoardFilteredSearchRoot',
- provide: {
- initialFilterParams,
- isSignedIn,
- releasesFetchPath,
- epicFeatureAvailable,
- iterationFeatureAvailable,
- },
- store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
- apolloProvider,
- render: (createElement) =>
- createElement(IssueBoardFilteredSearch, {
- props: { fullPath: store.state?.fullPath || '', boardType: store.state?.boardType || '' },
- }),
- });
-};
diff --git a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
deleted file mode 100644
index 0bc9cfbd867..00000000000
--- a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
-import store from '~/boards/stores';
-import createDefaultClient from '~/lib/graphql';
-import { parseBoolean } from '~/lib/utils/common_utils';
-
-Vue.use(VueApollo);
-
-const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
-});
-
-export default (params = {}) => {
- const boardsSwitcherElement = document.getElementById('js-multiple-boards-switcher');
- const { dataset } = boardsSwitcherElement;
- return new Vue({
- el: boardsSwitcherElement,
- name: 'BoardsSelectorRoot',
- components: {
- BoardsSelector,
- },
- apolloProvider,
- store,
- provide: {
- fullPath: params.fullPath,
- rootPath: params.rootPath,
- allowScopedLabels: params.allowScopedLabels,
- labelsManagePath: params.labelsManagePath,
- allowLabelCreate: parseBoolean(dataset.canAdminBoard),
- },
- data() {
- const boardsSelectorProps = {
- ...dataset,
- hasMissingBoards: parseBoolean(dataset.hasMissingBoards),
- canAdminBoard: parseBoolean(dataset.canAdminBoard),
- multipleIssueBoardsAvailable: parseBoolean(dataset.multipleIssueBoardsAvailable),
- scopedIssueBoardFeatureEnabled: parseBoolean(dataset.scopedIssueBoardFeatureEnabled),
- weights: JSON.parse(dataset.weights),
- };
-
- return { boardsSelectorProps };
- },
- render(createElement) {
- return createElement(BoardsSelector, {
- props: this.boardsSelectorProps,
- });
- },
- });
-};
diff --git a/app/assets/javascripts/boards/new_board.js b/app/assets/javascripts/boards/new_board.js
deleted file mode 100644
index 34f2fea79a9..00000000000
--- a/app/assets/javascripts/boards/new_board.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import Vue from 'vue';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import { getExperimentVariant } from '~/experimentation/utils';
-import { CANDIDATE_VARIANT } from '~/experimentation/constants';
-import NewBoardButton from './components/new_board_button.vue';
-
-export default () => {
- if (getExperimentVariant('prominent_create_board_btn') !== CANDIDATE_VARIANT) {
- return;
- }
-
- const el = document.querySelector('.js-new-board');
-
- if (!el) {
- return;
- }
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- provide: {
- multipleIssueBoardsAvailable: parseBoolean(el.dataset.multipleIssueBoardsAvailable),
- canAdminBoard: parseBoolean(el.dataset.canAdminBoard),
- },
- render(h) {
- return h(NewBoardButton);
- },
- });
-};
diff --git a/app/assets/javascripts/boards/toggle_epics_swimlanes.js b/app/assets/javascripts/boards/toggle_epics_swimlanes.js
deleted file mode 100644
index 2d1ec238274..00000000000
--- a/app/assets/javascripts/boards/toggle_epics_swimlanes.js
+++ /dev/null
@@ -1 +0,0 @@
-export default () => {};
diff --git a/app/assets/javascripts/boards/toggle_focus.js b/app/assets/javascripts/boards/toggle_focus.js
deleted file mode 100644
index 8f057e192dd..00000000000
--- a/app/assets/javascripts/boards/toggle_focus.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import Vue from 'vue';
-import ToggleFocus from './components/toggle_focus.vue';
-
-export default () => {
- const issueBoardsContentSelector = '.content-wrapper > .js-focus-mode-board';
-
- return new Vue({
- el: '#js-toggle-focus-btn',
- name: 'ToggleFocusRoot',
- render(h) {
- return h(ToggleFocus, {
- props: {
- issueBoardsContentSelector,
- },
- });
- },
- });
-};
diff --git a/app/assets/javascripts/boards/toggle_labels.js b/app/assets/javascripts/boards/toggle_labels.js
deleted file mode 100644
index 2d1ec238274..00000000000
--- a/app/assets/javascripts/boards/toggle_labels.js
+++ /dev/null
@@ -1 +0,0 @@
-export default () => {};