forked from vikunja/frontend
Compare commits
3 Commits
main
...
fix/task-l
Author | SHA1 | Date | |
---|---|---|---|
4924470f2b | |||
5e9ed290ac | |||
00248e7c91 |
20
package.json
20
package.json
|
@ -53,8 +53,8 @@
|
|||
"@infectoone/vue-ganttastic": "2.1.4",
|
||||
"@intlify/unplugin-vue-i18n": "0.8.2",
|
||||
"@kyvg/vue3-notification": "2.9.0",
|
||||
"@sentry/tracing": "7.40.0",
|
||||
"@sentry/vue": "7.40.0",
|
||||
"@sentry/tracing": "7.39.0",
|
||||
"@sentry/vue": "7.39.0",
|
||||
"@types/is-touch-device": "1.0.0",
|
||||
"@types/lodash.clonedeep": "4.5.7",
|
||||
"@types/sortablejs": "1.15.0",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"codemirror": "5.65.12",
|
||||
"date-fns": "2.29.3",
|
||||
"dayjs": "1.11.7",
|
||||
"dompurify": "3.0.1",
|
||||
"dompurify": "3.0.0",
|
||||
"easymde": "2.18.0",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"flatpickr": "4.6.13",
|
||||
|
@ -82,7 +82,7 @@
|
|||
"register-service-worker": "1.7.2",
|
||||
"snake-case": "3.0.4",
|
||||
"sortablejs": "1.15.0",
|
||||
"ufo": "1.1.1",
|
||||
"ufo": "1.1.0",
|
||||
"vue": "3.2.47",
|
||||
"vue-advanced-cropper": "2.8.8",
|
||||
"vue-flatpickr-component": "11.0.2",
|
||||
|
@ -105,10 +105,10 @@
|
|||
"@types/focus-within": "1.0.1",
|
||||
"@types/lodash.debounce": "4.0.7",
|
||||
"@types/marked": "4.0.8",
|
||||
"@types/node": "18.14.6",
|
||||
"@types/node": "18.14.2",
|
||||
"@types/postcss-preset-env": "7.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.54.0",
|
||||
"@typescript-eslint/parser": "5.54.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.53.0",
|
||||
"@typescript-eslint/parser": "5.53.0",
|
||||
"@vitejs/plugin-legacy": "4.0.1",
|
||||
"@vitejs/plugin-vue": "4.0.0",
|
||||
"@vue/eslint-config-typescript": "11.0.2",
|
||||
|
@ -119,7 +119,7 @@
|
|||
"caniuse-lite": "1.0.30001458",
|
||||
"csstype": "3.1.1",
|
||||
"cypress": "12.7.0",
|
||||
"esbuild": "0.17.11",
|
||||
"esbuild": "0.17.10",
|
||||
"eslint": "8.35.0",
|
||||
"eslint-plugin-vue": "9.9.0",
|
||||
"happy-dom": "8.9.0",
|
||||
|
@ -129,7 +129,7 @@
|
|||
"postcss-easing-gradients": "3.0.1",
|
||||
"postcss-easings": "3.0.1",
|
||||
"postcss-preset-env": "8.0.1",
|
||||
"rollup": "3.18.0",
|
||||
"rollup": "3.17.3",
|
||||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"sass": "1.58.3",
|
||||
"start-server-and-test": "2.0.0",
|
||||
|
@ -138,7 +138,7 @@
|
|||
"vite-plugin-inject-preload": "1.3.0",
|
||||
"vite-plugin-pwa": "0.14.4",
|
||||
"vite-svg-loader": "4.0.0",
|
||||
"vitest": "0.29.2",
|
||||
"vitest": "0.29.1",
|
||||
"vue-tsc": "1.2.0",
|
||||
"wait-on": "7.0.1",
|
||||
"workbox-cli": "6.5.4"
|
||||
|
|
486
pnpm-lock.yaml
486
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -221,7 +221,7 @@ function updateActiveLists(namespace: INamespace, activeLists: IList[]) {
|
|||
// This is a bit hacky: since we do have to filter out the archived items from the list
|
||||
// for vue draggable updating it is not as simple as replacing it.
|
||||
// To work around this, we merge the active lists with the archived ones. Doing so breaks the order
|
||||
// because now all archived lists are sorted after the active ones. This is fine because they are sorted
|
||||
// because now all archived lists are sorted after the active ones. This is fine because they are sorted
|
||||
// later when showing them anyway, and it makes the merging happening here a lot easier.
|
||||
const lists = [
|
||||
...activeLists,
|
||||
|
@ -246,8 +246,8 @@ async function saveListPosition(e: SortableEvent) {
|
|||
// If the list was dragged to the last position, Safari will report e.newIndex as the size of the listsActive
|
||||
// array instead of using the position. Because the index is wrong in that case, dragging the list will fail.
|
||||
// To work around that we're explicitly checking that case here and decrease the index.
|
||||
const newIndex = e.newIndex === listsActive.length ? e.newIndex - 1 : e.newIndex
|
||||
|
||||
const newIndex = e.newIndex === listsActive.length ? e.newIndex - 1 : e.newIndex
|
||||
|
||||
const list = listsActive[newIndex]
|
||||
const listBefore = listsActive[newIndex - 1] ?? null
|
||||
const listAfter = listsActive[newIndex + 1] ?? null
|
||||
|
@ -342,20 +342,13 @@ $vikunja-nav-selected-width: 0.4rem;
|
|||
}
|
||||
|
||||
.menu-list-dropdown {
|
||||
opacity: 1;
|
||||
opacity: 0;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
@media(hover: hover) and (pointer: fine) {
|
||||
.menu-list-dropdown {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover .menu-list-dropdown {
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover .menu-list-dropdown {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.menu-item-icon {
|
||||
|
@ -425,6 +418,7 @@ $vikunja-nav-selected-width: 0.4rem;
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.dragging-disabled) .handle {
|
||||
cursor: grab;
|
||||
}
|
||||
|
@ -433,7 +427,7 @@ $vikunja-nav-selected-width: 0.4rem;
|
|||
|
||||
.top-menu {
|
||||
margin-top: math.div($navbar-padding, 2);
|
||||
|
||||
|
||||
.menu-list {
|
||||
li {
|
||||
font-weight: 600;
|
||||
|
@ -488,24 +482,17 @@ $vikunja-nav-selected-width: 0.4rem;
|
|||
.favorite {
|
||||
margin-left: .25rem;
|
||||
transition: opacity $transition, color $transition;
|
||||
opacity: 1;
|
||||
opacity: 0;
|
||||
|
||||
&:hover,
|
||||
&.is-favorite {
|
||||
color: var(--warning);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media(hover: hover) and (pointer: fine) {
|
||||
.list-menu .favorite {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.list-menu:hover .favorite,
|
||||
.favorite.is-favorite {
|
||||
opacity: 1;
|
||||
}
|
||||
.favorite.is-favorite,
|
||||
.list-menu:hover .favorite {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.list-menu-title {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
@change="(event: Event) => updateData((event.target as HTMLInputElement).checked)"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label :for="checkBoxId" class="check" @click.prevent="check">
|
||||
<label :for="checkBoxId" class="check">
|
||||
<svg height="18px" viewBox="0 0 18 18" width="18px">
|
||||
<path
|
||||
d="M1,9 L1,3.5 C1,2 2,1 3.5,1 L14.5,1 C16,1 17,2 17,3.5 L17,14.5 C17,16 16,17 14.5,17 L3.5,17 C2,17 1,16 1,14.5 L1,9 Z"></path>
|
||||
|
@ -56,11 +56,6 @@ function updateData(newChecked: boolean) {
|
|||
emit('update:modelValue', newChecked)
|
||||
emit('change', newChecked)
|
||||
}
|
||||
|
||||
function check() {
|
||||
checked.value = !checked.value
|
||||
updateData(checked.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ const listStore = useListStore()
|
|||
top: var(--list-card-padding);
|
||||
right: var(--list-card-padding);
|
||||
transition: opacity $transition, color $transition;
|
||||
opacity: 1;
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--warning);
|
||||
|
@ -160,14 +160,8 @@ const listStore = useListStore()
|
|||
}
|
||||
}
|
||||
|
||||
@media(hover: hover) and (pointer: fine) {
|
||||
.list-card .favorite {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.list-card:hover .favorite {
|
||||
opacity: 1;
|
||||
}
|
||||
.list-card:hover .favorite {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.background-fade-in {
|
||||
|
@ -179,4 +173,4 @@ const listStore = useListStore()
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
|
@ -428,7 +428,7 @@ function searchTeams() {
|
|||
teamService.getAll({}, { s: t }),
|
||||
)
|
||||
const teamsResult = await Promise.all(teamSearchPromises)
|
||||
foundTeams.value = teamsResult.flat().map((team) => {
|
||||
foundTeams.value = teamsResult.flatMap((team) => {
|
||||
team.title = team.name
|
||||
return team
|
||||
})
|
||||
|
@ -458,13 +458,6 @@ async function doAction(type: ACTION_TYPE, item: DoAction) {
|
|||
params: { id: (item as DoAction<ITask>).id },
|
||||
})
|
||||
break
|
||||
case ACTION_TYPE.TEAM:
|
||||
closeQuickActions()
|
||||
await router.push({
|
||||
name: 'teams.edit',
|
||||
params: { id: (item as DoAction<ITeam>).id },
|
||||
})
|
||||
break
|
||||
case ACTION_TYPE.CMD:
|
||||
query.value = ''
|
||||
selectedCmd.value = item as DoAction<Command>
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
<template>
|
||||
<router-link
|
||||
:to="taskDetailRoute"
|
||||
:class="{'is-loading': taskService.loading}"
|
||||
class="task loader-container"
|
||||
>
|
||||
<div :class="{'is-loading': taskService.loading}" class="task loader-container" @click.stop.self="openTaskDetail">
|
||||
<fancycheckbox
|
||||
:disabled="(isArchived || disabled) && !canMarkAsDone"
|
||||
@change="markAsDone"
|
||||
v-model="task.done"
|
||||
/>
|
||||
|
||||
|
||||
<ColorBubble
|
||||
v-if="showListColor && listColor !== '' && currentList.id !== task.listId"
|
||||
:color="listColor"
|
||||
class="mr-1"
|
||||
/>
|
||||
|
||||
<div
|
||||
|
||||
<router-link
|
||||
:to="taskDetailRoute"
|
||||
:class="{ 'done': task.done, 'show-list': showList && taskList !== null}"
|
||||
class="tasktext"
|
||||
>
|
||||
|
@ -96,7 +93,7 @@
|
|||
</span>
|
||||
|
||||
<checklist-summary :task="task"/>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<progress
|
||||
class="progress is-small"
|
||||
|
@ -117,26 +114,27 @@
|
|||
|
||||
<BaseButton
|
||||
:class="{'is-favorite': task.isFavorite}"
|
||||
@click.prevent="toggleFavorite"
|
||||
@click="toggleFavorite"
|
||||
class="favorite"
|
||||
>
|
||||
<icon icon="star" v-if="task.isFavorite"/>
|
||||
<icon :icon="['far', 'star']" v-else/>
|
||||
</BaseButton>
|
||||
<slot />
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, watch, shallowReactive, toRef, type PropType, onMounted, onBeforeUnmount, computed} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import TaskModel, { getHexColor } from '@/models/task'
|
||||
import type {ITask} from '@/modelTypes/ITask'
|
||||
|
||||
import PriorityLabel from '@/components/tasks/partials/priorityLabel.vue'
|
||||
import Labels from '@/components/tasks/partials//labels.vue'
|
||||
import DeferTask from '@/components/tasks/partials//defer-task.vue'
|
||||
import Labels from '@/components/tasks/partials/labels.vue'
|
||||
import DeferTask from '@/components/tasks/partials/defer-task.vue'
|
||||
import ChecklistSummary from '@/components/tasks/partials/checklist-summary.vue'
|
||||
|
||||
import User from '@/components/misc/user.vue'
|
||||
|
@ -186,6 +184,7 @@ const props = defineProps({
|
|||
const emit = defineEmits(['task-updated'])
|
||||
|
||||
const {t} = useI18n({useScope: 'global'})
|
||||
const router = useRouter()
|
||||
|
||||
const taskService = shallowReactive(new TaskService())
|
||||
const task = ref<ITask>(new TaskModel())
|
||||
|
@ -275,6 +274,14 @@ function hideDeferDueDatePopup(e) {
|
|||
showDefer.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const taskLink = ref(null)
|
||||
function openTaskDetail() {
|
||||
const isTextSelected = window.getSelection().toString()
|
||||
if (!isTextSelected) {
|
||||
router.push(taskDetailRoute.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -288,14 +295,18 @@ function hideDeferDueDatePopup(e) {
|
|||
border-radius: $radius;
|
||||
border: 2px solid transparent;
|
||||
|
||||
color: var(--text);
|
||||
transition: color ease $transition-duration;
|
||||
|
||||
&:hover {
|
||||
color: var(--grey-900);
|
||||
background-color: var(--grey-100);
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
|
||||
|
||||
a.tasktext {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.tasktext,
|
||||
&.tasktext {
|
||||
white-space: nowrap;
|
||||
|
@ -338,8 +349,17 @@ function hideDeferDueDatePopup(e) {
|
|||
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--text);
|
||||
transition: color ease $transition-duration;
|
||||
|
||||
&:hover {
|
||||
color: var(--grey-900);
|
||||
}
|
||||
}
|
||||
|
||||
.favorite {
|
||||
opacity: 1;
|
||||
opacity: 0;
|
||||
text-align: center;
|
||||
width: 27px;
|
||||
transition: opacity $transition, color $transition;
|
||||
|
@ -354,26 +374,22 @@ function hideDeferDueDatePopup(e) {
|
|||
}
|
||||
}
|
||||
|
||||
.handle {
|
||||
&:hover .favorite,
|
||||
.favorite:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.handle {
|
||||
opacity: 0;
|
||||
transition: opacity $transition;
|
||||
margin-right: .25rem;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
@media(hover: hover) and (pointer: fine) {
|
||||
& .favorite,
|
||||
& .handle {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover .favorite,
|
||||
&:hover .handle {
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover .handle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
:deep(.fancycheckbox) {
|
||||
height: 18px;
|
||||
padding-top: 0;
|
||||
|
@ -425,4 +441,4 @@ function hideDeferDueDatePopup(e) {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
|
@ -5,22 +5,6 @@ import TaskCollectionService from '@/services/taskCollection'
|
|||
import type {ITask} from '@/modelTypes/ITask'
|
||||
import {error} from '@/message'
|
||||
|
||||
export type Order = 'asc' | 'desc' | 'none'
|
||||
|
||||
export interface SortBy {
|
||||
id?: Order
|
||||
index?: Order
|
||||
done?: Order
|
||||
title?: Order
|
||||
priority?: Order
|
||||
due_date?: Order
|
||||
start_date?: Order
|
||||
end_date?: Order
|
||||
percent_done?: Order
|
||||
created?: Order
|
||||
updated?: Order
|
||||
}
|
||||
|
||||
// FIXME: merge with DEFAULT_PARAMS in filters.vue
|
||||
export const getDefaultParams = () => ({
|
||||
sort_by: ['position', 'id'],
|
||||
|
@ -31,7 +15,7 @@ export const getDefaultParams = () => ({
|
|||
filter_concat: 'and',
|
||||
})
|
||||
|
||||
const SORT_BY_DEFAULT: SortBy = {
|
||||
const SORT_BY_DEFAULT = {
|
||||
id: 'desc',
|
||||
}
|
||||
|
||||
|
@ -60,7 +44,7 @@ const SORT_BY_DEFAULT: SortBy = {
|
|||
/**
|
||||
* This mixin provides a base set of methods and properties to get tasks on a list.
|
||||
*/
|
||||
export function useTaskList(listId, sortByDefault: SortBy = SORT_BY_DEFAULT) {
|
||||
export function useTaskList(listId, sortByDefault = SORT_BY_DEFAULT) {
|
||||
const params = ref({...getDefaultParams()})
|
||||
|
||||
const search = ref('')
|
||||
|
|
|
@ -113,8 +113,8 @@ export const checkAndSetApiUrl = (url: string): Promise<string> => {
|
|||
window.API_URL = oldUrl
|
||||
throw e
|
||||
})
|
||||
.then(success => {
|
||||
if (success) {
|
||||
.then(r => {
|
||||
if (typeof r !== 'undefined') {
|
||||
localStorage.setItem('API_URL', window.API_URL)
|
||||
return window.API_URL
|
||||
}
|
||||
|
|
|
@ -405,7 +405,7 @@
|
|||
"title": "Nuovo Filtro Salvato",
|
||||
"description": "Un filtro salvato è una lista virtuale che viene calcolata da un insieme di filtri di volta in volta. Una volta creato, apparirà in un namespace speciale.",
|
||||
"action": "Crea nuovo filtro salvato",
|
||||
"titleRequired": "È necessario un titolo per il filtro."
|
||||
"titleRequired": "Please provide a title for the filter."
|
||||
},
|
||||
"delete": {
|
||||
"header": "Elimina questo filtro salvato",
|
||||
|
|
|
@ -126,12 +126,6 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
|
|||
|
||||
/**
|
||||
* Returns an object with all route parameters and their values.
|
||||
* @example
|
||||
* getRouteReplacements(
|
||||
* '/tasks/{taskId}/assignees/{userId}',
|
||||
* { taskId: 7, userId: 2 },
|
||||
* )
|
||||
* // { "{taskId}": 7, "{userId}": 2 }
|
||||
*/
|
||||
getRouteReplacements(route : string, parameters : Record<string, unknown> = {}) {
|
||||
const replace$$1: Record<string, unknown> = {}
|
||||
|
@ -154,8 +148,6 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
|
|||
|
||||
/**
|
||||
* Returns a fully-ready-ready-to-make-a-request-to route with replaced parameters.
|
||||
* @example
|
||||
* getReplacedRoute('/lists/{listId}/tasks', { listId: 3 }) === '/lists/1/tasks'
|
||||
*/
|
||||
getReplacedRoute(path : string, pathparams : Record<string, unknown>) : string {
|
||||
const replacements = this.getRouteReplacements(path, pathparams)
|
||||
|
@ -311,7 +303,7 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
|
|||
* @param params Optional query parameters
|
||||
* @param page The page to get
|
||||
*/
|
||||
async getAll(model : Model = new AbstractModel({}), params = {}, page = 1): Promise<Model[]> {
|
||||
async getAll(model : Model = new AbstractModel({}), params = {}, page = 1) {
|
||||
if (this.paths.getAll === '') {
|
||||
throw new Error('This model is not able to get data.')
|
||||
}
|
||||
|
@ -331,7 +323,10 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
|
|||
return []
|
||||
}
|
||||
|
||||
return response.data.map(entry => this.modelGetAllFactory(entry))
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data.map(entry => this.modelGetAllFactory(entry))
|
||||
}
|
||||
return this.modelGetAllFactory(response.data)
|
||||
} finally {
|
||||
cancel()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import {HTTPFactory} from '@/helpers/fetcher'
|
|||
import {objectToCamelCase} from '@/helpers/case'
|
||||
|
||||
import type {IProvider} from '@/types/IProvider'
|
||||
import type {MIGRATORS} from '@/views/migrate/migrators'
|
||||
|
||||
export interface ConfigState {
|
||||
version: string,
|
||||
|
@ -15,10 +14,10 @@ export interface ConfigState {
|
|||
linkSharingEnabled: boolean,
|
||||
maxFileSize: string,
|
||||
registrationEnabled: boolean,
|
||||
availableMigrators: Array<keyof typeof MIGRATORS>,
|
||||
availableMigrators: [],
|
||||
taskAttachmentsEnabled: boolean,
|
||||
totpEnabled: boolean,
|
||||
enabledBackgroundProviders: Array<'unsplash' | 'upload'>,
|
||||
enabledBackgroundProviders: [],
|
||||
legal: {
|
||||
imprintUrl: string,
|
||||
privacyPolicyUrl: string,
|
||||
|
@ -79,12 +78,11 @@ export const useConfigStore = defineStore('config', () => {
|
|||
function setConfig(config: ConfigState) {
|
||||
Object.assign(state, config)
|
||||
}
|
||||
async function update(): Promise<boolean> {
|
||||
async function update() {
|
||||
const HTTP = HTTPFactory()
|
||||
const {data: config} = await HTTP.get('info')
|
||||
setConfig(objectToCamelCase(config))
|
||||
const success = !!config
|
||||
return success
|
||||
return config
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -196,7 +196,7 @@ import FilterPopup from '@/components/list/partials/filter-popup.vue'
|
|||
import Pagination from '@/components/misc/pagination.vue'
|
||||
import Popup from '@/components/misc/popup.vue'
|
||||
|
||||
import {useTaskList, SortBy} from '@/composables/useTaskList'
|
||||
import {useTaskList} from '@/composables/useTaskList'
|
||||
import type {ITask} from '@/modelTypes/ITask'
|
||||
|
||||
const ACTIVE_COLUMNS_DEFAULT = {
|
||||
|
@ -222,6 +222,21 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
|
||||
type Order = 'asc' | 'desc' | 'none'
|
||||
|
||||
interface SortBy {
|
||||
index: Order
|
||||
done?: Order
|
||||
title?: Order
|
||||
priority?: Order
|
||||
due_date?: Order
|
||||
start_date?: Order
|
||||
end_date?: Order
|
||||
percent_done?: Order
|
||||
created?: Order
|
||||
updated?: Order
|
||||
}
|
||||
|
||||
const SORT_BY_DEFAULT: SortBy = {
|
||||
index: 'desc',
|
||||
}
|
||||
|
@ -229,7 +244,7 @@ const SORT_BY_DEFAULT: SortBy = {
|
|||
const activeColumns = useStorage('tableViewColumns', {...ACTIVE_COLUMNS_DEFAULT})
|
||||
const sortBy = useStorage<SortBy>('tableViewSortBy', {...SORT_BY_DEFAULT})
|
||||
|
||||
const taskList = useTaskList(toRef(props, 'listId'), sortBy.value)
|
||||
const taskList = useTaskList(toRef(props, 'listId'))
|
||||
|
||||
const {
|
||||
loading,
|
||||
|
|
|
@ -16,7 +16,7 @@ interface IMigratorRecord {
|
|||
[key: Migrator['id']]: Migrator
|
||||
}
|
||||
|
||||
export const MIGRATORS = {
|
||||
export const MIGRATORS: IMigratorRecord = {
|
||||
wunderlist: {
|
||||
id: 'wunderlist',
|
||||
name: 'Wunderlist',
|
||||
|
@ -49,4 +49,4 @@ export const MIGRATORS = {
|
|||
icon: tickTickIcon as string,
|
||||
isFileMigrator: true,
|
||||
},
|
||||
} as const satisfies IMigratorRecord
|
||||
} as const
|
||||
|
|
Loading…
Reference in New Issue
Block a user