1
0

feat: rename list to project everywhere

fix: project table view

fix: e2e tests

fix: typo in readme

fix: list view route

fix: don't wait until background is loaded for list to show

fix: rename component imports

fix: lint

fix: parse task text

fix: use list card grid

fix: use correct class names

fix: i18n keys

fix: load project

fix: task overview

fix: list view spacing

fix: find project

fix: setLoading when updating a project

fix: loading saved filter

fix: project store loading

fix: color picker import

fix: cypress tests

feat: migrate old list settings

chore: add const for project settings

fix: wrong projecten rename from lists

chore: rename unused variable

fix: editor list

fix: shortcut list class name

fix: pagination list class name

fix: notifications list class name

fix: list view variable name

chore: clarify comment

fix: i18n keys

fix: router imports

fix: comment

chore: remove debugging leftover

fix: remove duplicate variables

fix: change comment

fix: list view variable name

fix: list view css class name

fix: list item property name

fix: name update tasks function correctly

fix: update comment

fix: project create route

fix: list view class names

fix: list view component name

fix: result list class name

fix: animation class list name

fix: change debug log

fix: revert a few navigation changes

fix: use @ for imports of all views

fix: rename link share list class

fix: remove unused css class

fix: dynamically import project components again
This commit is contained in:
kolaente
2022-11-13 22:04:57 +01:00
committed by Gitea
parent b9d3b5c756
commit befa6f27bb
133 changed files with 1873 additions and 1881 deletions

View File

