feat: provide listId prop via router

This commit is contained in:
Dominik Pschenitschni 2021-12-10 15:29:28 +01:00
parent 6d62ca1ada
commit 5916a44724
Signed by: dpschen
GPG Key ID: B257AC0149F43A77
10 changed files with 263 additions and 233 deletions

View File

@ -44,7 +44,7 @@
</template>
<script lang="ts" setup>
import {watch, computed, shallowRef, watchEffect} from 'vue'
import {watch, computed, shallowRef, watchEffect, h} from 'vue'
import {useStore} from 'vuex'
import {useRoute, useRouter} from 'vue-router'
import {useEventListener} from '@vueuse/core'
@ -66,19 +66,36 @@ function useRouteWithModal() {
}
})
const currentModal = shallowRef(null)
watchEffect(() => {
currentModal.value = historyState.value.backdropView
? route.matched[0]?.components.default
const hasBackdropView = historyState.value.backdropView
if (!hasBackdropView) {
currentModal.value = null
return
}
// logic from vue-router
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
const routePropsOption = route.matched[0]?.props.default
const routeProps = routePropsOption
? routePropsOption === true
? route.params
: typeof routePropsOption === 'function'
? routePropsOption(route)
: routePropsOption
: null
currentModal.value = h(
route.matched[0]?.components.default,
routeProps,
)
})
return { routeWithModal, currentModal }
}
useRouteWithModal()
const { routeWithModal, currentModal } = useRouteWithModal()
const store = useStore()

View File

