diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index 308cf9e905..d1d28c20be 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -52,7 +52,7 @@ import {computed, onMounted, onUnmounted, ref} from 'vue'
import NotificationService from '@/services/notification'
import BaseButton from '@/components/base/BaseButton.vue'
import User from '@/components/misc/user.vue'
-import { NOTIFICATION_NAMES as names, type INotification} from '@/models/notification'
+import { NOTIFICATION_NAMES as names, type INotification} from '@/modelTypes/INotification'
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {useStore} from '@/store'
import {useRouter} from 'vue-router'
diff --git a/src/components/tasks/partials/attachments.vue b/src/components/tasks/partials/attachments.vue
index b5043eee95..70d6e5b1e3 100644
--- a/src/components/tasks/partials/attachments.vue
+++ b/src/components/tasks/partials/attachments.vue
@@ -49,7 +49,7 @@
/>
- {{ a.file.getHumanSize() }}
+ {{ getHumanSize(a.file.size) }}
{{ a.file.mime }}
@@ -157,6 +157,7 @@ import {formatDate, formatDateSince, formatDateLong} from '@/helpers/time/format
import BaseButton from '@/components/base/BaseButton'
import type { IFile } from '@/models/file'
+import { getHumanSize } from '@/helpers/getHumanSize'
export default defineComponent({
name: 'attachments',
@@ -231,6 +232,7 @@ export default defineComponent({
})
},
methods: {
+ getHumanSize,
formatDate,
formatDateSince,
formatDateLong,
diff --git a/src/components/tasks/partials/relatedTasks.vue b/src/components/tasks/partials/relatedTasks.vue
index a46c4f6352..2e717fd952 100644
--- a/src/components/tasks/partials/relatedTasks.vue
+++ b/src/components/tasks/partials/relatedTasks.vue
@@ -144,7 +144,8 @@ import {defineComponent} from 'vue'
import TaskService from '../../../services/task'
import TaskModel from '../../../models/task'
import TaskRelationService from '../../../services/taskRelation'
-import TaskRelationModel, {RELATION_KINDS} from '@/models/taskRelation'
+import TaskRelationModel from '@/models/taskRelation'
+import { RELATION_KIND, RELATION_KINDS } from '@/types/IRelationKind'
import BaseButton from '@/components/base/BaseButton.vue'
import Multiselect from '@/components/input/multiselect.vue'
@@ -158,7 +159,7 @@ export default defineComponent({
foundTasks: [],
relationKinds: RELATION_KINDS,
newTaskRelationTask: new TaskModel(),
- newTaskRelationKind: 'related',
+ newTaskRelationKind: RELATION_KIND.RELATED,
taskRelationService: new TaskRelationService(),
showDeleteModal: false,
relationToDelete: {},
diff --git a/src/components/tasks/partials/repeatAfter.vue b/src/components/tasks/partials/repeatAfter.vue
index 4cb246276d..bf50384dcd 100644
--- a/src/components/tasks/partials/repeatAfter.vue
+++ b/src/components/tasks/partials/repeatAfter.vue
@@ -66,7 +66,10 @@ import {ref, reactive, watch, type PropType} from 'vue'
import {useI18n} from 'vue-i18n'
import {error} from '@/message'
-import {TASK_REPEAT_MODES, type ITask, type RepeatAfter} from '@/models/task'
+
+import {TASK_REPEAT_MODES} from '@/types/IRepeatMode'
+import type {IRepeatAfter} from '@/types/IRepeatAfter'
+import type {ITask} from '@/modelTypes/ITask'
const props = defineProps({
modelValue: {
@@ -116,7 +119,7 @@ function updateData() {
emit('change')
}
-function setRepeatAfter(amount: number, type: RepeatAfter['type']) {
+function setRepeatAfter(amount: number, type: IRepeatAfter['type']) {
Object.assign(repeatAfter, { amount, type})
updateData()
}
diff --git a/src/helpers/color/colorIsDark.ts b/src/helpers/color/colorIsDark.ts
index 3ae8ff286c..5548dab99f 100644
--- a/src/helpers/color/colorIsDark.ts
+++ b/src/helpers/color/colorIsDark.ts
@@ -1,4 +1,4 @@
-export function colorIsDark(color) {
+export function colorIsDark(color: string | undefined) {
if (typeof color === 'undefined') {
return true // Defaults to dark
}
diff --git a/src/helpers/getHumanSize.ts b/src/helpers/getHumanSize.ts
new file mode 100644
index 0000000000..2744e1eb06
--- /dev/null
+++ b/src/helpers/getHumanSize.ts
@@ -0,0 +1,18 @@
+const SIZES = [
+ 'B',
+ 'KB',
+ 'MB',
+ 'GB',
+ 'TB',
+ ] as const
+
+export function getHumanSize(inputSize: number) {
+ let iterator = 0
+ let size = inputSize
+ while (size > 1024) {
+ size /= 1024
+ iterator++
+ }
+
+ return Number(Math.round(Number(size + 'e2')) + 'e-2') + ' ' + SIZES[iterator]
+}
\ No newline at end of file
diff --git a/src/modelSchema/common/repeats.ts b/src/modelSchema/common/repeats.ts
new file mode 100644
index 0000000000..175b0c7277
--- /dev/null
+++ b/src/modelSchema/common/repeats.ts
@@ -0,0 +1,43 @@
+import { REPEAT_TYPES, type IRepeatAfter } from '@/types/IRepeatAfter'
+import { nativeEnum, number, object, preprocess } from 'zod'
+
+export const RepeatsSchema = preprocess(
+ (repeats: unknown) => {
+ // Parses the "repeat after x seconds" from the task into a usable js object inside the task.
+
+ if (typeof repeats !== 'number') {
+ return repeats
+ }
+
+ const repeatAfterHours = (repeats / 60) / 60
+
+ const repeatAfter : IRepeatAfter = {
+ type: 'hours',
+ amount: repeatAfterHours,
+ }
+
+ // if its dividable by 24, its something with days, otherwise hours
+ if (repeatAfterHours % 24 === 0) {
+ const repeatAfterDays = repeatAfterHours / 24
+ if (repeatAfterDays % 7 === 0) {
+ repeatAfter.type = 'weeks'
+ repeatAfter.amount = repeatAfterDays / 7
+ } else if (repeatAfterDays % 30 === 0) {
+ repeatAfter.type = 'months'
+ repeatAfter.amount = repeatAfterDays / 30
+ } else if (repeatAfterDays % 365 === 0) {
+ repeatAfter.type = 'years'
+ repeatAfter.amount = repeatAfterDays / 365
+ } else {
+ repeatAfter.type = 'days'
+ repeatAfter.amount = repeatAfterDays
+ }
+ }
+
+ return repeatAfter
+ },
+ object({
+ type: nativeEnum(REPEAT_TYPES),
+ amount: number().int(),
+ }),
+)
\ No newline at end of file
diff --git a/src/modelTypes/IAbstract.ts b/src/modelTypes/IAbstract.ts
new file mode 100644
index 0000000000..7ca1142d61
--- /dev/null
+++ b/src/modelTypes/IAbstract.ts
@@ -0,0 +1,5 @@
+import type {Right} from '@/constants/rights'
+
+export interface IAbstract {
+ maxRight: Right | null // FIXME: should this be readonly?
+}
\ No newline at end of file
diff --git a/src/modelTypes/IAttachment.ts b/src/modelTypes/IAttachment.ts
new file mode 100644
index 0000000000..b1b279b611
--- /dev/null
+++ b/src/modelTypes/IAttachment.ts
@@ -0,0 +1,11 @@
+import type {IAbstract} from './IAbstract'
+import type {IFile} from './IFile'
+import type {IUser} from './IUser'
+
+export interface IAttachment extends IAbstract {
+ id: number
+ taskId: number
+ createdBy: IUser
+ file: IFile
+ created: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/IAvatar.ts b/src/modelTypes/IAvatar.ts
new file mode 100644
index 0000000000..ab681996a0
--- /dev/null
+++ b/src/modelTypes/IAvatar.ts
@@ -0,0 +1,7 @@
+import type {IAbstract} from './IAbstract'
+
+export type AvatarProvider = 'default' | 'initials' | 'gravatar' | 'marble' | 'upload'
+
+export interface IAvatar extends IAbstract {
+ avatarProvider: AvatarProvider
+}
\ No newline at end of file
diff --git a/src/modelTypes/IBackgroundImage.ts b/src/modelTypes/IBackgroundImage.ts
new file mode 100644
index 0000000000..311d7bc726
--- /dev/null
+++ b/src/modelTypes/IBackgroundImage.ts
@@ -0,0 +1,12 @@
+import type {IAbstract} from './IAbstract'
+
+export interface IBackgroundImage extends IAbstract {
+ id: number
+ url: string
+ thumb: string
+ info: {
+ author: string
+ authorName: string
+ }
+ blurHash: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/IBucket.ts b/src/modelTypes/IBucket.ts
new file mode 100644
index 0000000000..e4c2c56856
--- /dev/null
+++ b/src/modelTypes/IBucket.ts
@@ -0,0 +1,17 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ITask} from './ITask'
+
+export interface IBucket extends IAbstract {
+ id: number
+ title: string
+ listId: number
+ limit: number
+ tasks: ITask[]
+ isDoneBucket: boolean
+ position: number
+
+ createdBy: IUser
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ICaldavToken.ts b/src/modelTypes/ICaldavToken.ts
new file mode 100644
index 0000000000..d7e1e68d59
--- /dev/null
+++ b/src/modelTypes/ICaldavToken.ts
@@ -0,0 +1,7 @@
+import type {IAbstract} from './IAbstract'
+
+export interface ICaldavToken extends IAbstract {
+ id: number;
+
+ created: Date;
+}
\ No newline at end of file
diff --git a/src/modelTypes/IEmailUpdate.ts b/src/modelTypes/IEmailUpdate.ts
new file mode 100644
index 0000000000..fbb39c1b93
--- /dev/null
+++ b/src/modelTypes/IEmailUpdate.ts
@@ -0,0 +1,6 @@
+import type {IAbstract} from './IAbstract'
+
+export interface IEmailUpdate extends IAbstract {
+ newEmail: string
+ password: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/IFile.ts b/src/modelTypes/IFile.ts
new file mode 100644
index 0000000000..70ae387395
--- /dev/null
+++ b/src/modelTypes/IFile.ts
@@ -0,0 +1,10 @@
+import type {IAbstract} from './IAbstract'
+
+export interface IFile extends IAbstract {
+ id: number
+ mime: string
+ name: string
+ size: number
+
+ created: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ILabel.ts b/src/modelTypes/ILabel.ts
new file mode 100644
index 0000000000..c7cbe778b6
--- /dev/null
+++ b/src/modelTypes/ILabel.ts
@@ -0,0 +1,15 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+
+export interface ILabel extends IAbstract {
+ id: number
+ title: string
+ hexColor: string
+ description: string
+ createdBy: IUser
+ listId: number
+ textColor: string
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ILabelTask.ts b/src/modelTypes/ILabelTask.ts
new file mode 100644
index 0000000000..dcc2acefed
--- /dev/null
+++ b/src/modelTypes/ILabelTask.ts
@@ -0,0 +1,7 @@
+import type {IAbstract} from './IAbstract'
+
+export interface ILabelTask extends IAbstract {
+ id: number
+ taskId: number
+ labelId: number
+}
\ No newline at end of file
diff --git a/src/modelTypes/ILinkShare.ts b/src/modelTypes/ILinkShare.ts
new file mode 100644
index 0000000000..d5eacb2412
--- /dev/null
+++ b/src/modelTypes/ILinkShare.ts
@@ -0,0 +1,17 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type { Right } from '@/constants/rights'
+
+export interface ILinkShare extends IAbstract {
+ id: number
+ hash: string
+ right: Right
+ sharedBy: IUser
+ sharingType: number // FIXME: use correct numbers
+ listId: number
+ name: string
+ password: string
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/IList.ts b/src/modelTypes/IList.ts
new file mode 100644
index 0000000000..c51633b527
--- /dev/null
+++ b/src/modelTypes/IList.ts
@@ -0,0 +1,26 @@
+import type {IAbstract} from './IAbstract'
+import type {ITask} from './ITask'
+import type {IUser} from './IUser'
+import type {ISubscription} from './ISubscription'
+import type {INamespace} from './INamespace'
+
+
+export interface IList extends IAbstract {
+ id: number
+ title: string
+ description: string
+ owner: IUser
+ tasks: ITask[]
+ namespaceId: INamespace['id']
+ isArchived: boolean
+ hexColor: string
+ identifier: string
+ backgroundInformation: any // FIXME: improve type
+ isFavorite: boolean
+ subscription: ISubscription
+ position: number
+ backgroundBlurHash: string
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/IListDuplicate.ts b/src/modelTypes/IListDuplicate.ts
new file mode 100644
index 0000000000..bdd924e345
--- /dev/null
+++ b/src/modelTypes/IListDuplicate.ts
@@ -0,0 +1,9 @@
+import type {IAbstract} from './IAbstract'
+import type {IList} from './IList'
+import type {INamespace} from './INamespace'
+
+export interface IListDuplicate extends IAbstract {
+ listId: number
+ namespaceId: INamespace['id']
+ list: IList
+}
\ No newline at end of file
diff --git a/src/modelTypes/INamespace.ts b/src/modelTypes/INamespace.ts
new file mode 100644
index 0000000000..95ee4700a6
--- /dev/null
+++ b/src/modelTypes/INamespace.ts
@@ -0,0 +1,18 @@
+import type {IAbstract} from './IAbstract'
+import type {IList} from './IList'
+import type {IUser} from './IUser'
+import type {ISubscription} from './ISubscription'
+
+export interface INamespace extends IAbstract {
+ id: number
+ title: string
+ description: string
+ owner: IUser
+ lists: IList[]
+ isArchived: boolean
+ hexColor: string
+ subscription: ISubscription
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/INotification.ts b/src/modelTypes/INotification.ts
new file mode 100644
index 0000000000..52d6dc2a9a
--- /dev/null
+++ b/src/modelTypes/INotification.ts
@@ -0,0 +1,51 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ITask} from './ITask'
+import type {ITaskComment} from './ITaskComment'
+import type {ITeam} from './ITeam'
+import type { IList } from './IList'
+
+export const NOTIFICATION_NAMES = {
+ 'TASK_COMMENT': 'task.comment',
+ 'TASK_ASSIGNED': 'task.assigned',
+ 'TASK_DELETED': 'task.deleted',
+ 'LIST_CREATED': 'list.created',
+ 'TEAM_MEMBER_ADDED': 'team.member.added',
+} as const
+
+interface Notification {
+ doer: IUser
+}
+interface NotificationTask extends Notification {
+ task: ITask
+ comment: ITaskComment
+}
+
+interface NotificationAssigned extends Notification {
+ task: ITask
+ assignee: IUser
+}
+
+interface NotificationDeleted extends Notification {
+ task: ITask
+}
+
+interface NotificationCreated extends Notification {
+ task: ITask
+ list: IList
+}
+
+interface NotificationMemberAdded extends Notification {
+ member: IUser
+ team: ITeam
+}
+
+export interface INotification extends IAbstract {
+ id: number
+ name: string
+ notification: NotificationTask | NotificationAssigned | NotificationDeleted | NotificationCreated | NotificationMemberAdded
+ read: boolean
+ readAt: Date | null
+
+ created: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/IPasswordReset.ts b/src/modelTypes/IPasswordReset.ts
new file mode 100644
index 0000000000..0b3d679ad4
--- /dev/null
+++ b/src/modelTypes/IPasswordReset.ts
@@ -0,0 +1,7 @@
+import type {IAbstract} from './IAbstract'
+
+export interface IPasswordReset extends IAbstract {
+ token: string
+ newPassword: string
+ email: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/IPasswordUpdate.ts b/src/modelTypes/IPasswordUpdate.ts
new file mode 100644
index 0000000000..003b43b8d4
--- /dev/null
+++ b/src/modelTypes/IPasswordUpdate.ts
@@ -0,0 +1,6 @@
+import type {IAbstract} from './IAbstract'
+
+export interface IPasswordUpdate extends IAbstract {
+ newPassword: string
+ oldPassword: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/ISavedFilter.ts b/src/modelTypes/ISavedFilter.ts
new file mode 100644
index 0000000000..5f206efa9d
--- /dev/null
+++ b/src/modelTypes/ISavedFilter.ts
@@ -0,0 +1,14 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {IFilter} from '@/types/IFilter'
+
+export interface ISavedFilter extends IAbstract {
+ id: number
+ title: string
+ description: string
+ filters: IFilter
+
+ owner: IUser
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ISubscription.ts b/src/modelTypes/ISubscription.ts
new file mode 100644
index 0000000000..51dbfbcfbe
--- /dev/null
+++ b/src/modelTypes/ISubscription.ts
@@ -0,0 +1,11 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+
+export interface ISubscription extends IAbstract {
+ id: number
+ entity: string // FIXME: correct type?
+ entityId: number // FIXME: correct type?
+ user: IUser
+
+ created: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITask.ts b/src/modelTypes/ITask.ts
new file mode 100644
index 0000000000..86bae8c2a3
--- /dev/null
+++ b/src/modelTypes/ITask.ts
@@ -0,0 +1,50 @@
+import type { Priority } from '@/constants/priorities'
+
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ILabel} from './ILabel'
+import type {IAttachment} from './IAttachment'
+import type {ISubscription} from './ISubscription'
+import type {IList} from './IList'
+import type {IBucket} from './IBucket'
+
+import type {IRelationKind} from '@/types/IRelationKind'
+import type {IRepeatAfter} from '@/types/IRepeatAfter'
+import type {IRepeatMode} from '@/types/IRepeatMode'
+export interface ITask extends IAbstract {
+ id: number
+ title: string
+ description: string
+ done: boolean
+ doneAt: Date | null
+ priority: Priority
+ labels: ILabel[]
+ assignees: IUser[]
+
+ dueDate: Date | null
+ startDate: Date | null
+ endDate: Date | null
+ repeatAfter: number | IRepeatAfter
+ repeatFromCurrentDate: boolean
+ repeatMode: IRepeatMode
+ reminderDates: Date[]
+ parentTaskId: ITask['id']
+ hexColor: string
+ percentDone: number
+ relatedTasks: Partial>,
+ attachments: IAttachment[]
+ identifier: string
+ index: number
+ isFavorite: boolean
+ subscription: ISubscription
+
+ position: number
+ kanbanPosition: number
+
+ createdBy: IUser
+ created: Date
+ updated: Date
+
+ listId: IList['id'] // Meta, only used when creating a new task
+ bucketId: IBucket['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITaskAssignee.ts b/src/modelTypes/ITaskAssignee.ts
new file mode 100644
index 0000000000..a508e4b866
--- /dev/null
+++ b/src/modelTypes/ITaskAssignee.ts
@@ -0,0 +1,9 @@
+import type {IAbstract} from './IAbstract'
+import type {ITask} from './ITask'
+import type {IUser} from './IUser'
+
+export interface ITaskAssignee extends IAbstract {
+ created: Date
+ userId: IUser['id']
+ taskId: ITask['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITaskComment.ts b/src/modelTypes/ITaskComment.ts
new file mode 100644
index 0000000000..4246ab13dc
--- /dev/null
+++ b/src/modelTypes/ITaskComment.ts
@@ -0,0 +1,13 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ITask} from './ITask'
+
+export interface ITaskComment extends IAbstract {
+ id: number
+ taskId: ITask['id']
+ comment: string
+ author: IUser
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITaskRelation.ts b/src/modelTypes/ITaskRelation.ts
new file mode 100644
index 0000000000..df286f5c00
--- /dev/null
+++ b/src/modelTypes/ITaskRelation.ts
@@ -0,0 +1,15 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ITask} from './ITask'
+
+import type {IRelationKind} from '@/types/IRelationKind'
+
+export interface ITaskRelation extends IAbstract {
+ id: number
+ otherTaskId: ITask['id']
+ taskId: ITask['id']
+ relationKind: IRelationKind
+
+ createdBy: IUser
+ created: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITeam.ts b/src/modelTypes/ITeam.ts
new file mode 100644
index 0000000000..cd5a7dc731
--- /dev/null
+++ b/src/modelTypes/ITeam.ts
@@ -0,0 +1,16 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {ITeamMember} from './ITeamMember'
+import type {Right} from '@/constants/rights'
+
+export interface ITeam extends IAbstract {
+ id: number
+ name: string
+ description: string
+ members: ITeamMember[]
+ right: Right
+
+ createdBy: IUser
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITeamList.ts b/src/modelTypes/ITeamList.ts
new file mode 100644
index 0000000000..a1abd692d0
--- /dev/null
+++ b/src/modelTypes/ITeamList.ts
@@ -0,0 +1,6 @@
+import type {ITeamShareBase} from './ITeamShareBase'
+import type {IList} from './IList'
+
+export interface ITeamList extends ITeamShareBase {
+ listId: IList['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITeamMember.ts b/src/modelTypes/ITeamMember.ts
new file mode 100644
index 0000000000..62a1d91ba2
--- /dev/null
+++ b/src/modelTypes/ITeamMember.ts
@@ -0,0 +1,7 @@
+import type {IUser} from './IUser'
+import type {IList} from './IList'
+
+export interface ITeamMember extends IUser {
+ admin: boolean
+ teamId: IList['id']
+}
diff --git a/src/modelTypes/ITeamNamespace.ts b/src/modelTypes/ITeamNamespace.ts
new file mode 100644
index 0000000000..e66a98bb68
--- /dev/null
+++ b/src/modelTypes/ITeamNamespace.ts
@@ -0,0 +1,6 @@
+import type {ITeamShareBase} from './ITeamShareBase'
+import type {INamespace} from './INamespace'
+
+export interface ITeamNamespace extends ITeamShareBase {
+ namespaceId: INamespace['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITeamShareBase.ts b/src/modelTypes/ITeamShareBase.ts
new file mode 100644
index 0000000000..793b88945f
--- /dev/null
+++ b/src/modelTypes/ITeamShareBase.ts
@@ -0,0 +1,11 @@
+import type {IAbstract} from './IAbstract'
+import type {ITeam} from './ITeam'
+import type {Right} from '@/constants/rights'
+
+export interface ITeamShareBase extends IAbstract {
+ teamId: ITeam['id']
+ right: Right
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/modelTypes/ITotp.ts b/src/modelTypes/ITotp.ts
new file mode 100644
index 0000000000..8c2147bba1
--- /dev/null
+++ b/src/modelTypes/ITotp.ts
@@ -0,0 +1,7 @@
+import type {IAbstract} from './IAbstract'
+
+export interface ITotp extends IAbstract {
+ secret: string
+ enabled: boolean
+ url: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/IUser.ts b/src/modelTypes/IUser.ts
new file mode 100644
index 0000000000..d2ee19ea82
--- /dev/null
+++ b/src/modelTypes/IUser.ts
@@ -0,0 +1,13 @@
+import type {IAbstract} from './IAbstract'
+import type {IUserSettings} from './IUserSettings'
+
+export interface IUser extends IAbstract {
+ id: number
+ email: string
+ username: string
+ name: string
+
+ created: Date
+ updated: Date
+ settings: IUserSettings
+}
\ No newline at end of file
diff --git a/src/modelTypes/IUserList.ts b/src/modelTypes/IUserList.ts
new file mode 100644
index 0000000000..20787db7ff
--- /dev/null
+++ b/src/modelTypes/IUserList.ts
@@ -0,0 +1,6 @@
+import type {IUserShareBase} from './IUserShareBase'
+import type {IList} from './IList'
+
+export interface IUserList extends IUserShareBase {
+ listId: IList['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/IUserNamespace.ts b/src/modelTypes/IUserNamespace.ts
new file mode 100644
index 0000000000..e2bd1b468e
--- /dev/null
+++ b/src/modelTypes/IUserNamespace.ts
@@ -0,0 +1,6 @@
+import type {IUserShareBase} from './IUserShareBase'
+import type {INamespace} from './INamespace'
+
+export interface IUserNamespace extends IUserShareBase {
+ namespaceId: INamespace['id']
+}
\ No newline at end of file
diff --git a/src/modelTypes/IUserSettings.ts b/src/modelTypes/IUserSettings.ts
new file mode 100644
index 0000000000..9550e1e676
--- /dev/null
+++ b/src/modelTypes/IUserSettings.ts
@@ -0,0 +1,14 @@
+
+import type {IAbstract} from './IAbstract'
+import type {IList} from './IList'
+
+export interface IUserSettings extends IAbstract {
+ name: string
+ emailRemindersEnabled: boolean
+ discoverableByName: boolean
+ discoverableByEmail: boolean
+ overdueTasksRemindersEnabled: boolean
+ defaultListId: undefined | IList['id']
+ weekStart: 0 | 1 | 2 | 3 | 4 | 5 | 6
+ timezone: string
+}
\ No newline at end of file
diff --git a/src/modelTypes/IUserShareBase.ts b/src/modelTypes/IUserShareBase.ts
new file mode 100644
index 0000000000..cc23a2be00
--- /dev/null
+++ b/src/modelTypes/IUserShareBase.ts
@@ -0,0 +1,11 @@
+import type {IAbstract} from './IAbstract'
+import type {IUser} from './IUser'
+import type {Right} from '@/constants/rights'
+
+export interface IUserShareBase extends IAbstract {
+ userId: IUser['id']
+ right: Right
+
+ created: Date
+ updated: Date
+}
\ No newline at end of file
diff --git a/src/models/abstractModel.ts b/src/models/abstractModel.ts
index f859c361da..8e0605e525 100644
--- a/src/models/abstractModel.ts
+++ b/src/models/abstractModel.ts
@@ -1,13 +1,11 @@
import {objectToCamelCase} from '@/helpers/case'
import {omitBy, isNil} from '@/helpers/utils'
import type {Right} from '@/constants/rights'
-
-export interface IAbstract {
- maxRight: Right | null // FIXME: should this be readonly?
-}
+import type {IAbstract} from '@/modelTypes/IAbstract'
export default abstract class AbstractModel implements IAbstract {
+
/**
* The max right the user has on this object, as returned by the x-max-right header from the api.
*/
diff --git a/src/models/attachment.ts b/src/models/attachment.ts
index 074d61b658..694609725b 100644
--- a/src/models/attachment.ts
+++ b/src/models/attachment.ts
@@ -1,14 +1,9 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, {type IUser} from './user'
-import FileModel, {type IFile} from './file'
-
-export interface IAttachment extends IAbstract {
- id: number
- taskId: number
- createdBy: IUser
- file: IFile
- created: Date
-}
+import AbstractModel from './abstractModel'
+import UserModel from './user'
+import FileModel from './file'
+import type { IUser } from '@/modelTypes/IUser'
+import type { IFile } from '@/modelTypes/IFile'
+import type { IAttachment } from '@/modelTypes/IAttachment'
export default class AttachmentModel extends AbstractModel implements IAttachment {
id = 0
diff --git a/src/models/avatar.ts b/src/models/avatar.ts
index daf221c0af..06f484fce3 100644
--- a/src/models/avatar.ts
+++ b/src/models/avatar.ts
@@ -1,13 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-
-export type AvatarProvider = 'default' | 'initials' | 'gravatar' | 'marble' | 'upload'
-
-export interface IAvatar extends IAbstract {
- avatarProvider: AvatarProvider
-}
+import AbstractModel from './abstractModel'
+import type { IAvatar } from '@/modelTypes/IAvatar'
export default class AvatarModel extends AbstractModel implements IAvatar {
- avatarProvider: AvatarProvider = 'default'
+ avatarProvider: IAvatar['avatarProvider'] = 'default'
constructor(data: Partial) {
super()
diff --git a/src/models/backgroundImage.ts b/src/models/backgroundImage.ts
index 137c83836e..8c1a213411 100644
--- a/src/models/backgroundImage.ts
+++ b/src/models/backgroundImage.ts
@@ -1,15 +1,5 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-
-export interface IBackgroundImage extends IAbstract {
- id: number
- url: string
- thumb: string
- info: {
- author: string
- authorName: string
- }
- blurHash: string
-}
+import AbstractModel from './abstractModel'
+import type {IBackgroundImage} from '@/modelTypes/IBackgroundImage'
export default class BackgroundImageModel extends AbstractModel implements IBackgroundImage {
id = 0
diff --git a/src/models/bucket.ts b/src/models/bucket.ts
index 94f6c2d08d..3394583c40 100644
--- a/src/models/bucket.ts
+++ b/src/models/bucket.ts
@@ -1,20 +1,10 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
-import TaskModel, { type ITask } from './task'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
+import TaskModel from './task'
-export interface IBucket extends IAbstract {
- id: number
- title: string
- listId: number
- limit: number
- tasks: ITask[]
- isDoneBucket: boolean
- position: number
-
- createdBy: IUser
- created: Date
- updated: Date
-}
+import type {IBucket} from '@/modelTypes/IBucket'
+import type {ITask} from '@/modelTypes/ITask'
+import type {IUser} from '@/modelTypes/IUser'
export default class BucketModel extends AbstractModel implements IBucket {
id = 0
diff --git a/src/models/caldavToken.ts b/src/models/caldavToken.ts
index 4a4d4c4daf..bc904c4772 100644
--- a/src/models/caldavToken.ts
+++ b/src/models/caldavToken.ts
@@ -1,15 +1,12 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
-export interface ICaldavToken extends IAbstract {
- id: number;
- created: Date;
-}
+import type {ICaldavToken} from '@/modelTypes/ICaldavToken'
export default class CaldavTokenModel extends AbstractModel implements ICaldavToken {
id: number
created: Date
- constructor(data? : Partial) {
+ constructor(data: Partial) {
super()
this.assignData(data)
diff --git a/src/models/emailUpdate.ts b/src/models/emailUpdate.ts
index 2f8c9a853c..aece407f11 100644
--- a/src/models/emailUpdate.ts
+++ b/src/models/emailUpdate.ts
@@ -1,9 +1,6 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
-interface IEmailUpdate extends IAbstract {
- newEmail: string
- password: string
-}
+import type {IEmailUpdate} from '@/modelTypes/IEmailUpdate'
export default class EmailUpdateModel extends AbstractModel implements IEmailUpdate {
newEmail = ''
diff --git a/src/models/file.ts b/src/models/file.ts
index ba5950c7b2..cb17d51514 100644
--- a/src/models/file.ts
+++ b/src/models/file.ts
@@ -1,12 +1,5 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-
-export interface IFile extends IAbstract {
- id: number
- mime: string
- name: string
- size: number
- created: Date
-}
+import AbstractModel from './abstractModel'
+import type {IFile} from '@/modelTypes/IFile'
export default class FileModel extends AbstractModel implements IFile {
id = 0
@@ -21,23 +14,4 @@ export default class FileModel extends AbstractModel implements IFile {
this.created = new Date(this.created)
}
-
- getHumanSize() {
- const sizes = {
- 0: 'B',
- 1: 'KB',
- 2: 'MB',
- 3: 'GB',
- 4: 'TB',
- }
-
- let it = 0
- let size = this.size
- while (size > 1024) {
- size /= 1024
- it++
- }
-
- return Number(Math.round(size + 'e2') + 'e-2') + ' ' + sizes[it]
- }
}
diff --git a/src/models/label.ts b/src/models/label.ts
index 5b3659b70b..1e14cf8209 100644
--- a/src/models/label.ts
+++ b/src/models/label.ts
@@ -1,22 +1,13 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
+
+import type {ILabel} from '@/modelTypes/ILabel'
+import type {IUser} from '@/modelTypes/IUser'
+
import {colorIsDark} from '@/helpers/color/colorIsDark'
const DEFAULT_LABEL_BACKGROUND_COLOR = 'e8e8e8'
-export interface ILabel extends IAbstract {
- id: number
- title: string
- hexColor: string
- description: string
- createdBy: IUser
- listId: number
- textColor: string
-
- created: Date
- updated: Date
-}
-
export default class LabelModel extends AbstractModel implements ILabel {
id = 0
title = ''
diff --git a/src/models/labelTask.ts b/src/models/labelTask.ts
index 8223edb4f2..b1e068224a 100644
--- a/src/models/labelTask.ts
+++ b/src/models/labelTask.ts
@@ -1,10 +1,6 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
-export interface ILabelTask extends IAbstract {
- id: number
- taskId: number
- labelId: number
-}
+import type { ILabelTask } from '@/modelTypes/ILabelTask'
export default class LabelTask extends AbstractModel implements ILabelTask {
id = 0
diff --git a/src/models/linkShare.ts b/src/models/linkShare.ts
index c7df693b0d..24aa8779cc 100644
--- a/src/models/linkShare.ts
+++ b/src/models/linkShare.ts
@@ -1,19 +1,9 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
-import {RIGHTS, type Right} from '@/constants/rights'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
-export interface ILinkShare extends IAbstract {
- id: number
- hash: string
- right: Right
- sharedBy: IUser
- sharingType: number // FIXME: use correct numbers
- listId: number
- name: string
- password: string
- created: Date
- updated: Date
-}
+import {RIGHTS, type Right} from '@/constants/rights'
+import type {ILinkShare} from '@/modelTypes/ILinkShare'
+import type {IUser} from '@/modelTypes/IUser'
export default class LinkShareModel extends AbstractModel implements ILinkShare {
id = 0
diff --git a/src/models/list.ts b/src/models/list.ts
index 7ef058c452..02387f18e9 100644
--- a/src/models/list.ts
+++ b/src/models/list.ts
@@ -1,31 +1,16 @@
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
-import TaskModel, { type ITask } from '@/models/task'
-import UserModel, { type IUser } from '@/models/user'
-import SubscriptionModel, { type ISubscription } from '@/models/subscription'
-import type { INamespace } from '@/models/namespace'
+import AbstractModel from './abstractModel'
+import TaskModel from '@/models/task'
+import UserModel from '@/models/user'
+import SubscriptionModel from '@/models/subscription'
+
+import type {IList} from '@/modelTypes/IList'
+import type {IUser} from '@/modelTypes/IUser'
+import type {ITask} from '@/modelTypes/ITask'
+import type {INamespace} from '@/modelTypes/INamespace'
+import type {ISubscription} from '@/modelTypes/ISubscription'
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
-export interface IList extends IAbstract {
- id: number
- title: string
- description: string
- owner: IUser
- tasks: ITask[]
- namespaceId: INamespace['id']
- isArchived: boolean
- hexColor: string
- identifier: string
- backgroundInformation: any // FIXME: improve type
- isFavorite: boolean
- subscription: ISubscription
- position: number
- backgroundBlurHash: string
-
- created: Date
- updated: Date
-}
-
export default class ListModel extends AbstractModel implements IList {
id = 0
title = ''
diff --git a/src/models/listDuplicateModel.ts b/src/models/listDuplicateModel.ts
index 4d8faf1f4c..8ed2ae74d5 100644
--- a/src/models/listDuplicateModel.ts
+++ b/src/models/listDuplicateModel.ts
@@ -1,12 +1,9 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import ListModel, { type IList } from './list'
-import type { INamespace } from './namespace'
+import AbstractModel from './abstractModel'
+import ListModel from './list'
-export interface IListDuplicate extends IAbstract {
- listId: number
- namespaceId: INamespace['id']
- list: IList
-}
+import type {IListDuplicate} from '@/modelTypes/IListDuplicate'
+import type {INamespace} from '@/modelTypes/INamespace'
+import type {IList} from '@/modelTypes/IList'
export default class ListDuplicateModel extends AbstractModel implements IListDuplicate {
listId = 0
diff --git a/src/models/namespace.ts b/src/models/namespace.ts
index f1962f1aff..dade605e8a 100644
--- a/src/models/namespace.ts
+++ b/src/models/namespace.ts
@@ -1,21 +1,12 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import ListModel, { type IList } from './list'
-import UserModel, { type IUser } from './user'
-import SubscriptionModel, { type ISubscription } from '@/models/subscription'
+import AbstractModel from './abstractModel'
+import ListModel from './list'
+import UserModel from './user'
+import SubscriptionModel from '@/models/subscription'
-export interface INamespace extends IAbstract {
- id: number
- title: string
- description: string
- owner: IUser
- lists: IList[]
- isArchived: boolean
- hexColor: string
- subscription: ISubscription
-
- created: Date
- updated: Date
-}
+import type {INamespace} from '@/modelTypes/INamespace'
+import type {IUser} from '@/modelTypes/IUser'
+import type {IList} from '@/modelTypes/IList'
+import type {ISubscription} from '@/modelTypes/ISubscription'
export default class NamespaceModel extends AbstractModel implements INamespace {
id = 0
diff --git a/src/models/notification.ts b/src/models/notification.ts
index bd9c872761..a1fc44ad57 100644
--- a/src/models/notification.ts
+++ b/src/models/notification.ts
@@ -1,60 +1,17 @@
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
+import AbstractModel from './abstractModel'
import {parseDateOrNull} from '@/helpers/parseDateOrNull'
-import UserModel, { type IUser } from '@/models/user'
-import TaskModel, { type ITask } from '@/models/task'
-import TaskCommentModel, { type ITaskComment } from '@/models/taskComment'
-import ListModel, { type IList } from '@/models/list'
-import TeamModel, { type ITeam } from '@/models/team'
+import UserModel from '@/models/user'
+import TaskModel from '@/models/task'
+import TaskCommentModel from '@/models/taskComment'
+import ListModel from '@/models/list'
+import TeamModel from '@/models/team'
-export const NOTIFICATION_NAMES = {
- 'TASK_COMMENT': 'task.comment',
- 'TASK_ASSIGNED': 'task.assigned',
- 'TASK_DELETED': 'task.deleted',
- 'LIST_CREATED': 'list.created',
- 'TEAM_MEMBER_ADDED': 'team.member.added',
-} as const
-
-interface Notification {
- doer: IUser
-}
-interface NotificationTask extends Notification {
- task: ITask
- comment: ITaskComment
-}
-
-interface NotificationAssigned extends Notification {
- task: ITask
- assignee: IUser
-}
-
-interface NotificationDeleted extends Notification {
- task: ITask
-}
-
-interface NotificationCreated extends Notification {
- task: ITask
- list: IList
-}
-
-interface NotificationMemberAdded extends Notification {
- member: IUser
- team: ITeam
-}
-
-export interface INotification extends IAbstract {
- id: number
- name: string
- notification: NotificationTask | NotificationAssigned | NotificationDeleted | NotificationCreated | NotificationMemberAdded
- read: boolean
- readAt: Date | null
-
- created: Date
-}
+import {NOTIFICATION_NAMES, type INotification} from '@/modelTypes/INotification'
export default class NotificationModel extends AbstractModel implements INotification {
id = 0
name = ''
- notification: NotificationTask | NotificationAssigned | NotificationDeleted | NotificationCreated | NotificationMemberAdded = null
+ notification: INotification['notification'] = null
read = false
readAt: Date | null = null
diff --git a/src/models/passwordReset.ts b/src/models/passwordReset.ts
index e982f7cd73..5140063f81 100644
--- a/src/models/passwordReset.ts
+++ b/src/models/passwordReset.ts
@@ -1,10 +1,6 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
-export interface IPasswordReset extends IAbstract {
- token: string
- newPassword: string
- email: string
-}
+import type {IPasswordReset} from '@/modelTypes/IPasswordReset'
export default class PasswordResetModel extends AbstractModel implements IPasswordReset {
token = ''
diff --git a/src/models/passwordUpdate.ts b/src/models/passwordUpdate.ts
index 1548ccb9b0..702fcd50fd 100644
--- a/src/models/passwordUpdate.ts
+++ b/src/models/passwordUpdate.ts
@@ -1,9 +1,6 @@
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
+import AbstractModel from './abstractModel'
-export interface IPasswordUpdate extends IAbstract {
- newPassword: string
- oldPassword: string
-}
+import type {IPasswordUpdate} from '@/modelTypes/IPasswordUpdate'
export default class PasswordUpdateModel extends AbstractModel implements IPasswordUpdate {
newPassword = ''
diff --git a/src/models/savedFilter.ts b/src/models/savedFilter.ts
index 8749d03594..c432014ffe 100644
--- a/src/models/savedFilter.ts
+++ b/src/models/savedFilter.ts
@@ -1,38 +1,14 @@
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
-import UserModel, { type IUser } from '@/models/user'
+import AbstractModel from './abstractModel'
+import UserModel from '@/models/user'
-export interface ISavedFilter extends IAbstract {
- id: number
- title: string
- description: string
- filters: {
- sortBy: ('done' | 'id')[]
- orderBy: ('asc' | 'desc')[]
- filterBy: 'done'[]
- filterValue: 'false'[]
- filterComparator: 'equals'[]
- filterConcat: 'and'
- filterIncludeNulls: boolean
- }
-
- owner: IUser
- created: Date
- updated: Date
-}
+import type {ISavedFilter} from '@/modelTypes/ISavedFilter'
+import type {IUser} from '@/modelTypes/IUser'
export default class SavedFilterModel extends AbstractModel implements ISavedFilter {
id = 0
title = ''
description = ''
- filters: {
- sortBy: ('done' | 'id')[]
- orderBy: ('asc' | 'desc')[]
- filterBy: 'done'[]
- filterValue: 'false'[]
- filterComparator: 'equals'[]
- filterConcat: 'and'
- filterIncludeNulls: boolean
- } = {
+ filters: ISavedFilter['filters'] = {
sortBy: ['done', 'id'],
orderBy: ['asc', 'desc'],
filterBy: ['done'],
diff --git a/src/models/subscription.ts b/src/models/subscription.ts
index 3ae79dd2e2..77ae3dec81 100644
--- a/src/models/subscription.ts
+++ b/src/models/subscription.ts
@@ -1,14 +1,8 @@
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
-import UserModel, { type IUser } from '@/models/user'
+import AbstractModel from './abstractModel'
+import UserModel from '@/models/user'
-export interface ISubscription extends IAbstract {
- id: number
- entity: string // FIXME: correct type?
- entityId: number // FIXME: correct type?
- user: IUser
-
- created: Date
-}
+import type {ISubscription} from '@/modelTypes/ISubscription'
+import type {IUser} from '@/modelTypes/IUser'
export default class SubscriptionModel extends AbstractModel implements ISubscription {
id = 0
diff --git a/src/models/task.ts b/src/models/task.ts
index e3c03b13d5..e8dafdf1c2 100644
--- a/src/models/task.ts
+++ b/src/models/task.ts
@@ -1,63 +1,35 @@
+
import { PRIORITIES, type Priority } from '@/constants/priorities'
-import AbstractModel, { type IAbstract } from '@/models/abstractModel'
-import UserModel, { type IUser } from '@/models/user'
-import LabelModel, { type ILabel } from '@/models/label'
-import AttachmentModel, {type IAttachment} from '@/models/attachment'
-import SubscriptionModel, { type ISubscription } from '@/models/subscription'
-import type { IList } from '@/models/list'
-import type {IRepeats} from '@/types/IRepeats'
+import type {ITask} from '@/modelTypes/ITask'
+import type {ILabel} from '@/modelTypes/ILabel'
+import type {IUser} from '@/modelTypes/IUser'
+import type {IAttachment} from '@/modelTypes/IAttachment'
+import type {IList} from '@/modelTypes/IList'
+import type {ISubscription} from '@/modelTypes/ISubscription'
+import type {IBucket} from '@/modelTypes/IBucket'
+
+import type {IRepeatAfter} from '@/types/IRepeatAfter'
+import {TASK_REPEAT_MODES, type IRepeatMode} from '@/types/IRepeatMode'
import {parseDateOrNull} from '@/helpers/parseDateOrNull'
-import type { IBucket } from './bucket'
+import type { IRelationKind } from '@/types/IRelationKind'
+
+import AbstractModel from './abstractModel'
+import LabelModel from './label'
+import UserModel from './user'
+import AttachmentModel from './attachment'
+import SubscriptionModel from './subscription'
const SUPPORTS_TRIGGERED_NOTIFICATION = 'Notification' in window && 'showTrigger' in Notification.prototype
export const TASK_DEFAULT_COLOR = '#1973ff'
-export const TASK_REPEAT_MODES = {
- 'REPEAT_MODE_DEFAULT': 0,
- 'REPEAT_MODE_MONTH': 1,
- 'REPEAT_MODE_FROM_CURRENT_DATE': 2,
-} as const
+export function getHexColor(hexColor: string) {
+ if (hexColor === '' || hexColor === '#') {
+ return TASK_DEFAULT_COLOR
+ }
-export type TaskRepeatMode = typeof TASK_REPEAT_MODES[keyof typeof TASK_REPEAT_MODES]
-
-export interface ITask extends IAbstract {
- id: number
- title: string
- description: string
- done: boolean
- doneAt: Date | null
- priority: Priority
- labels: ILabel[]
- assignees: IUser[]
-
- dueDate: Date | null
- startDate: Date | null
- endDate: Date | null
- repeatAfter: number | IRepeats
- repeatFromCurrentDate: boolean
- repeatMode: TaskRepeatMode
- reminderDates: Date[]
- parentTaskId: ITask['id']
- hexColor: string
- percentDone: number
- relatedTasks: { [relationKind: string]: ITask } // FIXME: use relationKinds
- attachments: IAttachment[]
- identifier: string
- index: number
- isFavorite: boolean
- subscription: ISubscription
-
- position: number
- kanbanPosition: number
-
- createdBy: IUser
- created: Date
- updated: Date
-
- listId: IList['id'] // Meta, only used when creating a new task
- bucketId: IBucket['id']
+ return hexColor
}
export default class TaskModel extends AbstractModel implements ITask {
@@ -73,14 +45,14 @@ export default class TaskModel extends AbstractModel implements ITask {
dueDate: Date | null = 0
startDate: Date | null = 0
endDate: Date | null = 0
- repeatAfter: number | IRepeats = 0
+ repeatAfter: number | IRepeatAfter = 0
repeatFromCurrentDate = false
- repeatMode: TaskRepeatMode = TASK_REPEAT_MODES.REPEAT_MODE_DEFAULT
+ repeatMode: IRepeatMode = TASK_REPEAT_MODES.REPEAT_MODE_DEFAULT
reminderDates: Date[] = []
parentTaskId: ITask['id'] = 0
hexColor = ''
percentDone = 0
- relatedTasks: { [relationKind: string]: ITask } = {}
+ relatedTasks: Partial> = {}
attachments: IAttachment[] = []
identifier = ''
index = 0
@@ -168,11 +140,7 @@ export default class TaskModel extends AbstractModel implements ITask {
}
getHexColor() {
- if (this.hexColor === '' || this.hexColor === '#') {
- return TASK_DEFAULT_COLOR
- }
-
- return this.hexColor
+ return getHexColor(this.hexColor)
}
/////////////////
diff --git a/src/models/taskAssignee.ts b/src/models/taskAssignee.ts
index 29a8db271d..5777e5b209 100644
--- a/src/models/taskAssignee.ts
+++ b/src/models/taskAssignee.ts
@@ -1,12 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import type { ITask } from './task'
-import type { IUser } from './user'
+import AbstractModel from './abstractModel'
-export interface ITaskAssignee extends IAbstract {
- created: Date
- userId: IUser['id']
- taskId: ITask['id']
-}
+import type {ITaskAssignee} from '@/modelTypes/ITaskAssignee'
+import type {IUser} from '@/modelTypes/IUser'
+import type {ITask} from '@/modelTypes/ITask'
export default class TaskAssigneeModel extends AbstractModel implements ITaskAssignee {
created: Date = null
diff --git a/src/models/taskComment.ts b/src/models/taskComment.ts
index bb5ceb101c..6c76e822ff 100644
--- a/src/models/taskComment.ts
+++ b/src/models/taskComment.ts
@@ -1,16 +1,9 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
-import type { ITask } from './task'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
-export interface ITaskComment extends IAbstract {
- id: number
- taskId: ITask['id']
- comment: string
- author: IUser
-
- created: Date
- updated: Date
-}
+import type {ITaskComment} from '@/modelTypes/ITaskComment'
+import type {ITask} from '@/modelTypes/ITask'
+import type {IUser} from '@/modelTypes/IUser'
export default class TaskCommentModel extends AbstractModel implements ITaskComment {
id = 0
diff --git a/src/models/taskRelation.ts b/src/models/taskRelation.ts
index db375faba4..e22eddb912 100644
--- a/src/models/taskRelation.ts
+++ b/src/models/taskRelation.ts
@@ -1,39 +1,16 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
-import type { ITask } from './task'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
-export const RELATION_KIND = {
- 'SUBTASK': 'subtask',
- 'PARENTTASK': 'parenttask',
- 'RELATED': 'related',
- 'DUPLICATES': 'duplicates',
- 'BLOCKING': 'blocking',
- 'BLOCKED': 'blocked',
- 'PROCEDES': 'precedes',
- 'FOLLOWS': 'follows',
- 'COPIEDFROM': 'copiedfrom',
- 'COPIEDTO': 'copiedto',
- } as const
-
-export const RELATION_KINDS = [...Object.values(RELATION_KIND)] as const
-
-export type RelationKind = typeof RELATION_KINDS[number]
-
-export interface ITaskRelation extends IAbstract {
- id: number
- otherTaskId: ITask['id']
- taskId: ITask['id']
- relationKind: RelationKind
-
- createdBy: IUser
- created: Date
-}
+import type {ITaskRelation} from '@/modelTypes/ITaskRelation'
+import type {ITask} from '@/modelTypes/ITask'
+import type {IUser} from '@/modelTypes/IUser'
+import type {IRelationKind} from '@/types/IRelationKind'
export default class TaskRelationModel extends AbstractModel implements ITaskRelation {
id = 0
otherTaskId: ITask['id'] = 0
taskId: ITask['id'] = 0
- relationKind: RelationKind = ''
+ relationKind: IRelationKind = ''
createdBy: IUser = UserModel
created: Date = null
diff --git a/src/models/team.ts b/src/models/team.ts
index 56e13dee51..5e3bd27e5c 100644
--- a/src/models/team.ts
+++ b/src/models/team.ts
@@ -1,19 +1,11 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserModel, { type IUser } from './user'
-import TeamMemberModel, { type ITeamMember } from './teamMember'
+import AbstractModel from './abstractModel'
+import UserModel from './user'
+import TeamMemberModel from './teamMember'
+
import {RIGHTS, type Right} from '@/constants/rights'
-
-export interface ITeam extends IAbstract {
- id: number
- name: string
- description: string
- members: ITeamMember[]
- right: Right
-
- createdBy: IUser
- created: Date
- updated: Date
-}
+import type {ITeam} from '@/modelTypes/ITeam'
+import type {ITeamMember} from '@/modelTypes/ITeamMember'
+import type {IUser} from '@/modelTypes/IUser'
export default class TeamModel extends AbstractModel implements ITeam {
id = 0
diff --git a/src/models/teamList.ts b/src/models/teamList.ts
index bb55b1cc20..eab202cf05 100644
--- a/src/models/teamList.ts
+++ b/src/models/teamList.ts
@@ -1,9 +1,7 @@
import TeamShareBaseModel from './teamShareBase'
-import type { IList } from './list'
-export interface ITeamList extends TeamShareBaseModel {
- listId: IList['id']
-}
+import type {ITeamList} from '@/modelTypes/ITeamList'
+import type {IList} from '@/modelTypes/IList'
export default class TeamListModel extends TeamShareBaseModel implements ITeamList {
listId: IList['id'] = 0
diff --git a/src/models/teamMember.ts b/src/models/teamMember.ts
index 6caf49328e..ee8768f020 100644
--- a/src/models/teamMember.ts
+++ b/src/models/teamMember.ts
@@ -1,10 +1,7 @@
import UserModel from './user'
-import type { IList } from './list'
-export interface ITeamMember extends UserModel {
- admin: boolean
- teamId: IList['id']
-}
+import type {ITeamMember} from '@/modelTypes/ITeamMember'
+import type {IList} from '@/modelTypes/IList'
export default class TeamMemberModel extends UserModel implements ITeamMember {
admin = false
diff --git a/src/models/teamNamespace.ts b/src/models/teamNamespace.ts
index 104d7a77d0..3d583ae801 100644
--- a/src/models/teamNamespace.ts
+++ b/src/models/teamNamespace.ts
@@ -1,9 +1,7 @@
import TeamShareBaseModel from './teamShareBase'
-import type { INamespace } from './namespace'
-export interface ITeamNamespace extends TeamShareBaseModel {
- namespaceId: INamespace['id']
-}
+import type {ITeamNamespace} from '@/modelTypes/ITeamNamespace'
+import type {INamespace} from '@/modelTypes/INamespace'
export default class TeamNamespaceModel extends TeamShareBaseModel implements ITeamNamespace {
namespaceId: INamespace['id'] = 0
diff --git a/src/models/teamShareBase.ts b/src/models/teamShareBase.ts
index 02495d1cd2..c7eb23c7ef 100644
--- a/src/models/teamShareBase.ts
+++ b/src/models/teamShareBase.ts
@@ -1,14 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
+
import {RIGHTS, type Right} from '@/constants/rights'
-import type { ITeam } from './team'
-
-export interface ITeamShareBase extends IAbstract {
- teamId: ITeam['id']
- right: Right
-
- created: Date
- updated: Date
-}
+import type {ITeamShareBase} from '@/modelTypes/ITeamShareBase'
+import type {ITeam} from '@/modelTypes/ITeam'
/**
* This class is a base class for common team sharing model.
diff --git a/src/models/totp.ts b/src/models/totp.ts
index 42242cf01c..5e094392df 100644
--- a/src/models/totp.ts
+++ b/src/models/totp.ts
@@ -1,10 +1,6 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
-export interface ITotp extends IAbstract {
- secret: string
- enabled: boolean
- url: string
-}
+import type {ITotp} from '@/modelTypes/ITotp'
export default class TotpModel extends AbstractModel implements ITotp {
secret = ''
diff --git a/src/models/user.ts b/src/models/user.ts
index cd6423b76c..41509c1711 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -1,16 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import UserSettingsModel, { type IUserSettings } from '@/models/userSettings'
+import AbstractModel from './abstractModel'
+import UserSettingsModel from '@/models/userSettings'
-export interface IUser extends IAbstract {
- id: number
- email: string
- username: string
- name: string
-
- created: Date
- updated: Date
- settings: IUserSettings
-}
+import type { IUser } from '@/modelTypes/IUser'
+import type { IUserSettings } from '@/modelTypes/IUserSettings'
export default class UserModel extends AbstractModel implements IUser {
id = 0
diff --git a/src/models/userList.ts b/src/models/userList.ts
index ae5f881124..ed264d9b83 100644
--- a/src/models/userList.ts
+++ b/src/models/userList.ts
@@ -1,9 +1,7 @@
import UserShareBaseModel from './userShareBase'
-import type { IList } from './list'
-export interface IUserList extends UserShareBaseModel {
- listId: IList['id']
-}
+import type {IUserList} from '@/modelTypes/IUserList'
+import type {IList} from '@/modelTypes/IList'
// This class extends the user share model with a 'rights' parameter which is used in sharing
export default class UserListModel extends UserShareBaseModel implements IUserList {
diff --git a/src/models/userNamespace.ts b/src/models/userNamespace.ts
index 4795b87377..326373837e 100644
--- a/src/models/userNamespace.ts
+++ b/src/models/userNamespace.ts
@@ -1,9 +1,7 @@
import UserShareBaseModel from './userShareBase'
-import type { INamespace } from './namespace'
-export interface IUserNamespace extends UserShareBaseModel {
- namespaceId: INamespace['id']
-}
+import type {INamespace} from '@/modelTypes/INamespace'
+import type {IUserNamespace} from '@/modelTypes/IUserNamespace'
// This class extends the user share model with a 'rights' parameter which is used in sharing
export default class UserNamespaceModel extends UserShareBaseModel implements IUserNamespace {
diff --git a/src/models/userSettings.ts b/src/models/userSettings.ts
index 382e71590c..6b5bd7ca48 100644
--- a/src/models/userSettings.ts
+++ b/src/models/userSettings.ts
@@ -1,17 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
-import type { IList } from './list'
+import AbstractModel from './abstractModel'
-export interface IUserSettings extends IAbstract {
- name: string
- emailRemindersEnabled: boolean
- discoverableByName: boolean
- discoverableByEmail: boolean
- overdueTasksRemindersEnabled: boolean
- defaultListId: undefined | IList['id']
- weekStart: 0 | 1 | 2 | 3 | 4 | 5 | 6
- timezone: string
-}
+import type {IUserSettings} from '@/modelTypes/IUserSettings'
+import type {IList} from '@/modelTypes/IList'
export default class UserSettingsModel extends AbstractModel implements IUserSettings {
name = ''
@@ -20,7 +11,7 @@ export default class UserSettingsModel extends AbstractModel implements IUserSet
discoverableByEmail = false
overdueTasksRemindersEnabled = true
defaultListId: undefined | IList['id'] = undefined
- weekStart: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 0
+ weekStart: IUserSettings['weekStart'] = 0
timezone = ''
constructor(data: Partial) {
diff --git a/src/models/userShareBase.ts b/src/models/userShareBase.ts
index 82ab543272..e21998d94f 100644
--- a/src/models/userShareBase.ts
+++ b/src/models/userShareBase.ts
@@ -1,14 +1,8 @@
-import AbstractModel, { type IAbstract } from './abstractModel'
+import AbstractModel from './abstractModel'
+
import {RIGHTS, type Right} from '@/constants/rights'
-import type { IUser } from './user'
-
-export interface IUserShareBase extends IAbstract {
- userId: IUser['id']
- right: Right
-
- created: Date
- updated: Date
-}
+import type {IUserShareBase} from '@/modelTypes/IUserShareBase'
+import type {IUser} from '@/modelTypes/IUser'
export default class UserShareBaseModel extends AbstractModel implements IUserShareBase {
userId: IUser['id'] = ''
diff --git a/src/modules/parseTaskText.ts b/src/modules/parseTaskText.ts
index 5be6d2ab00..319bada8f6 100644
--- a/src/modules/parseTaskText.ts
+++ b/src/modules/parseTaskText.ts
@@ -1,6 +1,6 @@
import {parseDate} from '../helpers/time/parseDate'
import {PRIORITIES} from '@/constants/priorities'
-import {REPEAT_TYPES, type IRepeats, type RepeatType} from '@/types/IRepeats'
+import {REPEAT_TYPES, type IRepeatAfter, type IRepeatType} from '@/types/IRepeatAfter'
const VIKUNJA_PREFIXES: Prefixes = {
label: '*',
@@ -30,7 +30,7 @@ export const PREFIXES = {
interface repeatParsedResult {
textWithoutMatched: string,
- repeats: IRepeats | null,
+ repeats: IRepeatAfter | null,
}
export interface ParsedTaskText {
@@ -40,7 +40,7 @@ export interface ParsedTaskText {
list: string | null,
priority: number | null,
assignees: string[],
- repeats: IRepeats | null,
+ repeats: IRepeatAfter | null,
}
interface Prefixes {
@@ -185,7 +185,7 @@ const getRepeats = (text: string): repeatParsedResult => {
default:
amount = results[3] ? parseInt(results[3]) : 1
}
- let type: RepeatType = REPEAT_TYPES.Hours
+ let type: IRepeatType = REPEAT_TYPES.Hours
switch (results[0]) {
case 'biennially':
diff --git a/src/store/index.ts b/src/store/index.ts
index 0033e07e10..34dc7c049a 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -1,7 +1,6 @@
import type {InjectionKey} from 'vue'
import {createStore, useStore as baseUseStore, Store} from 'vuex'
-
import {getBlobFromBlurHash} from '../helpers/getBlobFromBlurHash'
import {
BACKGROUND,
diff --git a/src/store/modules/attachments.ts b/src/store/modules/attachments.ts
index 208ab4cef6..172696e41f 100644
--- a/src/store/modules/attachments.ts
+++ b/src/store/modules/attachments.ts
@@ -2,7 +2,7 @@ import type { Module } from 'vuex'
import {findIndexById} from '@/helpers/utils'
import type { AttachmentState, RootStoreState } from '@/store/types'
-import type { IAttachment } from '@/models/attachment'
+import type { IAttachment } from '@/modelTypes/IAttachment'
const store : Module = {
namespaced: true,
diff --git a/src/store/modules/auth.ts b/src/store/modules/auth.ts
index a66b656b6c..c101381ca3 100644
--- a/src/store/modules/auth.ts
+++ b/src/store/modules/auth.ts
@@ -12,7 +12,7 @@ import {success} from '@/message'
import {redirectToProvider} from '@/helpers/redirectToProvider'
import type { RootStoreState, AuthState, Info} from '@/store/types'
import {AUTH_TYPES} from '@/store/types'
-import type { IUserSettings } from '@/models/userSettings'
+import type { IUserSettings } from '@/modelTypes/IUserSettings'
const defaultSettings = settings => {
diff --git a/src/store/modules/kanban.ts b/src/store/modules/kanban.ts
index c6e46d58aa..194121309c 100644
--- a/src/store/modules/kanban.ts
+++ b/src/store/modules/kanban.ts
@@ -9,9 +9,9 @@ import BucketService from '../../services/bucket'
import {setLoading} from '../helper'
import TaskCollectionService from '@/services/taskCollection'
import type { RootStoreState, KanbanState } from '@/store/types'
-import type { ITask } from '@/models/task'
-import type { IList } from '@/models/list'
-import type { IBucket } from '@/models/bucket'
+import type { ITask } from '@/modelTypes/ITask'
+import type { IList } from '@/modelTypes/IList'
+import type { IBucket } from '@/modelTypes/IBucket'
const TASKS_PER_BUCKET = 25
diff --git a/src/store/modules/labels.ts b/src/store/modules/labels.ts
index ce32db6d09..928b6b1e4c 100644
--- a/src/store/modules/labels.ts
+++ b/src/store/modules/labels.ts
@@ -7,7 +7,7 @@ import {setLoading} from '@/store/helper'
import type { LabelState, RootStoreState } from '@/store/types'
import {getLabelsByIds, filterLabelsByQuery} from '@/helpers/labels'
import {createNewIndexer} from '@/indexes'
-import type { ILabel } from '@/models/label'
+import type { ILabel } from '@/modelTypes/ILabel'
const {add, remove, update} = createNewIndexer('labels', ['title', 'description'])
diff --git a/src/store/modules/lists.ts b/src/store/modules/lists.ts
index 0d18a2c04f..be2e3fcfe0 100644
--- a/src/store/modules/lists.ts
+++ b/src/store/modules/lists.ts
@@ -5,7 +5,7 @@ import {setLoading} from '@/store/helper'
import {removeListFromHistory} from '@/modules/listHistory'
import {createNewIndexer} from '@/indexes'
import type {ListState, RootStoreState} from '@/store/types'
-import type {IList} from '@/models/list'
+import type {IList} from '@/modelTypes/IList'
const {add, remove, search, update} = createNewIndexer('lists', ['title', 'description'])
diff --git a/src/store/modules/namespaces.ts b/src/store/modules/namespaces.ts
index 0eccc99bbc..d835c7095d 100644
--- a/src/store/modules/namespaces.ts
+++ b/src/store/modules/namespaces.ts
@@ -4,8 +4,8 @@ import NamespaceService from '../../services/namespace'
import {setLoading} from '@/store/helper'
import {createNewIndexer} from '@/indexes'
import type {NamespaceState, RootStoreState} from '@/store/types'
-import type {INamespace} from '@/models/namespace'
-import type {IList} from '@/models/list'
+import type {INamespace} from '@/modelTypes/INamespace'
+import type {IList} from '@/modelTypes/IList'
const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description'])
diff --git a/src/store/modules/tasks.ts b/src/store/modules/tasks.ts
index 6588c51f76..332286917e 100644
--- a/src/store/modules/tasks.ts
+++ b/src/store/modules/tasks.ts
@@ -4,22 +4,27 @@ import {formatISO} from 'date-fns'
import TaskService from '@/services/task'
import TaskAssigneeService from '@/services/taskAssignee'
-import TaskAssigneeModel from '@/models/taskAssignee'
-import LabelTaskModel from '@/models/labelTask'
import LabelTaskService from '@/services/labelTask'
+import UserService from '@/services/user'
+
import {HAS_TASKS} from '../mutation-types'
import {setLoading} from '../helper'
import {getQuickAddMagicMode} from '@/helpers/quickAddMagicMode'
-
import {parseTaskText} from '@/modules/parseTaskText'
-import TaskModel, { type ITask } from '@/models/task'
+
+import TaskAssigneeModel from '@/models/taskAssignee'
+import LabelTaskModel from '@/models/labelTask'
+import TaskModel from '@/models/task'
import LabelTask from '@/models/labelTask'
-import LabelModel, { type ILabel } from '@/models/label'
-import UserService from '@/services/user'
+import LabelModel from '@/models/label'
+
+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 { RootStoreState, TaskState } from '@/store/types'
-import type { IUser } from '@/models/user'
-import type { IAttachment } from '@/models/attachment'
-import type { IList } from '@/models/list'
// IDEA: maybe use a small fuzzy search here to prevent errors
function findPropertyByValue(object, key, value) {
diff --git a/src/store/types.ts b/src/store/types.ts
index 96f061dca7..2cc467a1e7 100644
--- a/src/store/types.ts
+++ b/src/store/types.ts
@@ -1,9 +1,9 @@
-import type { IBucket } from '@/models/bucket'
-import type { IUserSettings } from '@/models/userSettings'
-import type { IList } from '@/models/list'
-import type { IAttachment } from '@/models/attachment'
-import type { ILabel } from '@/models/label'
-import type { INamespace } from '@/models/namespace'
+import type { IBucket } from '@/modelTypes/IBucket'
+import type { IUserSettings } from '@/modelTypes/IUserSettings'
+import type { IList } from '@/modelTypes/IList'
+import type { IAttachment } from '@/modelTypes/IAttachment'
+import type { ILabel } from '@/modelTypes/ILabel'
+import type { INamespace } from '@/modelTypes/INamespace'
export interface RootStoreState {
loading: boolean,
diff --git a/src/types/IFilter.ts b/src/types/IFilter.ts
new file mode 100644
index 0000000000..aca000ab69
--- /dev/null
+++ b/src/types/IFilter.ts
@@ -0,0 +1,9 @@
+export interface IFilter {
+ sortBy: ('done' | 'id')[]
+ orderBy: ('asc' | 'desc')[]
+ filterBy: 'done'[]
+ filterValue: 'false'[]
+ filterComparator: 'equals'[]
+ filterConcat: 'and'
+ filterIncludeNulls: boolean
+}
\ No newline at end of file
diff --git a/src/types/IRelationKind.ts b/src/types/IRelationKind.ts
new file mode 100644
index 0000000000..a9ffb3d672
--- /dev/null
+++ b/src/types/IRelationKind.ts
@@ -0,0 +1,16 @@
+export enum RELATION_KIND {
+ 'SUBTASK' = 'subtask',
+ 'PARENTTASK' = 'parenttask',
+ 'RELATED' = 'related',
+ 'DUPLICATES' = 'duplicates',
+ 'BLOCKING' = 'blocking',
+ 'BLOCKED' = 'blocked',
+ 'PROCEDES' = 'precedes',
+ 'FOLLOWS' = 'follows',
+ 'COPIEDFROM' = 'copiedfrom',
+ 'COPIEDTO' = 'copiedto',
+}
+
+export type IRelationKind = typeof RELATION_KIND[keyof typeof RELATION_KIND]
+
+export const RELATION_KINDS = [...Object.values(RELATION_KIND)] as const
\ No newline at end of file
diff --git a/src/types/IRepeats.ts b/src/types/IRepeatAfter.ts
similarity index 53%
rename from src/types/IRepeats.ts
rename to src/types/IRepeatAfter.ts
index e2ab90777f..0b132a2f7b 100644
--- a/src/types/IRepeats.ts
+++ b/src/types/IRepeatAfter.ts
@@ -6,9 +6,9 @@ export const REPEAT_TYPES = {
Years: 'years',
} as const
-export type RepeatType = typeof REPEAT_TYPES[keyof typeof REPEAT_TYPES]
+export type IRepeatType = typeof REPEAT_TYPES[keyof typeof REPEAT_TYPES]
-export interface IRepeats {
- type: RepeatType,
+export interface IRepeatAfter {
+ type: IRepeatType,
amount: number,
}
\ No newline at end of file
diff --git a/src/types/IRepeatMode.ts b/src/types/IRepeatMode.ts
new file mode 100644
index 0000000000..46297ff722
--- /dev/null
+++ b/src/types/IRepeatMode.ts
@@ -0,0 +1,7 @@
+export const TASK_REPEAT_MODES = {
+ 'REPEAT_MODE_DEFAULT': 0,
+ 'REPEAT_MODE_MONTH': 1,
+ 'REPEAT_MODE_FROM_CURRENT_DATE': 2,
+} as const
+
+export type IRepeatMode = typeof TASK_REPEAT_MODES[keyof typeof TASK_REPEAT_MODES]
diff --git a/src/views/list/ListList.vue b/src/views/list/ListList.vue
index 6c018fe13a..b5ef4aa5fd 100644
--- a/src/views/list/ListList.vue
+++ b/src/views/list/ListList.vue
@@ -156,7 +156,7 @@ import {calculateItemPosition} from '../../helpers/calculateItemPosition'
import type { ITask } from '@/models/task'
function sortTasks(tasks: ITask[]) {
- if (tasks === null || tasks === []) {
+ if (tasks === null || Array.isArray(tasks) && tasks.length === 0) {
return
}
return tasks.sort((a, b) => {
diff --git a/src/views/teams/EditTeam.vue b/src/views/teams/EditTeam.vue
index 5497ba3478..08a6c4025f 100644
--- a/src/views/teams/EditTeam.vue
+++ b/src/views/teams/EditTeam.vue
@@ -170,6 +170,7 @@ import {useStore} from '@/store'
import TeamService from '@/services/team'
import TeamMemberService from '@/services/teamMember'
import UserService from '@/services/user'
+
import {RIGHTS as Rights} from '@/constants/rights'
import Multiselect from '@/components/input/multiselect.vue'