diff --git a/src/components/dashboard/SendPanel.vue b/src/components/dashboard/SendPanel.vue index 7f44348..5fcc6a5 100644 --- a/src/components/dashboard/SendPanel.vue +++ b/src/components/dashboard/SendPanel.vue @@ -7,7 +7,6 @@ import { useGlobalVariables } from '../../stores/useGlobalVariables' import { prettyJson } from '../../utils/format' import { ElMessage } from 'element-plus' import HoverPreview from '../common/HoverPreview.vue' -import VariableEditor from './VariableEditor.vue' import UserPropertiesEditor from './UserPropertiesEditor.vue' import GlobalVariableManager from './GlobalVariableManager.vue' @@ -29,10 +28,16 @@ const activePresetId = ref(null) const showVariables = ref(false) const showV5Props = ref(false) const showGlobalVarMgr = ref(false) +const showAddPopover = ref(false) const sending = ref(false) +const dragIndex = ref(null) +const dragOverIndex = ref(null) + +/** Ordered list of pinned preset IDs (the tab bar) */ +const pinnedIds = ref([]) // Per-preset editor state (keyed by preset id) -const editorStates = ref>({}) +} +const editorStates = ref>({}) // ─── Computed ────────────────────────────────────────────────── @@ -59,6 +65,17 @@ const activeState = computed(() => activePresetId.value ? editorStates.value[activePresetId.value] : null, ) +/** Presets that are pinned (in tab order) */ +const pinnedPresets = computed(() => { + const map = new Map(props.presets.map((p) => [p.id, p])) + return pinnedIds.value.map((id) => map.get(id)).filter(Boolean) as Preset[] +}) + +/** Presets not yet pinned, available to add */ +const unpinnedPresets = computed(() => + props.presets.filter((p) => !pinnedIds.value.includes(p.id)), +) + const presetVariables = computed(() => { if (!activePreset.value) return [] const vars = extractVariables(activePreset.value.payloadTemplate) @@ -105,7 +122,26 @@ function initEditorState(preset: Preset) { } } -// ─── Switch active preset ────────────────────────────────────── +// ─── Pin / Unpin / Select ────────────────────────────────────── + +function pinPreset(presetId: string) { + if (pinnedIds.value.includes(presetId)) return + const preset = props.presets.find((p) => p.id === presetId) + if (!preset) return + initEditorState(preset) + pinnedIds.value.push(presetId) + activePresetId.value = presetId + showVariables.value = presetVariables.value.length > 0 + showAddPopover.value = false +} + +function unpinPreset(id: string) { + pinnedIds.value = pinnedIds.value.filter((pid) => pid !== id) + if (activePresetId.value === id) { + const remaining = pinnedIds.value + activePresetId.value = remaining.length > 0 ? remaining[0] : null + } +} function selectPreset(presetId: string) { const preset = props.presets.find((p) => p.id === presetId) @@ -115,19 +151,39 @@ function selectPreset(presetId: string) { showVariables.value = presetVariables.value.length > 0 } -// Auto-select first preset when presets change -watch(() => props.presets, (ps) => { - if (ps.length > 0) { - // Init all presets - for (const p of ps) initEditorState(p) - // Select first if none selected - if (!activePresetId.value || !ps.find((p) => p.id === activePresetId.value)) { - selectPreset(ps[0].id) - } - } else { - activePresetId.value = null +// ─── Drag and drop ───────────────────────────────────────────── + +function onDragStart(index: number) { + dragIndex.value = index +} + +function onDragOver(e: DragEvent, index: number) { + e.preventDefault() + dragOverIndex.value = index +} + +function onDragLeave() { + dragOverIndex.value = null +} + +function onDrop(index: number) { + if (dragIndex.value === null || dragIndex.value === index) { + dragIndex.value = null + dragOverIndex.value = null + return } -}, { immediate: true, deep: true }) + const arr = [...pinnedIds.value] + const [removed] = arr.splice(dragIndex.value, 1) + arr.splice(index, 0, removed) + pinnedIds.value = arr + dragIndex.value = null + dragOverIndex.value = null +} + +function onDragEnd() { + dragIndex.value = null + dragOverIndex.value = null +} // ─── Send ────────────────────────────────────────────────────── @@ -187,17 +243,6 @@ function onBindingChange(name: string, value: string) { setGlobalVar(name, value) } } - -// ─── Close tab ───────────────────────────────────────────────── - -function closePreset(id: string) { - // Keep the editor state but deselect - if (activePresetId.value === id) { - const idx = props.presets.findIndex((p) => p.id === id) - const next = props.presets[idx + 1] ?? props.presets[idx - 1] ?? null - activePresetId.value = next?.id ?? null - } -}