332 lines
14 KiB
JavaScript
332 lines
14 KiB
JavaScript
class SubToolbar extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.attachShadow({ mode: 'open' });
|
|
this._currentTool = 'home';
|
|
}
|
|
|
|
static get observedAttributes() {
|
|
return ['current-tool'];
|
|
}
|
|
|
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
if (name === 'current-tool' && oldValue !== newValue) {
|
|
this._currentTool = newValue;
|
|
this.updateSubMenu();
|
|
this.updateToolHeader();
|
|
}
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.render();
|
|
this.addEventListeners();
|
|
}
|
|
|
|
render() {
|
|
this.shadowRoot.innerHTML = `
|
|
<style>
|
|
:host {
|
|
width: 200px;
|
|
background: linear-gradient(180deg, #7986E7 0%, #8B6DB3 100%);
|
|
position: relative;
|
|
transition: width 0.3s ease;
|
|
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
:host(.collapsed) {
|
|
width: 0;
|
|
}
|
|
|
|
.sub-toolbar-wrapper {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
|
|
:host(.collapsed) .sub-toolbar-content {
|
|
transform: translateX(-200px);
|
|
}
|
|
|
|
.sub-toolbar-content {
|
|
width: 200px;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.sub-toolbar-header {
|
|
padding: 28px 20px;
|
|
height: 92px;
|
|
box-sizing: border-box;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: white;
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.sub-toolbar-header .icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.sub-menu {
|
|
display: none;
|
|
padding-top: 10px;
|
|
}
|
|
|
|
.sub-menu.active {
|
|
display: block;
|
|
}
|
|
|
|
.sub-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 10px 20px;
|
|
color: white;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.sub-item:hover {
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.sub-item.active {
|
|
background-color: rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
.icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.toolbar-toggle {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 50%;
|
|
transform: translate(50%, -50%);
|
|
width: 32px;
|
|
height: 32px;
|
|
background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
z-index: 1000;
|
|
transition: all 0.3s ease;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
:host(.collapsed) .toolbar-toggle {
|
|
right: 0;
|
|
}
|
|
|
|
.toolbar-toggle:hover {
|
|
transform: translate(50%, -50%) scale(1.1);
|
|
}
|
|
|
|
.toggle-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
</style>
|
|
<div class="sub-toolbar-wrapper">
|
|
<div class="sub-toolbar-content">
|
|
<div class="sub-toolbar-header">
|
|
<img src="assets/icons/png/home.png" alt="主页" class="icon" id="currentToolIcon">
|
|
<span id="currentToolName">主页</span>
|
|
</div>
|
|
<!-- 主页子菜单 -->
|
|
<div class="sub-menu active" data-parent="home">
|
|
<div class="sub-item" data-icon="dashboard">
|
|
<img src="assets/icons/png/dashboard.png" alt="概览" class="icon">
|
|
概览
|
|
</div>
|
|
<div class="sub-item" data-icon="clock">
|
|
<img src="assets/icons/png/clock.png" alt="更新记录" class="icon">
|
|
更新记录
|
|
</div>
|
|
<div class="sub-item" data-icon="check-square">
|
|
<img src="assets/icons/png/check-square.png" alt="待办事项" class="icon">
|
|
待办事项
|
|
</div>
|
|
<div class="sub-item" data-icon="help">
|
|
<img src="assets/icons/png/help.png" alt="帮助" class="icon">
|
|
帮助
|
|
</div>
|
|
<div class="sub-item" data-icon="question">
|
|
<img src="assets/icons/png/question.png" alt="Q&A" class="icon">
|
|
Q&A
|
|
</div>
|
|
</div>
|
|
<!-- 配置子菜单 -->
|
|
<div class="sub-menu" data-parent="config">
|
|
<div class="sub-item" data-icon="chip">
|
|
<img src="assets/icons/png/chip.png" alt="运行环境配置" class="icon">
|
|
运行环境配置
|
|
</div>
|
|
<div class="sub-item" data-icon="cube">
|
|
<img src="assets/icons/png/cube.png" alt="模型配置" class="icon">
|
|
模型配置
|
|
</div>
|
|
<div class="sub-item" data-icon="settings">
|
|
<img src="assets/icons/png/settings.png" alt="服务配置" class="icon">
|
|
服务配置
|
|
</div>
|
|
</div>
|
|
<!-- 开发子菜单 -->
|
|
<div class="sub-menu" data-parent="develop">
|
|
<div class="sub-item" data-icon="plug">
|
|
<img src="assets/icons/png/plug.png" alt="接口配置" class="icon">
|
|
接口配置
|
|
</div>
|
|
<div class="sub-item" data-icon="cube">
|
|
<img src="assets/icons/png/cube.png" alt="模型开发" class="icon">
|
|
模型开发
|
|
</div>
|
|
<div class="sub-item" data-icon="settings">
|
|
<img src="assets/icons/png/settings.png" alt="服务开发" class="icon">
|
|
服务开发
|
|
</div>
|
|
</div>
|
|
<!-- 运行子菜单 -->
|
|
<div class="sub-menu" data-parent="run">
|
|
<div class="sub-item" data-icon="flask">
|
|
<img src="assets/icons/png/flask.png" alt="运行测试" class="icon">
|
|
运行测试
|
|
</div>
|
|
<div class="sub-item" data-icon="rocket">
|
|
<img src="assets/icons/png/rocket.png" alt="运行仿真" class="icon">
|
|
运行仿真
|
|
</div>
|
|
<div class="sub-item" data-icon="file">
|
|
<img src="assets/icons/png/file.png" alt="运行日志" class="icon">
|
|
运行日志
|
|
</div>
|
|
</div>
|
|
<!-- 监控子菜单 -->
|
|
<div class="sub-menu" data-parent="monitor">
|
|
<div class="sub-item" data-icon="server">
|
|
<img src="assets/icons/png/server.png" alt="资源监控" class="icon">
|
|
资源监控
|
|
</div>
|
|
<div class="sub-item" data-icon="desktop">
|
|
<img src="assets/icons/png/desktop.png" alt="仿真监控" class="icon">
|
|
仿真监控
|
|
</div>
|
|
<div class="sub-item" data-icon="cubes">
|
|
<img src="assets/icons/png/cubes.png" alt="模型监控" class="icon">
|
|
模型监控
|
|
</div>
|
|
<div class="sub-item" data-icon="chart-bar">
|
|
<img src="assets/icons/png/chart-bar.png" alt="数据监控" class="icon">
|
|
数据监控
|
|
</div>
|
|
<div class="sub-item" data-icon="database">
|
|
<img src="assets/icons/png/database.png" alt="数据采集" class="icon">
|
|
数据采集
|
|
</div>
|
|
</div>
|
|
<!-- 系统管理子菜单 -->
|
|
<div class="sub-menu" data-parent="system">
|
|
<div class="sub-item" data-icon="user">
|
|
<img src="assets/icons/png/user.png" alt="个人中心" class="icon">
|
|
个人中心
|
|
</div>
|
|
<div class="sub-item" data-icon="file-text">
|
|
<img src="assets/icons/png/file-text.png" alt="系统日志" class="icon">
|
|
系统日志
|
|
</div>
|
|
<div class="sub-item admin-only" data-icon="users">
|
|
<img src="assets/icons/png/users.png" alt="用户管理" class="icon">
|
|
用户管理
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="toolbar-toggle" title="收起">
|
|
<img src="assets/icons/png/chevron-dleft.png" alt="收起" class="toggle-icon">
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
updateSubMenu() {
|
|
const subMenus = this.shadowRoot.querySelectorAll('.sub-menu');
|
|
subMenus.forEach(menu => {
|
|
menu.classList.toggle('active', menu.getAttribute('data-parent') === this._currentTool);
|
|
});
|
|
}
|
|
|
|
addEventListeners() {
|
|
// 切换按钮事件
|
|
const toggleButton = this.shadowRoot.querySelector('.toolbar-toggle');
|
|
toggleButton.addEventListener('click', () => {
|
|
this.classList.toggle('collapsed');
|
|
const isCollapsed = this.classList.contains('collapsed');
|
|
toggleButton.querySelector('img').src = `assets/icons/png/chevron-d${isCollapsed ? 'right' : 'left'}.png`;
|
|
toggleButton.querySelector('img').alt = isCollapsed ? '展开' : '收起';
|
|
toggleButton.title = isCollapsed ? '展开' : '收起';
|
|
});
|
|
|
|
// 子菜单项点击事件
|
|
const subItems = this.shadowRoot.querySelectorAll('.sub-item');
|
|
subItems.forEach(item => {
|
|
item.addEventListener('click', () => {
|
|
// 移除同级菜单项的激活状态
|
|
const siblings = item.parentElement.querySelectorAll('.sub-item');
|
|
siblings.forEach(si => si.classList.remove('active'));
|
|
// 激活当前菜单项
|
|
item.classList.add('active');
|
|
|
|
// 触发自定义事件
|
|
const event = new CustomEvent('sub-item-selected', {
|
|
detail: {
|
|
parent: item.closest('.sub-menu').getAttribute('data-parent'),
|
|
text: item.textContent.trim(),
|
|
icon: item.getAttribute('data-icon')
|
|
},
|
|
bubbles: true,
|
|
composed: true
|
|
});
|
|
this.dispatchEvent(event);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 更新管理员选项的显示状态
|
|
updateAdminItems(accessLevel) {
|
|
const adminItems = this.shadowRoot.querySelectorAll('.admin-only');
|
|
adminItems.forEach(item => {
|
|
item.style.display = accessLevel >= 3 ? 'flex' : 'none';
|
|
});
|
|
}
|
|
|
|
updateToolHeader() {
|
|
const toolIcons = {
|
|
'home': { icon: 'home', text: '主页' },
|
|
'develop': { icon: 'develop', text: '开发' },
|
|
'config': { icon: 'sliders', text: '配置' },
|
|
'run': { icon: 'play', text: '运行' },
|
|
'monitor': { icon: 'chart', text: '监控' },
|
|
'system': { icon: 'cogs', text: '管理' }
|
|
};
|
|
|
|
const currentTool = toolIcons[this._currentTool] || toolIcons['home'];
|
|
const iconElement = this.shadowRoot.getElementById('currentToolIcon');
|
|
const nameElement = this.shadowRoot.getElementById('currentToolName');
|
|
|
|
iconElement.src = `assets/icons/png/${currentTool.icon}.png`;
|
|
iconElement.alt = currentTool.text;
|
|
nameElement.textContent = currentTool.text;
|
|
}
|
|
}
|
|
|
|
customElements.define('sub-toolbar', SubToolbar);
|