mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
change dashboard ui to use api instead of inertia props
This commit is contained in:
committed by
Constantin Graf
parent
01f6f0f5ea
commit
6ba0b19d40
@@ -1,32 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import RecentlyTrackedTasksCardEntry from '@/Components/Dashboard/RecentlyTrackedTasksCardEntry.vue';
|
||||
import DashboardCard from '@/Components/Dashboard/DashboardCard.vue';
|
||||
import { CheckCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { PlusCircleIcon } from '@heroicons/vue/24/solid';
|
||||
import { router } from '@inertiajs/vue3';
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { computed } from "vue";
|
||||
import RecentlyTrackedTasksCardEntry from "@/Components/Dashboard/RecentlyTrackedTasksCardEntry.vue";
|
||||
import DashboardCard from "@/Components/Dashboard/DashboardCard.vue";
|
||||
import { CheckCircleIcon } from "@heroicons/vue/20/solid";
|
||||
import SecondaryButton from "@/packages/ui/src/Buttons/SecondaryButton.vue";
|
||||
import { PlusCircleIcon } from "@heroicons/vue/24/solid";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import { getCurrentMembershipId, getCurrentOrganizationId } from "@/utils/useUser";
|
||||
import { api } from "@/packages/api/src";
|
||||
import { LoadingSpinner } from "@/packages/ui/src";
|
||||
|
||||
const props = defineProps<{
|
||||
latestTasks: {
|
||||
id: string;
|
||||
name: string;
|
||||
project_name: string;
|
||||
project_id: string;
|
||||
}[];
|
||||
}>();
|
||||
// Get the organization ID using the utility function
|
||||
const organizationId = computed(() => getCurrentOrganizationId());
|
||||
|
||||
// Function to fetch latest tasks using the API client
|
||||
|
||||
// Set up the query
|
||||
const { data: timeEntriesResponse, isLoading, refetch } = useQuery({
|
||||
queryKey: ["timeEntries", organizationId],
|
||||
queryFn: () => {
|
||||
return api.getTimeEntries({
|
||||
params: {
|
||||
organization: organizationId.value!
|
||||
},
|
||||
queries: {
|
||||
member_id: getCurrentMembershipId()
|
||||
}
|
||||
});
|
||||
},
|
||||
enabled: computed(() => !!organizationId.value)
|
||||
});
|
||||
|
||||
const latestTasks = computed(() => {
|
||||
if (!timeEntriesResponse.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return timeEntriesResponse.value.data;
|
||||
});
|
||||
|
||||
const filteredLatestTasks = computed(() => {
|
||||
// do not include running time entries
|
||||
const finishedTimeEntries = latestTasks.value.filter((item) => item.end !== null);
|
||||
|
||||
// filter out duplicates based on description, task, project, tags and billable
|
||||
return finishedTimeEntries.filter((item, index, self) => {
|
||||
return index === self.findIndex((t) => (
|
||||
t.description === item.description &&
|
||||
t.task_id === item.task_id &&
|
||||
t.project_id === item.project_id &&
|
||||
t.tags.length === item.tags.length &&
|
||||
t.tags.every((tag) => item.tags.includes(tag)) &&
|
||||
t.billable === item.billable
|
||||
));
|
||||
}).slice(0, 4);
|
||||
});
|
||||
|
||||
|
||||
// Listen for dashboard refresh events
|
||||
window.addEventListener("dashboard:refresh", () => {
|
||||
refetch();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DashboardCard title="Recently Tracked Tasks" :icon="CheckCircleIcon">
|
||||
<RecentlyTrackedTasksCardEntry
|
||||
v-for="lastTask in props.latestTasks"
|
||||
:key="lastTask.id"
|
||||
:class="props.latestTasks.length === 4 ? 'last:border-0' : ''"
|
||||
:project_id="lastTask.project_id"
|
||||
:task_id="lastTask.id"
|
||||
:title="lastTask.name"></RecentlyTrackedTasksCardEntry>
|
||||
<DashboardCard title="Recent Time Entries" :icon="CheckCircleIcon">
|
||||
<div v-if="isLoading" class="flex justify-center items-center h-40">
|
||||
<LoadingSpinner />
|
||||
</div>
|
||||
<div v-else-if="filteredLatestTasks && filteredLatestTasks.length > 0">
|
||||
<RecentlyTrackedTasksCardEntry
|
||||
v-for="lastTask in filteredLatestTasks"
|
||||
:key="lastTask.id"
|
||||
:time-entry="lastTask"
|
||||
:class="filteredLatestTasks.length === 4 ? 'last:border-0' : ''"></RecentlyTrackedTasksCardEntry>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.latestTasks.length === 0"
|
||||
v-else
|
||||
class="text-center flex flex-1 justify-center items-center">
|
||||
<div>
|
||||
<PlusCircleIcon
|
||||
@@ -36,12 +87,12 @@ const props = defineProps<{
|
||||
</h3>
|
||||
<p class="pb-5 text-sm">Create tasks inside of a project!</p>
|
||||
<SecondaryButton @click="router.visit(route('projects'))"
|
||||
>Go to Projects
|
||||
>Go to Projects
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.latestTasks.length === 1"
|
||||
v-if="latestTasks && latestTasks.length === 1"
|
||||
class="text-center flex flex-1 justify-center items-center text-sm">
|
||||
<div>
|
||||
<PlusCircleIcon
|
||||
@@ -49,7 +100,7 @@ const props = defineProps<{
|
||||
<h3 class="text-white font-semibold">Add more tasks</h3>
|
||||
<p class="pb-5">Create tasks inside of a project!</p>
|
||||
<SecondaryButton @click="router.visit(route('projects'))"
|
||||
>Go to Projects
|
||||
>Go to Projects
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user