7b15300ab7
- 优化资源面板标签页布局,将图标置于文字上方 - 新增复合技和地图两个标签页 更新标签页数据结构以支持图标配置 移除未使用的naive-ui和vueuse依赖导入
147 lines
4.4 KiB
Vue
147 lines
4.4 KiB
Vue
<script setup lang="ts">
|
|
import { NButton, NIcon, NInput, NTabPane, NTabs, NText, type TabPaneProps } from 'naive-ui';
|
|
import { computed, ref, type Component } from 'vue';
|
|
import AlarmTree from './alarm-tree.vue';
|
|
import CameraTree from './camera-tree.vue';
|
|
import { ChevronLeftIcon, MapPinIcon, MapPinnedIcon, MonitorIcon, SirenIcon, WandSparklesIcon } from 'lucide-vue-next';
|
|
import { useResourcePanelStore } from '../stores';
|
|
import { storeToRefs } from 'pinia';
|
|
import BulletCamera from './icon/bullet-camera.vue';
|
|
|
|
const PANEL_WIDTH_EXPANDED = '480px';
|
|
const PANEL_WIDTH_COLLAPSED = '72px';
|
|
|
|
interface ResourceTabPane extends TabPaneProps {
|
|
name: string;
|
|
tab: string;
|
|
icon?: Component;
|
|
component?: Component;
|
|
}
|
|
|
|
const resourceTabPanes: ResourceTabPane[] = [
|
|
{ name: 'camera', tab: '摄像头', icon: BulletCamera, component: CameraTree },
|
|
{ name: 'alarm', tab: '警报器', icon: SirenIcon, component: AlarmTree },
|
|
{ name: 'monitor', tab: '监视器', icon: MonitorIcon },
|
|
{ name: 'combine-tech', tab: '复合技', icon: WandSparklesIcon },
|
|
{ name: 'leaflet-map', tab: '地图', icon: MapPinnedIcon },
|
|
];
|
|
|
|
const activeTabName = ref(resourceTabPanes.at(0)?.name ?? '');
|
|
|
|
const showSearchInput = computed(() => {
|
|
return ['camera', 'alarm'].includes(activeTabName.value);
|
|
});
|
|
|
|
const resourcePanelStore = useResourcePanelStore();
|
|
const { collapsed, searchPattern } = storeToRefs(resourcePanelStore);
|
|
|
|
const collapseResourcePanel = () => {
|
|
if (!collapsed.value) {
|
|
resourcePanelStore.toggleCollapsed();
|
|
}
|
|
};
|
|
|
|
const expandResourcePanel = () => {
|
|
if (collapsed.value) {
|
|
resourcePanelStore.toggleCollapsed();
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="resource-panel__wrapper"
|
|
:style="{
|
|
width: collapsed ? PANEL_WIDTH_COLLAPSED : PANEL_WIDTH_EXPANDED,
|
|
}"
|
|
>
|
|
<div
|
|
class="resource-panel"
|
|
:style="{
|
|
width: PANEL_WIDTH_EXPANDED,
|
|
}"
|
|
>
|
|
<div class="resource-panel__title">
|
|
<div style="display: grid; place-items: center" :style="{ width: PANEL_WIDTH_COLLAPSED }">
|
|
<NText>资源</NText>
|
|
</div>
|
|
<template v-if="showSearchInput">
|
|
<div style="width: 240px; margin-left: auto">
|
|
<NInput clearable :size="'tiny'" :placeholder="'搜索'" v-model:value="searchPattern" />
|
|
</div>
|
|
</template>
|
|
<div style="margin: 0px 16px; display: grid; place-items: center" :style="{ marginLeft: showSearchInput ? '8px' : 'auto' }">
|
|
<NButton text @click="collapseResourcePanel">
|
|
<NIcon :component="ChevronLeftIcon"></NIcon>
|
|
</NButton>
|
|
</div>
|
|
</div>
|
|
<div class="resource-panel__tabs-wrapper">
|
|
<NTabs
|
|
:type="'bar'"
|
|
:size="'small'"
|
|
:placement="'left'"
|
|
v-model:value="activeTabName"
|
|
:tab-style="{
|
|
height: '64px',
|
|
width: '72px',
|
|
}"
|
|
:style="{
|
|
height: '100%', // 为了确保 tabs 高度和 panel 高度一致,否则设备树会超出 panel 高度,导致虚拟滚动失效
|
|
'--n-pane-padding-top': '0',
|
|
'--n-tab-gap-vertical': '0',
|
|
// '--n-tab-padding-vertical': '14px 6px',
|
|
}"
|
|
>
|
|
<NTabPane
|
|
v-for="{ name: resourceName, tab: resourceTab, icon: resourceIcon, component } in resourceTabPanes"
|
|
:key="resourceName"
|
|
:name="resourceName"
|
|
:tab-props="{ onClick: () => expandResourcePanel() }"
|
|
>
|
|
<template #tab>
|
|
<div style="width: 48px; display: flex; flex-direction: column; justify-content: center; align-items: center">
|
|
<NIcon :size="18" :component="resourceIcon"></NIcon>
|
|
<div style="font-size: 12px">{{ resourceTab }}</div>
|
|
</div>
|
|
</template>
|
|
<template #default>
|
|
<template v-if="!!component">
|
|
<component :is="component" />
|
|
</template>
|
|
</template>
|
|
</NTabPane>
|
|
</NTabs>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.resource-panel__wrapper {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
transition: width 0.3s ease;
|
|
|
|
.resource-panel {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
|
|
&__title {
|
|
min-height: 42px;
|
|
max-height: 42px;
|
|
padding: 8px 0px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
&__tabs-wrapper {
|
|
flex: 1;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
}
|
|
</style>
|