1 parent
67d30a6f32
commit
3157946186
3 files changed
+39
-37
No files matched your search
@@ -5,11 +5,16 @@ interface Props {
|
|||||||
alert?: boolean
|
alert?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<Props>()
|
const { label, value, alert } = defineProps<Props>()
|
||||||
|
const emit = defineEmits<{ click: [] }>()
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
emit('click')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-card :border="!alert" :variant="alert ? 'flat' : undefined" :color="alert ? 'error' : undefined">
|
<v-card :border="!alert" variant="flat" :color="alert ? 'error' : undefined" @click="onClick">
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div class="text-label-large" :class="{ 'text-medium-emphasis': !alert }">{{ label }}</div>
|
<div class="text-label-large" :class="{ 'text-medium-emphasis': !alert }">{{ label }}</div>
|
||||||
<div class="text-headline-large">{{ value }}</div>
|
<div class="text-headline-large">{{ value }}</div>
|
||||||
@@ -30,14 +30,18 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="projects.length" class="d-flex align-center ga-3">
|
<div v-if="projects.length" class="d-flex align-center ga-2">
|
||||||
<div>Project:</div>
|
<div>Project:</div>
|
||||||
<v-menu>
|
<v-menu>
|
||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
<v-btn-group variant="flat" density="compact" border>
|
<v-btn density="comfortable" v-bind="props">
|
||||||
<v-btn rounded="0" :text="currentProjectName" v-bind="props" />
|
<div class="d-flex ga-1 align-center">
|
||||||
<v-btn rounded="0" to="/settings/projects" icon="mdi-cog" />
|
<v-chip v-if="current" size="small" variant="flat" color="primary" density="compact">
|
||||||
</v-btn-group>
|
{{ current.key }}
|
||||||
|
</v-chip>
|
||||||
|
<div>{{ currentProjectName }}</div>
|
||||||
|
</div>
|
||||||
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<v-list
|
<v-list
|
||||||
@@ -51,9 +55,9 @@ onMounted(async () => {
|
|||||||
@update:selected="select"
|
@update:selected="select"
|
||||||
>
|
>
|
||||||
<v-list-item slim v-for="project in projects" :key="project.id" :value="project.id">
|
<v-list-item slim v-for="project in projects" :key="project.id" :value="project.id">
|
||||||
<v-list-item-title>
|
<v-list-item-title class="d-flex ga-1 align-center">
|
||||||
<v-chip size="small" color="primary" variant="flat" density="compact">{{ project.key }}</v-chip>
|
<v-chip size="small" color="primary" variant="flat" density="compact">{{ project.key }}</v-chip>
|
||||||
{{ project.name }}
|
<div>{{ project.name }}</div>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
|||||||
+21
-28
@@ -8,7 +8,7 @@ import { useStatusStore } from '@/stores/status.ts'
|
|||||||
import { authClient } from '@/lib/auth-client.ts'
|
import { authClient } from '@/lib/auth-client.ts'
|
||||||
import type { Issue } from '@/api/issue.api.ts'
|
import type { Issue } from '@/api/issue.api.ts'
|
||||||
import type { Project } from '@/api/project.api.ts'
|
import type { Project } from '@/api/project.api.ts'
|
||||||
import DashboardCard from '@/components/DashboardCard.vue'
|
import DashboardCountCard from '@/components/DashboardCountCard.vue'
|
||||||
|
|
||||||
const ACTIVE_STATUSES: Issue['status'][] = ['OPEN', 'IN_PROGRESS']
|
const ACTIVE_STATUSES: Issue['status'][] = ['OPEN', 'IN_PROGRESS']
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ const projectStore = useProjectStore()
|
|||||||
const statusStore = useStatusStore()
|
const statusStore = useStatusStore()
|
||||||
|
|
||||||
const { stats } = storeToRefs(issueStore)
|
const { stats } = storeToRefs(issueStore)
|
||||||
const { projects } = storeToRefs(projectStore)
|
const { projects, currentProjectId } = storeToRefs(projectStore)
|
||||||
|
|
||||||
const currentUserId = computed(() => session.value.data?.user.id ?? null)
|
const currentUserId = computed(() => session.value.data?.user.id ?? null)
|
||||||
|
|
||||||
@@ -54,6 +54,14 @@ watch(
|
|||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
currentProjectId,
|
||||||
|
(id) => {
|
||||||
|
void issueStore.getStat(id)
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
function isOverdue(issue: Issue) {
|
function isOverdue(issue: Issue) {
|
||||||
return !!issue.dueDate && new Date(issue.dueDate).getTime() < Date.now()
|
return !!issue.dueDate && new Date(issue.dueDate).getTime() < Date.now()
|
||||||
}
|
}
|
||||||
@@ -96,35 +104,20 @@ function openProject(project: Project) {
|
|||||||
projectStore.select(project)
|
projectStore.select(project)
|
||||||
router.push('/issues')
|
router.push('/issues')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onClickCard(status?: string) {
|
||||||
|
router.push({ path: '/issues', query: { status } })
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- <v-alert v-if="!session.data" type="info" variant="tonal">-->
|
<div v-if="session.data" class="d-flex flex-column ga-2">
|
||||||
<!-- <div class="d-flex align-center justify-space-between ga-4">-->
|
<div class="dashboard_grid">
|
||||||
<!-- <div>Войдите, чтобы видеть свои задачи и проекты</div>-->
|
<dashboard-count-card label="Всего задач" :value="stats?.total ?? 0" @click="onClickCard()" />
|
||||||
<!-- <v-btn variant="flat" to="/sign-in">Sign In</v-btn>-->
|
<dashboard-count-card label="Открыто" :value="statCount('OPEN')" @click="onClickCard('OPEN')" />
|
||||||
<!-- </div>-->
|
<dashboard-count-card label="В работе" :value="statCount('IN_PROGRESS')" @click="onClickCard('IN_PROGRESS')" />
|
||||||
<!-- </v-alert>-->
|
<dashboard-count-card label="Просрочено" :value="overdueCount" :alert="overdueCount > 0" />
|
||||||
|
|
||||||
<v-banner
|
|
||||||
v-if="!session.data"
|
|
||||||
color="error"
|
|
||||||
icon="mdi-alert"
|
|
||||||
text="Войдите, чтобы видеть свои задачи и проекты"
|
|
||||||
lines="one"
|
|
||||||
>
|
|
||||||
<template v-slot:actions>
|
|
||||||
<v-btn variant="flat" to="/sign-in">Sign In</v-btn>
|
|
||||||
</template>
|
|
||||||
</v-banner>
|
|
||||||
|
|
||||||
<div v-else class="d-flex flex-column ga-2">
|
|
||||||
<div class="dash_grid">
|
|
||||||
<dashboard-card label="Всего задач" :value="stats?.total ?? 0" />
|
|
||||||
<dashboard-card label="Открыто" :value="statCount('OPEN')" />
|
|
||||||
<dashboard-card label="В работе" :value="statCount('IN_PROGRESS')" />
|
|
||||||
<dashboard-card label="Просрочено" :value="overdueCount" :alert="overdueCount > 0" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-row density="compact">
|
<v-row density="compact">
|
||||||
@@ -210,7 +203,7 @@ function openProject(project: Project) {
|
|||||||
.cursor-pointer {
|
.cursor-pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.dash_grid {
|
.dashboard_grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
|||||||
Reference in new issue
Block a user