444 lines
16 KiB
JavaScript
Raw Normal View History

2025-05-07 13:46:48 +08:00
class InterfaceToolbar extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
2025-05-07 13:46:48 +08:00
this.showAdvancedSearch = false;
}
connectedCallback() {
this.render();
this.addEventListeners();
}
addEventListeners() {
const addBtn = this.shadowRoot.querySelector('.add-btn');
const deleteBtn = this.shadowRoot.querySelector('.delete-btn');
const importBtn = this.shadowRoot.querySelector('.import-btn');
2025-05-07 13:46:48 +08:00
const searchInput = this.shadowRoot.querySelector('.search-input');
const searchBtn = this.shadowRoot.querySelector('.search-btn');
const resetBtn = this.shadowRoot.querySelector('.reset-btn');
const advancedSearchBtn = this.shadowRoot.querySelector('.advanced-search-btn');
const advancedSearchPanel = this.shadowRoot.querySelector('.advanced-search-panel');
const productSelect = this.shadowRoot.querySelector('#filterProduct');
const ataSelect = this.shadowRoot.querySelector('#filterAta');
const structSelect = this.shadowRoot.querySelector('#filterStruct');
const importModal = this.shadowRoot.querySelector('#importModal');
const importExcelBtn = this.shadowRoot.querySelector('#importExcelBtn');
const importIdlBtn = this.shadowRoot.querySelector('#importIdlBtn');
const cancelImportBtn = this.shadowRoot.querySelector('#cancelImportBtn');
2025-05-07 13:46:48 +08:00
addBtn.addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('add-variable'));
});
2025-05-07 13:46:48 +08:00
deleteBtn.addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('delete-variable'));
});
2025-05-07 13:46:48 +08:00
importBtn.addEventListener('click', () => {
importModal.style.display = 'block';
});
importExcelBtn.addEventListener('click', () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.xlsx,.xls';
input.onchange = (e) => {
const file = e.target.files[0];
if (file) {
this.dispatchEvent(new CustomEvent('import-data', {
detail: { file, type: 'excel' }
}));
importModal.style.display = 'none';
}
};
input.click();
});
importIdlBtn.addEventListener('click', () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.idl';
input.onchange = (e) => {
const file = e.target.files[0];
if (file) {
this.dispatchEvent(new CustomEvent('import-data', {
detail: { file, type: 'idl' }
}));
importModal.style.display = 'none';
}
};
input.click();
});
cancelImportBtn.addEventListener('click', () => {
importModal.style.display = 'none';
});
// 点击模态框外部关闭
importModal.addEventListener('click', (e) => {
if (e.target === importModal) {
importModal.style.display = 'none';
}
});
2025-05-07 13:46:48 +08:00
searchBtn.addEventListener('click', () => {
const keyword = searchInput.value.trim();
this.dispatchEvent(new CustomEvent('search', {
detail: { keyword }
}));
});
2025-05-07 13:46:48 +08:00
resetBtn.addEventListener('click', () => {
// 重置搜索框
searchInput.value = '';
// 重置高级搜索下拉框
productSelect.value = '';
ataSelect.value = '';
structSelect.value = '';
// 触发重置事件
this.dispatchEvent(new CustomEvent('reset-search'));
});
2025-05-07 13:46:48 +08:00
advancedSearchBtn.addEventListener('click', () => {
this.showAdvancedSearch = !this.showAdvancedSearch;
advancedSearchPanel.style.display = this.showAdvancedSearch ? 'flex' : 'none';
advancedSearchBtn.classList.toggle('active');
});
2025-05-07 13:46:48 +08:00
// 监听高级搜索的筛选条件变化
[productSelect, ataSelect, structSelect].forEach(select => {
select.addEventListener('change', () => {
this.dispatchEvent(new CustomEvent('advanced-search', {
detail: {
productName: productSelect.value,
ataName: ataSelect.value,
structName: structSelect.value
}
}));
2025-05-07 13:46:48 +08:00
});
});
}
render() {
this.shadowRoot.innerHTML = `
<style>
.toolbar {
display: flex;
gap: 10px;
2025-05-07 13:46:48 +08:00
align-items: center;
padding: 10px;
background-color: #f5f5f5;
2025-05-07 13:46:48 +08:00
border-radius: 4px;
}
2025-05-07 13:46:48 +08:00
.toolbar-group {
display: flex;
gap: 10px;
align-items: center;
}
.toolbar-group.left {
flex: 1;
}
.toolbar-group.center {
display: flex;
gap: 10px;
align-items: center;
}
.toolbar-group.right {
flex: 1;
justify-content: flex-end;
}
.search-group {
display: flex;
align-items: center;
gap: 5px;
}
.search-input {
2025-05-07 13:46:48 +08:00
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
width: 200px;
}
2025-05-07 13:46:48 +08:00
.btn {
padding: 6px 12px;
border: none;
border-radius: 4px;
2025-05-07 13:46:48 +08:00
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
background-color: #fff;
color: #333;
}
.btn:hover {
background-color: #f0f0f0;
}
.add-btn {
background-color: #4CAF50;
color: white;
}
2025-05-07 13:46:48 +08:00
.add-btn:hover {
background-color: #45a049;
}
.delete-btn {
background-color: #f44336;
2025-05-07 13:46:48 +08:00
color: white;
}
.delete-btn:hover {
background-color: #da190b;
}
2025-05-07 13:46:48 +08:00
.import-btn {
background-color: #2196F3;
color: white;
}
.import-btn:hover {
background-color: #1976D2;
}
.icon-btn {
padding: 6px;
border: none;
border-radius: 4px;
cursor: pointer;
background: none;
color: #666;
display: flex;
align-items: center;
justify-content: center;
}
.icon-btn img {
width: 16px;
height: 16px;
}
.icon-btn:hover {
background-color: #e0e0e0;
}
.advanced-search-btn {
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
background-color: #fff;
}
.advanced-search-btn.active {
background-color: #e0e0e0;
}
.advanced-search-panel {
display: none;
gap: 10px;
padding: 10px;
background-color: #f5f5f5;
border-radius: 4px;
margin-top: 10px;
}
.advanced-search-panel select {
padding: 6px;
border: 1px solid #ddd;
border-radius: 4px;
min-width: 150px;
}
.modal {
display: none;
2025-05-07 13:46:48 +08:00
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 8px;
width: 800px;
max-width: 90%;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-title {
font-size: 18px;
font-weight: bold;
}
.modal-body {
display: flex;
gap: 20px;
}
.import-section {
flex: 1;
padding: 20px;
border: 1px solid #ddd;
border-radius: 4px;
}
.import-section h3 {
margin-top: 0;
margin-bottom: 15px;
}
.import-btn-section {
margin-bottom: 15px;
}
.import-description {
font-size: 14px;
color: #666;
line-height: 1.5;
}
.modal-footer {
margin-top: 20px;
text-align: right;
}
.cancel-btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
background-color: #f5f5f5;
color: #333;
cursor: pointer;
}
.cancel-btn:hover {
background-color: #e0e0e0;
}
</style>
<div class="toolbar">
2025-05-07 13:46:48 +08:00
<div class="toolbar-group left">
<button class="btn add-btn">
<i class="fas fa-plus"></i>
添加变量
</button>
<button class="btn delete-btn">
<i class="fas fa-trash"></i>
删除变量
</button>
</div>
<div class="toolbar-group center">
<button class="btn import-btn">
<i class="fas fa-upload"></i>
导入数据
</button>
</div>
<div class="toolbar-group right">
<div class="search-group">
<input type="text" class="search-input" placeholder="搜索接口名称...">
<button class="icon-btn search-btn" title="搜索">
<img src="assets/icons/png/search_b.png" alt="搜索">
</button>
<button class="icon-btn reset-btn" title="重置">
<img src="assets/icons/png/refresh_b.png" alt="重置">
</button>
<button class="advanced-search-btn">高级搜索</button>
</div>
</div>
</div>
<div class="advanced-search-panel">
<select id="filterProduct">
<option value="">选择构型</option>
</select>
<select id="filterAta">
<option value="">选择ATA章节</option>
</select>
<select id="filterStruct">
<option value="">选择接口结构体</option>
</select>
</div>
<div class="modal" id="importModal">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">导入数据</div>
</div>
<div class="modal-body">
<div class="import-section">
<h3>从ICD导入</h3>
<div class="import-btn-section">
<button class="btn import-btn" id="importExcelBtn">
<i class="fas fa-file-excel"></i>
选择Excel文件
</button>
</div>
<div class="import-description">
支持从Excel文件(.xlsx/.xls)导入接口数据<br>
请确保Excel文件格式正确包含所有必要的字段<br>
导入过程中请勿关闭页面
</div>
</div>
<div class="import-section">
<h3>从IDL导入</h3>
<div class="import-btn-section">
<button class="btn import-btn" id="importIdlBtn">
<i class="fas fa-file-code"></i>
选择IDL文件
</button>
</div>
<div class="import-description">
支持从IDL文件(.idl)导入接口数据<br>
请确保IDL文件格式正确包含所有必要的接口定义<br>
导入过程中请勿关闭页面
</div>
</div>
</div>
<div class="modal-footer">
<button class="cancel-btn" id="cancelImportBtn">取消</button>
</div>
</div>
</div>
`;
}
2025-05-07 13:46:48 +08:00
updateFilterOptions(options) {
const productSelect = this.shadowRoot.querySelector('#filterProduct');
const ataSelect = this.shadowRoot.querySelector('#filterAta');
const structSelect = this.shadowRoot.querySelector('#filterStruct');
// 更新构型选项
productSelect.innerHTML = '<option value="">选择构型</option>' +
options.products.map(product => `<option value="${product}">${product}</option>`).join('');
// 更新ATA章节选项
ataSelect.innerHTML = '<option value="">选择ATA章节</option>' +
options.atas.map(ata => `<option value="${ata}">${ata}</option>`).join('');
// 更新接口结构体选项
structSelect.innerHTML = '<option value="">选择接口结构体</option>' +
options.structs.map(struct => `<option value="${struct}">${struct}</option>`).join('');
}
}
2025-05-07 13:46:48 +08:00
customElements.define('interface-toolbar', InterfaceToolbar);