corrad-bp/components/process-flow/KeyValueTable.vue
Md Afiq Iskandar 03000b710b Enhance API Node Configuration Component with Authorization and Request Features
- Added support for additional HTTP methods (HEAD, OPTIONS) in the API node configuration.
- Refactored the request configuration section to focus on authorization, including dynamic fields for various auth types (Bearer, Basic, API Key).
- Introduced a new KeyValueTable component for managing query parameters and headers, improving user experience in configuring API requests.
- Updated the request body handling to support multiple body types (form-data, x-www-form-urlencoded, raw, binary) with appropriate UI elements.
- Enhanced response handling and testing steps to align with the new configuration structure, ensuring a seamless API interaction experience.
2025-07-16 08:39:43 +08:00

68 lines
2.6 KiB
Vue

<template>
<div>
<div v-for="(row, idx) in rows" :key="idx" class="flex items-center gap-2 mb-2">
<input
v-model="row.key"
:placeholder="placeholderKey"
class="w-32 px-2 py-1 border rounded text-sm"
@input="emitChange"
/>
<input
v-model="row.value"
:placeholder="placeholderValue"
class="flex-1 px-2 py-1 border rounded text-sm"
@input="emitChange"
:ref="el => valueInputs[idx] = el"
/>
<VariableBrowser
v-if="allowVariableInsert && variables && variables.length"
:available-variables="variables"
:placeholder="'Insert variable...'"
:allow-create="false"
@update:modelValue="varName => insertVariable(idx, varName)"
class="w-32"
/>
<button @click="removeRow(idx)" class="px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200"></button>
</div>
<button @click="addRow" class="mt-1 px-3 py-1 text-xs bg-gray-100 text-gray-700 rounded hover:bg-gray-200">+ Add</button>
</div>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue';
import VariableBrowser from './VariableBrowser.vue';
const props = defineProps({
modelValue: { type: Array, default: () => [] },
placeholderKey: { type: String, default: 'Key' },
placeholderValue: { type: String, default: 'Value' },
allowVariableInsert: { type: Boolean, default: false },
variables: { type: Array, default: () => [] }
});
const emit = defineEmits(['update:modelValue']);
const rows = ref(props.modelValue.map(r => ({ ...r })));
const valueInputs = ref([]);
watch(() => props.modelValue, v => { rows.value = v.map(r => ({ ...r })); });
function emitChange() { emit('update:modelValue', rows.value.map(r => ({ ...r }))); }
function addRow() { rows.value.push({ key: '', value: '' }); emitChange(); }
function removeRow(idx) { rows.value.splice(idx, 1); emitChange(); }
function insertVariable(idx, varName) {
if (!varName) return;
const input = valueInputs.value[idx];
if (input && input.selectionStart !== undefined) {
const start = input.selectionStart;
const end = input.selectionEnd;
const before = rows.value[idx].value.substring(0, start);
const after = rows.value[idx].value.substring(end);
rows.value[idx].value = before + `{${varName}}` + after;
emitChange();
// Move cursor after inserted variable
nextTick(() => {
input.focus();
input.selectionStart = input.selectionEnd = start + varName.length + 2;
});
} else {
rows.value[idx].value += `{${varName}}`;
emitChange();
}
}
</script>