diff options
Diffstat (limited to 'app/assets/javascripts/boards/index.js')
-rw-r--r-- | app/assets/javascripts/boards/index.js | 344 |
1 files changed, 71 insertions, 273 deletions
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index de7c8a3bd6b..21c1bb23dc6 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -2,41 +2,20 @@ import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'; import PortalVue from 'portal-vue'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; -import { mapActions, mapGetters } from 'vuex'; -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 { - setWeightFetchingState, - setEpicFetchingState, - getMilestoneTitle, -} from 'ee_else_ce/boards/ee_functions'; 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 BoardContent from '~/boards/components/board_content.vue'; -import './models/label'; -import './models/assignee'; -import '~/boards/models/milestone'; -import '~/boards/models/project'; +import BoardApp from '~/boards/components/board_app.vue'; import '~/boards/filters/due_date_filters'; import { issuableTypes } from '~/boards/constants'; import eventHub from '~/boards/eventhub'; import FilteredSearchBoards from '~/boards/filtered_search_boards'; import initBoardsFilteredSearch from '~/boards/mount_filtered_search_issue_boards'; import store from '~/boards/stores'; -import boardsStore from '~/boards/stores/boards_store'; import toggleFocusMode from '~/boards/toggle_focus'; import createDefaultClient from '~/lib/graphql'; -import { - NavigationType, - convertObjectPropsToCamelCase, - parseBoolean, -} from '~/lib/utils/common_utils'; -import { __ } from '~/locale'; -import sidebarEventHub from '~/sidebar/event_hub'; +import { NavigationType, parseBoolean } from '~/lib/utils/common_utils'; import introspectionQueryResultData from '~/sidebar/fragmentTypes.json'; import { fullBoardId } from './boards_util'; import boardConfigToggle from './config_toggle'; @@ -61,10 +40,75 @@ const apolloProvider = new VueApollo({ ), }); -let issueBoardsApp; +function mountBoardApp(el) { + const { boardId, groupId, fullPath, rootPath } = el.dataset; + + store.dispatch('setInitialBoardData', { + boardId, + fullBoardId: fullBoardId(boardId), + fullPath, + boardType: el.dataset.parent, + disabled: parseBoolean(el.dataset.disabled) || true, + issuableType: issuableTypes.issue, + boardConfig: { + milestoneId: parseInt(el.dataset.boardMilestoneId, 10), + milestoneTitle: el.dataset.boardMilestoneTitle || '', + iterationId: parseInt(el.dataset.boardIterationId, 10), + iterationTitle: el.dataset.boardIterationTitle || '', + assigneeId: el.dataset.boardAssigneeId, + assigneeUsername: el.dataset.boardAssigneeUsername, + labels: el.dataset.labels ? JSON.parse(el.dataset.labels) : [], + labelIds: el.dataset.labelIds ? JSON.parse(el.dataset.labelIds) : [], + weight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null, + }, + }); + + if (!gon?.features?.issueBoardsFilteredSearch) { + // Warning: FilteredSearchBoards has an implicit dependency on the Vuex state 'boardConfig' + // Improve this situation in the future. + const filterManager = new FilteredSearchBoards({ path: '' }, true, []); + filterManager.setup(); + + eventHub.$on('updateTokens', () => { + filterManager.updateTokens(); + }); + } + + // eslint-disable-next-line no-new + new Vue({ + el, + store, + apolloProvider, + provide: { + disabled: parseBoolean(el.dataset.disabled), + boardId, + groupId: Number(groupId), + rootPath, + currentUserId: gon.current_user_id || null, + canUpdate: parseBoolean(el.dataset.canUpdate), + canAdminList: parseBoolean(el.dataset.canAdminList), + labelsManagePath: el.dataset.labelsManagePath, + labelsFilterBasePath: el.dataset.labelsFilterBasePath, + timeTrackingLimitToHours: parseBoolean(el.dataset.timeTrackingLimitToHours), + 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), + }, + render: (createComponent) => createComponent(BoardApp), + }); +} export default () => { - const $boardApp = document.getElementById('board-app'); + const $boardApp = document.getElementById('js-issuable-board-app'); + // check for browser back and trigger a hard reload to circumvent browser caching. window.addEventListener('pageshow', (event) => { const isNavTypeBackForward = @@ -75,257 +119,11 @@ export default () => { } }); - if (issueBoardsApp) { - issueBoardsApp.$destroy(true); - } - if (gon?.features?.issueBoardsFilteredSearch) { initBoardsFilteredSearch(apolloProvider); } - if (!gon?.features?.graphqlBoardLists) { - boardsStore.create(); - boardsStore.setTimeTrackingLimitToHours($boardApp.dataset.timeTrackingLimitToHours); - } - - // eslint-disable-next-line @gitlab/no-runtime-template-compiler - issueBoardsApp = new Vue({ - el: $boardApp, - components: { - BoardContent, - BoardSidebar, - BoardSettingsSidebar: () => import('~/boards/components/board_settings_sidebar.vue'), - }, - provide: { - boardId: $boardApp.dataset.boardId, - groupId: Number($boardApp.dataset.groupId), - rootPath: $boardApp.dataset.rootPath, - currentUserId: gon.current_user_id || null, - canUpdate: parseBoolean($boardApp.dataset.canUpdate), - canAdminList: parseBoolean($boardApp.dataset.canAdminList), - labelsManagePath: $boardApp.dataset.labelsManagePath, - labelsFilterBasePath: $boardApp.dataset.labelsFilterBasePath, - timeTrackingLimitToHours: parseBoolean($boardApp.dataset.timeTrackingLimitToHours), - multipleAssigneesFeatureAvailable: parseBoolean( - $boardApp.dataset.multipleAssigneesFeatureAvailable, - ), - epicFeatureAvailable: parseBoolean($boardApp.dataset.epicFeatureAvailable), - iterationFeatureAvailable: parseBoolean($boardApp.dataset.iterationFeatureAvailable), - weightFeatureAvailable: parseBoolean($boardApp.dataset.weightFeatureAvailable), - boardWeight: $boardApp.dataset.boardWeight - ? parseInt($boardApp.dataset.boardWeight, 10) - : null, - scopedLabelsAvailable: parseBoolean($boardApp.dataset.scopedLabels), - milestoneListsAvailable: parseBoolean($boardApp.dataset.milestoneListsAvailable), - assigneeListsAvailable: parseBoolean($boardApp.dataset.assigneeListsAvailable), - iterationListsAvailable: parseBoolean($boardApp.dataset.iterationListsAvailable), - issuableType: issuableTypes.issue, - emailsDisabled: parseBoolean($boardApp.dataset.emailsDisabled), - }, - store, - 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, - }; - }, - computed: { - ...mapGetters(['shouldUseGraphQL']), - detailIssueVisible() { - return Object.keys(this.detailIssue.issue).length; - }, - }, - created() { - this.setInitialBoardData({ - boardId: $boardApp.dataset.boardId, - fullBoardId: fullBoardId($boardApp.dataset.boardId), - fullPath: $boardApp.dataset.fullPath, - boardType: this.parent, - disabled: this.disabled, - issuableType: issuableTypes.issue, - boardConfig: { - milestoneId: parseInt($boardApp.dataset.boardMilestoneId, 10), - milestoneTitle: $boardApp.dataset.boardMilestoneTitle || '', - iterationId: parseInt($boardApp.dataset.boardIterationId, 10), - iterationTitle: $boardApp.dataset.boardIterationTitle || '', - assigneeId: $boardApp.dataset.boardAssigneeId, - assigneeUsername: $boardApp.dataset.boardAssigneeUsername, - labels: $boardApp.dataset.labels ? JSON.parse($boardApp.dataset.labels) : [], - labelIds: $boardApp.dataset.labelIds ? JSON.parse($boardApp.dataset.labelIds) : [], - weight: $boardApp.dataset.boardWeight - ? parseInt($boardApp.dataset.boardWeight, 10) - : null, - }, - }); - boardsStore.setEndpoints({ - boardsEndpoint: this.boardsEndpoint, - recentBoardsEndpoint: this.recentBoardsEndpoint, - listsEndpoint: this.listsEndpoint, - bulkUpdatePath: this.bulkUpdatePath, - boardId: $boardApp.dataset.boardId, - fullPath: $boardApp.dataset.fullPath, - }); - boardsStore.rootPath = this.boardsEndpoint; - - eventHub.$on('updateTokens', this.updateTokens); - eventHub.$on('newDetailIssue', this.updateDetailIssue); - eventHub.$on('clearDetailIssue', this.clearDetailIssue); - sidebarEventHub.$on('toggleSubscription', this.toggleSubscription); - eventHub.$on('initialBoardLoad', this.initialBoardLoad); - }, - beforeDestroy() { - eventHub.$off('updateTokens', this.updateTokens); - eventHub.$off('newDetailIssue', this.updateDetailIssue); - eventHub.$off('clearDetailIssue', this.clearDetailIssue); - sidebarEventHub.$off('toggleSubscription', this.toggleSubscription); - eventHub.$off('initialBoardLoad', this.initialBoardLoad); - }, - mounted() { - if (!gon?.features?.issueBoardsFilteredSearch) { - this.filterManager = new FilteredSearchBoards( - boardsStore.filter, - true, - boardsStore.cantEdit, - ); - this.filterManager.setup(); - } - - this.performSearch(); - - boardsStore.disabled = this.disabled; - - if (!this.shouldUseGraphQL) { - this.initialBoardLoad(); - } - }, - methods: { - ...mapActions(['setInitialBoardData', 'performSearch', 'setError']), - initialBoardLoad() { - boardsStore - .all() - .then((res) => res.data) - .then((lists) => { - lists.forEach((list) => boardsStore.addList(list)); - this.loading = false; - }) - .catch((error) => { - this.setError({ - error, - message: __('An error occurred while fetching the board lists. Please try again.'), - }); - }); - }, - updateTokens() { - this.filterManager.updateTokens(); - }, - updateDetailIssue(newIssue, multiSelect = false) { - const { sidebarInfoEndpoint } = newIssue; - if (sidebarInfoEndpoint && newIssue.subscribed === undefined) { - newIssue.setFetchingState('subscriptions', true); - setWeightFetchingState(newIssue, true); - setEpicFetchingState(newIssue, true); - boardsStore - .getIssueInfo(sidebarInfoEndpoint) - .then((res) => res.data) - .then((data) => { - const { - subscribed, - totalTimeSpent, - timeEstimate, - humanTimeEstimate, - humanTotalTimeSpent, - weight, - epic, - assignees, - } = convertObjectPropsToCamelCase(data); - - newIssue.setFetchingState('subscriptions', false); - setWeightFetchingState(newIssue, false); - setEpicFetchingState(newIssue, false); - newIssue.updateData({ - humanTimeSpent: humanTotalTimeSpent, - timeSpent: totalTimeSpent, - humanTimeEstimate, - timeEstimate, - subscribed, - weight, - epic, - assignees, - }); - }) - .catch(() => { - newIssue.setFetchingState('subscriptions', false); - setWeightFetchingState(newIssue, false); - this.setError({ message: __('An error occurred while fetching sidebar data') }); - }); - } - - if (multiSelect) { - boardsStore.toggleMultiSelect(newIssue); - - if (boardsStore.detail.issue) { - boardsStore.clearDetailIssue(); - return; - } - - return; - } - - boardsStore.setIssueDetail(newIssue); - }, - clearDetailIssue(multiSelect = false) { - if (multiSelect) { - boardsStore.clearMultiSelect(); - } - boardsStore.clearDetailIssue(); - }, - toggleSubscription(id) { - const { issue } = boardsStore.detail; - if (issue.id === id && issue.toggleSubscriptionEndpoint) { - issue.setFetchingState('subscriptions', true); - boardsStore - .toggleIssueSubscription(issue.toggleSubscriptionEndpoint) - .then(() => { - issue.setFetchingState('subscriptions', false); - issue.updateData({ - subscribed: !issue.subscribed, - }); - }) - .catch(() => { - issue.setFetchingState('subscriptions', false); - this.setError({ - message: __('An error occurred when toggling the notification subscription'), - }); - }); - } - }, - getNodes(data) { - return data[this.parent]?.board?.lists.nodes; - }, - }, - }); - - // eslint-disable-next-line no-new, @gitlab/no-runtime-template-compiler - new Vue({ - el: document.getElementById('js-add-list'), - data() { - return { - filters: boardsStore.state.filters, - ...getMilestoneTitle($boardApp), - }; - }, - mounted() { - initNewListDropdown(); - }, - }); + mountBoardApp($boardApp); const createColumnTriggerEl = document.querySelector('.js-create-column-trigger'); if (createColumnTriggerEl) { @@ -342,7 +140,7 @@ export default () => { }); } - boardConfigToggle(boardsStore); + boardConfigToggle(); toggleFocusMode(); toggleLabels(); |