mirror of
https://github.com/halo-dev/halo.git
synced 2025-12-20 16:44:38 +08:00
Move folder console to ui
This commit is contained in:
288
ui/console-src/modules/dashboard/Dashboard.vue
Normal file
288
ui/console-src/modules/dashboard/Dashboard.vue
Normal file
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<VPageHeader :title="$t('core.dashboard.title')">
|
||||
<template #icon>
|
||||
<IconDashboard class="mr-2 self-center" />
|
||||
</template>
|
||||
<template #actions>
|
||||
<VSpace>
|
||||
<VButton v-if="settings" @click="widgetsModal = true">
|
||||
<template #icon>
|
||||
<IconAddCircle class="h-full w-full" />
|
||||
</template>
|
||||
{{ $t("core.dashboard.actions.add_widget") }}
|
||||
</VButton>
|
||||
<VButton type="secondary" @click="settings = !settings">
|
||||
<template #icon>
|
||||
<IconSettings v-if="!settings" class="h-full w-full" />
|
||||
<IconSave v-else class="h-full w-full" />
|
||||
</template>
|
||||
{{
|
||||
settings
|
||||
? $t("core.dashboard.actions.done")
|
||||
: $t("core.dashboard.actions.setting")
|
||||
}}
|
||||
</VButton>
|
||||
</VSpace>
|
||||
</template>
|
||||
</VPageHeader>
|
||||
|
||||
<div class="dashboard m-4">
|
||||
<grid-layout
|
||||
v-model:layout="layout"
|
||||
:col-num="12"
|
||||
:is-draggable="settings"
|
||||
:is-resizable="settings"
|
||||
:margin="[10, 10]"
|
||||
:responsive="false"
|
||||
:row-height="30"
|
||||
:use-css-transforms="true"
|
||||
:vertical-compact="true"
|
||||
>
|
||||
<template v-for="(item, index) in layout" :key="index">
|
||||
<grid-item
|
||||
v-if="currentUserHasPermission(item.permissions)"
|
||||
:h="item.h"
|
||||
:i="item.i"
|
||||
:w="item.w"
|
||||
:x="item.x"
|
||||
:y="item.y"
|
||||
>
|
||||
<component :is="item.widget" />
|
||||
<div v-if="settings" class="absolute right-2 top-2">
|
||||
<IconCloseCircle
|
||||
class="cursor-pointer text-lg text-gray-500 hover:text-gray-900"
|
||||
@click="handleRemove(item)"
|
||||
/>
|
||||
</div>
|
||||
</grid-item>
|
||||
</template>
|
||||
</grid-layout>
|
||||
</div>
|
||||
|
||||
<VModal
|
||||
v-if="widgetsModal"
|
||||
height="calc(100vh - 20px)"
|
||||
:width="1280"
|
||||
:layer-closable="true"
|
||||
:title="$t('core.dashboard.widgets.modal_title')"
|
||||
@close="widgetsModal = false"
|
||||
>
|
||||
<VTabbar
|
||||
v-model:active-id="activeId"
|
||||
:items="
|
||||
widgetsGroup.map((group) => {
|
||||
return { id: group.id, label: group.label };
|
||||
})
|
||||
"
|
||||
type="outline"
|
||||
></VTabbar>
|
||||
<div class="mt-4">
|
||||
<template v-for="(group, groupIndex) in widgetsGroup" :key="groupIndex">
|
||||
<grid-layout
|
||||
v-if="activeId === group.id"
|
||||
:col-num="12"
|
||||
:is-draggable="false"
|
||||
:is-resizable="false"
|
||||
:layout="group.widgets"
|
||||
:margin="[10, 10]"
|
||||
:responsive="true"
|
||||
:row-height="30"
|
||||
:use-css-transforms="true"
|
||||
:vertical-compact="true"
|
||||
>
|
||||
<template v-for="(item, index) in group.widgets" :key="index">
|
||||
<grid-item
|
||||
v-if="currentUserHasPermission(item.permissions)"
|
||||
:h="item.h"
|
||||
:i="item.i"
|
||||
:w="item.w"
|
||||
:x="item.x"
|
||||
:y="item.y"
|
||||
class="cursor-pointer"
|
||||
@click="handleAddWidget(item)"
|
||||
>
|
||||
<component :is="item.widget" />
|
||||
</grid-item>
|
||||
</template>
|
||||
</grid-layout>
|
||||
</template>
|
||||
</div>
|
||||
</VModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
IconAddCircle,
|
||||
IconCloseCircle,
|
||||
IconDashboard,
|
||||
IconSave,
|
||||
IconSettings,
|
||||
VButton,
|
||||
VModal,
|
||||
VPageHeader,
|
||||
VSpace,
|
||||
VTabbar,
|
||||
} from "@halo-dev/components";
|
||||
import { ref } from "vue";
|
||||
import { useStorage } from "@vueuse/core";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { usePermission } from "@/utils/permission";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { currentUserHasPermission } = usePermission();
|
||||
|
||||
const widgetsGroup = [
|
||||
{
|
||||
id: "post",
|
||||
label: t("core.dashboard.widgets.groups.post"),
|
||||
widgets: [
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 3,
|
||||
h: 3,
|
||||
i: 0,
|
||||
widget: "PostStatsWidget",
|
||||
},
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 6,
|
||||
h: 10,
|
||||
i: 1,
|
||||
widget: "RecentPublishedWidget",
|
||||
permissions: ["system:posts:view"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "page",
|
||||
label: t("core.dashboard.widgets.groups.page"),
|
||||
widgets: [
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 3,
|
||||
h: 3,
|
||||
i: 0,
|
||||
widget: "SinglePageStatsWidget",
|
||||
permissions: ["system:singlepages:view"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "comment",
|
||||
label: t("core.dashboard.widgets.groups.comment"),
|
||||
widgets: [{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "CommentStatsWidget" }],
|
||||
},
|
||||
{
|
||||
id: "user",
|
||||
label: t("core.dashboard.widgets.groups.user"),
|
||||
widgets: [{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" }],
|
||||
},
|
||||
{
|
||||
id: "other",
|
||||
label: t("core.dashboard.widgets.groups.other"),
|
||||
widgets: [
|
||||
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "ViewsStatsWidget" },
|
||||
{ x: 0, y: 0, w: 6, h: 10, i: 1, widget: "QuickLinkWidget" },
|
||||
{ x: 0, y: 0, w: 6, h: 10, i: 2, widget: "NotificationWidget" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
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: 0,
|
||||
y: 3,
|
||||
w: 6,
|
||||
h: 12,
|
||||
i: 4,
|
||||
widget: "QuickLinkWidget",
|
||||
},
|
||||
{
|
||||
x: 6,
|
||||
y: 3,
|
||||
w: 6,
|
||||
h: 12,
|
||||
i: 5,
|
||||
widget: "NotificationWidget",
|
||||
permissions: [],
|
||||
},
|
||||
]);
|
||||
|
||||
// eslint-disable-next-line
|
||||
function handleAddWidget(widget: any) {
|
||||
layout.value = [
|
||||
...layout.value,
|
||||
{
|
||||
...widget,
|
||||
i: layout.value.length,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
function handleRemove(item: any) {
|
||||
const cloneWidgets = cloneDeep(layout.value);
|
||||
cloneWidgets.splice(item.i, 1);
|
||||
// eslint-disable-next-line
|
||||
layout.value = cloneWidgets.map((widget: any, index: number) => {
|
||||
return {
|
||||
...widget,
|
||||
i: index,
|
||||
};
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.vue-grid-layout {
|
||||
@apply -m-[10px];
|
||||
}
|
||||
|
||||
.vue-grid-item {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.vue-grid-item.vue-grid-placeholder {
|
||||
@apply bg-gray-200 !important;
|
||||
@apply opacity-100 !important;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user