Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
['name' => 'page#indexBoard', 'url' => '/board/{boardId}', 'verb' => 'GET'],
['name' => 'page#indexBoardDetails', 'url' => '/board/{boardId}/details', 'verb' => 'GET'],
['name' => 'page#indexCard', 'url' => '/board/{boardId}/card/{cardId}', 'verb' => 'GET'],
// Declared after the more specific board routes so those keep priority.
['name' => 'page#indexBoardView', 'url' => '/board/{boardId}/{viewMode}', 'verb' => 'GET', 'requirements' => ['viewMode' => 'kanban|gantt']],

['name' => 'page#redirectToCard', 'url' => '/card/{cardId}', 'verb' => 'GET'],

Expand Down
6 changes: 6 additions & 0 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ public function indexBoardDetails(int $boardId): TemplateResponse {
return $this->index();
}

#[NoAdminRequired]
#[NoCSRFRequired]
public function indexBoardView(int $boardId, string $viewMode): TemplateResponse {
return $this->index();
}

#[NoAdminRequired]
#[NoCSRFRequired]
public function indexCard(int $cardId): TemplateResponse {
Expand Down
14 changes: 14 additions & 0 deletions src/components/board/Board.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ export default {
type: Number,
default: null,
},
/**
* View to open the board in, coming from the /board/:id/:viewMode
* route. Applied for this session only, so linking to a view does not
* change the user's stored preference for the board.
*/
initialViewMode: {
type: String,
default: null,
},
},
data() {
return {
Expand Down Expand Up @@ -186,6 +195,11 @@ export default {
await this.$store.dispatch('loadBoardById', this.id)
await this.$store.dispatch('loadStacks', this.id)

// Only after loadBoardById, as the mutation needs currentBoard
if (this.initialViewMode) {
this.$store.commit('setViewModeForSession', this.initialViewMode)
}

const routeCardId = this.$route?.params?.cardId ? parseInt(this.$route.params.cardId) : null
// If an archived card is requested, and we cannot find it in the current we load the archived stacks instead
if (routeCardId && !this.$store.getters.cardById(routeCardId)) {
Expand Down
19 changes: 19 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ const router = new Router({
navFilter: BOARD_FILTERS.SHARED,
},
},
{
// Opens a board directly in a given view, so a board can be linked
// to as e.g. a Gantt chart. The view is applied for this session
// only and does not overwrite the user's stored preference.
path: '/board/:id/:viewMode(kanban|gantt)',
name: 'board.view',
components: {
default: Board,
sidebar: Sidebar,
},
props: {
default: (route) => {
return {
id: parseInt(route.params.id, 10),
initialViewMode: route.params.viewMode,
}
},
},
},
{
path: '/board/:id',
name: 'board',
Expand Down
14 changes: 14 additions & 0 deletions src/store/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,20 @@ export default function storeFactory() {
Vue.set(state.viewModeByBoard, state.currentBoard.id, mode)
localStorage.setItem(`deck.viewMode.${state.currentBoard.id}`, mode)
},
/**
* Set the view mode without storing it as the user's preference.
*
* Used by the /board/:id/:viewMode routes, so that opening a link
* to a specific view does not change how the recipient sees that
* board afterwards.
*
* @param {object} state the store state
* @param {string} mode the view mode to apply
*/
setViewModeForSession(state, mode) {
if (!state.currentBoard) return
Vue.set(state.viewModeByBoard, state.currentBoard.id, mode)
},
},
actions: {
setFullApp({ commit }, isFullApp) {
Expand Down