FURTHER CASTING

This commit is contained in:
Dominik Pschenitschni
2025-01-19 18:54:39 +01:00
parent c38f56ac3d
commit 2dde5176ea
10 changed files with 115 additions and 51 deletions

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import {computed, ref, shallowReactive, watch, watchEffect} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {useRoute, useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects'
@@ -40,15 +40,19 @@ definePage({
// }
// }
// },
props: route => ({
projectId: parseInt(route.params.projectId as string),
viewId: route.params.viewId ? parseInt(route.params.viewId as string): undefined,
}),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project'>
return {
projectId: Number(castedRoute.params.projectId),
viewId: castedRoute.params.viewId ? parseInt(castedRoute.params.viewId): undefined,
}
},
})
const props = defineProps<{
projectId: number,
viewId: number,
viewId?: number,
}>()
const router = useRouter()
@@ -112,7 +116,7 @@ watch(
)
function redirectToDefaultViewIfNecessary() {
if (props.viewId === 0 || !currentView.value) {
if (props.viewId === undefined || props.viewId === 0 || !currentView.value) {
// Ideally, we would do that in the router redirect, but the projects (and therefore, the views)
// are not always loaded then.

View File

@@ -19,7 +19,7 @@ export default {name: 'ProjectSettingArchive'}
<script setup lang="ts">
import {computed} from 'vue'
import {useRouter, useRoute} from 'vue-router'
import {useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useI18n} from 'vue-i18n'
import {success} from '@/message'
@@ -28,18 +28,28 @@ import {useTitle} from '@/composables/useTitle'
import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects'
import type { IProject } from '@/modelTypes/IProject'
definePage({
name: 'project.settings.archive',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.archive'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{
projectId: IProject['id'],
}>()
const {t} = useI18n({useScope: 'global'})
const projectStore = useProjectStore()
const router = useRouter()
const route = useRoute()
const project = computed(() => projectStore.projects[route.params.projectId])
const project = computed(() => projectStore.projects[props.projectId])
useTitle(() => t('project.archive.title', {project: project.value.title}))
async function archiveProject() {

View File

@@ -112,7 +112,7 @@ export default { name: 'ProjectSettingBackground' }
<script setup lang="ts">
import {ref, computed, shallowReactive} from 'vue'
import {useI18n} from 'vue-i18n'
import {useRoute, useRouter} from 'vue-router'
import {useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useDebounceFn} from '@vueuse/core'
import BaseButton from '@/components/base/BaseButton.vue'
@@ -133,17 +133,26 @@ import {useTitle} from '@/composables/useTitle'
import CreateEdit from '@/components/misc/CreateEdit.vue'
import {success} from '@/message'
import type { IProject } from '@/modelTypes/IProject'
definePage({
name: 'project.settings.background',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.background'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{
projectId: IProject['id'],
}>()
const SEARCH_DEBOUNCE = 300
const {t} = useI18n({useScope: 'global'})
const baseStore = useBaseStore()
const route = useRoute()
const router = useRouter()
useTitle(() => t('project.background.title'))
@@ -206,7 +215,7 @@ async function setBackground(backgroundId: string) {
const project = await backgroundService.update({
id: backgroundId,
projectId: route.params.projectId,
projectId: props.projectId,
})
await baseStore.handleSetCurrentProject({project, forceUpdate: true})
projectStore.setProject(project)
@@ -220,7 +229,7 @@ async function uploadBackground() {
}
const project = await backgroundUploadService.value.create(
route.params.projectId,
props.projectId,
backgroundUploadInput.value?.files[0],
)
await baseStore.handleSetCurrentProject({project, forceUpdate: true})

View File

@@ -33,41 +33,50 @@
<script setup lang="ts">
import {computed, ref, watchEffect} from 'vue'
import {useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useTitle} from '@/composables/useTitle'
import {useI18n} from 'vue-i18n'
import {useRoute, useRouter} from 'vue-router'
import {success} from '@/message'
import Loading from '@/components/misc/Loading.vue'
import {useProjectStore} from '@/stores/projects'
import TaskService from '@/services/task'
import type { IProject } from '@/modelTypes/IProject'
definePage({
name: 'project.settings.delete',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.delete'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{
projectId: IProject['id'],
}>()
const {t} = useI18n({useScope: 'global'})
const projectStore = useProjectStore()
const route = useRoute()
const router = useRouter()
const totalTasks = ref<number | null>(null)
const project = computed(() => projectStore.projects[route.params.projectId])
const project = computed(() => projectStore.projects[props.projectId])
const projectIdsToDelete = ref<number[]>([])
watchEffect(
async () => {
if (!route.params.projectId) {
if (!props.projectId) {
return
}
projectIdsToDelete.value = projectStore
.getChildProjects(parseInt(route.params.projectId))
.getChildProjects(props.projectId)
.map(p => p.id)
projectIdsToDelete.value.push(parseInt(route.params.projectId))
projectIdsToDelete.value.push(props.projectId)
const taskService = new TaskService()
await taskService.getAll({}, {filter: `project in ${projectIdsToDelete.value.join(',')}`})

View File

@@ -13,7 +13,7 @@
<script setup lang="ts">
import {ref, watch} from 'vue'
import {useRoute} from 'vue-router'
import {type RouteLocationNormalizedLoaded} from 'vue-router'
import {useI18n} from 'vue-i18n'
import CreateEdit from '@/components/misc/CreateEdit.vue'
@@ -27,16 +27,23 @@ import type {IProject} from '@/modelTypes/IProject'
definePage({
name: 'project.settings.duplicate',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.duplicate'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{
projectId: IProject['id'],
}>()
const {t} = useI18n({useScope: 'global'})
useTitle(() => t('project.duplicate.title'))
const route = useRoute()
const projectStore = useProjectStore()
const {project, isLoading, duplicateProject} = useProject(route.params.projectId)
const {project, isLoading, duplicateProject} = useProject(() => props.projectId)
const parentProject = ref<IProject | null>(null)
watch(

View File

@@ -84,7 +84,7 @@ export default {name: 'ProjectSettingEdit'}
<script setup lang="ts">
import {watch, ref} from 'vue'
import {useRouter} from 'vue-router'
import {useRoute, useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useI18n} from 'vue-i18n'
import Editor from '@/components/input/AsyncEditor'
@@ -104,7 +104,11 @@ import {RIGHTS} from '@/constants/rights'
definePage({
name: 'project.settings.edit',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.edit'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{

View File

@@ -32,7 +32,7 @@ export default {name: 'ProjectSettingShare'}
<script lang="ts" setup>
import {ref, computed, watchEffect} from 'vue'
import {useRoute} from 'vue-router'
import {useRoute, type RouteLocationNormalizedLoaded} from 'vue-router'
import {useI18n} from 'vue-i18n'
import {useTitle} from '@vueuse/core'
@@ -51,7 +51,11 @@ import {useConfigStore} from '@/stores/config'
definePage({
name: 'project.settings.share',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.share'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const {t} = useI18n({useScope: 'global'})

View File

@@ -15,11 +15,16 @@ import ProjectModel from '@/models/project'
import Message from '@/components/misc/Message.vue'
import draggable from 'zhyswan-vuedraggable'
import {calculateItemPosition} from '@/helpers/calculateItemPosition'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
definePage({
name: 'project.settings.views',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.views'>
return { projectId: Number(castedRoute.params.projectId) }
},
})
const props = defineProps<{

View File

@@ -3,8 +3,8 @@ export default {name: 'ProjectSettingWebhooks'}
</script>
<script lang="ts" setup>
import {ref, computed, watchEffect} from 'vue'
import {useRoute} from 'vue-router'
import {ref, watchEffect} from 'vue'
import type {RouteLocationNormalizedLoaded} from 'vue-router'
import {useI18n} from 'vue-i18n'
import {useTitle} from '@vueuse/core'
@@ -28,9 +28,17 @@ import {isValidHttpUrl} from '@/helpers/isValidHttpUrl'
definePage({
name: 'project.settings.webhooks',
meta: { showAsModal: true },
props: route => ({ projectId: Number(route.params.projectId as string) }),
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'project.settings.webhooks'>
return { projectId: parseInt(castedRoute.params.projectId, 2) }
},
})
const props = defineProps<{
projectId: number
}>()
const {t} = useI18n({useScope: 'global'})
const project = ref<IProject>()
@@ -46,13 +54,7 @@ async function loadProject(projectId: number) {
await loadWebhooks()
}
const route = useRoute()
const projectId = computed(() => route.params.projectId !== undefined
? parseInt(route.params.projectId as string)
: undefined,
)
watchEffect(() => projectId.value !== undefined && loadProject(projectId.value))
watchEffect(() => props.projectId !== undefined && loadProject(props.projectId))
const webhooks = ref<IWebhook[]>()
const webhookService = new WebhookService()

View File

@@ -260,7 +260,7 @@
<script lang="ts" setup>
import {computed, ref} from 'vue'
import {useI18n} from 'vue-i18n'
import {useRoute, useRouter} from 'vue-router'
import {useRouter, type RouteLocationNormalizedLoaded} from 'vue-router'
import Editor from '@/components/input/AsyncEditor'
import FancyCheckbox from '@/components/input/FancyCheckbox.vue'
@@ -282,11 +282,22 @@ import type {ITeam} from '@/modelTypes/ITeam'
import type {IUser} from '@/modelTypes/IUser'
import type {ITeamMember} from '@/modelTypes/ITeamMember'
definePage({ name: 'teams.edit' })
definePage({
name: 'teams.edit',
props: route => {
// https://github.com/posva/unplugin-vue-router/discussions/513#discussioncomment-10695660
const castedRoute = route as RouteLocationNormalizedLoaded<'teams.edit'>
return { id: Number(castedRoute.params.id) }
},
})
const props = defineProps<{
teamId: ITeam['id'],
}>()
const authStore = useAuthStore()
const configStore = useConfigStore()
const route = useRoute()
const router = useRouter()
const {t} = useI18n({useScope: 'global'})
@@ -304,7 +315,6 @@ const teamMemberService = ref<TeamMemberService>(new TeamMemberService())
const userService = ref<UserService>(new UserService())
const team = ref<ITeam>()
const teamId = computed(() => Number(route.params.id))
const memberToDelete = ref<ITeamMember>()
const newMember = ref<IUser>()
const foundUsers = ref<IUser[]>()
@@ -320,7 +330,7 @@ const title = ref('')
loadTeam()
async function loadTeam() {
team.value = await teamService.value.get({id: teamId.value})
team.value = await teamService.value.get({id: props.teamId})
title.value = t('team.edit.title', {team: team.value?.name})
useTitle(() => title.value)
}
@@ -345,7 +355,7 @@ async function deleteTeam() {
async function deleteMember() {
try {
await teamMemberService.value.delete({
teamId: teamId.value,
teamId: props.teamId,
username: memberToDelete.value.username,
})
success({message: t('team.edit.deleteUser.success')})
@@ -362,7 +372,7 @@ async function addUser() {
return
}
await teamMemberService.value.create({
teamId: teamId.value,
teamId: props.teamId,
username: newMember.value.username,
})
newMember.value = null
@@ -373,7 +383,7 @@ async function addUser() {
async function toggleUserType(member: ITeamMember) {
// FIXME: direct manipulation
member.admin = !member.admin
member.teamId = teamId.value
member.teamId = props.teamId
const r = await teamMemberService.value.update(member)
for (const tm in team.value.members) {
if (team.value.members[tm].id === member.id) {
@@ -401,7 +411,7 @@ async function findUser(query: string) {
async function leave() {
try {
await teamMemberService.value.delete({
teamId: teamId.value,
teamId: props.teamId,
username: userInfo.value.username,
})
success({message: t('team.edit.leave.success')})