perf: refine user detail page

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/624/head
Ryan Wang 2022-09-27 16:47:13 +08:00
parent b6321d1bb8
commit 3e8112cbbb
3 changed files with 43 additions and 30 deletions

View File

@ -32,11 +32,20 @@ export default defineConfig({
fileName: (format) => `halo-components.${format}.js`, fileName: (format) => `halo-components.${format}.js`,
}, },
rollupOptions: { rollupOptions: {
external: ["vue", "vue-router"], external: [
"vue",
"vue-router",
"@vueuse/core",
"@vueuse/components",
"@vueuse/router",
],
output: { output: {
globals: { globals: {
vue: "Vue", vue: "Vue",
"vue-router": "VueRouter", "vue-router": "VueRouter",
"@vueuse/core": "VueUse",
"@vueuse/components": "VueUse",
"@vueuse/router": "VueUse",
}, },
exports: "named", exports: "named",
generatedCode: "es5", generatedCode: "es5",

View File

@ -5,6 +5,7 @@ import { computed, inject } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import type { User } from "@halo-dev/api-client"; import type { User } from "@halo-dev/api-client";
import { rbacAnnotations } from "@/constants/annotations"; import { rbacAnnotations } from "@/constants/annotations";
import { formatDatetime } from "@/utils/date";
const user = inject<Ref<User>>("user"); const user = inject<Ref<User>>("user");
@ -17,10 +18,10 @@ const roles = computed(() => {
const router = useRouter(); const router = useRouter();
</script> </script>
<template> <template>
<div class="border-t border-gray-200"> <div class="border-t border-gray-100">
<dl class="divide-y divide-gray-100"> <dl class="divide-y divide-gray-50">
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">显示名称</dt> <dt class="text-sm font-medium text-gray-900">显示名称</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
@ -28,7 +29,7 @@ const router = useRouter();
</dd> </dd>
</div> </div>
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">用户名</dt> <dt class="text-sm font-medium text-gray-900">用户名</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
@ -36,7 +37,7 @@ const router = useRouter();
</dd> </dd>
</div> </div>
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">电子邮箱</dt> <dt class="text-sm font-medium text-gray-900">电子邮箱</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
@ -44,7 +45,7 @@ const router = useRouter();
</dd> </dd>
</div> </div>
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">角色</dt> <dt class="text-sm font-medium text-gray-900">角色</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
@ -61,31 +62,25 @@ const router = useRouter();
</dd> </dd>
</div> </div>
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">描述</dt> <dt class="text-sm font-medium text-gray-900">描述</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
{{ user?.spec?.bio }} {{ user?.spec?.bio || "无" }}
</dd> </dd>
</div> </div>
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
>
<dt class="text-sm font-medium text-gray-900">两步验证</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
{{ user?.spec.twoFactorAuthEnabled ? "开启" : "关闭" }}
</dd>
</div>
<div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">注册时间</dt> <dt class="text-sm font-medium text-gray-900">注册时间</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
{{ user?.metadata?.creationTimestamp }} {{ formatDatetime(user?.metadata?.creationTimestamp) }}
</dd> </dd>
</div> </div>
<!-- TODO: add display last login time support -->
<div <div
class="bg-white py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4" v-if="false"
class="bg-white py-5 px-2 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4"
> >
<dt class="text-sm font-medium text-gray-900">最近登录时间</dt> <dt class="text-sm font-medium text-gray-900">最近登录时间</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0"> <dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">

View File

@ -1,7 +1,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { BasicLayout } from "@halo-dev/admin-shared"; import { BasicLayout } from "@halo-dev/admin-shared";
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import { IconUpload, VButton, VSpace, VTabbar } from "@halo-dev/components"; import {
IconUpload,
VButton,
VSpace,
VTabbar,
VAvatar,
} from "@halo-dev/components";
import { onMounted, provide, ref, watch } from "vue"; import { onMounted, provide, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import type { User } from "@halo-dev/api-client"; import type { User } from "@halo-dev/api-client";
@ -14,11 +20,11 @@ const tabs = [
label: "详情", label: "详情",
routeName: "UserDetail", routeName: "UserDetail",
}, },
{ // {
id: "tokens", // id: "tokens",
label: "个人令牌", // label: "",
routeName: "PersonalAccessTokens", // routeName: "PersonalAccessTokens",
}, // },
]; ];
const user = ref<User>(); const user = ref<User>();
@ -83,17 +89,20 @@ const handleTabChange = (id: string) => {
<div class="h-48 bg-gradient-to-r from-gray-800 to-red-500"></div> <div class="h-48 bg-gradient-to-r from-gray-800 to-red-500"></div>
<div class="px-4 sm:px-6 lg:px-8"> <div class="px-4 sm:px-6 lg:px-8">
<div class="-mt-12 flex items-end space-x-5 sm:-mt-16"> <div class="-mt-12 flex items-end space-x-5 sm:-mt-16">
<div class="flex"> <div v-if="user?.spec?.avatar" class="inline-flex items-center">
<div class="h-24 w-24 sm:h-32 sm:w-32"> <div class="h-24 w-24 sm:h-32 sm:w-32">
<img <VAvatar
:src="user?.spec?.avatar" :src="user?.spec?.avatar"
alt="Avatar" circle
class="h-full w-full rounded-full bg-white ring-4 ring-white drop-shadow-lg" width="100%"
height="100%"
class="ring-4 ring-white drop-shadow-lg"
/> />
</div> </div>
</div> </div>
<div <div
class="mt-6 sm:flex sm:min-w-0 sm:flex-1 sm:items-center sm:justify-end sm:space-x-6 sm:pb-1" class="mt-6 sm:flex sm:min-w-0 sm:flex-1 sm:items-center sm:justify-end sm:space-x-6 sm:pb-1"
:class="{ '!mt-12': !user?.spec?.avatar }"
> >
<div class="mt-6 block min-w-0 flex-1"> <div class="mt-6 block min-w-0 flex-1">
<h1 class="truncate text-xl font-bold text-gray-900"> <h1 class="truncate text-xl font-bold text-gray-900">