@ -3,21 +3,21 @@ import {defineStore, acceptHMRUpdate} from 'pinia'
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
import ListModel from '@/models/list'
import ListService from '../services/list'
import ProjectModel from '@/models/project'
import ProjectService from '../services/project'
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
import {useMenuActive} from '@/composables/useMenuActive'
import {useAuthStore} from '@/stores/auth'
import type {IList} from '@/modelTypes/IList'
import type {IProject} from '@/modelTypes/IProject'
export const useBaseStore = defineStore('base', () => {
const loading = ref(false)
const ready = ref(false)
// This is used to highlight the current list in menu for all list related views
const currentList = ref<IList | null>(new ListModel({
// This is used to highlight the current project in menu for all project related views
const currentProject = ref<IProject | null>(new ProjectModel({
id: 0,
isArchived: false,
}))
@ -33,21 +33,21 @@ export const useBaseStore = defineStore('base', () => {
loading.value = newLoading
}
function setCurrentList(newCurrentList: IList | null) {
// Server updates don't return the right. Therefore, the right is reset after updating the list which is
function setCurrentProject(newCurrentProject: IProject | null) {
// Server updates don't return the right. Therefore, the right is reset after updating the project which is
// confusing because all the buttons will disappear in that case. To prevent this, we're keeping the right
// when updating the list in global state.
// when updating the project in global state.
if (
typeof currentList.value?.maxRight !== 'undefined' &&
newCurrentList !== null &&
typeof currentProject.value?.maxRight !== 'undefined' &&
newCurrentProject !== null &&
(
typeof newCurrentList.maxRight === 'undefined' ||
newCurrentList.maxRight === null
typeof newCurrentProject.maxRight === 'undefined' ||
newCurrentProject.maxRight === null
)
) {
newCurrentList.maxRight = currentList.value.maxRight
newCurrentProject.maxRight = currentProject.value.maxRight
}
currentList.value = newCurrentList
currentProject.value = newCurrentProject
}
function setHasTasks(newHasTasks: boolean) {
@ -78,44 +78,44 @@ export const useBaseStore = defineStore('base', () => {
ready.value = value
}
async function handleSetCurrentList(
{list, forceUpdate = false}: {list: IList | null, forceUpdate?: boolean},
async function handleSetCurrentProject(
{project, forceUpdate = false}: {project: IProject | null, forceUpdate?: boolean},
) {
if (list === null) {
setCurrentList({})
if (project === null) {
setCurrentProject({})
setBackground('')
setBlurHash('')
return
}
// The forceUpdate parameter is used only when updating a list background directly because in that case
// the current list stays the same, but we want to show the new background right away.
if (list.id !== currentList.value?.id || forceUpdate) {
if (list.backgroundInformation) {
// The forceUpdate parameter is used only when updating a project background directly because in that case
// the current project stays the same, but we want to show the new background right away.
if (project.id !== currentProject.value?.id || forceUpdate) {
if (project.backgroundInformation) {
try {
const blurHash = await getBlobFromBlurHash(list.backgroundBlurHash)
const blurHash = await getBlobFromBlurHash(project.backgroundBlurHash)
if (blurHash) {
setBlurHash(window.URL.createObjectURL(blurHash))
}
const listService = new ListService()
const background = await listService.background(list)
const projectService = new ProjectService()
const background = await projectService.background(project)
setBackground(background)
} catch (e) {
console.error('Error getting background image for list', list.id, e)
console.error('Error getting background image for project', project.id, e)
}
}
}
if (
typeof list.backgroundInformation === 'undefined' ||
list.backgroundInformation === null
typeof project.backgroundInformation === 'undefined' ||
project.backgroundInformation === null
) {
setBackground('')
setBlurHash('')
}
setCurrentList(list)
setCurrentProject(project)
}
const authStore = useAuthStore()
@ -128,7 +128,7 @@ export const useBaseStore = defineStore('base', () => {
return {
loading: readonly(loading),
ready: readonly(ready),
currentList: readonly(currentList),
currentProject: readonly(currentProject),
background: readonly(background),
blurHash: readonly(blurHash),
hasTasks: readonly(hasTasks),
@ -138,7 +138,7 @@ export const useBaseStore = defineStore('base', () => {
setLoading,
setReady,
setCurrentList,
setCurrentProject,
setHasTasks,
setKeyboardShortcutsActive,
setQuickActionsActive,
@ -146,7 +146,7 @@ export const useBaseStore = defineStore('base', () => {
setBlurHash,
setLogoVisible,
handleSetCurrentList,
handleSetCurrentProject,
loadApp,
...useMenuActive(),

View File

@ -12,7 +12,7 @@ import TaskCollectionService from '@/services/taskCollection'
import {setModuleLoading} from '@/stores/helper'
import type {ITask} from '@/modelTypes/ITask'
import type {IList} from '@/modelTypes/IList'
import type {IProject} from '@/modelTypes/IProject'
import type {IBucket} from '@/modelTypes/IBucket'
const TASKS_PER_BUCKET = 25
@ -45,7 +45,7 @@ const addTaskToBucketAndSort = (buckets: IBucket[], task: ITask) => {
*/
export const useKanbanStore = defineStore('kanban', () => {
const buckets = ref<IBucket[]>([])
const listId = ref<IList['id']>(0)
const projectId = ref<IProject['id']>(0)
const bucketLoading = ref<{[id: IBucket['id']]: boolean}>({})
const taskPagesPerBucket = ref<{[id: IBucket['id']]: number}>({})
const allTasksLoadedForBucket = ref<{[id: IBucket['id']]: boolean}>({})
@ -68,8 +68,8 @@ export const useKanbanStore = defineStore('kanban', () => {
isLoading.value = newIsLoading
}
function setListId(newListId: IList['id']) {
listId.value = Number(newListId)
function setProjectId(newProjectId: IProject['id']) {
projectId.value = Number(newProjectId)
}
function setBuckets(newBuckets: IBucket[]) {
@ -223,20 +223,20 @@ export const useKanbanStore = defineStore('kanban', () => {
allTasksLoadedForBucket.value[bucketId] = true
}
async function loadBucketsForList({listId, params}: {listId: IList['id'], params}) {
async function loadBucketsForProject({projectId, params}: {projectId: IProject['id'], params}) {
const cancel = setModuleLoading(setIsLoading)
// Clear everything to prevent having old buckets in the list if loading the buckets from this list takes a few moments
// Clear everything to prevent having old buckets in the project if loading the buckets from this project takes a few moments
setBuckets([])
const bucketService = new BucketService()
try {
const newBuckets = await bucketService.getAll({listId}, {
const newBuckets = await bucketService.getAll({projectId}, {
...params,
per_page: TASKS_PER_BUCKET,
})
setBuckets(newBuckets)
setListId(listId)
setProjectId(projectId)
return newBuckets
} finally {
cancel()
@ -244,8 +244,8 @@ export const useKanbanStore = defineStore('kanban', () => {
}
async function loadNextTasksForBucket(
{listId, ps = {}, bucketId} :
{listId: IList['id'], ps, bucketId: IBucket['id']},
{projectId, ps = {}, bucketId} :
{projectId: IProject['id'], ps, bucketId: IBucket['id']},
) {
const isLoading = bucketLoading.value[bucketId] ?? false
if (isLoading) {
@ -288,7 +288,7 @@ export const useKanbanStore = defineStore('kanban', () => {
const taskService = new TaskCollectionService()
try {
const tasks = await taskService.getAll({listId}, params, page)
const tasks = await taskService.getAll({projectId}, params, page)
addTasksToBucket({tasks, bucketId: bucketId})
setTasksLoadedForBucketPage({bucketId, page})
if (taskService.totalPages <= page) {
@ -322,7 +322,7 @@ export const useKanbanStore = defineStore('kanban', () => {
const response = await bucketService.delete(bucket)
removeBucket(bucket)
// We reload all buckets because tasks are being moved from the deleted bucket
loadBucketsForList({listId: bucket.listId, params})
loadBucketsForProject({projectId: bucket.projectId, params})
return response
} finally {
cancel()
@ -366,7 +366,7 @@ export const useKanbanStore = defineStore('kanban', () => {
}
await updateBucket({ id, title })
success({message: i18n.global.t('list.kanban.bucketTitleSavedSuccess')})
success({message: i18n.global.t('project.kanban.bucketTitleSavedSuccess')})
}
return {
@ -382,7 +382,7 @@ export const useKanbanStore = defineStore('kanban', () => {
setTaskInBucket,
addTaskToBucket,
removeTaskInBucket,
loadBucketsForList,
loadBucketsForProject,
loadNextTasksForBucket,
createBucket,
deleteBucket,

View File

@ -35,7 +35,7 @@ export const useLabelStore = defineStore('label', () => {
})
// **
// * Checks if a list of labels is available in the store and filters them then query
// * Checks if a project of labels is available in the store and filters them then query
// **
const filterLabelsByQuery = computed(() => {
return (labelsToHide: ILabel[], query: string) => {

View File

@ -5,29 +5,29 @@ import NamespaceService from '../services/namespace'
import {setModuleLoading} from '@/stores/helper'
import {createNewIndexer} from '@/indexes'
import type {INamespace} from '@/modelTypes/INamespace'
import type {IList} from '@/modelTypes/IList'
import {useListStore} from '@/stores/lists'
import type {IProject} from '@/modelTypes/IProject'
import {useProjectStore} from '@/stores/projects'
const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description'])
export const useNamespaceStore = defineStore('namespace', () => {
const listStore = useListStore()
const projectStore = useProjectStore()
const isLoading = ref(false)
// FIXME: should be object with id as key
const namespaces = ref<INamespace[]>([])
const getListAndNamespaceById = computed(() => (listId: IList['id'], ignorePseudoNamespaces = false) => {
const getProjectAndNamespaceById = computed(() => (projectId: IProject['id'], ignorePseudoNamespaces = false) => {
for (const n in namespaces.value) {
if (ignorePseudoNamespaces && namespaces.value[n].id < 0) {
continue
}
for (const l in namespaces.value[n].lists) {
if (namespaces.value[n].lists[l].id === listId) {
for (const l in namespaces.value[n].projects) {
if (namespaces.value[n].projects[l].id === projectId) {
return {
list: namespaces.value[n].lists[l],
project: namespaces.value[n].projects[l],
namespace: namespaces.value[n],
}
}
@ -60,9 +60,9 @@ export const useNamespaceStore = defineStore('namespace', () => {
newNamespaces.forEach(n => {
add(n)
// Check for each list in that namespace if it has a subscription and set it if not
n.lists.forEach(l => {
if (l.subscription === null || l.subscription.entity !== 'list') {
// Check for each project in that namespace if it has a subscription and set it if not
n.projects.forEach(l => {
if (l.subscription === null || l.subscription.entity !== 'project') {
l.subscription = n.subscription
}
})
@ -76,13 +76,13 @@ export const useNamespaceStore = defineStore('namespace', () => {
return
}
if (!namespace.lists || namespace.lists.length === 0) {
namespace.lists = namespaces.value[namespaceIndex].lists
if (!namespace.projects || namespace.projects.length === 0) {
namespace.projects = namespaces.value[namespaceIndex].projects
}
// Check for each list in that namespace if it has a subscription and set it if not
namespace.lists.forEach(l => {
if (l.subscription === null || l.subscription.entity !== 'list') {
// Check for each project in that namespace if it has a subscription and set it if not
namespace.projects.forEach(l => {
if (l.subscription === null || l.subscription.entity !== 'project') {
l.subscription = namespace.subscription
}
})
@ -91,15 +91,15 @@ export const useNamespaceStore = defineStore('namespace', () => {
update(namespace)
}
function setListInNamespaceById(list: IList) {
function setProjectInNamespaceById(project: IProject) {
for (const n in namespaces.value) {
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
// We don't have the namespace id on the project which means we need to loop over all projects until we find it.
// FIXME: Not ideal at all - we should fix that at the api level.
if (namespaces.value[n].id === list.namespaceId) {
for (const l in namespaces.value[n].lists) {
if (namespaces.value[n].lists[l].id === list.id) {
if (namespaces.value[n].id === project.namespaceId) {
for (const l in namespaces.value[n].projects) {
if (namespaces.value[n].projects[l].id === project.id) {
const namespace = namespaces.value[n]
namespace.lists[l] = list
namespace.projects[l] = project
namespaces.value[n] = namespace
return
}
@ -123,23 +123,23 @@ export const useNamespaceStore = defineStore('namespace', () => {
}
}
function addListToNamespace(list: IList) {
function addProjectToNamespace(project: IProject) {
for (const n in namespaces.value) {
if (namespaces.value[n].id === list.namespaceId) {
namespaces.value[n].lists.push(list)
if (namespaces.value[n].id === project.namespaceId) {
namespaces.value[n].projects.push(project)
return
}
}
}
function removeListFromNamespaceById(list: IList) {
function removeProjectFromNamespaceById(project: IProject) {
for (const n in namespaces.value) {
// We don't have the namespace id on the list which means we need to loop over all lists until we find it.
// We don't have the namespace id on the project which means we need to loop over all projects until we find it.
// FIXME: Not ideal at all - we should fix that at the api level.
if (namespaces.value[n].id === list.namespaceId) {
for (const l in namespaces.value[n].lists) {
if (namespaces.value[n].lists[l].id === list.id) {
namespaces.value[n].lists.splice(l, 1)
if (namespaces.value[n].id === project.namespaceId) {
for (const l in namespaces.value[n].projects) {
if (namespaces.value[n].projects[l].id === project.id) {
namespaces.value[n].projects.splice(l, 1)
return
}
}
@ -156,10 +156,10 @@ export const useNamespaceStore = defineStore('namespace', () => {
const namespaces = await namespaceService.getAll({}, {is_archived: true}) as INamespace[]
setNamespaces(namespaces)
// Put all lists in the list state
const lists = namespaces.flatMap(({lists}) => lists)
// Put all projects in the project state
const projects = namespaces.flatMap(({projects}) => projects)
listStore.setLists(lists)
projectStore.setProjects(projects)
return namespaces
} finally {
@ -176,7 +176,7 @@ export const useNamespaceStore = defineStore('namespace', () => {
}
function removeFavoritesNamespaceIfEmpty() {
if (namespaces.value[0].id === -2 && namespaces.value[0].lists.length === 0) {
if (namespaces.value[0].id === -2 && namespaces.value[0].projects.length === 0) {
namespaces.value.splice(0, 1)
}
}
@ -211,17 +211,17 @@ export const useNamespaceStore = defineStore('namespace', () => {
isLoading: readonly(isLoading),
namespaces: readonly(namespaces),
getListAndNamespaceById,
getProjectAndNamespaceById,
getNamespaceById,
searchNamespace,
setNamespaces,
setNamespaceById,
setListInNamespaceById,
setProjectInNamespaceById,
addNamespace,
removeNamespaceById,
addListToNamespace,
removeListFromNamespaceById,
addProjectToNamespace,
removeProjectFromNamespaceById,
loadNamespaces,
loadNamespacesIfFavoritesDontExist,
removeFavoritesNamespaceIfEmpty,

View File

@ -2,57 +2,57 @@ import {watch, reactive, shallowReactive, unref, toRefs, readonly, ref, computed
import {acceptHMRUpdate, defineStore} from 'pinia'
import {useI18n} from 'vue-i18n'
import ListService from '@/services/list'
import ProjectService from '@/services/project'
import {setModuleLoading} from '@/stores/helper'
import {removeListFromHistory} from '@/modules/listHistory'
import {removeProjectFromHistory} from '@/modules/projectHistory'
import {createNewIndexer} from '@/indexes'
import {useNamespaceStore} from './namespaces'
import type {IList} from '@/modelTypes/IList'
import type {IProject} from '@/modelTypes/IProject'
import type {MaybeRef} from '@vueuse/core'
import ListModel from '@/models/list'
import ProjectModel from '@/models/project'
import {success} from '@/message'
import {useBaseStore} from '@/stores/base'
const {add, remove, search, update} = createNewIndexer('lists', ['title', 'description'])
const {add, remove, search, update} = createNewIndexer('projects', ['title', 'description'])
const FavoriteListsNamespace = -2
const FavoriteProjectsNamespace = -2
export interface ListState {
[id: IList['id']]: IList
export interface ProjectState {
[id: IProject['id']]: IProject
}
export const useListStore = defineStore('list', () => {
export const useProjectStore = defineStore('project', () => {
const baseStore = useBaseStore()
const namespaceStore = useNamespaceStore()
const isLoading = ref(false)
// The lists are stored as an object which has the list ids as keys.
const lists = ref<ListState>({})
// The projects are stored as an object which has the project ids as keys.
const projects = ref<ProjectState>({})
const getListById = computed(() => {
return (id: IList['id']) => typeof lists.value[id] !== 'undefined' ? lists.value[id] : null
const getProjectById = computed(() => {
return (id: IProject['id']) => typeof projects.value[id] !== 'undefined' ? projects.value[id] : null
})
const findListByExactname = computed(() => {
const findProjectByExactname = computed(() => {
return (name: string) => {
const list = Object.values(lists.value).find(l => {
const project = Object.values(projects.value).find(l => {
return l.title.toLowerCase() === name.toLowerCase()
})
return typeof list === 'undefined' ? null : list
return typeof project === 'undefined' ? null : project
}
})
const searchList = computed(() => {
const searchProject = computed(() => {
return (query: string, includeArchived = false) => {
return search(query)
?.filter(value => value > 0)
.map(id => lists.value[id])
.filter(list => list.isArchived === includeArchived)
.map(id => projects.value[id])
.filter(project => project.isArchived === includeArchived)
|| []
}
})
@ -61,82 +61,82 @@ export const useListStore = defineStore('list', () => {
isLoading.value = newIsLoading
}
function setList(list: IList) {
lists.value[list.id] = list
update(list)
function setProject(project: IProject) {
projects.value[project.id] = project
update(project)
if (baseStore.currentList?.id === list.id) {
baseStore.setCurrentList(list)
if (baseStore.currentProject?.id === project.id) {
baseStore.setCurrentProject(project)
}
}
function setLists(newLists: IList[]) {
newLists.forEach(l => {
lists.value[l.id] = l
function setProjects(newProjects: IProject[]) {
newProjects.forEach(l => {
projects.value[l.id] = l
add(l)
})
}
function removeListById(list: IList) {
remove(list)
delete lists.value[list.id]
function removeProjectById(project: IProject) {
remove(project)
delete projects.value[project.id]
}
function toggleListFavorite(list: IList) {
// The favorites pseudo list is always favorite
// Archived lists cannot be marked favorite
if (list.id === -1 || list.isArchived) {
function toggleProjectFavorite(project: IProject) {
// The favorites pseudo project is always favorite
// Archived projects cannot be marked favorite
if (project.id === -1 || project.isArchived) {
return
}
return updateList({
...list,
isFavorite: !list.isFavorite,
return updateProject({
...project,
isFavorite: !project.isFavorite,
})
}
async function createList(list: IList) {
async function createProject(project: IProject) {
const cancel = setModuleLoading(setIsLoading)
const listService = new ListService()
const projectService = new ProjectService()
try {
const createdList = await listService.create(list)
createdList.namespaceId = list.namespaceId
namespaceStore.addListToNamespace(createdList)
setList(createdList)
return createdList
const createdProject = await projectService.create(project)
createdProject.namespaceId = project.namespaceId
namespaceStore.addProjectToNamespace(createdProject)
setProject(createdProject)
return createdProject
} finally {
cancel()
}
}
async function updateList(list: IList) {
async function updateProject(project: IProject) {
const cancel = setModuleLoading(setIsLoading)
const listService = new ListService()
const projectService = new ProjectService()
try {
await listService.update(list)
setList(list)
namespaceStore.setListInNamespaceById(list)
await projectService.update(project)
setProject(project)
namespaceStore.setProjectInNamespaceById(project)
// the returned list from listService.update is the same!
// the returned project from projectService.update is the same!
// in order to not create a manipulation in pinia store we have to create a new copy
const newList = {
...list,
namespaceId: FavoriteListsNamespace,
const newProject = {
...project,
namespaceId: FavoriteProjectsNamespace,
}
namespaceStore.removeListFromNamespaceById(newList)
if (list.isFavorite) {
namespaceStore.addListToNamespace(newList)
namespaceStore.removeProjectFromNamespaceById(newProject)
if (project.isFavorite) {
namespaceStore.addProjectToNamespace(newProject)
}
namespaceStore.loadNamespacesIfFavoritesDontExist()
namespaceStore.removeFavoritesNamespaceIfEmpty()
return newList
return newProject
} catch (e) {
// Reset the list state to the initial one to avoid confusion for the user
setList({
...list,
isFavorite: !list.isFavorite,
// Reset the project state to the initial one to avoid confusion for the user
setProject({
...project,
isFavorite: !project.isFavorite,
})
throw e
} finally {
@ -144,15 +144,15 @@ export const useListStore = defineStore('list', () => {
}
}
async function deleteList(list: IList) {
async function deleteProject(project: IProject) {
const cancel = setModuleLoading(setIsLoading)
const listService = new ListService()
const projectService = new ProjectService()
try {
const response = await listService.delete(list)
removeListById(list)
namespaceStore.removeListFromNamespaceById(list)
removeListFromHistory({id: list.id})
const response = await projectService.delete(project)
removeProjectById(project)
namespaceStore.removeProjectFromNamespaceById(project)
removeProjectFromHistory({id: project.id})
return response
} finally {
cancel()
@ -161,51 +161,51 @@ export const useListStore = defineStore('list', () => {
return {
isLoading: readonly(isLoading),
lists: readonly(lists),
projects: readonly(projects),
getListById,
findListByExactname,
searchList,
getProjectById,
findProjectByExactname,
searchProject,
setList,
setLists,
removeListById,
toggleListFavorite,
createList,
updateList,
deleteList,
setProject,
setProjects,
removeProjectById,
toggleProjectFavorite,
createProject,
updateProject,
deleteProject,
}
})
export function useList(listId: MaybeRef<IList['id']>) {
const listService = shallowReactive(new ListService())
const {loading: isLoading} = toRefs(listService)
const list: IList = reactive(new ListModel())
export function useProject(projectId: MaybeRef<IProject['id']>) {
const projectService = shallowReactive(new ProjectService())
const {loading: isLoading} = toRefs(projectService)
const project: IProject = reactive(new ProjectModel())
const {t} = useI18n({useScope: 'global'})
watch(
() => unref(listId),
async (listId) => {
const loadedList = await listService.get(new ListModel({id: listId}))
Object.assign(list, loadedList)
() => unref(projectId),
async (projectId) => {
const loadedProject = await projectService.get(new ProjectModel({id: projectId}))
Object.assign(project, loadedProject)
},
{immediate: true},
)
const listStore = useListStore()
const projectStore = useProjectStore()
async function save() {
await listStore.updateList(list)
success({message: t('list.edit.success')})
await projectStore.updateProject(project)
success({message: t('project.edit.success')})
}
return {
isLoading: readonly(isLoading),
list,
project,
save,
}
}
// support hot reloading
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useListStore, import.meta.hot))
import.meta.hot.accept(acceptHMRUpdate(useProjectStore, import.meta.hot))
}

View File

@ -21,11 +21,11 @@ import type {ILabel} from '@/modelTypes/ILabel'
import type {ITask} from '@/modelTypes/ITask'
import type {IUser} from '@/modelTypes/IUser'
import type {IAttachment} from '@/modelTypes/IAttachment'
import type {IList} from '@/modelTypes/IList'
import type {IProject} from '@/modelTypes/IProject'
import {setModuleLoading} from '@/stores/helper'
import {useLabelStore} from '@/stores/labels'
import {useListStore} from '@/stores/lists'
import {useProjectStore} from '@/stores/projects'
import {useAttachmentStore} from '@/stores/attachments'
import {useKanbanStore} from '@/stores/kanban'
import {useBaseStore} from '@/stores/base'
@ -83,7 +83,7 @@ export const useTaskStore = defineStore('task', () => {
const kanbanStore = useKanbanStore()
const attachmentStore = useAttachmentStore()
const labelStore = useLabelStore()
const listStore = useListStore()
const projectStore = useProjectStore()
const tasks = ref<{ [id: ITask['id']]: ITask }>({}) // TODO: or is this ITask[]
const isLoading = ref(false)
@ -292,7 +292,7 @@ export const useTaskStore = defineStore('task', () => {
return response
}
// Remove the label from the list
// Remove the label from the project
const labels = t.task.labels.filter(({ id }) => id !== label.id)
kanbanStore.setTaskInBucketByIndex({
@ -337,40 +337,40 @@ export const useTaskStore = defineStore('task', () => {
return task
}
function findListId(
{ list: listName, listId }:
{ list: string, listId: IList['id'] }) {
let foundListId = null
// Uses the following ways to get the list id of the new task:
function findProjectId(
{ project: projectName, projectId }:
{ project: string, projectId: IProject['id'] }) {
let foundProjectId = null
// Uses the following ways to get the project id of the new task:
// 1. If specified in quick add magic, look in store if it exists and use it if it does
if (listName !== null) {
const list = listStore.findListByExactname(listName)
foundListId = list === null ? null : list.id
if (typeof projectName !== 'undefined' && projectName !== null) {
const project = projectStore.findProjectByExactname(projectName)
foundProjectId = project === null ? null : project.id
}
// 2. Else check if a list was passed as parameter
if (foundListId === null && listId !== 0) {
foundListId = listId
// 2. Else check if a project was passed as parameter
if (foundProjectId === null && projectId !== 0) {
foundProjectId = projectId
}
// 3. Otherwise use the id from the route parameter
if (typeof router.currentRoute.value.params.listId !== 'undefined') {
foundListId = Number(router.currentRoute.value.params.listId)
if (typeof router.currentRoute.value.params.projectId !== 'undefined') {
foundProjectId = Number(router.currentRoute.value.params.projectId)
}
// 4. If none of the above worked, reject the promise with an error.
if (typeof foundListId === 'undefined' || listId === null) {
throw new Error('NO_LIST')
if (typeof foundProjectId === 'undefined' || projectId === null) {
throw new Error('NO_PROJECT')
}
return foundListId
return foundProjectId
}
async function createNewTask({
title,
bucketId,
listId,
projectId,
position,
} :
Partial<ITask>,
@ -379,14 +379,14 @@ export const useTaskStore = defineStore('task', () => {
const quickAddMagicMode = getQuickAddMagicMode()
const parsedTask = parseTaskText(title, quickAddMagicMode)
const foundListId = await findListId({
list: parsedTask.list,
listId: listId || 0,
const foundProjectId = await findProjectId({
project: parsedTask.project,
projectId: projectId || 0,
})
if(foundListId === null || foundListId === 0) {
if(foundProjectId === null || foundProjectId === 0) {
cancel()
throw new Error('NO_LIST')
throw new Error('NO_PROJECT')
}
const assignees = await findAssignees(parsedTask.assignees)
@ -405,7 +405,7 @@ export const useTaskStore = defineStore('task', () => {
const task = new TaskModel({
title: cleanedTitle,
listId: foundListId,
projectId: foundProjectId,
dueDate,
priority: parsedTask.priority,
assignees,
@ -451,7 +451,7 @@ export const useTaskStore = defineStore('task', () => {
addLabelsToTask,
createNewTask,
setCoverImage,
findListId,
findProjectId,
ensureLabelsExist,
}
})