1
0

feat: improve store and model typing

This commit is contained in:
Dominik Pschenitschni
2022-07-21 00:42:36 +02:00
parent c9e85cb52b
commit 3766b5e51b
98 changed files with 1050 additions and 507 deletions

View File

@ -76,14 +76,14 @@
</template>
<script setup lang="ts">
import {ref, reactive, computed, shallowReactive, watch, nextTick} from 'vue'
import {ref, reactive, computed, shallowReactive, watch, nextTick, type PropType} from 'vue'
import {useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
import Editor from '@/components/input/AsyncEditor'
import TaskService from '@/services/task'
import TaskModel from '@/models/task'
import TaskModel, { type ITask } from '@/models/task'
import EditLabels from './partials/editLabels.vue'
import Reminders from './partials/reminders.vue'
import ColorPicker from '../input/colorPicker.vue'
@ -93,14 +93,16 @@ import {success} from '@/message'
const {t} = useI18n({useScope: 'global'})
const router = useRouter()
const props = defineProps<{
task?: TaskModel | null,
}>()
const props = defineProps({
task: {
type: Object as PropType<ITask | null>,
},
})
const taskService = shallowReactive(new TaskService())
const editorActive = ref(false)
let taskEditTask: TaskModel | undefined
let taskEditTask: ITask | undefined
// FIXME: this initialization should not be necessary here

View File

@ -147,8 +147,7 @@
import {defineComponent} from 'vue'
import AttachmentService from '../../../services/attachment'
import AttachmentModel from '../../../models/attachment'
import type FileModel from '@/models/file'
import AttachmentModel, { type IAttachment } from '@/models/attachment'
import User from '@/components/misc/user.vue'
import {mapState} from 'vuex'
@ -157,6 +156,7 @@ import { uploadFiles, generateAttachmentUrl } from '@/helpers/attachments'
import {formatDate, formatDateSince, formatDateLong} from '@/helpers/time/formatDate'
import BaseButton from '@/components/base/BaseButton'
import type { IFile } from '@/models/file'
export default defineComponent({
name: 'attachments',
@ -192,7 +192,7 @@ export default defineComponent({
setup(props) {
const copy = useCopyToClipboard()
function copyUrl(attachment: AttachmentModel) {
function copyUrl(attachment: IAttachment) {
copy(generateAttachmentUrl(props.taskId, attachment.id))
}
@ -235,7 +235,7 @@ export default defineComponent({
formatDateSince,
formatDateLong,
downloadAttachment(attachment: AttachmentModel) {
downloadAttachment(attachment: IAttachment) {
this.attachmentService.download(attachment)
},
uploadNewAttachment() {
@ -245,7 +245,7 @@ export default defineComponent({
this.uploadFiles(this.$refs.files.files)
},
uploadFiles(files: FileModel[]) {
uploadFiles(files: IFile[]) {
uploadFiles(this.attachmentService, this.taskId, files)
},
async deleteAttachment() {

View File

@ -10,15 +10,15 @@
</template>
<script setup lang="ts">
import {computed} from 'vue'
import {computed, type PropType} from 'vue'
import { useI18n } from 'vue-i18n'
import {getChecklistStatistics} from '@/helpers/checklistFromText'
import TaskModel from '@/models/task'
import type {ITask} from '@/models/task'
const props = defineProps({
task: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
})

View File

@ -159,12 +159,12 @@ import {useI18n} from 'vue-i18n'
import Editor from '@/components/input/AsyncEditor'
import TaskCommentService from '@/services/taskComment'
import TaskCommentModel from '@/models/taskComment'
import TaskCommentModel, { type ITaskComment } from '@/models/taskComment'
import {uploadFile} from '@/helpers/attachments'
import {success} from '@/message'
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
import type TaskModel from '@/models/task'
import type { ITask } from '@/models/task'
const props = defineProps({
taskId: {
type: Number,
@ -178,7 +178,7 @@ const props = defineProps({
const {t} = useI18n({useScope: 'global'})
const store = useStore()
const comments = ref<TaskCommentModel[]>([])
const comments = ref<ITaskComment[]>([])
const showDeleteModal = ref(false)
const commentToDelete = reactive(new TaskCommentModel())
@ -188,8 +188,8 @@ const commentEdit = reactive(new TaskCommentModel())
const newComment = reactive(new TaskCommentModel())
const saved = ref<TaskModel['id'] | null>(null)
const saving = ref<TaskModel['id'] | null>(null)
const saved = ref<ITask['id'] | null>(null)
const saving = ref<ITask['id'] | null>(null)
const userAvatar = computed(() => store.state.auth.info.getAvatarUrl(48))
const currentUserId = computed(() => store.state.auth.info.id)
@ -215,7 +215,7 @@ function attachmentUpload(...args) {
const taskCommentService = shallowReactive(new TaskCommentService())
async function loadComments(taskId: TaskModel['id']) {
async function loadComments(taskId: ITask['id']) {
if (!enabled.value) {
return
}
@ -259,12 +259,12 @@ async function addComment() {
}
}
function toggleEdit(comment: TaskCommentModel) {
function toggleEdit(comment: ITaskComment) {
isCommentEdit.value = !isCommentEdit.value
Object.assign(commentEdit, comment)
}
function toggleDelete(commentId: TaskCommentModel['id']) {
function toggleDelete(commentId: ITaskComment['id']) {
showDeleteModal.value = !showDeleteModal.value
commentToDelete.id = commentId
}
@ -294,7 +294,7 @@ async function editComment() {
}
}
async function deleteComment(commentToDelete: TaskCommentModel) {
async function deleteComment(commentToDelete: ITaskComment) {
try {
await taskCommentService.delete(commentToDelete)
const index = comments.value.findIndex(({id}) => id === commentToDelete.id)

View File

@ -27,13 +27,13 @@
</template>
<script lang="ts" setup>
import {computed, toRefs} from 'vue'
import TaskModel from '@/models/task'
import {computed, toRefs, type PropType} from 'vue'
import type { ITask } from '@/models/task'
import {formatISO, formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
const props = defineProps({
task: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
})

View File

@ -38,17 +38,17 @@
</template>
<script setup lang="ts">
import {ref, shallowReactive, computed, watch, onMounted, onBeforeUnmount} from 'vue'
import {ref, shallowReactive, computed, watch, onMounted, onBeforeUnmount, type PropType} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import flatPickr from 'vue-flatpickr-component'
import TaskService from '@/services/task'
import TaskModel from '@/models/task'
import { type ITask } from '@/models/task'
const props = defineProps({
modelValue: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
})
@ -58,7 +58,7 @@ const {t} = useI18n({useScope: 'global'})
const store = useStore()
const taskService = shallowReactive(new TaskService())
const task = ref<TaskModel>()
const task = ref<ITask>()
// We're saving the due date seperately to prevent null errors in very short periods where the task is null.
const dueDate = ref<Date>()

View File

@ -30,17 +30,17 @@
</template>
<script setup lang="ts">
import {ref,computed, watch} from 'vue'
import {ref,computed, watch, type PropType} from 'vue'
import {useStore} from 'vuex'
import Editor from '@/components/input/AsyncEditor'
import TaskModel from '@/models/task'
import type { ITask } from '@/models/task'
const props = defineProps({
modelValue: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
attachmentUpload: {
@ -54,7 +54,7 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue'])
const task = ref<TaskModel>({description: ''})
const task = ref<ITask>({description: ''})
const saved = ref(false)
// Since loading is global state, this variable ensures we're only showing the saving icon when saving the description.

View File

@ -37,9 +37,9 @@ import Multiselect from '@/components/input/multiselect.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import {includesById} from '@/helpers/utils'
import type UserModel from '@/models/user'
import ListUserService from '@/services/listUsers'
import {success} from '@/message'
import type { IUser } from '@/models/user'
const props = defineProps({
taskId: {
@ -54,7 +54,7 @@ const props = defineProps({
default: false,
},
modelValue: {
type: Array as PropType<UserModel[]>,
type: Array as PropType<IUser[]>,
default: () => [],
},
})
@ -65,7 +65,7 @@ const {t} = useI18n({useScope: 'global'})
const listUserService = shallowReactive(new ListUserService())
const foundUsers = ref([])
const assignees = ref<UserModel[]>([])
const assignees = ref<IUser[]>([])
watch(
() => props.modelValue,
@ -78,13 +78,13 @@ watch(
},
)
async function addAssignee(user: UserModel) {
async function addAssignee(user: IUser) {
await store.dispatch('tasks/addAssignee', {user: user, taskId: props.taskId})
emit('update:modelValue', assignees.value)
success({message: t('task.assignee.assignSuccess')})
}
async function removeAssignee(user: UserModel) {
async function removeAssignee(user: IUser) {
await store.dispatch('tasks/removeAssignee', {user: user, taskId: props.taskId})
// Remove the assignee from the list

View File

@ -43,7 +43,7 @@ import {type PropType, ref, computed, shallowReactive, watch} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import LabelModel from '@/models/label'
import LabelModel, { type ILabel } from '@/models/label'
import LabelTaskService from '@/services/labelTask'
import {success} from '@/message'
@ -52,7 +52,7 @@ import Multiselect from '@/components/input/multiselect.vue'
const props = defineProps({
modelValue: {
type: Array as PropType<LabelModel[]>,
type: Array as PropType<ILabel[]>,
default: () => [],
},
taskId: {
@ -71,7 +71,7 @@ const store = useStore()
const {t} = useI18n({useScope: 'global'})
const labelTaskService = shallowReactive(new LabelTaskService())
const labels = ref<LabelModel[]>([])
const labels = ref<ILabel[]>([])
const query = ref('')
watch(
@ -92,7 +92,7 @@ function findLabel(newQuery: string) {
query.value = newQuery
}
async function addLabel(label: LabelModel, showNotification = true) {
async function addLabel(label: ILabel, showNotification = true) {
const bubble = () => {
emit('update:modelValue', labels.value)
emit('change', labels.value)
@ -110,7 +110,7 @@ async function addLabel(label: LabelModel, showNotification = true) {
}
}
async function removeLabel(label: LabelModel) {
async function removeLabel(label: ILabel) {
if (props.taskId !== 0) {
await store.dispatch('tasks/removeLabel', {label, taskId: props.taskId})
}

View File

@ -32,18 +32,18 @@
</template>
<script setup lang="ts">
import {ref, computed} from 'vue'
import {ref, computed, type PropType} from 'vue'
import {useStore} from 'vuex'
import BaseButton from '@/components/base/BaseButton.vue'
import Done from '@/components/misc/Done.vue'
import TaskModel from '@/models/task'
import type {ITask} from '@/models/task'
import { useRouter } from 'vue-router'
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
const props = defineProps({
task: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
canWrite: {

View File

@ -74,7 +74,7 @@ import User from '../../../components/misc/user.vue'
import Done from '@/components/misc/Done.vue'
import Labels from '../../../components/tasks/partials/labels.vue'
import ChecklistSummary from './checklist-summary.vue'
import TaskModel, {TASK_DEFAULT_COLOR} from '@/models/task'
import {TASK_DEFAULT_COLOR, type ITask} from '@/models/task'
import {formatDateLong, formatISO, formatDateSince} from '@/helpers/time/formatDate'
import {colorIsDark} from '@/helpers/color/colorIsDark'
@ -96,7 +96,7 @@ export default defineComponent({
},
props: {
task: {
type: Object as PropType<TaskModel>,
type: Object as PropType<ITask>,
required: true,
},
loading: {
@ -117,7 +117,7 @@ export default defineComponent({
formatISO,
formatDateSince,
colorIsDark,
async toggleTaskDone(task: TaskModel) {
async toggleTaskDone(task: ITask) {
this.loadingInternal = true
try {
const done = !task.done

View File

@ -11,12 +11,12 @@
</template>
<script setup lang="ts">
import type LabelModel from '@/models/label'
import type { PropType } from 'vue'
import type { ILabel } from '@/models/label'
defineProps({
labels: {
type: Array as PropType<LabelModel[]>,
type: Array as PropType<ILabel[]>,
required: true,
},
})

View File

@ -21,15 +21,12 @@ import {reactive, ref, watch} from 'vue'
import type {PropType} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import ListModel from '@/models/list'
import ListModel, { type IList } from '@/models/list'
import Multiselect from '@/components/input/multiselect.vue'
const props = defineProps({
modelValue: {
type: Object as PropType<ListModel>,
validator(value) {
return value instanceof ListModel
},
type: Object as PropType<IList>,
required: false,
},
})
@ -38,7 +35,7 @@ const emit = defineEmits(['update:modelValue'])
const store = useStore()
const {t} = useI18n({useScope: 'global'})
const list: ListModel= reactive(new ListModel())
const list: IList = reactive(new ListModel())
watch(
() => props.modelValue,
@ -57,7 +54,7 @@ function findLists(query: string) {
foundLists.value = store.getters['lists/searchList'](query)
}
function select(l: ListModel | null) {
function select(l: IList | null) {
Object.assign(list, l)
emit('update:modelValue', list)
}

View File

@ -63,14 +63,14 @@
<script setup lang="ts">
import {ref, reactive, watch, type PropType} from 'vue'
import {error} from '@/message'
import {useI18n} from 'vue-i18n'
import {TASK_REPEAT_MODES, type RepeatAfter} from '@/models/task'
import type TaskModel from '@/models/task'
import {error} from '@/message'
import {TASK_REPEAT_MODES, type ITask, type RepeatAfter} from '@/models/task'
const props = defineProps({
modelValue: {
type: Object as PropType<TaskModel>,
type: Object as PropType<ITask>,
default: () => ({}),
required: true,
},
@ -84,7 +84,7 @@ const {t} = useI18n({useScope: 'global'})
const emit = defineEmits(['update:modelValue', 'change'])
const task = ref<TaskModel>()
const task = ref<ITask>()
const repeatAfter = reactive({
amount: 0,
type: '',

View File

@ -98,7 +98,7 @@
<script lang="ts">
import {defineComponent} from 'vue'
import TaskModel from '../../../models/task'
import TaskModel, { type ITask } from '../../../models/task'
import PriorityLabel from './priorityLabel.vue'
import TaskService from '../../../services/task'
import BaseButton from '@/components/base/BaseButton.vue'
@ -129,7 +129,7 @@ export default defineComponent({
},
props: {
theTask: {
type: TaskModel,
type: Object as PropType<ITask>,
required: true,
},
isArchived: {