corrad-af-2024/components/api-platform/EnvironmentModal.vue

226 lines
7.8 KiB
Vue

<template>
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col">
<!-- Header -->
<div class="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Environment Management</h3>
<rs-button
variant="text"
size="sm"
@click="$emit('close')"
class="p-2"
>
<Icon name="ic:outline-close" size="16" />
</rs-button>
</div>
<!-- Content -->
<div class="flex-1 overflow-hidden flex">
<!-- Environments List -->
<div class="w-1/3 border-r border-gray-200 dark:border-gray-700 p-4">
<div class="flex items-center justify-between mb-4">
<h4 class="font-medium text-gray-900 dark:text-white">Environments</h4>
<rs-button
variant="secondary-outline"
size="sm"
@click="createEnvironment"
class="p-2"
>
<Icon name="ic:outline-add" size="14" />
</rs-button>
</div>
<div class="space-y-2">
<div
v-for="env in environments"
:key="env.id"
@click="selectedEnvId = env.id"
:class="[
'p-3 rounded-lg cursor-pointer border-2 transition-colors',
selectedEnvId === env.id
? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20'
: 'border-transparent hover:bg-gray-50 dark:hover:bg-gray-700'
]"
>
<div class="flex items-center justify-between">
<span class="font-medium text-gray-900 dark:text-white">{{ env.name }}</span>
<rs-button
variant="text"
size="sm"
@click.stop="deleteEnvironment(env.id)"
class="p-1 text-red-500 hover:text-red-600"
>
<Icon name="ic:outline-delete" size="14" />
</rs-button>
</div>
<p class="text-sm text-gray-500 dark:text-gray-400">{{ env.variables.length }} variables</p>
</div>
</div>
</div>
<!-- Environment Details -->
<div class="flex-1 p-4">
<div v-if="selectedEnvironment" class="h-full flex flex-col">
<!-- Environment Name -->
<div class="mb-4">
<FormKit
type="text"
v-model="selectedEnvironment.name"
label="Environment Name"
validation="required"
outer-class="!mb-0"
/>
</div>
<!-- Variables -->
<div class="flex-1 flex flex-col">
<div class="flex items-center justify-between mb-4">
<h5 class="font-medium text-gray-900 dark:text-white">Variables</h5>
<rs-button
variant="secondary-outline"
size="sm"
@click="addVariable"
class="flex items-center gap-2"
>
<Icon name="ic:outline-add" size="14" />
Add Variable
</rs-button>
</div>
<div class="flex-1 overflow-y-auto space-y-3">
<div
v-for="(variable, index) in selectedEnvironment.variables"
:key="index"
class="border border-gray-200 dark:border-gray-700 rounded-lg p-4"
>
<div class="flex items-start gap-3">
<div class="flex-1">
<FormKit
type="text"
v-model="variable.key"
placeholder="Variable key (e.g., baseUrl)"
outer-class="!mb-2"
inner-class="!mb-0"
/>
<FormKit
type="text"
v-model="variable.value"
placeholder="Variable value (e.g., https://api.example.com)"
outer-class="!mb-0"
inner-class="!mb-0"
/>
</div>
<rs-button
variant="text"
size="sm"
@click="removeVariable(index)"
class="p-2 text-red-500 hover:text-red-600"
>
<Icon name="ic:outline-delete" size="16" />
</rs-button>
</div>
</div>
<div v-if="selectedEnvironment.variables.length === 0" class="text-center py-8 text-gray-500 dark:text-gray-400">
<Icon name="ic:outline-code" size="32" class="mx-auto mb-2 opacity-50" />
<p class="text-sm mb-4">No variables defined</p>
<div class="flex justify-center">
<rs-button
variant="primary"
size="sm"
@click="addVariable"
class="flex items-center gap-2"
>
<Icon name="ic:outline-add" size="14" />
Add First Variable
</rs-button>
</div>
</div>
</div>
</div>
</div>
<div v-else class="h-full flex items-center justify-center text-gray-500 dark:text-gray-400">
<div class="text-center">
<Icon name="ic:outline-layers" size="48" class="mx-auto mb-4 opacity-50" />
<p>Select an environment to edit</p>
</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="flex items-center justify-between p-6 border-t border-gray-200 dark:border-gray-700">
<div class="text-sm text-gray-500 dark:text-gray-400">
Variables can be used as <code>{<!-- -->{variableName}<!-- -->}</code> in requests
</div>
<rs-button
variant="primary"
@click="$emit('close')"
>
Done
</rs-button>
</div>
</div>
</div>
</template>
<script setup>
const emit = defineEmits(['close'])
const { environments, showNotification } = useApiPlatform()
const selectedEnvId = ref('')
const selectedEnvironment = computed(() => {
return environments.value.find(env => env.id === selectedEnvId.value)
})
const createEnvironment = () => {
const name = prompt('Environment name:')
if (name && name.trim()) {
const newEnv = {
id: Date.now(),
name: name.trim(),
variables: []
}
environments.value.push(newEnv)
selectedEnvId.value = newEnv.id
showNotification('Environment created', 'success')
}
}
const deleteEnvironment = (envId) => {
if (confirm('Are you sure you want to delete this environment?')) {
const index = environments.value.findIndex(env => env.id === envId)
if (index !== -1) {
environments.value.splice(index, 1)
if (selectedEnvId.value === envId) {
selectedEnvId.value = ''
}
showNotification('Environment deleted', 'success')
}
}
}
const addVariable = () => {
if (selectedEnvironment.value) {
selectedEnvironment.value.variables.push({
key: '',
value: ''
})
}
}
const removeVariable = (index) => {
if (selectedEnvironment.value) {
selectedEnvironment.value.variables.splice(index, 1)
}
}
// Select first environment by default
onMounted(() => {
if (environments.value.length > 0) {
selectedEnvId.value = environments.value[0].id
}
})
</script>