修改minicard 和 侧壁案例
This commit is contained in:
parent
5148df4491
commit
4277e5cc92
|
@ -11,7 +11,7 @@ $tertiary-color: #c4c744;
|
|||
$bg-color-1: #3B8AFF;
|
||||
$bg-color-2: #0051B5;
|
||||
|
||||
$unfocused-color: #8A92A6;
|
||||
$unfocused-color: #a4abbc;
|
||||
|
||||
$light-text-color: #04040B;
|
||||
$light-unfocused-color: $unfocused-color;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import {useDataStore} from "~/strores/DataStore";
|
||||
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
||||
|
||||
import { MoveDown,CircleAlert,CircleX } from 'lucide-vue-next';
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
|
@ -32,14 +32,15 @@ const dataStore = useDataStore()
|
|||
const mainStore = useMainLayoutStore()
|
||||
const status=ref<string>("success")
|
||||
//监听dataStore变更
|
||||
const value=ref<number>(Number(values.value[0]))
|
||||
dataStore.$subscribe((_, state) => {
|
||||
//获得d3YT#cpuUserUsage的key的value
|
||||
const watcher = Array.isArray(props.watcher) ? [...props.watcher] : [props.watcher];
|
||||
// 使用map函数从state.data中取出每个watcherKey对应的值
|
||||
values.value = watcher.map(watcherKey => state.data[watcherKey as string]);
|
||||
//检测第一个值超过50则warning 超过80则error
|
||||
const value=Number(values.value[0])
|
||||
status.value = value > 80 ? "error" : value > 50 ? "warning" : "success";
|
||||
value.value=Number(values.value[0])
|
||||
status.value = value.value > 80 ? "error" : value.value > 50 ? "warning" : "success";
|
||||
})
|
||||
|
||||
</script>
|
||||
|
@ -48,26 +49,23 @@ dataStore.$subscribe((_, state) => {
|
|||
<n-popover trigger="hover" placement="bottom">
|
||||
<template #trigger>
|
||||
<div class="mini-card-box">
|
||||
<!-- <svg fill="none" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">-->
|
||||
<!-- <circle cx="36" cy="36" r="32" stroke="#E9ECEF" stroke-width="2"/>-->
|
||||
<!-- <circle :id="title" :stroke-dasharray="circumference" cx="36"-->
|
||||
<!-- cy="36" r="32" stroke="red"-->
|
||||
<!-- stroke-linecap="round"-->
|
||||
<!-- stroke-width="4" transform="rotate(-90, 36, 36)"/>-->
|
||||
<!-- <path-->
|
||||
<!-- :id="title+'Arrow'"-->
|
||||
<!-- d="M26.1904 44.784C25.8209 45.1944 25.854 45.8267 26.2645 46.1963C26.6749 46.5658 27.3072 46.5327 27.6767 46.1223L26.1904 44.784ZM43.7763 27.8042C43.7474 27.2527 43.2768 26.829 42.7253 26.8579L33.7376 27.3289C33.1861 27.3578 32.7624 27.8284 32.7913 28.3799C32.8202 28.9314 33.2908 29.3551 33.8423 29.3262L41.8313 28.9075L42.25 36.8965C42.2789 37.4481 42.7495 37.8717 43.301 37.8428C43.8525 37.8139 44.2762 37.3434 44.2473 36.7919L43.7763 27.8042ZM27.6767 46.1223L43.5208 28.5257L42.0345 27.1874L26.1904 44.784L27.6767 46.1223Z"-->
|
||||
<!-- fill="#ADB5BD"/>-->
|
||||
<!-- </svg>-->
|
||||
<n-progress type="dashboard" processing gap-position="bottom" :status="status" :percentage="
|
||||
<n-progress type="circle" processing :status="status" :percentage="
|
||||
values[0]
|
||||
" style="width: 4.427vw; max-width:120px;min-width: 80px" />
|
||||
" style="width: 68px;">
|
||||
<MoveDown class="arrow" :style="{transform:`rotate(${(100-value)/100*360*-1}deg)`}" v-if="status==='success'"/>
|
||||
<div class="warning" v-if="status==='warning'">
|
||||
<CircleAlert />
|
||||
</div>
|
||||
<div class="error" v-if="status==='error'">
|
||||
<CircleX />
|
||||
</div>
|
||||
</n-progress>
|
||||
<div class="text">
|
||||
<h3>
|
||||
{{ title }}
|
||||
</h3>
|
||||
<h2>
|
||||
<span>{{ Number(values[0]??0).toFixed(2)}}{{ unit }}</span>
|
||||
{{ Number(values[0]??0).toFixed(2)}}{{ unit }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,10 +84,12 @@ dataStore.$subscribe((_, state) => {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
background: $light-bg-color;
|
||||
padding: $padding*1.5;
|
||||
padding: 20px 24px ;
|
||||
|
||||
|
||||
border-radius: $radius;
|
||||
box-shadow: 0 10px 30px 0 rgba(17, 38, 146, 0.05);
|
||||
gap: $gap*3;
|
||||
gap: 25px;
|
||||
border: $border;
|
||||
*{
|
||||
@include SC_Font()
|
||||
|
@ -104,28 +104,76 @@ dataStore.$subscribe((_, state) => {
|
|||
}
|
||||
}
|
||||
|
||||
.arrow{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
stroke: $light-unfocused-color;
|
||||
//旋转中心为几何中心
|
||||
transform-origin: center;
|
||||
//过度
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $gap;
|
||||
|
||||
justify-content: center;
|
||||
h2, h3 {
|
||||
color: $light-unfocused-color;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 175%; /* 28px */
|
||||
//不允许换行
|
||||
text-wrap: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 25px;
|
||||
font-weight: 800;
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: $light-text-color;
|
||||
.dark-mode & {
|
||||
color: $dark-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.warning,.error{
|
||||
display: flex;
|
||||
place-items: center;
|
||||
place-content: center;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 50%;
|
||||
animation: background-fade-error 0.5s infinite ease-in-out;
|
||||
svg{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
stroke: #fff;
|
||||
}
|
||||
}
|
||||
.warning{
|
||||
animation: background-fade 1s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes background-fade {
|
||||
0% {
|
||||
background-color: rgba(255, 255, 0, 0.3); /* 黄色,完全透明 */
|
||||
}
|
||||
50% {
|
||||
background-color: rgba(255, 255, 0, 1); /* 黄色,完全不透明 */
|
||||
}
|
||||
100% {
|
||||
background-color: rgba(255, 255, 0, 0.3); /* 黄色,完全透明 */
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes background-fade-error {
|
||||
0% {
|
||||
background-color: rgba(255, 0, 0, 0.3); /* 红色,完全透明 */
|
||||
}
|
||||
50% {
|
||||
background-color: rgba(255, 0, 0, 1); /* 红色,完全不透明 */
|
||||
box-shadow: 0 0 10px rgba(255, 0, 0, 0.5); /* 红色阴影 */
|
||||
}
|
||||
100% {
|
||||
background-color: rgba(255, 0, 0, 0.3); /* 红色,完全透明 */
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -11,6 +11,7 @@ import {useLoadStore} from "~/strores/LoadStore";
|
|||
import type {HttpType} from "~/types/baseType";
|
||||
import type {UserInfoType} from "~/types/UserType";
|
||||
import {deepEqual} from "~/utils";
|
||||
import { Atom ,LineChart,Combine} from 'lucide-vue-next';
|
||||
|
||||
const layout = ref<IGridItem[]>([])
|
||||
const presetLayouts = ref<Layouts>(<Layouts>{})
|
||||
|
@ -28,22 +29,6 @@ onMounted(() => {
|
|||
})
|
||||
const visible = ref(false)
|
||||
const cardVisible = ref(false)
|
||||
const items = ref([
|
||||
{
|
||||
label: '添加图表',
|
||||
icon: 'pi pi-chart-line',
|
||||
command: () => {
|
||||
visible.value = true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '添加信息卡片',
|
||||
icon: 'pi pi-plus',
|
||||
command: () => {
|
||||
cardVisible.value = true
|
||||
}
|
||||
},
|
||||
])
|
||||
|
||||
const layoutChangedEvent = _.throttle((newLayout: IGridItem[]) => {
|
||||
let breakPoint = 'lg';
|
||||
|
@ -103,40 +88,38 @@ watchDebounced(
|
|||
</script>
|
||||
<template>
|
||||
<div class="main-grid-layout">
|
||||
<SpeedDial :model="items" class="speed-button" :tooltipOptions="{ position: 'left' }" />
|
||||
<Dialog
|
||||
v-model:visible="visible"
|
||||
:pt="{
|
||||
root: {
|
||||
style:'border:unset;background-color:unset;'
|
||||
},
|
||||
mask: {
|
||||
style: 'backdrop-filter: blur(20px)'
|
||||
}
|
||||
}"
|
||||
modal
|
||||
>
|
||||
<template #container="{ closeCallback }">
|
||||
<SettingCard :close-callback="closeCallback"/>
|
||||
</template>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
v-model:visible="cardVisible"
|
||||
:pt="{
|
||||
root: {
|
||||
style:'border:unset;background-color:unset;'
|
||||
},
|
||||
mask: {
|
||||
style: 'backdrop-filter: blur(20px)'
|
||||
}
|
||||
|
||||
}"
|
||||
modal
|
||||
>
|
||||
<template #container="{ closeCallback }">
|
||||
<AddCard :close-callback="closeCallback"/>
|
||||
<n-float-button :right="42" :bottom="90" position="fixed" style="z-index: 200" type="primary" menu-trigger="hover">
|
||||
<n-icon>
|
||||
<Atom/>
|
||||
</n-icon>
|
||||
<template #menu>
|
||||
<n-float-button @click=" visible = true" >
|
||||
<n-icon>
|
||||
<LineChart/>
|
||||
</n-icon>
|
||||
</n-float-button>
|
||||
<n-float-button @click="cardVisible = true">
|
||||
<n-icon>
|
||||
<Combine />
|
||||
</n-icon>
|
||||
</n-float-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</n-float-button >
|
||||
<n-modal
|
||||
v-model:show="visible"
|
||||
preset="card"
|
||||
style="width: 500px"
|
||||
>
|
||||
<SettingCard />
|
||||
</n-modal>
|
||||
<n-modal
|
||||
v-model:show="cardVisible"
|
||||
preset="card"
|
||||
style="width: 500px"
|
||||
>
|
||||
<AddCard/>
|
||||
</n-modal>
|
||||
<GridLayout
|
||||
ref="el"
|
||||
v-model:layout="layout"
|
||||
|
|
|
@ -119,7 +119,7 @@ onMounted(() => {
|
|||
'Authorization': 'Bearer ' + useCookie('token').value
|
||||
},
|
||||
params: {
|
||||
serverId: mainLayoutStore.SelectServer.id
|
||||
serverId: mainLayoutStore.SelectServer.value
|
||||
},
|
||||
baseURL: useRuntimeConfig().public.baseUrl
|
||||
}).then(res => {
|
||||
|
@ -175,15 +175,12 @@ onMounted(() => {
|
|||
<div v-if="select===1" class="step2-box">
|
||||
<div v-for="(chart,index) in ServerSelect" class="Select-box">
|
||||
<p>数据槽 {{ index + 1 }}</p>
|
||||
<Dropdown v-model="ServerSelect[index]" :highlightOnSelect="false" :options="ServerValues" :pt="{
|
||||
root:{
|
||||
style:'background:#eee'
|
||||
}
|
||||
}"
|
||||
checkmark optionLabel="dataName" placeholder="选择一个数据来源"/>
|
||||
<n-select v-model:value="ServerSelect[index]" :options="ServerValues.map(serverId=>{})" />
|
||||
<Icon :size="20" :stroke-width="0.7" name="X" @click="removeServerValue(index)"/>
|
||||
</div>
|
||||
<Button icon="pi pi-plus" label="添加一个数据槽" @click="addServerValue"/>
|
||||
<n-button type="info" @click="addServerValue">
|
||||
添加一个数据槽
|
||||
</n-button>
|
||||
</div>
|
||||
<div v-if="select===2" class="step3-box">
|
||||
<div v-for="setting in CardSettings" class="setting-box">
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
13123
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -25,7 +25,6 @@ onMounted(()=>{
|
|||
|
||||
|
||||
|
||||
|
||||
const mainLayoutStore = useMainLayoutStore()
|
||||
const connection = new HubConnectionBuilder()
|
||||
.withUrl(`${useRuntimeConfig().public.baseUrl}/TerminalHub`,{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
||||
import {type MenuOption, NIcon} from "naive-ui";
|
||||
import { LayoutGrid,Computer,Cpu,Cctv,UserRoundCog,Goal,Settings,LogOut,PanelLeftClose,PanelLeftOpen } from 'lucide-vue-next';
|
||||
import { LayoutGrid,Computer,Cpu,Cctv,UserRoundCog,Goal,Settings,LogOut,PanelLeftClose,PanelLeftOpen,SquareTerminal } from 'lucide-vue-next';
|
||||
import type {Component} from "vue";
|
||||
import { useLoadingBar } from 'naive-ui'
|
||||
const {$gsap} = useNuxtApp()
|
||||
|
@ -25,6 +25,11 @@ const menuOptions: MenuOption[] = [
|
|||
key: 'host',
|
||||
icon:renderIcon(Computer),
|
||||
children: [
|
||||
{
|
||||
label: '终端',
|
||||
key: 'terminal',
|
||||
icon:renderIcon(SquareTerminal)
|
||||
},
|
||||
{
|
||||
label: 'CPU',
|
||||
key: 'host/cpu',
|
||||
|
@ -58,6 +63,9 @@ const menuOptions: MenuOption[] = [
|
|||
icon:renderIcon(LogOut)
|
||||
}
|
||||
]
|
||||
defineExpose({
|
||||
menuOptions
|
||||
})
|
||||
watch(()=>activeKey.value,async (newValue)=>{
|
||||
loadingBar.start()
|
||||
await navigateTo("/"+newValue)
|
||||
|
|
|
@ -1,22 +1,45 @@
|
|||
<script lang="ts" setup>
|
||||
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
||||
import SidebarRight from "~/components/SidebarRight.vue";
|
||||
import { Signature } from 'lucide-vue-next';
|
||||
import {Signature} from 'lucide-vue-next';
|
||||
|
||||
const router = useRouter()
|
||||
const routes=computed(()=>{
|
||||
const route=router.currentRoute.value.name as string
|
||||
const routes = computed(() => {
|
||||
const route = router.currentRoute.value.name as string
|
||||
return route.split('-').map(x => {
|
||||
return x.charAt(0).toUpperCase() + x.slice(1)
|
||||
})
|
||||
})
|
||||
const visibleRight = ref(false)
|
||||
const value=ref()
|
||||
type menuType = {
|
||||
[key: string]: string;
|
||||
}
|
||||
const menus: menuType = {
|
||||
'Home': '概览',
|
||||
'Host': '主机',
|
||||
'Cpu': '处理器',
|
||||
'Network': '网络',
|
||||
'ServerUser': '用户监测',
|
||||
'Id': '用户',
|
||||
'User': '账号管理',
|
||||
'InspectionRecords': '巡检记录',
|
||||
'Settings': '设置'
|
||||
}
|
||||
const getMenuInfo = (key: string) => {
|
||||
return menus[key] ?? key
|
||||
}
|
||||
const value = ref()
|
||||
const options = ref(['@gmail.com', '@outlook.com', '@yahoo.com'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="title-bar-layout">
|
||||
<n-breadcrumb separator=">">
|
||||
<n-breadcrumb-item v-for="i in routes" :key="i">
|
||||
{{ getMenuInfo(i) }}
|
||||
</n-breadcrumb-item>
|
||||
</n-breadcrumb>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<n-auto-complete
|
||||
v-model:value="value"
|
||||
:input-props="{
|
||||
|
@ -26,10 +49,6 @@ const options = ref(['@gmail.com', '@outlook.com', '@yahoo.com'])
|
|||
placeholder="搜索"
|
||||
clearable
|
||||
/>
|
||||
<div class="action">
|
||||
<Icon name="BellRing" @click="visibleRight=true" :stroke-width="1.5" :size="20"/>
|
||||
<Icon name="Mail" :stroke-width="1.5" :size="20"/>
|
||||
</div>
|
||||
<div class="user">
|
||||
<UserMini/>
|
||||
</div>
|
||||
|
@ -50,19 +69,20 @@ const options = ref(['@gmail.com', '@outlook.com', '@yahoo.com'])
|
|||
border-bottom: $border;
|
||||
gap: $gap*2;
|
||||
@include SC_Font();
|
||||
|
||||
.dark-mode & {
|
||||
background: $dark-bg-color;
|
||||
border-bottom: $border-dark;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.n-breadcrumb){
|
||||
ul{
|
||||
:deep(.n-breadcrumb) {
|
||||
ul {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
align-content: center;
|
||||
|
||||
li>span{
|
||||
li > span {
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
|
||||
|
@ -70,42 +90,4 @@ const options = ref(['@gmail.com', '@outlook.com', '@yahoo.com'])
|
|||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 700;
|
||||
font-size: 26px;
|
||||
color: $light-text-color;
|
||||
|
||||
.dark-mode & {
|
||||
color: $dark-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.user {
|
||||
grid-column: 4;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
gap: $gap*2;
|
||||
grid-column: 3;
|
||||
svg{
|
||||
cursor: pointer;
|
||||
stroke: rgba(51, 51, 51, 0.5);
|
||||
&:hover{
|
||||
stroke: $light-text-color;
|
||||
}
|
||||
.dark-mode &{
|
||||
stroke: rgba(255, 255, 255, 0.5);
|
||||
&:hover{
|
||||
stroke: $dark-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.p-breadcrumb){
|
||||
background: unset;
|
||||
.p-menuitem-text{
|
||||
color: #D3D3D3;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -201,7 +201,7 @@ onKeyStroke('Shift', (e) => {
|
|||
<Term/>
|
||||
</n-modal>
|
||||
<div class="main-box">
|
||||
<n-back-top :right="50" style="z-index: 200"/>
|
||||
<n-back-top :right="40" style="z-index: 200"/>
|
||||
<div ref="mainRef" class="main">
|
||||
<div class="hero">
|
||||
<div class="hero-box">
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'main',
|
||||
middleware: ['auth']
|
||||
})
|
||||
const panels=ref<(string|number)[]>([1, 2, 3, 4, 5])
|
||||
const name=ref<string|number>(1)
|
||||
const handleAdd=()=>{
|
||||
//添加一个
|
||||
|
||||
panels.value.push(panels.value.length+1)
|
||||
|
||||
}
|
||||
const handleClose=(name: number|string)=>{
|
||||
panels.value=panels.value.filter((item)=>item!=name)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="terminal-layout">
|
||||
<Term/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "base";
|
||||
.terminal-layout{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: $radius;
|
||||
border: $border;
|
||||
}
|
||||
|
||||
</style>
|
Loading…
Reference in New Issue