refactor: move entity component to @halo-dev/components package

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/613/head
Ryan Wang 2022-09-14 11:17:15 +08:00
parent a49d03d025
commit 6892135644
18 changed files with 283 additions and 196 deletions

View File

@ -19,3 +19,4 @@ export * from "./components/pagination";
export * from "./components/codemirror";
export * from "./components/empty";
export * from "./components/status";
export * from "./components/entity";

View File

@ -0,0 +1,89 @@
<script lang="ts" setup>
import { IconMore, VSpace } from "@halo-dev/components";
import { computed } from "vue";
const props = withDefaults(
defineProps<{
isSelected?: boolean;
}>(),
{
isSelected: false,
}
);
const classes = computed(() => {
const result = [];
if (props.isSelected) {
result.push("entity-selected");
}
return result;
});
</script>
<template>
<div :class="classes" class="entity-wrapper group">
<div v-show="isSelected" class="entity-selected-indicator"></div>
<slot name="prepend" />
<div class="entity-body">
<div v-if="$slots.checkbox" class="entity-checkbox">
<slot name="checkbox" />
</div>
<div class="entity-start">
<slot name="start" />
</div>
<div class="entity-end">
<slot name="end" />
</div>
<div v-if="$slots.dropdownItems" class="entity-dropdown">
<FloatingDropdown>
<div class="entity-dropdown-trigger group-hover:bg-gray-100">
<IconMore />
</div>
<template #popper>
<div class="w-48 p-2">
<VSpace class="w-full" direction="column">
<slot name="dropdownItems"></slot>
</VSpace>
</div>
</template>
</FloatingDropdown>
</div>
</div>
</div>
</template>
<style lang="scss">
.entity-wrapper {
@apply relative block cursor-pointer px-4 py-3 transition-all hover:bg-gray-50;
&.entity-selected {
@apply bg-gray-100;
}
.entity-selected-indicator {
@apply absolute inset-y-0 left-0 w-0.5 bg-primary;
}
.entity-body {
@apply relative flex flex-row items-center;
}
.entity-checkbox {
@apply mr-4 hidden items-center sm:flex;
}
.entity-start {
@apply flex flex-1 items-center gap-4;
}
.entity-end {
@apply flex flex-col items-end gap-4 sm:flex-row sm:items-center sm:gap-6;
}
.entity-dropdown {
@apply ml-4 inline-flex items-center;
}
.entity-dropdown-trigger {
@apply cursor-pointer rounded p-1 transition-all hover:text-blue-600;
}
}
</style>

View File

