XNSim/XNSimHtml/components/header-tools.js

171 lines
5.7 KiB
JavaScript

class HeaderTools extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.render();
this.addEventListeners();
}
// 添加getter方法
get selectedProduct() {
return this.shadowRoot.getElementById('productSelect').value;
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: flex;
align-items: center;
gap: 12px;
margin-left: auto;
}
.tool-item {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.tool-item:hover {
background-color: rgba(0, 0, 0, 0.05);
}
.tool-item img {
width: 20px;
height: 20px;
}
.product-container {
display: flex;
align-items: center;
gap: 8px;
}
.product-label {
font-size: 14px;
color: #666;
}
.product-select {
min-width: 120px;
height: 32px;
padding: 0 8px;
border: 1px solid #e0e0e0;
border-radius: 4px;
background-color: white;
cursor: pointer;
}
.search-box {
display: flex;
align-items: center;
height: 32px;
border: 1px solid #e0e0e0;
border-radius: 4px;
background-color: white;
padding: 0 8px;
margin-left: 50px; /* 增加与下拉框的间距 */
}
.search-box input {
border: none;
outline: none;
padding: 0 8px;
width: 120px;
}
.search-box img {
width: 16px;
height: 16px;
opacity: 0.5;
}
</style>
<div class="product-container">
<span class="product-label">构型:</span>
<select class="product-select" id="productSelect">
<option value="">选择构型</option>
</select>
</div>
<div class="search-box">
<input type="text" placeholder="搜索...">
<img src="assets/icons/png/search_b.png" alt="搜索">
</div>
<div class="tool-item" id="fontSizeBtn" title="调整字体大小">
<img src="assets/icons/png/font_b.png" alt="字体">
</div>
<div class="tool-item" id="themeBtn" title="调整主题">
<img src="assets/icons/png/palette_b.png" alt="主题">
</div>
<div class="tool-item" id="notificationBtn" title="通知">
<img src="assets/icons/png/bell_b.png" alt="通知">
</div>
<div class="tool-item" id="onlineUsersBtn" title="在线用户">
<img src="assets/icons/png/users_b.png" alt="在线用户">
</div>
`;
}
addEventListeners() {
// 加载构型列表
this.loadProducts();
// 字体大小调整
this.shadowRoot.getElementById('fontSizeBtn').addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('font-size-click'));
});
// 主题调整
this.shadowRoot.getElementById('themeBtn').addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('theme-click'));
});
// 通知
this.shadowRoot.getElementById('notificationBtn').addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('notification-click'));
});
// 在线用户
this.shadowRoot.getElementById('onlineUsersBtn').addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('online-users-click'));
});
// 构型选择
this.shadowRoot.getElementById('productSelect').addEventListener('change', (e) => {
this.dispatchEvent(new CustomEvent('product-change', {
detail: { product: e.target.value }
}));
});
}
async loadProducts() {
try {
const response = await fetch('/api/products');
if (!response.ok) {
throw new Error('获取构型列表失败');
}
const products = await response.json();
const select = this.shadowRoot.getElementById('productSelect');
// 清空现有选项
select.innerHTML = '<option value="">选择构型</option>';
products.forEach(product => {
const option = document.createElement('option');
option.value = product.ProductName;
option.textContent = product.ProductName;
select.appendChild(option);
});
} catch (error) {
console.error('加载构型列表失败:', error);
// 可以在这里添加错误提示UI
}
}
}
customElements.define('header-tools', HeaderTools);