perf: refine dashboard widgets

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/622/head
Ryan Wang 2022-09-23 22:50:06 +08:00
parent e13d086236
commit 9d020c073e
6 changed files with 42 additions and 62 deletions

View File

@ -72,12 +72,6 @@
<template v-for="(group, groupIndex) in widgetsGroup" :key="groupIndex">
<div v-if="activeId === group.id" class="mt-4">
<VAlert
v-if="group.notice"
:description="group.notice"
class="mb-4"
title="提示"
/>
<grid-layout
:col-num="12"
:is-draggable="false"
@ -114,7 +108,6 @@ import {
IconDashboard,
IconSave,
IconSettings,
VAlert,
VButton,
VModal,
VPageHeader,
@ -125,17 +118,13 @@ import { ref } from "vue";
import { useStorage } from "@vueuse/core";
import cloneDeep from "lodash.clonedeep";
const settings = ref(false);
const widgetsModal = ref(false);
const activeId = ref("post");
const widgetsGroup = [
{
id: "post",
label: "文章",
widgets: [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "PostStatsWidget" },
{ x: 3, y: 0, w: 6, h: 10, i: 1, widget: "RecentPublishedWidget" },
{ x: 0, y: 0, w: 6, h: 10, i: 1, widget: "RecentPublishedWidget" },
],
},
{
@ -148,15 +137,9 @@ const widgetsGroup = [
label: "用户",
widgets: [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" },
{ x: 3, y: 0, w: 6, h: 10, i: 1, widget: "RecentLoginWidget" },
{ x: 0, y: 0, w: 6, h: 10, i: 1, widget: "RecentLoginWidget" },
],
},
{
id: "plugin-journal",
label: "日志",
notice: "此组件由插件 plugin-journal 提供",
widgets: [{ x: 0, y: 0, w: 5, h: 8, i: 0, widget: "JournalPublishWidget" }],
},
{
id: "other",
label: "其他",
@ -167,29 +150,25 @@ const widgetsGroup = [
},
];
const settings = ref(false);
const widgetsModal = ref(false);
const activeId = ref(widgetsGroup[0].id);
const layout = useStorage("widgets", [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "PostStatsWidget" },
{ x: 3, y: 0, w: 3, h: 3, i: 1, widget: "UserStatsWidget" },
{ x: 6, y: 0, w: 3, h: 3, i: 2, widget: "CommentStatsWidget" },
{ x: 9, y: 0, w: 3, h: 3, i: 3, widget: "ViewsStatsWidget" },
{ x: 8, y: 3, w: 4, h: 10, i: 4, widget: "RecentLoginWidget" },
{ x: 0, y: 3, w: 4, h: 10, i: 5, widget: "QuickLinkWidget" },
{
x: 5,
x: 4,
y: 3,
w: 4,
h: 10,
i: 4,
i: 6,
widget: "RecentPublishedWidget",
},
{ x: 9, y: 3, w: 3, h: 10, i: 5, widget: "RecentLoginWidget" },
{
x: 0,
y: 13,
w: 4,
h: 10,
i: 6,
widget: "JournalPublishWidget",
},
{ x: 0, y: 3, w: 5, h: 10, i: 7, widget: "QuickLinkWidget" },
]);
// eslint-disable-next-line

View File

@ -3,7 +3,6 @@ import Dashboard from "./Dashboard.vue";
import { IconDashboard } from "@halo-dev/components";
import CommentStatsWidget from "./widgets/CommentStatsWidget.vue";
import JournalPublishWidget from "./widgets/JournalPublishWidget.vue";
import PostStatsWidget from "./widgets/PostStatsWidget.vue";
import QuickLinkWidget from "./widgets/QuickLinkWidget.vue";
import RecentLoginWidget from "./widgets/RecentLoginWidget.vue";
@ -15,7 +14,6 @@ export default definePlugin({
name: "dashboardModule",
components: [
CommentStatsWidget,
JournalPublishWidget,
PostStatsWidget,
QuickLinkWidget,
RecentLoginWidget,

View File

@ -1,9 +1,23 @@
<script lang="ts" name="CommentStatsWidget" setup>
import { apiClient } from "@/utils/api-client";
import { VCard } from "@halo-dev/components";
import { onMounted, ref } from "vue";
const commentTotal = ref<number>(0);
const handleFetchComments = async () => {
const { data } =
await apiClient.extension.comment.listcontentHaloRunV1alpha1Comment();
commentTotal.value = data.total;
};
onMounted(handleFetchComments);
</script>
<template>
<VCard class="h-full">
<dt class="truncate text-sm font-medium text-gray-500">评论</dt>
<dd class="mt-1 text-3xl font-semibold text-gray-900">53</dd>
<dd class="mt-1 text-3xl font-semibold text-gray-900">
{{ commentTotal }}
</dd>
</VCard>
</template>

View File

@ -1,15 +0,0 @@
<script lang="ts" name="JournalPublishWidget" setup>
import { VButton, VCard, VTextarea } from "@halo-dev/components";
</script>
<template>
<VCard
:body-class="['h-full', 'overflow-y-auto']"
class="h-full"
title="日志发表"
>
<VTextarea :rows="6" />
<template #footer>
<VButton type="secondary">发布</VButton>
</template>
</VCard>
</template>

View File

@ -10,12 +10,12 @@ const { users } = useUserFetch({ fetchOnMounted: true });
class="h-full"
title="最近登录"
>
<div class="h-full p-4">
<div class="h-full">
<ul class="divide-y divide-gray-200" role="list">
<li
v-for="(user, index) in users"
:key="index"
class="cursor-pointer py-4 hover:bg-gray-50"
class="cursor-pointer p-4 hover:bg-gray-50"
>
<div class="flex items-center space-x-4">
<div class="flex flex-shrink-0 items-center">
@ -34,8 +34,8 @@ const { users } = useUserFetch({ fetchOnMounted: true });
</p>
</div>
<div>
<time class="text-sm text-gray-500" datetime="2020-01-07 20:00">
2020-01-07 20:00
<time class="text-sm text-gray-500">
{{ user.status?.lastLoginAt }}
</time>
</div>
</div>

View File

@ -1,16 +1,20 @@
<script lang="ts" name="RecentPublishedWidget" setup>
import { VCard, VSpace } from "@halo-dev/components";
import { onMounted, ref } from "vue";
import type { Post } from "@halo-dev/api-client";
import type { ListedPost } from "@halo-dev/api-client";
import { apiClient } from "@/utils/api-client";
import { formatDatetime } from "@/utils/date";
const posts = ref<Post[]>([] as Post[]);
const posts = ref<ListedPost[]>([] as ListedPost[]);
const handleFetchPosts = async () => {
try {
const { data } =
await apiClient.extension.post.listcontentHaloRunV1alpha1Post();
const { data } = await apiClient.post.listPosts({
sort: "PUBLISH_TIME",
publishPhase: "PUBLISHED",
page: 1,
size: 10,
});
posts.value = data.items;
} catch (e) {
console.error("Failed to fetch posts", e);
@ -23,19 +27,19 @@ onMounted(handleFetchPosts);
<VCard
:body-class="['h-full', '!p-0', 'overflow-y-auto']"
class="h-full"
title="最近发布"
title="最近文章"
>
<div class="h-full p-4">
<div class="h-full">
<ul class="divide-y divide-gray-200" role="list">
<li
v-for="(post, index) in posts"
:key="index"
class="cursor-pointer py-4 hover:bg-gray-50"
class="cursor-pointer p-4 hover:bg-gray-50"
>
<div class="flex items-center space-x-4">
<div class="min-w-0 flex-1">
<p class="truncate text-sm font-medium text-gray-900">
{{ post.spec.title }}
{{ post.post.spec.title }}
</p>
<div class="mt-1 flex">
<VSpace>
@ -47,7 +51,7 @@ onMounted(handleFetchPosts);
<div>
<time class="text-sm text-gray-500">
{{ formatDatetime(post.metadata.creationTimestamp) }}
{{ formatDatetime(post.post.spec.publishTime) }}
</time>
</div>
</div>