diff --git a/sidepanel.html b/sidepanel.html index a46c944..c3931b0 100644 --- a/sidepanel.html +++ b/sidepanel.html @@ -16,44 +16,53 @@ - + 配置选项 ▼ - - - Gemini API 密钥 - - - - Apps Script 链接 - - - - AI 模型名称 - + + + + + Gemini API 密钥 + + + + Apps Script 链接 + + + + AI 模型名称 + + - - - 预设管理 - - - - 添加新预设 + + + 预设管理 + + + + 添加新预设 - - + + - 保存所有设置 + 保存所有设置 - - - + + + 执行提取任务 + + + + + 提取 + diff --git a/sidepanel.js b/sidepanel.js index 273fc08..2f0f794 100644 --- a/sidepanel.js +++ b/sidepanel.js @@ -13,7 +13,8 @@ const newPresetName = document.getElementById('newPresetName'); const newPresetFields = document.getElementById('newPresetFields'); const addPresetBtn = document.getElementById('addPreset'); const presetList = document.getElementById('presetList'); -const presetButtonsContainer = document.getElementById('presetButtons'); +const presetSelect = document.getElementById('presetSelect'); +const runPresetBtn = document.getElementById('runPreset'); // Collapsible logic const toggleConfig = document.getElementById('toggleConfig'); @@ -25,6 +26,8 @@ const DEFAULT_PRESETS = [ { id: 'p2', name: '提取外设', fields: '品牌, 型号, 连接方式, 电池寿命, 价格, URL' } ]; +let currentPresets = []; + toggleConfig.addEventListener('click', () => { const isHidden = configContent.classList.toggle('hidden'); configChevron.classList.toggle('rotate-180', !isHidden); @@ -43,11 +46,11 @@ chrome.storage.local.get(['geminiApiKey', 'googleScriptUrl', 'geminiModel', 'use if (data.googleScriptUrl) scriptUrlInput.value = data.googleScriptUrl; if (data.geminiModel) modelInput.value = data.geminiModel; - const presets = data.userPresets || DEFAULT_PRESETS; - renderPresets(presets); + currentPresets = data.userPresets || DEFAULT_PRESETS; + renderPresets(currentPresets); }); -// Save settings (including presets is handled separately via add/delete) +// Save settings saveConfigBtn.addEventListener('click', () => { const apiKey = apiKeyInput.value.trim(); const scriptUrl = scriptUrlInput.value.trim(); @@ -70,53 +73,57 @@ addPresetBtn.addEventListener('click', async () => { const { userPresets = DEFAULT_PRESETS } = await chrome.storage.local.get('userPresets'); const newPreset = { id: Date.now().toString(), name, fields }; - const updatedPresets = [...userPresets, newPreset]; + currentPresets = [...userPresets, newPreset]; - await chrome.storage.local.set({ userPresets: updatedPresets }); + await chrome.storage.local.set({ userPresets: currentPresets }); newPresetName.value = ''; newPresetFields.value = ''; - renderPresets(updatedPresets); + renderPresets(currentPresets); }); async function deletePreset(id) { const { userPresets = DEFAULT_PRESETS } = await chrome.storage.local.get('userPresets'); - const updatedPresets = userPresets.filter(p => p.id !== id); - await chrome.storage.local.set({ userPresets: updatedPresets }); - renderPresets(updatedPresets); + currentPresets = userPresets.filter(p => p.id !== id); + await chrome.storage.local.set({ userPresets: currentPresets }); + renderPresets(currentPresets); } function renderPresets(presets) { // Clear containers presetList.innerHTML = ''; - presetButtonsContainer.innerHTML = ''; + presetSelect.innerHTML = ''; presets.forEach(preset => { // 1. Render in Settings List const item = document.createElement('div'); - item.className = 'flex items-center justify-between bg-gray-50 p-2 rounded border border-gray-200 text-xs'; + item.className = 'flex items-center justify-between bg-gray-50 p-2.5 rounded border border-gray-200 text-xs shadow-sm'; item.innerHTML = ` - ${preset.name} - ${preset.fields} + ${preset.name} + ${preset.fields} - ✕ + + + `; item.querySelector('button').onclick = () => deletePreset(preset.id); presetList.appendChild(item); - // 2. Render as Action Button - const btn = document.createElement('button'); - btn.className = 'flex flex-col items-center justify-center p-4 bg-white border border-gray-200 rounded-lg hover:border-indigo-400 hover:bg-indigo-50 group transition-all'; - btn.innerHTML = ` - ⚙️ - ${preset.name} - `; - btn.onclick = () => handleExtraction('preset', preset); - presetButtonsContainer.appendChild(btn); + // 2. Render as Dropdown Option + const opt = document.createElement('option'); + opt.value = preset.id; + opt.textContent = preset.name; + presetSelect.appendChild(opt); }); } // Action Handlers +runPresetBtn.addEventListener('click', () => { + const selectedId = presetSelect.value; + const preset = currentPresets.find(p => p.id === selectedId); + if (preset) handleExtraction('preset', preset); +}); + sendCustomBtn.addEventListener('click', () => handleExtraction('custom', { fields: customInput.value })); async function handleExtraction(type, presetObj) { diff --git a/style.css b/style.css index f3ca925..613afb2 100644 --- a/style.css +++ b/style.css @@ -71,6 +71,11 @@ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helve .rounded { border-radius: 0.25rem; } .rounded-lg { border-radius: 0.5rem; } .shadow-sm { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } +.max-h-40 { max-height: 10rem; } +.text-\[10px\] { font-size: 10px; } +.mt-0\.5 { margin-top: 0.125rem; } +.space-y-2\.5 > * + * { margin-top: 0.625rem; } +.pr-1 { padding-right: 0.25rem; } .hidden { display: none; } .rotate-180 { transform: rotate(180deg); } .cursor-pointer { cursor: pointer; }