@ -20,16 +20,10 @@ const emit = defineEmits<{
</script>
<template>
<div class="inline-flex flex-col gap-1">
<div
v-if="title || $slots.title"
class="inline-flex flex-col items-center sm:flex-row"
>
<div class="entity-field-wrapper">
<div v-if="title || $slots.title" class="entity-field-title-body">
<slot name="title">
<div
class="mr-0 truncate text-sm font-medium text-gray-900 sm:mr-2"
@click="emit('click')"
>
<div class="entity-field-title" @click="emit('click')">
<RouterLink v-if="route" :to="route">
{{ title }}
</RouterLink>
@ -42,13 +36,35 @@ const emit = defineEmits<{
</div>
<div
v-if="description || $slots.description"
class="inline-flex items-center"
class="entity-field-description-body"
>
<slot name="description">
<span v-if="description" class="text-xs text-gray-500">
<span v-if="description" class="entity-field-description">
{{ description }}
</span>
</slot>
</div>
</div>
</template>
<style lang="scss">
.entity-field-wrapper {
@apply inline-flex flex-col gap-1;
.entity-field-title-body {
@apply inline-flex flex-col items-center sm:flex-row;
.entity-field-title {
@apply mr-0 truncate text-sm font-medium text-gray-900 sm:mr-2;
}
}
.entity-field-description-body {
@apply inline-flex items-center;
.entity-field-description {
@apply text-xs text-gray-500;
}
}
}
</style>

View File

@ -0,0 +1,9 @@
import { mount } from "@vue/test-utils";
import { describe, expect, it } from "vitest";
import { VEntity } from "..";
describe("Entity", () => {
it("should render", () => {
expect(mount(VEntity)).toBeDefined();
});
});

View File

@ -0,0 +1,9 @@
import { mount } from "@vue/test-utils";
import { describe, expect, it } from "vitest";
import { VEntityField } from "..";
describe("EntityField", () => {
it("should render", () => {
expect(mount(VEntityField)).toBeDefined();
});
});

View File

@ -0,0 +1,2 @@
export { default as VEntity } from "./Entity.vue";
export { default as VEntityField } from "./EntityField.vue";

View File

@ -1,55 +0,0 @@
<script lang="ts" setup>
import { IconMore, VSpace } from "@halo-dev/components";
withDefaults(
defineProps<{
isSelected?: boolean;
}>(),
{
isSelected: false,
}
);
</script>
<template>
<div
:class="{
'bg-gray-100': isSelected,
}"
class="group relative block cursor-pointer px-4 py-3 transition-all hover:bg-gray-50"
>
<div
v-show="isSelected"
class="absolute inset-y-0 left-0 w-0.5 bg-primary"
></div>
<slot name="prepend" />
<div class="relative flex flex-row items-center">
<div v-if="$slots.checkbox" class="mr-4 hidden items-center sm:flex">
<slot name="checkbox" />
</div>
<div class="flex flex-1 items-center gap-4">
<slot name="start" />
</div>
<div
class="flex flex-col items-end gap-4 sm:flex-row sm:items-center sm:gap-6"
>
<slot name="end" />
</div>
<div v-if="$slots.menuItems" class="ml-4 inline-flex items-center">
<FloatingDropdown>
<div
class="cursor-pointer rounded p-1 transition-all hover:text-blue-600 group-hover:bg-gray-100"
>
<IconMore />
</div>
<template #popper>
<div class="w-48 p-2">
<VSpace class="w-full" direction="column">
<slot name="menuItems"></slot>
</VSpace>
</div>
</template>
</FloatingDropdown>
</div>
</div>
</div>
</template>

View File

@ -17,6 +17,8 @@ import {
IconCloseCircle,
IconFolder,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import LazyImage from "@/components/image/LazyImage.vue";
import UserDropdownSelector from "@/components/dropdown-selector/UserDropdownSelector.vue";
@ -36,8 +38,6 @@ import cloneDeep from "lodash.clonedeep";
import { isImage } from "@/utils/image";
import { useRouteQuery } from "@vueuse/router";
import { useFetchAttachmentGroup } from "./composables/use-attachment-group";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
const policyVisible = ref(false);
const uploadVisible = ref(false);
@ -557,7 +557,7 @@ onMounted(() => {
role="list"
>
<li v-for="(attachment, index) in attachments.items" :key="index">
<Entity :is-selected="isChecked(attachment)">
<VEntity :is-selected="isChecked(attachment)">
<template #checkbox>
<input
:checked="selectedAttachments.has(attachment)"
@ -567,7 +567,7 @@ onMounted(() => {
/>
</template>
<template #start>
<EntityField>
<VEntityField>
<template #description>
<div
class="h-10 w-10 rounded border bg-white p-1 hover:shadow-sm"
@ -580,8 +580,8 @@ onMounted(() => {
/>
</div>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:title="attachment.spec.displayName"
@click="handleClickItem(attachment)"
>
@ -595,15 +595,15 @@ onMounted(() => {
</span>
</VSpace>
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField
<VEntityField
:description="
getPolicyName(attachment.spec.policyRef?.name)
"
/>
<EntityField>
<VEntityField>
<template #description>
<RouterLink
:to="{
@ -615,8 +615,8 @@ onMounted(() => {
{{ attachment.spec.uploadedBy?.name }}
</RouterLink>
</template>
</EntityField>
<EntityField v-if="attachment.metadata.deletionTimestamp">
</VEntityField>
<VEntityField v-if="attachment.metadata.deletionTimestamp">
<template #description>
<VStatusDot
v-tooltip="`删除中`"
@ -624,17 +624,17 @@ onMounted(() => {
animate
/>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="
formatDatetime(attachment.metadata.creationTimestamp)
"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton v-close-popper block type="danger"> 删除 </VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>
</div>

View File

@ -1,10 +1,15 @@
<script lang="ts" setup>
import { ref } from "vue";
import { VEmpty, VSpace, VButton, IconAddCircle } from "@halo-dev/components";
import {
VEmpty,
VSpace,
VButton,
IconAddCircle,
VEntity,
VEntityField,
} from "@halo-dev/components";
import type { PagesPublicState } from "@halo-dev/admin-shared";
import { useExtensionPointsState } from "@/composables/usePlugins";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
const pagesPublicState = ref<PagesPublicState>({
functionalPages: [],
@ -40,15 +45,15 @@ useExtensionPointsState("PAGES", pagesPublicState);
:key="index"
v-permission="page.permissions"
>
<Entity>
<VEntity>
<template #start>
<EntityField
<VEntityField
:title="page.name"
:route="page.path"
:description="page.url"
></EntityField>
></VEntityField>
</template>
</Entity>
</VEntity>
</li>
</ul>
</template>

View File

@ -16,6 +16,8 @@ import {
VEmpty,
VAvatar,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import SinglePageSettingModal from "./components/SinglePageSettingModal.vue";
import UserDropdownSelector from "@/components/dropdown-selector/UserDropdownSelector.vue";
@ -30,8 +32,6 @@ import { apiClient } from "@halo-dev/admin-shared";
import { formatDatetime } from "@/utils/date";
import { RouterLink } from "vue-router";
import cloneDeep from "lodash.clonedeep";
import Entity from "../../../components/entity/Entity.vue";
import EntityField from "../../../components/entity/EntityField.vue";
enum SinglePagePhase {
DRAFT = "未发布",
@ -334,7 +334,7 @@ const handleSelectUser = (user?: User) => {
role="list"
>
<li v-for="(singlePage, index) in singlePages.items" :key="index">
<Entity :is-selected="checkAll">
<VEntity :is-selected="checkAll">
<template #checkbox>
<input
v-model="checkAll"
@ -343,7 +343,7 @@ const handleSelectUser = (user?: User) => {
/>
</template>
<template #start>
<EntityField
<VEntityField
:title="singlePage.page.spec.title"
:description="singlePage.page.status?.permalink"
:route="{
@ -364,10 +364,10 @@ const handleSelectUser = (user?: User) => {
<VStatusDot state="success" animate />
</RouterLink>
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField>
<VEntityField>
<template #description>
<RouterLink
v-for="(
@ -389,9 +389,9 @@ const handleSelectUser = (user?: User) => {
></VAvatar>
</RouterLink>
</template>
</EntityField>
<EntityField :description="finalStatus(singlePage.page)" />
<EntityField>
</VEntityField>
<VEntityField :description="finalStatus(singlePage.page)" />
<VEntityField>
<template #description>
<IconEye
v-if="singlePage.page.spec.visible === 'PUBLIC'"
@ -409,14 +409,14 @@ const handleSelectUser = (user?: User) => {
class="cursor-pointer text-sm transition-all hover:text-blue-600"
/>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="
formatDatetime(singlePage.page.metadata.creationTimestamp)
"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -434,7 +434,7 @@ const handleSelectUser = (user?: User) => {
删除
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>

View File

@ -18,11 +18,11 @@ import {
VSpace,
VAvatar,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import UserDropdownSelector from "@/components/dropdown-selector/UserDropdownSelector.vue";
import PostSettingModal from "./components/PostSettingModal.vue";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
import PostTag from "../posts/tags/components/PostTag.vue";
import { onMounted, ref, watch, watchEffect } from "vue";
import type {
@ -740,7 +740,7 @@ function handleContributorFilterItemChange(user?: User) {
role="list"
>
<li v-for="(post, index) in posts.items" :key="index">
<Entity :is-selected="checkSelection(post.post)">
<VEntity :is-selected="checkSelection(post.post)">
<template #checkbox>
<input
v-model="selectedPostNames"
@ -751,7 +751,7 @@ function handleContributorFilterItemChange(user?: User) {
/>
</template>
<template #start>
<EntityField
<VEntityField
:title="post.post.spec.title"
:route="{
name: 'PostEditor',
@ -797,10 +797,10 @@ function handleContributorFilterItemChange(user?: User) {
<span class="text-xs text-gray-500"> 评论 0 </span>
</VSpace>
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField>
<VEntityField>
<template #description>
<RouterLink
v-for="(contributor, contributorIndex) in post.contributors"
@ -820,9 +820,11 @@ function handleContributorFilterItemChange(user?: User) {
></VAvatar>
</RouterLink>
</template>
</EntityField>
<EntityField :description="finalStatus(post.post)"></EntityField>
<EntityField>
</VEntityField>
<VEntityField
:description="finalStatus(post.post)"
></VEntityField>
<VEntityField>
<template #description>
<IconEye
v-if="post.post.spec.visible === 'PUBLIC'"
@ -840,14 +842,14 @@ function handleContributorFilterItemChange(user?: User) {
class="cursor-pointer text-sm transition-all hover:text-blue-600"
/>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="
formatDatetime(post.post.metadata.creationTimestamp)
"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -865,7 +867,7 @@ function handleContributorFilterItemChange(user?: User) {
删除
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>

View File

@ -1,11 +1,15 @@
<script lang="ts" setup>
import { IconList, VButton, VStatusDot } from "@halo-dev/components";
import {
IconList,
VButton,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import Draggable from "vuedraggable";
import type { CategoryTree } from "../utils";
import { ref } from "vue";
import { formatDatetime } from "@/utils/date";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
withDefaults(
defineProps<{
@ -51,7 +55,7 @@ function onDelete(category: CategoryTree) {
>
<template #item="{ element: category }">
<li>
<Entity>
<VEntity>
<template #prepend>
<div
class="drag-element absolute inset-y-0 left-0 hidden w-3.5 cursor-move items-center bg-gray-100 transition-all hover:bg-gray-200 group-hover:flex"
@ -60,25 +64,25 @@ function onDelete(category: CategoryTree) {
</div>
</template>
<template #start>
<EntityField
<VEntityField
:title="category.spec.displayName"
:description="category.status.permalink"
/>
</template>
<template #end>
<EntityField v-if="category.metadata.deletionTimestamp">
<VEntityField v-if="category.metadata.deletionTimestamp">
<template #description>
<VStatusDot v-tooltip="``" state="warning" animate />
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="`${category.status?.posts?.length || 0} 篇文章`"
/>
<EntityField
<VEntityField
:description="formatDatetime(category.metadata.creationTimestamp)"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -96,7 +100,7 @@ function onDelete(category: CategoryTree) {
删除
</VButton>
</template>
</Entity>
</VEntity>
<CategoryListItem
:categories="category.spec.children"
class="pl-10 transition-all duration-300"

View File

@ -14,11 +14,11 @@ import {
VPageHeader,
VSpace,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import TagEditingModal from "./components/TagEditingModal.vue";
import PostTag from "./components/PostTag.vue";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
// types
import type { Tag } from "@halo-dev/api-client";
@ -175,30 +175,30 @@ onMounted(async () => {
role="list"
>
<li v-for="(tag, index) in tags" :key="index">
<Entity
<VEntity
:is-selected="selectedTag?.metadata.name === tag.metadata.name"
>
<template #start>
<EntityField :description="tag.status?.permalink">
<VEntityField :description="tag.status?.permalink">
<template #title>
<PostTag :tag="tag" />
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField v-if="tag.metadata.deletionTimestamp">
<VEntityField v-if="tag.metadata.deletionTimestamp">
<template #description>
<VStatusDot v-tooltip="``" state="warning" animate />
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="`${tag.status?.posts?.length || 0} 篇文章`"
/>
<EntityField
<VEntityField
:description="formatDatetime(tag.metadata.creationTimestamp)"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -216,7 +216,7 @@ onMounted(async () => {
删除
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>

View File

@ -1,10 +1,15 @@
<script lang="ts" setup>
import { IconList, VButton, VTag, VStatusDot } from "@halo-dev/components";
import {
IconList,
VButton,
VTag,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import Draggable from "vuedraggable";
import { ref } from "vue";
import type { MenuTreeItem } from "@/modules/interface/menus/utils";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
withDefaults(
defineProps<{
@ -66,7 +71,7 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
>
<template #item="{ element: menuItem }">
<li>
<Entity>
<VEntity>
<template #prepend>
<div
class="drag-element absolute inset-y-0 left-0 hidden w-3.5 cursor-move items-center bg-gray-100 transition-all hover:bg-gray-200 group-hover:flex"
@ -75,7 +80,7 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
</div>
</template>
<template #start>
<EntityField
<VEntityField
:title="menuItem.status.displayName"
:description="menuItem.status.href"
>
@ -84,16 +89,16 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
{{ getMenuItemRefDisplayName(menuItem) }}
</VTag>
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField v-if="menuItem.metadata.deletionTimestamp">
<VEntityField v-if="menuItem.metadata.deletionTimestamp">
<template #description>
<VStatusDot v-tooltip="``" state="warning" animate />
</template>
</EntityField>
</VEntityField>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -111,7 +116,7 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
删除
</VButton>
</template>
</Entity>
</VEntity>
<MenuItemListItem
:menu-tree-items="menuItem.spec.children"
class="pl-10 transition-all duration-300"

View File

@ -6,14 +6,14 @@ import {
VEmpty,
VSpace,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import MenuEditingModal from "./MenuEditingModal.vue";
import { defineExpose, onMounted, ref } from "vue";
import type { Menu } from "@halo-dev/api-client";
import { apiClient } from "@halo-dev/admin-shared";
import { useRouteQuery } from "@vueuse/router";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
const props = withDefaults(
defineProps<{
@ -145,23 +145,23 @@ defineExpose({
:key="index"
@click="handleSelect(menu)"
>
<Entity
<VEntity
:is-selected="selectedMenu?.metadata.name === menu.metadata.name"
>
<template #start>
<EntityField
<VEntityField
:title="menu.spec?.displayName"
:description="`${menu.spec.menuItems?.length || 0} 个菜单项`"
></EntityField>
></VEntityField>
</template>
<template #end>
<EntityField v-if="menu.metadata.deletionTimestamp">
<VEntityField v-if="menu.metadata.deletionTimestamp">
<template #description>
<VStatusDot v-tooltip="``" state="warning" animate />
</template>
</EntityField>
</VEntityField>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -179,7 +179,7 @@ defineExpose({
删除
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>
<template #footer>

View File

@ -5,9 +5,9 @@ import {
VSwitch,
VTag,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
import { toRefs } from "vue";
import { usePluginLifeCycle } from "../composables/use-plugin";
import type { Plugin } from "@halo-dev/api-client";
@ -27,9 +27,9 @@ const { plugin } = toRefs(props);
const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
</script>
<template>
<Entity>
<VEntity>
<template #start>
<EntityField>
<VEntityField>
<template #description>
<div class="h-12 w-12 rounded border bg-white p-1 hover:shadow-sm">
<img
@ -39,8 +39,8 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
/>
</div>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:title="plugin?.spec.displayName"
:description="plugin?.spec.description"
:route="{
@ -55,10 +55,10 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
</VTag>
</VSpace>
</template>
</EntityField>
</VEntityField>
</template>
<template #end>
<EntityField v-if="plugin?.status?.phase === 'FAILED'">
<VEntityField v-if="plugin?.status?.phase === 'FAILED'">
<template #description>
<VStatusDot
v-tooltip="`${plugin?.status?.reason}:${plugin?.status?.message}`"
@ -66,8 +66,8 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
animate
/>
</template>
</EntityField>
<EntityField>
</VEntityField>
<VEntityField>
<template #description>
<a
:href="plugin?.spec.homepage"
@ -77,13 +77,13 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
@{{ plugin?.spec.author }}
</a>
</template>
</EntityField>
<EntityField :description="plugin?.spec.version" />
<EntityField
</VEntityField>
<VEntityField :description="plugin?.spec.version" />
<VEntityField
v-if="plugin?.metadata.creationTimestamp"
:description="formatDatetime(plugin?.metadata.creationTimestamp)"
/>
<EntityField>
<VEntityField>
<template #description>
<div
v-permission="['system:plugins:manage']"
@ -95,12 +95,12 @@ const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
/>
</div>
</template>
</EntityField>
</VEntityField>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton v-close-popper block type="danger" @click="uninstall">
卸载
</VButton>
</template>
</Entity>
</VEntity>
</template>

View File

@ -16,10 +16,10 @@ import {
VSpace,
VTag,
VStatusDot,
VEntity,
VEntityField,
} from "@halo-dev/components";
import RoleEditingModal from "./components/RoleEditingModal.vue";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
// constants
import { rbacAnnotations } from "@/constants/annotations";
@ -201,9 +201,9 @@ const handleDelete = async (role: Role) => {
</template>
<ul class="box-border h-full w-full divide-y divide-gray-100" role="list">
<li v-for="(role, index) in roles" :key="index">
<Entity>
<VEntity>
<template #start>
<EntityField
<VEntityField
:title="
role.metadata.annotations?.[rbacAnnotations.DISPLAY_NAME] ||
role.metadata.name
@ -223,25 +223,25 @@ const handleDelete = async (role: Role) => {
name: role.metadata.name,
},
}"
></EntityField>
></VEntityField>
</template>
<template #end>
<EntityField v-if="role.metadata.deletionTimestamp">
<VEntityField v-if="role.metadata.deletionTimestamp">
<template #description>
<VStatusDot v-tooltip="``" state="warning" animate />
</template>
</EntityField>
<EntityField description="0 个用户" />
<EntityField>
</VEntityField>
<VEntityField description="0 个用户" />
<VEntityField>
<template #description>
<VTag> 系统保留</VTag>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="formatDatetime(role.metadata.creationTimestamp)"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -262,7 +262,7 @@ const handleDelete = async (role: Role) => {
基于此角色创建
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>

View File

@ -11,6 +11,8 @@ import {
VSpace,
VTag,
VAvatar,
VEntity,
VEntityField,
} from "@halo-dev/components";
import UserEditingModal from "./components/UserEditingModal.vue";
import UserPasswordChangeModal from "./components/UserPasswordChangeModal.vue";
@ -20,8 +22,6 @@ import type { User, UserList } from "@halo-dev/api-client";
import { rbacAnnotations } from "@/constants/annotations";
import { formatDatetime } from "@/utils/date";
import { useRouteQuery } from "@vueuse/router";
import Entity from "@/components/entity/Entity.vue";
import EntityField from "@/components/entity/EntityField.vue";
const checkAll = ref(false);
const editingModal = ref<boolean>(false);
@ -276,7 +276,7 @@ onMounted(() => {
</template>
<ul class="box-border h-full w-full divide-y divide-gray-100" role="list">
<li v-for="(user, index) in users.items" :key="index">
<Entity :is-selected="checkAll">
<VEntity :is-selected="checkAll">
<template #checkbox>
<input
v-model="checkAll"
@ -286,7 +286,7 @@ onMounted(() => {
/>
</template>
<template #start>
<EntityField>
<VEntityField>
<template #description>
<VAvatar
:alt="user.spec.displayName"
@ -294,8 +294,8 @@ onMounted(() => {
size="md"
></VAvatar>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:title="user.spec.displayName"
:description="user.metadata.name"
:route="{
@ -305,7 +305,7 @@ onMounted(() => {
/>
</template>
<template #end>
<EntityField>
<VEntityField>
<template #description>
<div
v-for="(role, roleIndex) in getRoles(user)"
@ -317,12 +317,12 @@ onMounted(() => {
</VTag>
</div>
</template>
</EntityField>
<EntityField
</VEntityField>
<VEntityField
:description="formatDatetime(user.metadata.creationTimestamp)"
/>
</template>
<template #menuItems>
<template #dropdownItems>
<VButton
v-close-popper
block
@ -339,7 +339,7 @@ onMounted(() => {
修改密码
</VButton>
</template>
</Entity>
</VEntity>
</li>
</ul>