85 lines
1.8 KiB
Vue
85 lines
1.8 KiB
Vue
|
|
<script setup lang="ts">
|
||
|
|
import { ref, onMounted } from 'vue'
|
||
|
|
import { NButton, NSpin } from 'naive-ui'
|
||
|
|
import ProvidersPanel from '@/components/models/ProvidersPanel.vue'
|
||
|
|
import ProviderFormModal from '@/components/models/ProviderFormModal.vue'
|
||
|
|
import { useModelsStore } from '@/stores/models'
|
||
|
|
|
||
|
|
const modelsStore = useModelsStore()
|
||
|
|
const showModal = ref(false)
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
modelsStore.fetchProviders()
|
||
|
|
})
|
||
|
|
|
||
|
|
function openCreateModal() {
|
||
|
|
showModal.value = true
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleModalClose() {
|
||
|
|
showModal.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleSaved() {
|
||
|
|
await modelsStore.fetchProviders()
|
||
|
|
handleModalClose()
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<div class="models-view">
|
||
|
|
<header class="models-header">
|
||
|
|
<h2 class="header-title">Models</h2>
|
||
|
|
<NButton type="primary" @click="openCreateModal">
|
||
|
|
<template #icon>
|
||
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||
|
|
</template>
|
||
|
|
Add Provider
|
||
|
|
</NButton>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<div class="models-content">
|
||
|
|
<NSpin :show="modelsStore.loading && modelsStore.providers.length === 0">
|
||
|
|
<ProvidersPanel />
|
||
|
|
</NSpin>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<ProviderFormModal
|
||
|
|
v-if="showModal"
|
||
|
|
@close="handleModalClose"
|
||
|
|
@saved="handleSaved"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<style scoped lang="scss">
|
||
|
|
@use '@/styles/variables' as *;
|
||
|
|
|
||
|
|
.models-view {
|
||
|
|
height: 100vh;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.models-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
padding: 12px 20px;
|
||
|
|
border-bottom: 1px solid $border-color;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.header-title {
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: $text-primary;
|
||
|
|
}
|
||
|
|
|
||
|
|
.models-content {
|
||
|
|
flex: 1;
|
||
|
|
overflow-y: auto;
|
||
|
|
padding: 20px;
|
||
|
|
}
|
||
|
|
</style>
|