feature/feat-useList-composable #2589

Closed
dpschen wants to merge 7 commits from dpschen/frontend:feature/feat-useList-composable into main
5 changed files with 104 additions and 52 deletions
Showing only changes of commit f9a825b577 - Show all commits

View File

@ -300,6 +300,7 @@ const router = createRouter({
meta: {
showAsModal: true,
},
props: route => ({ listId: Number(route.params.listId as string) }),
},
{
path: '/lists/:listId/settings/share',

View File

@ -1,8 +1,22 @@
import {computed, ref, shallowReactive, unref, watch} from 'vue'
import {useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
import type {MaybeRef} from '@vueuse/core'
import {success} from '@/message'
import AbstractService from './abstractService'
import ListModel from '@/models/list'
import type {IList} from '@/modelTypes/IList'
import TaskService from './task'
import {colorFromHex} from '@/helpers/color/colorFromHex'
import ListDuplicateModel from '@/models/listDuplicateModel'
import ListDuplicateService from './listDuplicateService'
import {useListStore} from '@/stores/lists'
import {useNamespaceStore} from '@/stores/namespaces'
import type {IList} from '@/modelTypes/IList'
import type {INamespace} from '@/modelTypes/INamespace'
export default class ListService extends AbstractService<IList> {
constructor() {
@ -62,4 +76,59 @@ export default class ListService extends AbstractService<IList> {
cancel()
}
}
}
export function useList(listId?: MaybeRef<IList['id']>) {
const {t} = useI18n({useScope: 'global'})
const router = useRouter()
const listStore = useListStore()
const namespaceStore = useNamespaceStore()
const currentListId = computed(() => unref(listId))
const list = ref<IList>(new ListModel())
const listDuplicateService = shallowReactive(new ListDuplicateService())
const isDuplicatingList = computed(() => listDuplicateService.loading)
// load list
watch(() => unref(listId), async (watchedListId) => {
if (watchedListId === undefined) {
return
}
list.value = listStore.getListById(watchedListId) || list.value
// TODO: load list from server
}, {immediate: true})
async function duplicateList(namespaceId: INamespace['id']) {
const listDuplicate = new ListDuplicateModel({
listId: currentListId.value,
namespaceId: namespaceId,
})
const duplicate = await listDuplicateService.create(listDuplicate)
namespaceStore.addListToNamespace(duplicate.list)
listStore.setList(duplicate.list)
success({message: t('list.duplicate.success')})
router.push({name: 'list.index', params: {listId: duplicate.list.id}})
}
async function deleteList() {
if (!list.value) {
return
}
await listStore.deleteList(list.value)
success({message: t('list.delete.success')})
router.push({name: 'home'})
}
return {
duplicateList,
isDuplicatingList,
}
}

View File

@ -27,34 +27,36 @@
</template>
<script setup lang="ts">
import {computed, ref, watchEffect} from 'vue'
import {computed, ref, watch} from 'vue'
import {useTitle} from '@/composables/useTitle'
import {useI18n} from 'vue-i18n'
import {useRoute, useRouter} from 'vue-router'
import {success} from '@/message'
import TaskCollectionService from '@/services/taskCollection'
import Loading from '@/components/misc/loading.vue'
import {useListStore} from '@/stores/lists'
import type {IList} from '@/modelTypes/IList'
const props = defineProps<{
listId: IList['id']
}>()
const {t} = useI18n({useScope: 'global'})
const listStore = useListStore()
const route = useRoute()
const router = useRouter()
const totalTasks = ref<number | null>(null)
const list = computed(() => listStore.getListById(route.params.listId))
watchEffect(
() => {
if (!route.params.listId) {
watch(
() => props.listId,
async (currentListId) => {
if (!currentListId) {
return
}
const taskCollectionService = new TaskCollectionService()
taskCollectionService.getAll({listId: route.params.listId}).then(() => {
totalTasks.value = taskCollectionService.totalPages * taskCollectionService.resultCount
})
await taskCollectionService.getAll({listId: currentListId})
totalTasks.value = taskCollectionService.totalPages * taskCollectionService.resultCount
},
)

View File

@ -4,7 +4,7 @@
primary-icon="paste"
:primary-label="$t('list.duplicate.label')"
@primary="duplicateList"
:loading="listDuplicateService.loading"
:loading="isDuplicatingList"
>
<p>{{ $t('list.duplicate.text') }}</p>
@ -20,22 +20,23 @@
</template>
<script setup lang="ts">
import {ref, shallowReactive} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {ref, toRefs} from 'vue'
import {useI18n} from 'vue-i18n'
import ListDuplicateService from '@/services/listDuplicateService'
import CreateEdit from '@/components/misc/create-edit.vue'
import Multiselect from '@/components/input/multiselect.vue'
import ListDuplicateModel from '@/models/listDuplicateModel'
import type {INamespace} from '@/modelTypes/INamespace'
import type {IList} from '@/modelTypes/IList'
import {success} from '@/message'
import {useTitle} from '@/composables/useTitle'
import {useNamespaceSearch} from '@/composables/useNamespaceSearch'
import {useListStore} from '@/stores/lists'
import {useNamespaceStore} from '@/stores/namespaces'
import {useList} from '@/services/list'
const props = defineProps<{
listId: IList['id']
}>()
const {listId} = toRefs(props)
const {t} = useI18n({useScope: 'global'})
useTitle(() => t('list.duplicate.title'))
@ -46,30 +47,12 @@ const {
} = useNamespaceSearch()
const selectedNamespace = ref<INamespace>()
function selectNamespace(namespace: INamespace) {
selectedNamespace.value = namespace
}
const route = useRoute()
const router = useRouter()
const listStore = useListStore()
const namespaceStore = useNamespaceStore()
const listDuplicateService = shallowReactive(new ListDuplicateService())
async function duplicateList() {
const listDuplicate = new ListDuplicateModel({
// FIXME: should be parameter
listId: route.params.listId,
namespaceId: selectedNamespace.value?.id,
})
const duplicate = await listDuplicateService.create(listDuplicate)
namespaceStore.addListToNamespace(duplicate.list)
listStore.setList(duplicate.list)
success({message: t('list.duplicate.success')})
router.push({name: 'list.index', params: {listId: duplicate.list.id}})
}
const {
duplicateList,
isDuplicatingList,
} = useList(listId)
</script>

View File

@ -70,7 +70,7 @@ export default { name: 'list-setting-edit' }
</script>
<script setup lang="ts">
import type {PropType} from 'vue'
import {toRefs, type PropType} from 'vue'
import {useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
@ -85,24 +85,21 @@ import {useList} from '@/stores/lists'
import {useTitle} from '@/composables/useTitle'
const props = defineProps({
listId: {
type: Number as PropType<IList['id']>,
required: true,
},
})
const props = defineProps<{
listId: IList['id']
}>()
const {listId} = toRefs(props)
const router = useRouter()
const {t} = useI18n({useScope: 'global'})
const {list, save: saveList, isLoading} = useList(props.listId)
const {list, save: saveList, isLoading} = useList(listId)
useTitle(() => list?.title ? t('list.edit.title', {list: list.title}) : '')
async function save() {
await saveList()
await useBaseStore().handleSetCurrentList({list})
await useBaseStore().handleSetCurrentList({list: list.value})
router.back()
}
</script>