feat: implement modals with vue router 4 #816

Merged
konrad merged 62 commits from dpschen/frontend:feature/vue3-modals-with-router-4 into main 2022-02-05 16:49:04 +00:00
6 changed files with 104 additions and 72 deletions
Showing only changes of commit 7eed0628d0 - Show all commits

View File

@ -2,6 +2,8 @@ import { createRouter, createWebHistory, RouteLocation } from 'vue-router'
import {saveLastVisited} from '@/helpers/saveLastVisited' import {saveLastVisited} from '@/helpers/saveLastVisited'
import {store} from '@/store' import {store} from '@/store'
import {getListView} from '@/helpers/saveListView'
import HomeComponent from '../views/Home' import HomeComponent from '../views/Home'
import NotFoundComponent from '../views/404' import NotFoundComponent from '../views/404'
import About from '../views/About' import About from '../views/About'
@ -23,12 +25,12 @@ import NewLabelComponent from '../views/labels/NewLabel'
// Migration // Migration
import MigrationComponent from '../views/migrator/Migrate' import MigrationComponent from '../views/migrator/Migrate'
import MigrateServiceComponent from '../views/migrator/MigrateService' import MigrateServiceComponent from '../views/migrator/MigrateService'
// List Views // List Views
import ShowListComponent from '../views/list/ShowList' import ListList from '../views/list/ListList'
import Kanban from '../views/list/views/Kanban' import ListGantt from '../views/list/ListGantt'
import List from '../views/list/views/List' import ListTable from '../views/list/ListTable'
import Gantt from '../views/list/views/Gantt' import ListKanban from '../views/list/ListKanban'
import Table from '../views/list/views/Table'
// List Settings // List Settings
import ListSettingEdit from '../views/list/settings/edit' import ListSettingEdit from '../views/list/settings/edit'
@ -323,29 +325,37 @@ const router = createRouter({
{ {
path: '/lists/:listId', path: '/lists/:listId',
name: 'list.index', name: 'list.index',
component: ShowListComponent, beforeEnter(to) {
children: [ // Redirect the user to list view by default
{
path: '/lists/:listId/list', const savedListView = getListView(to.params.listId)
name: 'list.list', console.debug('Replaced list view with', savedListView)
component: List,
}, return {
{ name: savedListView,
path: '/lists/:listId/gantt', params: {listId: to.params.listId},
name: 'list.gantt', }
component: Gantt, },
}, },
{ {
path: '/lists/:listId/table', path: '/lists/:listId/list',
name: 'list.table', name: 'list.list',
component: Table, component: ListList,
}, },
{ {
path: '/lists/:listId/kanban', path: '/lists/:listId/gantt',
name: 'list.kanban', name: 'list.gantt',
component: Kanban, component: ListGantt,
}, },
], {
path: '/lists/:listId/table',
name: 'list.table',
component: ListTable,
},
{
path: '/lists/:listId/kanban',
name: 'list.kanban',
component: ListKanban,
}, },
{ {
path: '/teams', path: '/teams',

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="gantt-chart-container"> <ListWrapper>
<card :padding="false" class="has-overflow"> <template #header>
<div class="gantt-options p-4"> <div class="gantt-options p-4">
<fancycheckbox class="is-block" v-model="showTaskswithoutDates"> <fancycheckbox class="is-block" v-model="showTaskswithoutDates">
{{ $t('list.gantt.showTasksWithoutDates') }} {{ $t('list.gantt.showTasksWithoutDates') }}
@ -44,6 +44,12 @@
</div> </div>
</div> </div>
</div> </div>
</template>
<template #default>
<div class="gantt-chart-container">
<card :padding="false" class="has-overflow">
<gantt-chart <gantt-chart
:date-from="dateFrom" :date-from="dateFrom"
:date-to="dateTo" :date-to="dateTo"
@ -53,7 +59,9 @@
/> />
</card> </card>
</div> </div>
</template>
</ListWrapper>
</template> </template>
<script setup> <script setup>
@ -64,6 +72,7 @@ import flatPickr from 'vue-flatpickr-component'
import { i18n } from '@/i18n' import { i18n } from '@/i18n'
import { store } from '@/store' import { store } from '@/store'
import ListWrapper from './ListWrapper'
import GanttChart from '@/components/tasks/gantt-component' import GanttChart from '@/components/tasks/gantt-component'
import Fancycheckbox from '@/components/input/fancycheckbox' import Fancycheckbox from '@/components/input/fancycheckbox'

View File

@ -1,17 +1,22 @@
<template> <template>
<div class="kanban-view"> <ListWrapper>
<div class="filter-container" v-if="isSavedFilter"> <template #header>
<div class="filter-container" v-if="isSavedFilter">
<div class="items"> <div class="items">
<filter-popup <filter-popup
v-model="params" v-model="params"
@update:modelValue="loadBuckets" @update:modelValue="loadBuckets"
/> />
</div> </div>
</div> </div>
<div </template>
:class="{ 'is-loading': loading && !oneTaskUpdating}"
class="kanban kanban-bucket-container loader-container" <template #default>
> <div class="kanban-view">
<div
:class="{ 'is-loading': loading && !oneTaskUpdating}"
class="kanban kanban-bucket-container loader-container"
>
<draggable <draggable
v-bind="dragOptions" v-bind="dragOptions"
:modelValue="buckets" :modelValue="buckets"
@ -218,22 +223,25 @@
</template> </template>
</modal> </modal>
</transition> </transition>
</div> </div>
</template>
</ListWrapper>
</template> </template>
<script> <script>
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import cloneDeep from 'lodash.clonedeep' import cloneDeep from 'lodash.clonedeep'
import BucketModel from '../../../models/bucket' import BucketModel from '../../models/bucket'
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {saveListView} from '@/helpers/saveListView' import {saveListView} from '@/helpers/saveListView'
import Rights from '../../../models/constants/rights.json' import Rights from '../../models/constants/rights.json'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types' import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
import ListWrapper from './ListWrapper'
import FilterPopup from '@/components/list/partials/filter-popup.vue' import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Dropdown from '@/components/misc/dropdown.vue' import Dropdown from '@/components/misc/dropdown.vue'
import {getCollapsedBucketState, saveCollapsedBucketState} from '@/helpers/saveCollapsedBucketState' import {getCollapsedBucketState, saveCollapsedBucketState} from '@/helpers/saveCollapsedBucketState'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition' import {calculateItemPosition} from '../../helpers/calculateItemPosition'
import KanbanCard from '@/components/tasks/partials/kanban-card' import KanbanCard from '@/components/tasks/partials/kanban-card'
const DRAG_OPTIONS = { const DRAG_OPTIONS = {
@ -250,6 +258,7 @@ const MIN_SCROLL_HEIGHT_PERCENT = 0.25
export default { export default {
name: 'Kanban', name: 'Kanban',
components: { components: {
ListWrapper,
KanbanCard, KanbanCard,
Dropdown, Dropdown,
FilterPopup, FilterPopup,

View File

@ -1,8 +1,6 @@
<template> <template>
<div <ListWrapper>
:class="{ 'is-loading': loading }" <template #header>
class="loader-container is-max-width-desktop list-view"
>
<div <div
class="filter-container" class="filter-container"
v-if="list.isSavedFilter && !list.isSavedFilter()" v-if="list.isSavedFilter && !list.isSavedFilter()"
@ -47,7 +45,13 @@
/> />
</div> </div>
</div> </div>
</template>
<template #default>
<div
:class="{ 'is-loading': loading }"
class="loader-container is-max-width-desktop list-view"
>
<card :padding="false" :has-content="false" class="has-overflow"> <card :padding="false" :has-content="false" class="has-overflow">
<template <template
v-if="!list.isArchived && canWrite && list.id > 0" v-if="!list.isArchived && canWrite && list.id > 0"
@ -122,19 +126,22 @@
:current-page="currentPage" :current-page="currentPage"
/> />
</card> </card>
</div> </div>
</template>
</ListWrapper>
</template> </template>
<script> <script>
import { ref } from 'vue' import { ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import EditTask from '../../../components/tasks/edit-task' import ListWrapper from './ListWrapper'
import AddTask from '../../../components/tasks/add-task' import EditTask from '@/components/tasks/edit-task'
import SingleTaskInList from '../../../components/tasks/partials/singleTaskInList' import AddTask from '@/components/tasks/add-task'
import SingleTaskInList from '@/components/tasks/partials/singleTaskInList'
import { useTaskList } from '@/composables/taskList' import { useTaskList } from '@/composables/taskList'
import {saveListView} from '@/helpers/saveListView' import {saveListView} from '@/helpers/saveListView'
import Rights from '../../../models/constants/rights.json' import Rights from '../../models/constants/rights.json'
import FilterPopup from '@/components/list/partials/filter-popup.vue' import FilterPopup from '@/components/list/partials/filter-popup.vue'
import {HAS_TASKS} from '@/store/mutation-types' import {HAS_TASKS} from '@/store/mutation-types'
import Nothing from '@/components/misc/nothing.vue' import Nothing from '@/components/misc/nothing.vue'
@ -142,7 +149,7 @@ import Pagination from '@/components/misc/pagination.vue'
import {ALPHABETICAL_SORT} from '@/components/list/partials/filters.vue' import {ALPHABETICAL_SORT} from '@/components/list/partials/filters.vue'
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition' import {calculateItemPosition} from '../../helpers/calculateItemPosition'
function sortTasks(tasks) { function sortTasks(tasks) {
if (tasks === null || tasks === []) { if (tasks === null || tasks === []) {
@ -177,6 +184,7 @@ export default {
} }
}, },
components: { components: {
ListWrapper,
Nothing, Nothing,
FilterPopup, FilterPopup,
SingleTaskInList, SingleTaskInList,

View File

@ -1,6 +1,7 @@
<template> <template>
<div :class="{'is-loading': loading}" class="table-view loader-container"> <ListWrapper>
<div class="filter-container"> <template #header>
<div class="filter-container">
<div class="items"> <div class="items">
<popup> <popup>
<template #trigger="{toggle}"> <template #trigger="{toggle}">
@ -59,9 +60,12 @@
@update:modelValue="loadTasks()" @update:modelValue="loadTasks()"
/> />
</div> </div>
</div> </div>
</template>
<card :padding="false" :has-content="false"> <template #default>
<div :class="{'is-loading': loading}" class="table-view loader-container">
<card :padding="false" :has-content="false">
<div class="has-horizontal-overflow"> <div class="has-horizontal-overflow">
<table class="table has-actions is-hoverable is-fullwidth mb-0"> <table class="table has-actions is-hoverable is-fullwidth mb-0">
<thead> <thead>
@ -172,14 +176,17 @@
:total-pages="totalPages" :total-pages="totalPages"
:current-page="currentPage" :current-page="currentPage"
/> />
</card> </card>
</div> </div>
</template>
</ListWrapper>
</template> </template>
<script setup> <script setup>
import { ref, reactive, computed, toRaw } from 'vue' import { ref, reactive, computed, toRaw } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import ListWrapper from './ListWrapper'
import Done from '@/components/misc/Done.vue' import Done from '@/components/misc/Done.vue'
import User from '@/components/misc/user' import User from '@/components/misc/user'
import PriorityLabel from '@/components/tasks/partials/priorityLabel' import PriorityLabel from '@/components/tasks/partials/priorityLabel'
@ -254,7 +261,6 @@ function beforeLoad(params) {
const { const {
tasks, tasks,
loading, loading,
showTaskFilter,
params, params,
loadTasks, loadTasks,
totalPages, totalPages,

View File

@ -34,6 +34,7 @@
{{ $t('list.kanban.title') }} {{ $t('list.kanban.title') }}
</router-link> </router-link>
</div> </div>
<slot name="header" />
</div> </div>
<transition name="fade"> <transition name="fade">
<Message variant="warning" v-if="currentList.isArchived" class="mb-4"> <Message variant="warning" v-if="currentList.isArchived" class="mb-4">
@ -41,13 +42,13 @@
</Message> </Message>
</transition> </transition>
<router-view/> <slot />
</div> </div>
</template> </template>
<script setup> <script setup>
import {ref, shallowRef, computed, watchEffect} from 'vue' import {ref, shallowRef, computed, watchEffect} from 'vue'
import {useRouter, useRoute} from 'vue-router' import {useRoute} from 'vue-router'
import Message from '@/components/misc/message' import Message from '@/components/misc/message'
@ -57,26 +58,15 @@ import ListService from '@/services/list'
import {store} from '@/store' import {store} from '@/store'
import {CURRENT_LIST} from '@/store/mutation-types' import {CURRENT_LIST} from '@/store/mutation-types'
import {getListView} from '@/helpers/saveListView'
import {getListTitle} from '@/helpers/getListTitle' import {getListTitle} from '@/helpers/getListTitle'
import {saveListToHistory} from '@/modules/listHistory' import {saveListToHistory} from '@/modules/listHistory'
import { useTitle } from '@/composables/useTitle' import { useTitle } from '@/composables/useTitle'
const route = useRoute() const route = useRoute()
const router = useRouter()
const listService = shallowRef(new ListService()) const listService = shallowRef(new ListService())
const loadedListId = ref(0) const loadedListId = ref(0)
// beforeRouteEnter(to) {
// Redirect the user to list view by default
if (route.name !== 'list.index') {
const savedListView = getListView(route.params.listId)
console.debug('Replaced list view with', savedListView)
router.replace({name: 'list.list', params: {id: route.params.listId}})
}
// },
const currentList = computed(() => { const currentList = computed(() => {
return typeof store.state.currentList === 'undefined' ? { return typeof store.state.currentList === 'undefined' ? {
id: 0, id: 0,