debian-mirror-gitlab/app/assets/javascripts/boards/index.js

346 lines
12 KiB
JavaScript
Raw Normal View History

2021-06-08 01:23:25 +05:30
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
2017-08-17 22:00:37 +05:30
import Vue from 'vue';
2021-03-11 19:13:27 +05:30
import VueApollo from 'vue-apollo';
2021-02-22 17:27:13 +05:30
import { mapActions, mapGetters } from 'vuex';
2018-03-27 19:54:05 +05:30
2020-01-01 13:55:28 +05:30
import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
import {
2021-01-03 14:25:43 +05:30
setWeightFetchingState,
2020-01-01 13:55:28 +05:30
setEpicFetchingState,
getMilestoneTitle,
} from 'ee_else_ce/boards/ee_functions';
2021-03-11 19:13:27 +05:30
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';
2020-10-24 23:57:45 +05:30
import BoardContent from '~/boards/components/board_content.vue';
2019-09-04 21:01:54 +05:30
import './models/label';
import './models/assignee';
2019-09-30 21:07:59 +05:30
import '~/boards/models/milestone';
import '~/boards/models/project';
2021-03-11 19:13:27 +05:30
import '~/boards/filters/due_date_filters';
2021-04-17 20:07:23 +05:30
import { issuableTypes } from '~/boards/constants';
2021-03-11 19:13:27 +05:30
import eventHub from '~/boards/eventhub';
import FilteredSearchBoards from '~/boards/filtered_search_boards';
2019-12-26 22:10:19 +05:30
import store from '~/boards/stores';
2019-09-30 21:07:59 +05:30
import boardsStore from '~/boards/stores/boards_store';
2021-03-11 19:13:27 +05:30
import toggleFocusMode from '~/boards/toggle_focus';
import createDefaultClient from '~/lib/graphql';
2019-07-31 22:56:46 +05:30
import {
NavigationType,
convertObjectPropsToCamelCase,
parseBoolean,
} from '~/lib/utils/common_utils';
2021-03-11 19:13:27 +05:30
import { __ } from '~/locale';
import sidebarEventHub from '~/sidebar/event_hub';
2021-06-08 01:23:25 +05:30
import introspectionQueryResultData from '~/sidebar/fragmentTypes.json';
import { fullBoardId } from './boards_util';
2021-04-17 20:07:23 +05:30
import boardConfigToggle from './config_toggle';
2019-09-30 21:07:59 +05:30
import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
2020-05-24 23:13:21 +05:30
Vue.use(VueApollo);
2021-06-08 01:23:25 +05:30
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData,
});
2020-05-24 23:13:21 +05:30
const apolloProvider = new VueApollo({
2021-06-08 01:23:25 +05:30
defaultClient: createDefaultClient(
{},
{
cacheConfig: {
fragmentMatcher,
},
assumeImmutableResults: true,
},
),
2020-05-24 23:13:21 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
let issueBoardsApp;
2018-03-27 19:54:05 +05:30
export default () => {
2017-08-17 22:00:37 +05:30
const $boardApp = document.getElementById('board-app');
2018-12-05 23:21:45 +05:30
// check for browser back and trigger a hard reload to circumvent browser caching.
2021-03-08 18:12:59 +05:30
window.addEventListener('pageshow', (event) => {
2018-12-13 13:39:08 +05:30
const isNavTypeBackForward =
window.performance && window.performance.navigation.type === NavigationType.TYPE_BACK_FORWARD;
2018-12-05 23:21:45 +05:30
if (event.persisted || isNavTypeBackForward) {
window.location.reload();
}
});
2018-12-13 13:39:08 +05:30
if (issueBoardsApp) {
issueBoardsApp.$destroy(true);
2017-08-17 22:00:37 +05:30
}
2021-03-08 18:12:59 +05:30
if (!gon?.features?.graphqlBoardLists) {
boardsStore.create();
boardsStore.setTimeTrackingLimitToHours($boardApp.dataset.timeTrackingLimitToHours);
}
2017-08-17 22:00:37 +05:30
2021-03-11 19:13:27 +05:30
// eslint-disable-next-line @gitlab/no-runtime-template-compiler
2018-12-13 13:39:08 +05:30
issueBoardsApp = new Vue({
2017-08-17 22:00:37 +05:30
el: $boardApp,
components: {
2020-06-23 00:09:42 +05:30
BoardContent,
2018-12-13 13:39:08 +05:30
BoardSidebar,
2020-10-24 23:57:45 +05:30
BoardSettingsSidebar: () => import('~/boards/components/board_settings_sidebar.vue'),
2017-08-17 22:00:37 +05:30
},
2020-11-24 15:15:51 +05:30
provide: {
boardId: $boardApp.dataset.boardId,
2021-01-03 14:25:43 +05:30
groupId: Number($boardApp.dataset.groupId),
2020-11-24 15:15:51 +05:30
rootPath: $boardApp.dataset.rootPath,
2021-01-29 00:20:46 +05:30
currentUserId: gon.current_user_id || null,
2021-03-11 19:13:27 +05:30
canUpdate: parseBoolean($boardApp.dataset.canUpdate),
2021-04-29 21:17:54 +05:30
canAdminList: parseBoolean($boardApp.dataset.canAdminList),
2021-01-03 14:25:43 +05:30
labelsManagePath: $boardApp.dataset.labelsManagePath,
labelsFilterBasePath: $boardApp.dataset.labelsFilterBasePath,
2021-01-29 00:20:46 +05:30
timeTrackingLimitToHours: parseBoolean($boardApp.dataset.timeTrackingLimitToHours),
2021-06-08 01:23:25 +05:30
multipleAssigneesFeatureAvailable: parseBoolean(
$boardApp.dataset.multipleAssigneesFeatureAvailable,
),
epicFeatureAvailable: parseBoolean($boardApp.dataset.epicFeatureAvailable),
iterationFeatureAvailable: parseBoolean($boardApp.dataset.iterationFeatureAvailable),
2021-01-29 00:20:46 +05:30
weightFeatureAvailable: parseBoolean($boardApp.dataset.weightFeatureAvailable),
boardWeight: $boardApp.dataset.boardWeight
? parseInt($boardApp.dataset.boardWeight, 10)
: null,
scopedLabelsAvailable: parseBoolean($boardApp.dataset.scopedLabels),
2021-04-17 20:07:23 +05:30
milestoneListsAvailable: parseBoolean($boardApp.dataset.milestoneListsAvailable),
assigneeListsAvailable: parseBoolean($boardApp.dataset.assigneeListsAvailable),
iterationListsAvailable: parseBoolean($boardApp.dataset.iterationListsAvailable),
2021-04-29 21:17:54 +05:30
issuableType: issuableTypes.issue,
emailsDisabled: parseBoolean($boardApp.dataset.emailsDisabled),
2020-11-24 15:15:51 +05:30
},
2019-12-26 22:10:19 +05:30
store,
2020-05-24 23:13:21 +05:30
apolloProvider,
data() {
return {
state: boardsStore.state,
loading: 0,
boardsEndpoint: $boardApp.dataset.boardsEndpoint,
recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
listsEndpoint: $boardApp.dataset.listsEndpoint,
disabled: parseBoolean($boardApp.dataset.disabled),
bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
detailIssue: boardsStore.detail,
parent: $boardApp.dataset.parent,
};
2017-08-17 22:00:37 +05:30
},
computed: {
2021-01-29 00:20:46 +05:30
...mapGetters(['shouldUseGraphQL']),
2018-11-18 11:00:15 +05:30
detailIssueVisible() {
2017-08-17 22:00:37 +05:30
return Object.keys(this.detailIssue.issue).length;
},
},
2018-11-18 11:00:15 +05:30
created() {
2021-03-08 18:12:59 +05:30
this.setInitialBoardData({
2020-11-24 15:15:51 +05:30
boardId: $boardApp.dataset.boardId,
2021-06-08 01:23:25 +05:30
fullBoardId: fullBoardId($boardApp.dataset.boardId),
2020-04-08 14:13:33 +05:30
fullPath: $boardApp.dataset.fullPath,
2020-11-24 15:15:51 +05:30
boardType: this.parent,
disabled: this.disabled,
2021-04-17 20:07:23 +05:30
issuableType: issuableTypes.issue,
2021-02-22 17:27:13 +05:30
boardConfig: {
milestoneId: parseInt($boardApp.dataset.boardMilestoneId, 10),
milestoneTitle: $boardApp.dataset.boardMilestoneTitle || '',
iterationId: parseInt($boardApp.dataset.boardIterationId, 10),
iterationTitle: $boardApp.dataset.boardIterationTitle || '',
2021-03-08 18:12:59 +05:30
assigneeId: $boardApp.dataset.boardAssigneeId,
2021-02-22 17:27:13 +05:30
assigneeUsername: $boardApp.dataset.boardAssigneeUsername,
2021-03-08 18:12:59 +05:30
labels: $boardApp.dataset.labels ? JSON.parse($boardApp.dataset.labels) : [],
labelIds: $boardApp.dataset.labelIds ? JSON.parse($boardApp.dataset.labelIds) : [],
2021-02-22 17:27:13 +05:30
weight: $boardApp.dataset.boardWeight
? parseInt($boardApp.dataset.boardWeight, 10)
: null,
},
2020-11-24 15:15:51 +05:30
});
2021-03-08 18:12:59 +05:30
boardsStore.setEndpoints({
boardsEndpoint: this.boardsEndpoint,
recentBoardsEndpoint: this.recentBoardsEndpoint,
listsEndpoint: this.listsEndpoint,
bulkUpdatePath: this.bulkUpdatePath,
boardId: $boardApp.dataset.boardId,
fullPath: $boardApp.dataset.fullPath,
});
2018-12-13 13:39:08 +05:30
boardsStore.rootPath = this.boardsEndpoint;
2017-08-17 22:00:37 +05:30
eventHub.$on('updateTokens', this.updateTokens);
2018-03-17 18:26:18 +05:30
eventHub.$on('newDetailIssue', this.updateDetailIssue);
eventHub.$on('clearDetailIssue', this.clearDetailIssue);
sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
2021-01-03 14:25:43 +05:30
eventHub.$on('initialBoardLoad', this.initialBoardLoad);
2017-08-17 22:00:37 +05:30
},
beforeDestroy() {
eventHub.$off('updateTokens', this.updateTokens);
2018-03-17 18:26:18 +05:30
eventHub.$off('newDetailIssue', this.updateDetailIssue);
eventHub.$off('clearDetailIssue', this.clearDetailIssue);
sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
2021-01-03 14:25:43 +05:30
eventHub.$off('initialBoardLoad', this.initialBoardLoad);
2017-08-17 22:00:37 +05:30
},
2018-11-18 11:00:15 +05:30
mounted() {
2021-04-29 21:17:54 +05:30
this.filterManager = new FilteredSearchBoards(boardsStore.filter, true, boardsStore.cantEdit);
2021-04-17 20:07:23 +05:30
2021-04-29 21:17:54 +05:30
this.filterManager.setup();
2018-03-17 18:26:18 +05:30
2020-11-24 15:15:51 +05:30
this.performSearch();
2020-05-24 23:13:21 +05:30
2020-11-24 15:15:51 +05:30
boardsStore.disabled = this.disabled;
2017-08-17 22:00:37 +05:30
2021-01-29 00:20:46 +05:30
if (!this.shouldUseGraphQL) {
2021-01-03 14:25:43 +05:30
this.initialBoardLoad();
}
},
methods: {
2021-09-04 01:27:46 +05:30
...mapActions(['setInitialBoardData', 'performSearch', 'setError']),
2021-01-03 14:25:43 +05:30
initialBoardLoad() {
2020-05-24 23:13:21 +05:30
boardsStore
.all()
2021-03-08 18:12:59 +05:30
.then((res) => res.data)
.then((lists) => {
lists.forEach((list) => boardsStore.addList(list));
2020-05-24 23:13:21 +05:30
this.loading = false;
})
2021-09-04 01:27:46 +05:30
.catch((error) => {
this.setError({
error,
message: __('An error occurred while fetching the board lists. Please try again.'),
});
2020-05-24 23:13:21 +05:30
});
2021-01-03 14:25:43 +05:30
},
2017-08-17 22:00:37 +05:30
updateTokens() {
this.filterManager.updateTokens();
2018-03-17 18:26:18 +05:30
},
2019-12-21 20:55:43 +05:30
updateDetailIssue(newIssue, multiSelect = false) {
2018-11-08 19:23:39 +05:30
const { sidebarInfoEndpoint } = newIssue;
2018-03-17 18:26:18 +05:30
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
newIssue.setFetchingState('subscriptions', true);
2021-01-03 14:25:43 +05:30
setWeightFetchingState(newIssue, true);
2019-10-12 21:52:04 +05:30
setEpicFetchingState(newIssue, true);
2020-01-01 13:55:28 +05:30
boardsStore
.getIssueInfo(sidebarInfoEndpoint)
2021-03-08 18:12:59 +05:30
.then((res) => res.data)
.then((data) => {
2019-07-31 22:56:46 +05:30
const {
subscribed,
totalTimeSpent,
timeEstimate,
humanTimeEstimate,
humanTotalTimeSpent,
weight,
epic,
2020-01-01 13:55:28 +05:30
assignees,
2019-07-31 22:56:46 +05:30
} = convertObjectPropsToCamelCase(data);
2018-03-17 18:26:18 +05:30
newIssue.setFetchingState('subscriptions', false);
2021-01-03 14:25:43 +05:30
setWeightFetchingState(newIssue, false);
2019-10-12 21:52:04 +05:30
setEpicFetchingState(newIssue, false);
2018-03-17 18:26:18 +05:30
newIssue.updateData({
2019-07-31 22:56:46 +05:30
humanTimeSpent: humanTotalTimeSpent,
timeSpent: totalTimeSpent,
humanTimeEstimate,
timeEstimate,
subscribed,
weight,
epic,
2020-01-01 13:55:28 +05:30
assignees,
2018-03-17 18:26:18 +05:30
});
})
.catch(() => {
newIssue.setFetchingState('subscriptions', false);
2021-01-03 14:25:43 +05:30
setWeightFetchingState(newIssue, false);
2021-09-04 01:27:46 +05:30
this.setError({ message: __('An error occurred while fetching sidebar data') });
2018-03-17 18:26:18 +05:30
});
}
2019-12-21 20:55:43 +05:30
if (multiSelect) {
boardsStore.toggleMultiSelect(newIssue);
if (boardsStore.detail.issue) {
boardsStore.clearDetailIssue();
return;
}
return;
}
2019-09-04 21:01:54 +05:30
boardsStore.setIssueDetail(newIssue);
2018-03-17 18:26:18 +05:30
},
2019-12-21 20:55:43 +05:30
clearDetailIssue(multiSelect = false) {
if (multiSelect) {
boardsStore.clearMultiSelect();
}
2019-09-04 21:01:54 +05:30
boardsStore.clearDetailIssue();
2018-03-17 18:26:18 +05:30
},
toggleSubscription(id) {
2018-12-13 13:39:08 +05:30
const { issue } = boardsStore.detail;
2018-03-17 18:26:18 +05:30
if (issue.id === id && issue.toggleSubscriptionEndpoint) {
issue.setFetchingState('subscriptions', true);
2020-01-01 13:55:28 +05:30
boardsStore
.toggleIssueSubscription(issue.toggleSubscriptionEndpoint)
2018-03-17 18:26:18 +05:30
.then(() => {
issue.setFetchingState('subscriptions', false);
issue.updateData({
subscribed: !issue.subscribed,
});
})
.catch(() => {
issue.setFetchingState('subscriptions', false);
2021-09-04 01:27:46 +05:30
this.setError({
message: __('An error occurred when toggling the notification subscription'),
});
2018-03-17 18:26:18 +05:30
});
}
2018-11-18 11:00:15 +05:30
},
2020-05-24 23:13:21 +05:30
getNodes(data) {
return data[this.parent]?.board?.lists.nodes;
},
2017-08-17 22:00:37 +05:30
},
});
2021-03-11 19:13:27 +05:30
// eslint-disable-next-line no-new, @gitlab/no-runtime-template-compiler
2018-12-13 13:39:08 +05:30
new Vue({
2017-08-17 22:00:37 +05:30
el: document.getElementById('js-add-list'),
data: {
2018-12-13 13:39:08 +05:30
filters: boardsStore.state.filters,
2019-10-12 21:52:04 +05:30
...getMilestoneTitle($boardApp),
2017-08-17 22:00:37 +05:30
},
2018-11-18 11:00:15 +05:30
mounted() {
2018-12-13 13:39:08 +05:30
initNewListDropdown();
2018-03-17 18:26:18 +05:30
},
2017-08-17 22:00:37 +05:30
});
2021-03-11 19:13:27 +05:30
const createColumnTriggerEl = document.querySelector('.js-create-column-trigger');
if (createColumnTriggerEl) {
// eslint-disable-next-line no-new
new Vue({
el: createColumnTriggerEl,
components: {
BoardAddNewColumnTrigger,
},
store,
render(createElement) {
return createElement('board-add-new-column-trigger');
},
});
}
2019-09-30 21:07:59 +05:30
boardConfigToggle(boardsStore);
2021-04-29 21:17:54 +05:30
toggleFocusMode();
2019-12-26 22:10:19 +05:30
toggleLabels();
2021-01-03 14:25:43 +05:30
2021-04-17 20:07:23 +05:30
if (gon.licensed_features?.swimlanes) {
2021-01-03 14:25:43 +05:30
toggleEpicsSwimlanes();
}
2021-02-22 17:27:13 +05:30
mountMultipleBoardsSwitcher({
2021-03-08 18:12:59 +05:30
fullPath: $boardApp.dataset.fullPath,
rootPath: $boardApp.dataset.boardsEndpoint,
2021-03-11 19:13:27 +05:30
recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
2021-02-22 17:27:13 +05:30
});
2018-03-27 19:54:05 +05:30
};