@ -1,5 +1,5 @@
import { ref, watch, computed } from 'vue'
import { useRoute } from 'vue-router'
import { ref, shallowReactive, watch, computed } from 'vue'
import {useRoute} from 'vue-router'
import TaskCollectionService from '@/services/taskCollection'
@ -13,102 +13,104 @@ export const getDefaultParams = () => ({
filter_concat: 'and',
})
const filters = {
done: {
value: false,
comparator: 'equals',
concat: 'and',
},
}
const SORT_BY_DEFAULT = {
id: 'desc',
}
/**
* This mixin provides a base set of methods and properties to get tasks on a list.
*/
export function useTaskList(initTasks) {
const taskCollectionService = ref(new TaskCollectionService())
const loading = computed(() => taskCollectionService.value.loading)
const totalPages = computed(() => taskCollectionService.value.totalPages)
export function useTaskList(listId) {
const params = ref({...getDefaultParams()})
const search = ref('')
const page = ref(1)
const sortBy = ref({ ...SORT_BY_DEFAULT })
// This makes sure an id sort order is always sorted last.
// When tasks would be sorted first by id and then by whatever else was specified, the id sort takes
// precedence over everything else, making any other sort columns pretty useless.
function formatSortOrder(params) {
let hasIdFilter = false
const sortKeys = Object.keys(sortBy.value)
for (const s of sortKeys) {
if (s === 'id') {
sortKeys.splice(s, 1)
hasIdFilter = true
break
}
}
if (hasIdFilter) {
sortKeys.push('id')
}
params.sort_by = sortKeys
params.order_by = sortKeys.map(s => sortBy.value[s])
return params
}
const getAllTasksParams = computed(() => {
let loadParams = {...params.value}
if (search.value !== '') {
loadParams.s = search.value
}
loadParams = formatSortOrder(loadParams)
return [
{listId: listId.value},
loadParams,
page.value || 1,
]
})
const taskCollectionService = shallowReactive(new TaskCollectionService())
const loading = computed(() => taskCollectionService.loading)
const totalPages = computed(() => taskCollectionService.totalPages)
const tasks = ref([])
const currentPage = ref(0)
const loadedList = ref(null)
const searchTerm = ref('')
const showTaskFilter = ref(false)
const params = ref({...getDefaultParams()})
const route = useRoute()
async function loadTasks(
page = 1,
search = '',
loadParams = { ...params.value },
forceLoading = false,
) {
// Because this function is triggered every time on topNavigation, we're putting a condition here to only load it when we actually want to show tasks
// FIXME: This is a bit hacky -> Cleanup.
if (
route.name !== 'list.list' &&
route.name !== 'list.table' &&
!forceLoading
) {
return
}
if (search !== '') {
loadParams.s = search
}
const list = {listId: parseInt(route.params.listId)}
const currentList = {
id: list.listId,
params: loadParams,
search,
page,
}
if (
JSON.stringify(currentList) === JSON.stringify(loadedList.value) &&
!forceLoading
) {
return
}
tasks.value = []
tasks.value = await taskCollectionService.value.getAll(list, loadParams, page)
currentPage.value = page
loadedList.value = JSON.parse(JSON.stringify(currentList))
async function loadTasks() {
tasks.value = await taskCollectionService.getAll(...getAllTasksParams.value)
return tasks.value
}
async function loadTasksForPage(query) {
const { page, search } = query
initTasks(params)
return await loadTasks(
// The page parameter can be undefined, in the case where the user loads a new list from the side bar menu
typeof page === 'undefined' ? 1 : Number(page),
search,
params.value,
)
}
async function loadTasksOnSavedFilter() {
if (
typeof route.params.listId !== 'undefined' &&
parseInt(route.params.listId) < 0
) {
await loadTasks(1, '', null, true)
}
}
const route = useRoute()
watch(() => route.query, (query) => {
const { page: pageQuery, search: searchQuery } = query
search.value = searchQuery
page.value = pageQuery
function initTaskList() {
// Only listen for query path changes
watch(() => route.query, loadTasksForPage, { immediate: true })
watch(() => route.path, loadTasksOnSavedFilter)
}
}, { immediate: true })
// Only listen for query path changes
watch(() => JSON.stringify(getAllTasksParams.value), (newParams, oldParams) => {
if (oldParams === newParams) {
return
}
loadTasks()
}, { immediate: true })
return {
tasks,
initTaskList,
loading,
totalPages,
currentPage,
showTaskFilter,
currentPage: page,
loadTasks,
searchTerm,
searchTerm: search,
params,
}
}

View File

@ -244,6 +244,9 @@ const router = createRouter({
path: '/tasks/:id',
name: 'task.detail',
component: TaskDetailViewModal,
props: route => ({
taskId: parseInt(route.params.id),
}),
},
{
path: '/tasks/by/upcoming',
@ -341,21 +344,33 @@ const router = createRouter({
path: '/lists/:listId/list',
name: 'list.list',
component: ListList,
props: route => ({
listId: parseInt(route.params.listId),
}),
},
{
path: '/lists/:listId/gantt',
name: 'list.gantt',
component: ListGantt,
props: route => ({
listId: parseInt(route.params.listId),
}),
},
{
path: '/lists/:listId/table',
name: 'list.table',
component: ListTable,
props: route => ({
listId: parseInt(route.params.listId),
}),
},
{
path: '/lists/:listId/kanban',
name: 'list.kanban',
component: ListKanban,
props: route => ({
listId: parseInt(route.params.listId),
}),
},
{
path: '/teams',

View File

@ -1,5 +1,5 @@
<template>
<ListWrapper class="list-gantt">
<ListWrapper class="list-gantt" :list-id="props.listId" viewName="gantt">
<template #header>
<div class="gantt-options p-4">
<fancycheckbox class="is-block" v-model="showTaskswithoutDates">
@ -54,7 +54,7 @@
:date-from="dateFrom"
:date-to="dateTo"
:day-width="dayWidth"
:list-id="Number($route.params.listId)"
:list-id="props.listId"
:show-taskswithout-dates="showTaskswithoutDates"
/>
@ -64,16 +64,23 @@
</ListWrapper>
</template>
<script setup>
<script setup lang="ts">
import { ref, computed } from 'vue'
import flatPickr from 'vue-flatpickr-component'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
import ListWrapper from './ListWrapper'
import GanttChart from '@/components/tasks/gantt-component'
import Fancycheckbox from '@/components/input/fancycheckbox'
import ListWrapper from './ListWrapper.vue'
import GanttChart from '@/components/tasks/gantt-component.vue'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
const props = defineProps({
listId: {
type: Number,
required: true,
},
})
const DEFAULT_DAY_COUNT = 35
@ -85,7 +92,7 @@ const dateFrom = ref(new Date((new Date()).setDate(now.value.getDate() - 15)))
const dateTo = ref(new Date((new Date()).setDate(now.value.getDate() + 30)))
const {t} = useI18n()
const {store} = useStore()
const store = useStore()
const flatPickerConfig = computed(() => ({
altFormat: t('date.altFormatShort'),
altInput: true,

View File

@ -1,5 +1,5 @@
<template>
<ListWrapper class="list-kanban">
<ListWrapper class="list-kanban" :list-id="listId" viewName="kanban">
<template #header>
<div class="filter-container" v-if="isSavedFilter">
<div class="items">
@ -263,6 +263,14 @@ export default {
FilterPopup,
draggable,
},
props: {
listId: {
type: Number,
required: true,
},
},
data() {
return {
taskContainerRefs: {},
@ -310,7 +318,7 @@ export default {
},
loadBucketParameter() {
return {
listId: this.$route.params.listId,
listId: this.listId,
params: this.params,
}
},
@ -350,16 +358,11 @@ export default {
methods: {
loadBuckets() {
// Prevent trying to load buckets if the task popup view is active
if (this.$route.name !== 'list.kanban') {
return
}
const {listId, params} = this.loadBucketParameter
this.collapsedBuckets = getCollapsedBucketState(listId)
console.debug(`Loading buckets, loadedListId = ${this.loadedListId}, $route.params =`, this.$route.params)
console.debug(`Loading buckets, loadedListId = ${this.loadedListId}, $attrs = ${this.$attrs} $route.params =`, this.$route.params)
this.$store.dispatch('kanban/loadBucketsForList', {listId, params})
},
@ -434,7 +437,7 @@ export default {
const task = await this.$store.dispatch('tasks/createNewTask', {
title: this.newTaskText,
bucketId,
listId: this.$route.params.listId,
listId: this.listId,
})
this.newTaskText = ''
this.$store.commit('kanban/addTaskToBucket', task)
@ -456,7 +459,7 @@ export default {
const newBucket = new BucketModel({
title: this.newBucketTitle,
listId: parseInt(this.$route.params.listId),
listId: this.listId,
})
await this.$store.dispatch('kanban/createBucket', newBucket)
@ -476,7 +479,7 @@ export default {
async deleteBucket() {
const bucket = new BucketModel({
id: this.bucketToDelete,
listId: parseInt(this.$route.params.listId),
listId: this.listId,
})
try {
@ -564,7 +567,7 @@ export default {
collapseBucket(bucket) {
this.collapsedBuckets[bucket.id] = true
saveCollapsedBucketState(this.$route.params.listId, this.collapsedBuckets)
saveCollapsedBucketState(this.listId, this.collapsedBuckets)
},
unCollapseBucket(bucket) {
if (!this.collapsedBuckets[bucket.id]) {
@ -572,7 +575,7 @@ export default {
}
this.collapsedBuckets[bucket.id] = false
saveCollapsedBucketState(this.$route.params.listId, this.collapsedBuckets)
saveCollapsedBucketState(this.listId, this.collapsedBuckets)
},
},
}

View File

@ -1,5 +1,5 @@
<template>
<ListWrapper class="list-list">
<ListWrapper class="list-list" :list-id="listId" viewName="list">
<template #header>
<div
class="filter-container"
@ -132,9 +132,9 @@
</template>
<script>
import { ref } from 'vue'
import { ref, toRef, defineComponent } from 'vue'
import ListWrapper from './ListWrapper'
import ListWrapper from './ListWrapper.vue'
import EditTask from '@/components/tasks/edit-task'
import AddTask from '@/components/tasks/add-task'
import SingleTaskInList from '@/components/tasks/partials/singleTaskInList'
@ -167,8 +167,16 @@ function sortTasks(tasks) {
})
}
export default {
export default defineComponent({
name: 'List',
props: {
listId: {
type: Number,
required: true,
},
},
data() {
return {
ctaVisible: false,
@ -192,19 +200,17 @@ export default {
Pagination,
},
setup() {
setup(props) {
const taskEditTask = ref(null)
const isTaskEdit = ref(false)
// This function initializes the tasks page and loads the first page of tasks
function beforeLoad() {
taskEditTask.value = null
isTaskEdit.value = false
}
// function beforeLoad() {
// taskEditTask.value = null
// isTaskEdit.value = false
// }
const taskList = useTaskList(beforeLoad)
taskList.initTaskList()
const taskList = useTaskList(toRef(props, 'listId'))
return {
taskEditTask,
@ -312,7 +318,7 @@ export default {
this.tasks[e.newIndex] = updatedTask
},
},
}
})
</script>
<style lang="scss" scoped>

View File

@ -1,5 +1,5 @@
<template>
<ListWrapper class="list-table">
<ListWrapper class="list-table" :list-id="listId" viewName="table">
<template #header>
<div class="filter-container">
<div class="items">
@ -15,50 +15,47 @@
</template>
<template #content="{isOpen}">
<card class="columns-filter" :class="{'is-open': isOpen}">
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.id">#</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.done">
<fancycheckbox v-model="activeColumns.id">#</fancycheckbox>
<fancycheckbox v-model="activeColumns.done">
{{ $t('task.attributes.done') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.title">
<fancycheckbox v-model="activeColumns.title">
{{ $t('task.attributes.title') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.priority">
<fancycheckbox v-model="activeColumns.priority">
{{ $t('task.attributes.priority') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.labels">
<fancycheckbox v-model="activeColumns.labels">
{{ $t('task.attributes.labels') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.assignees">
<fancycheckbox v-model="activeColumns.assignees">
{{ $t('task.attributes.assignees') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.dueDate">
<fancycheckbox v-model="activeColumns.dueDate">
{{ $t('task.attributes.dueDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.startDate">
<fancycheckbox v-model="activeColumns.startDate">
{{ $t('task.attributes.startDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.endDate">
<fancycheckbox v-model="activeColumns.endDate">
{{ $t('task.attributes.endDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.percentDone">
<fancycheckbox v-model="activeColumns.percentDone">
{{ $t('task.attributes.percentDone') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.created">
<fancycheckbox v-model="activeColumns.created">
{{ $t('task.attributes.created') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.updated">
<fancycheckbox v-model="activeColumns.updated">
{{ $t('task.attributes.updated') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.createdBy">
<fancycheckbox v-model="activeColumns.createdBy">
{{ $t('task.attributes.createdBy') }}
</fancycheckbox>
</card>
</template>
</popup>
<filter-popup
v-model="params"
@update:modelValue="loadTasks()"
/>
<filter-popup v-model="params" />
</div>
</div>
</template>
@ -182,21 +179,23 @@
</ListWrapper>
</template>
<script setup>
import { ref, reactive, computed, toRaw } from 'vue'
<script setup lang="ts">
import { toRef, computed } from 'vue'
import { useRouter } from 'vue-router'
import ListWrapper from './ListWrapper'
import { useStorage } from '@vueuse/core'
import ListWrapper from './ListWrapper.vue'
import Done from '@/components/misc/Done.vue'
import User from '@/components/misc/user'
import PriorityLabel from '@/components/tasks/partials/priorityLabel'
import Labels from '@/components/tasks/partials/labels'
import DateTableCell from '@/components/tasks/partials/date-table-cell'
import Fancycheckbox from '@/components/input/fancycheckbox'
import Sort from '@/components/tasks/partials/sort'
import User from '@/components/misc/user.vue'
import PriorityLabel from '@/components/tasks/partials/priorityLabel.vue'
import Labels from '@/components/tasks/partials/labels.vue'
import DateTableCell from '@/components/tasks/partials/date-table-cell.vue'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import Sort from '@/components/tasks/partials/sort.vue'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Pagination from '@/components/misc/pagination.vue'
import Popup from '@/components/misc/popup'
import Popup from '@/components/misc/popup.vue'
import { useTaskList } from '@/composables/taskList'
@ -216,57 +215,27 @@ const ACTIVE_COLUMNS_DEFAULT = {
createdBy: false,
}
const props = defineProps({
listId: {
type: Number,
required: true,
},
})
const SORT_BY_DEFAULT = {
id: 'desc',
}
function useSavedView(activeColumns, sortBy) {
const savedShowColumns = localStorage.getItem('tableViewColumns')
if (savedShowColumns !== null) {
Object.assign(activeColumns, JSON.parse(savedShowColumns))
}
const savedSortBy = localStorage.getItem('tableViewSortBy')
if (savedSortBy !== null) {
sortBy.value = JSON.parse(savedSortBy)
}
}
const activeColumns = reactive({ ...ACTIVE_COLUMNS_DEFAULT })
const sortBy = ref({ ...SORT_BY_DEFAULT })
useSavedView(activeColumns, sortBy)
function beforeLoad(params) {
// This makes sure an id sort order is always sorted last.
// When tasks would be sorted first by id and then by whatever else was specified, the id sort takes
// precedence over everything else, making any other sort columns pretty useless.
let hasIdFilter = false
const sortKeys = Object.keys(sortBy.value)
for (const s of sortKeys) {
if (s === 'id') {
sortKeys.splice(s, 1)
hasIdFilter = true
break
}
}
if (hasIdFilter) {
sortKeys.push('id')
}
params.value.sort_by = sortKeys
params.value.order_by = sortKeys.map(s => sortBy.value[s])
}
const activeColumns = useStorage('tableViewColumns', { ...ACTIVE_COLUMNS_DEFAULT })
const sortBy = useStorage('tableViewSortBy', { ...SORT_BY_DEFAULT })
const {
tasks,
loading,
params,
loadTasks,
totalPages,
currentPage,
searchTerm,
initTaskList,
} = useTaskList(beforeLoad)
} = useTaskList(toRef(props, 'listId'))
Object.assign(params.value, {
filter_by: [],
@ -274,8 +243,19 @@ Object.assign(params.value, {
filter_comparator: [],
})
const router = useRouter()
// FIXME: by doing this we can have multiple sort orders
function sort(property) {
const order = sortBy.value[property]
if (typeof order === 'undefined' || order === 'none') {
sortBy.value[property] = 'desc'
} else if (order === 'desc') {
sortBy.value[property] = 'asc'
} else {
delete sortBy.value[property]
}
}
const router = useRouter()
const taskDetailRoutes = computed(() => Object.fromEntries(
tasks.value.map(({id}) => ([
id,
@ -286,26 +266,6 @@ const taskDetailRoutes = computed(() => Object.fromEntries(
},
])),
))
function sort(property) {
const order = sortBy.value[property]
if (typeof order === 'undefined' || order === 'none') {
sortBy.value[property] = 'desc'
} else if (order === 'desc') {
sortBy.value[property] = 'asc'
} else {
delete sortBy.value[property]
}
beforeLoad(currentPage.value, searchTerm.value)
// Save the order to be able to retrieve them later
localStorage.setItem('tableViewSortBy', JSON.stringify(sortBy.value))
}
function saveTaskColumns() {
localStorage.setItem('tableViewColumns', JSON.stringify(toRaw(activeColumns)))
}
initTaskList()
</script>
<style lang="scss" scoped>

View File

@ -8,28 +8,28 @@
<router-link
v-shortcut="'g l'"
:title="$t('keyboardShortcuts.list.switchToListView')"
:class="{'is-active': $route.name === 'list.list'}"
:class="{'is-active': viewName === 'list'}"
:to="{ name: 'list.list', params: { listId } }">
{{ $t('list.list.title') }}
</router-link>
<router-link
v-shortcut="'g g'"
:title="$t('keyboardShortcuts.list.switchToGanttView')"
:class="{'is-active': $route.name === 'list.gantt'}"
:class="{'is-active': viewName === 'gantt'}"
:to="{ name: 'list.gantt', params: { listId } }">
{{ $t('list.gantt.title') }}
</router-link>
<router-link
v-shortcut="'g t'"
:title="$t('keyboardShortcuts.list.switchToTableView')"
:class="{'is-active': $route.name === 'list.table'}"
:class="{'is-active': viewName === 'table'}"
:to="{ name: 'list.table', params: { listId } }">
{{ $t('list.table.title') }}
</router-link>
<router-link
v-shortcut="'g k'"
:title="$t('keyboardShortcuts.list.switchToKanbanView')"
:class="{'is-active': $route.name === 'list.kanban'}"
:class="{'is-active': viewName === 'kanban'}"
:to="{ name: 'list.kanban', params: { listId } }">
{{ $t('list.kanban.title') }}
</router-link>
@ -46,11 +46,11 @@
</div>
</template>
<script setup>
<script setup lang="ts">
import {ref, shallowRef, computed, watchEffect} from 'vue'
import {useRoute} from 'vue-router'
import Message from '@/components/misc/message'
import Message from '@/components/misc/message.vue'
import ListModel from '@/models/list'
import ListService from '@/services/list'
@ -63,11 +63,22 @@ import {saveListView} from '@/helpers/saveListView'
import {saveListToHistory} from '@/modules/listHistory'
import { useTitle } from '@/composables/useTitle'
const props = defineProps({
listId: {
type: Number,
required: true,
},
viewName: {
type: String,
required: true,
},
})
const route = useRoute()
// Save the current list view to local storage
// We use local storage and not vuex here to make it persistent across reloads.
saveListView(route.params.listId, route.name)
saveListView(props.listId, props.viewName)
const listService = shallowRef(new ListService())
const loadedListId = ref(0)
@ -80,14 +91,12 @@ const currentList = computed(() => {
} : store.state.currentList
})
// Computed property to let "listId" always have a value
const listId = computed(() => typeof route.params.listId === 'undefined' ? 0 : parseInt(route.params.listId))
// call again the method if the listId changes
watchEffect(() => loadList(listId.value))
watchEffect(() => loadList(props.listId))
useTitle(() => currentList.value.id ? getListTitle(currentList.value) : '')
async function loadList(listIdToLoad) {
async function loadList(listIdToLoad: number) {
const listData = {id: listIdToLoad}
saveListToHistory(listData)
@ -97,8 +106,8 @@ async function loadList(listIdToLoad) {
// We don't do this for the table view because that does not change tasks.
// FIXME: remove this
if (
route.name === 'list.list' ||
route.name === 'list.gantt'
props.viewName === 'list.list' ||
props.viewName === 'list.gantt'
) {
store.commit('kanban/setListId', 0)
}
@ -116,7 +125,7 @@ async function loadList(listIdToLoad) {
return
}
console.debug(`Loading list, $route.name = ${route.name}, $route.params =`, route.params, `, loadedListId = ${loadedListId.value}, currentList = `, currentList.value)
console.debug(`Loading list, props.viewName = ${props.viewName}, $route.params =`, route.params, `, loadedListId = ${loadedListId.value}, currentList = `, currentList.value)
// We create an extra list object instead of creating it in list.value because that would trigger a ui update which would result in bad ux.
const list = new ListModel(listData)
@ -124,7 +133,7 @@ async function loadList(listIdToLoad) {
const loadedList = await listService.value.get(list)
await store.dispatch(CURRENT_LIST, loadedList)
} finally {
loadedListId.value = listId.value
loadedListId.value = props.listId
}
}
</script>

View File

@ -475,6 +475,14 @@ export default {
description,
heading,
},
props: {
taskId: {
type: Number,
required: true,
},
},
data() {
return {
taskService: new TaskService(),
@ -525,10 +533,6 @@ export default {
},
},
computed: {
taskId() {
const {id} = this.$route.params
return id === undefined ? id : Number(id)
},
currentList() {
return this.$store.state[CURRENT_LIST]
},

View File

@ -7,15 +7,22 @@
<a @click="close()" class="close">
<icon icon="times"/>
</a>
<task-detail-view/>
<task-detail-view :task-id="props.taskId"/>
</modal>
</template>
<script setup>
<script setup lang="ts">
import {computed} from 'vue'
import {useRouter, useRoute} from 'vue-router'
import TaskDetailView from './TaskDetailView'
import TaskDetailView from './TaskDetailView.vue'
const props = defineProps({
taskId: {
type: Number,
required: true,
},
})
const route = useRoute()
const historyState = computed(() => route.fullPath && window.history.state)