feat: port attachments store to pinia
This commit is contained in:
parent
c2ba1b2828
commit
20e9420638
4 changed files with 38 additions and 30 deletions
|
@ -138,9 +138,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive, computed} from 'vue'
|
import {ref, shallowReactive, computed, type PropType} from 'vue'
|
||||||
import {useDropZone} from '@vueuse/core'
|
import {useDropZone} from '@vueuse/core'
|
||||||
import {useStore} from '@/store'
|
|
||||||
|
|
||||||
import User from '@/components/misc/user.vue'
|
import User from '@/components/misc/user.vue'
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
|
@ -148,7 +147,9 @@ import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
import AttachmentService from '@/services/attachment'
|
import AttachmentService from '@/services/attachment'
|
||||||
import type AttachmentModel from '@/models/attachment'
|
import type AttachmentModel from '@/models/attachment'
|
||||||
import type {IAttachment} from '@/modelTypes/IAttachment'
|
import type {IAttachment} from '@/modelTypes/IAttachment'
|
||||||
|
import type {ITask} from '@/modelTypes/ITask'
|
||||||
|
|
||||||
|
import {useAttachmentStore} from '@/stores/attachments'
|
||||||
import {formatDateSince, formatDateLong} from '@/helpers/time/formatDate'
|
import {formatDateSince, formatDateLong} from '@/helpers/time/formatDate'
|
||||||
import {uploadFiles, generateAttachmentUrl} from '@/helpers/attachments'
|
import {uploadFiles, generateAttachmentUrl} from '@/helpers/attachments'
|
||||||
import {getHumanSize} from '@/helpers/getHumanSize'
|
import {getHumanSize} from '@/helpers/getHumanSize'
|
||||||
|
@ -157,7 +158,7 @@ import {error, success} from '@/message'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
taskId: {
|
taskId: {
|
||||||
type: Number,
|
type: Number as PropType<ITask['id']>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
initialAttachments: {
|
initialAttachments: {
|
||||||
|
@ -170,8 +171,8 @@ const props = defineProps({
|
||||||
|
|
||||||
const attachmentService = shallowReactive(new AttachmentService())
|
const attachmentService = shallowReactive(new AttachmentService())
|
||||||
|
|
||||||
const store = useStore()
|
const attachmentStore = useAttachmentStore()
|
||||||
const attachments = computed(() => store.state.attachments.attachments)
|
const attachments = computed(() => attachmentStore.attachments)
|
||||||
|
|
||||||
function onDrop(files: File[] | null) {
|
function onDrop(files: File[] | null) {
|
||||||
if (files && files.length !== 0) {
|
if (files && files.length !== 0) {
|
||||||
|
@ -213,10 +214,7 @@ async function deleteAttachment() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await attachmentService.delete(attachmentToDelete.value)
|
const r = await attachmentService.delete(attachmentToDelete.value)
|
||||||
store.commit(
|
attachmentStore.removeById(this.attachmentToDelete.id)
|
||||||
'attachments/removeById',
|
|
||||||
attachmentToDelete.value.id,
|
|
||||||
)
|
|
||||||
success(r)
|
success(r)
|
||||||
setAttachmentToDelete(null)
|
setAttachmentToDelete(null)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -236,7 +234,7 @@ async function viewOrDownload(attachment: AttachmentModel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const copy = useCopyToClipboard()
|
const copy = useCopyToClipboard()
|
||||||
function copyUrl(attachment: AttachmentModel) {
|
function copyUrl(attachment: IAttachment) {
|
||||||
copy(generateAttachmentUrl(props.taskId, attachment.id))
|
copy(generateAttachmentUrl(props.taskId, attachment.id))
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -27,6 +27,7 @@ import type { IList } from '@/modelTypes/IList'
|
||||||
import type { RootStoreState, TaskState } from '@/store/types'
|
import type { RootStoreState, TaskState } from '@/store/types'
|
||||||
import {useLabelStore} from '@/stores/labels'
|
import {useLabelStore} from '@/stores/labels'
|
||||||
import {useListStore} from '@/stores/lists'
|
import {useListStore} from '@/stores/lists'
|
||||||
|
import {useAttachmentStore} from '@/stores/attachments'
|
||||||
import {playPop} from '@/helpers/playPop'
|
import {playPop} from '@/helpers/playPop'
|
||||||
|
|
||||||
// IDEA: maybe use a small fuzzy search here to prevent errors
|
// IDEA: maybe use a small fuzzy search here to prevent errors
|
||||||
|
@ -138,7 +139,8 @@ const tasksStore : Module<TaskState, RootStoreState>= {
|
||||||
}
|
}
|
||||||
ctx.commit('kanban/setTaskInBucketByIndex', newTask, {root: true})
|
ctx.commit('kanban/setTaskInBucketByIndex', newTask, {root: true})
|
||||||
}
|
}
|
||||||
ctx.commit('attachments/add', attachment, {root: true})
|
const attachmentStore = useAttachmentStore()
|
||||||
|
attachmentStore.add(attachment)
|
||||||
},
|
},
|
||||||
|
|
||||||
async addAssignee(ctx, {
|
async addAssignee(ctx, {
|
||||||
|
@ -282,7 +284,7 @@ const tasksStore : Module<TaskState, RootStoreState>= {
|
||||||
const labelStore = useLabelStore()
|
const labelStore = useLabelStore()
|
||||||
|
|
||||||
const labelAddsToWaitFor = parsedLabels.map(async labelTitle => {
|
const labelAddsToWaitFor = parsedLabels.map(async labelTitle => {
|
||||||
let label = validateLabel(labelStore.labels, labelTitle)
|
let label = validateLabel(Object.values(labelStore.labels), labelTitle)
|
||||||
if (typeof label === 'undefined') {
|
if (typeof label === 'undefined') {
|
||||||
// label not found, create it
|
// label not found, create it
|
||||||
const labelModel = new LabelModel({title: labelTitle})
|
const labelModel = new LabelModel({title: labelTitle})
|
||||||
|
|
|
@ -1,29 +1,34 @@
|
||||||
import type { Module } from 'vuex'
|
import {defineStore, acceptHMRUpdate} from 'pinia'
|
||||||
import {findIndexById} from '@/helpers/utils'
|
import {findIndexById} from '@/helpers/utils'
|
||||||
|
|
||||||
import type { AttachmentState, RootStoreState } from '@/store/types'
|
import type {AttachmentState} from '@/store/types'
|
||||||
import type { IAttachment } from '@/modelTypes/IAttachment'
|
import type {IAttachment} from '@/modelTypes/IAttachment'
|
||||||
|
|
||||||
const store : Module<AttachmentState, RootStoreState> = {
|
export const useAttachmentStore = defineStore('attachment', {
|
||||||
namespaced: true,
|
state: (): AttachmentState => ({
|
||||||
state: () => ({
|
|
||||||
attachments: [],
|
attachments: [],
|
||||||
}),
|
}),
|
||||||
mutations: {
|
|
||||||
set(state, attachments: IAttachment[]) {
|
actions: {
|
||||||
|
set(attachments: IAttachment[]) {
|
||||||
console.debug('Set attachments', attachments)
|
console.debug('Set attachments', attachments)
|
||||||
state.attachments = attachments
|
this.attachments = attachments
|
||||||
},
|
},
|
||||||
add(state, attachment: IAttachment) {
|
|
||||||
|
add(attachment: IAttachment) {
|
||||||
console.debug('Add attachement', attachment)
|
console.debug('Add attachement', attachment)
|
||||||
state.attachments.push(attachment)
|
this.attachments.push(attachment)
|
||||||
},
|
},
|
||||||
removeById(state, id: IAttachment['id']) {
|
|
||||||
const attachmentIndex = findIndexById<IAttachment>(state.attachments, id)
|
removeById(id: IAttachment['id']) {
|
||||||
state.attachments.splice(attachmentIndex, 1)
|
const attachmentIndex = findIndexById(this.attachments, id)
|
||||||
|
this.attachments.splice(attachmentIndex, 1)
|
||||||
console.debug('Remove attachement', id)
|
console.debug('Remove attachement', id)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
export default store
|
// support hot reloading
|
||||||
|
if (import.meta.hot) {
|
||||||
|
import.meta.hot.accept(acceptHMRUpdate(useAttachmentStore, import.meta.hot))
|
||||||
|
}
|
|
@ -463,6 +463,7 @@ import {getListTitle} from '@/helpers/getListTitle'
|
||||||
import type {IList} from '@/modelTypes/IList'
|
import type {IList} from '@/modelTypes/IList'
|
||||||
import {colorIsDark} from '@/helpers/color/colorIsDark'
|
import {colorIsDark} from '@/helpers/color/colorIsDark'
|
||||||
import {useNamespaceStore} from '@/stores/namespaces'
|
import {useNamespaceStore} from '@/stores/namespaces'
|
||||||
|
import {useAttachmentStore} from '@/stores/attachments'
|
||||||
|
|
||||||
function scrollIntoView(el) {
|
function scrollIntoView(el) {
|
||||||
if (!el) {
|
if (!el) {
|
||||||
|
@ -595,7 +596,8 @@ export default defineComponent({
|
||||||
return typeof this.task !== 'undefined' && typeof this.task.maxRight !== 'undefined' && this.task.maxRight > rights.READ
|
return typeof this.task !== 'undefined' && typeof this.task.maxRight !== 'undefined' && this.task.maxRight > rights.READ
|
||||||
},
|
},
|
||||||
hasAttachments() {
|
hasAttachments() {
|
||||||
return this.$store.state.attachments.attachments.length > 0
|
const attachmentsStore = useAttachmentStore()
|
||||||
|
return attachmentsStore.attachments.length > 0
|
||||||
},
|
},
|
||||||
shouldShowClosePopup() {
|
shouldShowClosePopup() {
|
||||||
return this.$route.name.includes('kanban')
|
return this.$route.name.includes('kanban')
|
||||||
|
@ -624,7 +626,8 @@ export default defineComponent({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.task = await this.taskService.get({id: taskId})
|
this.task = await this.taskService.get({id: taskId})
|
||||||
this.$store.commit('attachments/set', this.task.attachments)
|
const attachmentStore = useAttachmentStore()
|
||||||
|
attachmentStore.set(this.task.attachments)
|
||||||
this.taskColor = this.task.hexColor
|
this.taskColor = this.task.hexColor
|
||||||
this.setActiveFields()
|
this.setActiveFields()
|
||||||
await this.$nextTick()
|
await this.$nextTick()
|
||||||
|
|
Loading…
Reference in a new issue