feat(frontend) : add database info section and form field
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,8 @@ import { getApplication, updateApplication, deleteApplication } from '~/services
|
||||
import { createEnvironment, updateEnvironment, deleteEnvironment, toggleMaintenance } from '~/services/environments'
|
||||
import type { DeployResult } from '~/services/dto/deploy'
|
||||
import { getAvailableTags, deploy } from '~/services/deploy'
|
||||
import type { EnvironmentHealth } from '~/services/dto/dashboard'
|
||||
import { getEnvironmentHealth } from '~/services/dashboard'
|
||||
import type { EnvironmentHealth, DatabaseInfo } from '~/services/dto/dashboard'
|
||||
import { getEnvironmentHealth, getDatabaseInfo } from '~/services/dashboard'
|
||||
import type { LogOutput } from '~/services/dto/logs'
|
||||
import { getDockerLogs, getSymfonyLog } from '~/services/logs'
|
||||
|
||||
@@ -31,6 +31,9 @@ const deployResult = ref<DeployResult | null>(null)
|
||||
const healthByEnvId = ref<Record<number, EnvironmentHealth>>({})
|
||||
const loadingHealth = ref(false)
|
||||
|
||||
// Database info per env
|
||||
const dbInfoByEnvId = ref<Record<number, DatabaseInfo>>({})
|
||||
|
||||
// Log modals
|
||||
const showLogModal = ref(false)
|
||||
const logContent = ref('')
|
||||
@@ -54,6 +57,7 @@ const envForm = ref<EnvironmentWrite>({
|
||||
deployScriptPath: '',
|
||||
maintenanceFilePath: '',
|
||||
appUrl: '',
|
||||
databaseName: '',
|
||||
logFiles: [],
|
||||
})
|
||||
const isSubmittingEnv = ref(false)
|
||||
@@ -66,6 +70,7 @@ async function loadApplication() {
|
||||
loading.value = false
|
||||
}
|
||||
loadHealthData()
|
||||
loadDatabaseData()
|
||||
}
|
||||
|
||||
// Application edit
|
||||
@@ -103,7 +108,7 @@ async function handleDeleteApp() {
|
||||
// Environment CRUD
|
||||
function openCreateEnvModal() {
|
||||
editingEnvId.value = null
|
||||
envForm.value = { name: '', containerName: '', deployScriptPath: '', maintenanceFilePath: '', appUrl: '', logFiles: [] }
|
||||
envForm.value = { name: '', containerName: '', deployScriptPath: '', maintenanceFilePath: '', appUrl: '', databaseName: '', logFiles: [] }
|
||||
showEnvModal.value = true
|
||||
}
|
||||
|
||||
@@ -115,6 +120,7 @@ function openEditEnvModal(env: Environment) {
|
||||
deployScriptPath: env.deployScriptPath,
|
||||
maintenanceFilePath: env.maintenanceFilePath,
|
||||
appUrl: env.appUrl ?? '',
|
||||
databaseName: env.databaseName ?? '',
|
||||
logFiles: env.logFiles.map(lf => ({ label: lf.label, path: lf.path })),
|
||||
}
|
||||
showEnvModal.value = true
|
||||
@@ -215,6 +221,20 @@ async function loadHealthData() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDatabaseData() {
|
||||
if (!application.value?.environments?.length) return
|
||||
const promises = application.value.environments.map(async (env) => {
|
||||
if (!env.databaseName) return
|
||||
try {
|
||||
const info = await getDatabaseInfo(env.id!)
|
||||
dbInfoByEnvId.value[env.id!] = info
|
||||
} catch {
|
||||
// silently ignore — no database configured or unreachable
|
||||
}
|
||||
})
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
function formatUptime(startedAt: string): string {
|
||||
if (!startedAt) return '-'
|
||||
const start = new Date(startedAt)
|
||||
@@ -471,6 +491,50 @@ onMounted(loadApplication)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Database info -->
|
||||
<div v-if="dbInfoByEnvId[env.id!]" class="mt-4 border-t border-neutral-200 py-3">
|
||||
<p class="text-sm font-bold uppercase tracking-wider mb-2">{{ t('environments.database.title') }}</p>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-6 gap-3">
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.status') }}</p>
|
||||
<span
|
||||
class="inline-block rounded-full px-2.5 py-0.5 text-xs font-semibold mt-1"
|
||||
:class="dbInfoByEnvId[env.id!].connected
|
||||
? 'bg-green-100 text-green-700'
|
||||
: 'bg-red-100 text-red-700'"
|
||||
>
|
||||
{{ dbInfoByEnvId[env.id!].connected
|
||||
? t('environments.database.connected')
|
||||
: t('environments.database.unreachable') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.name') }}</p>
|
||||
<p class="text-sm font-mono text-neutral-800 mt-1">{{ dbInfoByEnvId[env.id!].name }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.size') }}</p>
|
||||
<p class="text-sm text-neutral-800 mt-1">{{ dbInfoByEnvId[env.id!].size || '-' }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.tableCount') }}</p>
|
||||
<p class="text-sm text-neutral-800 mt-1">{{ dbInfoByEnvId[env.id!].tableCount }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.activeConnections') }}</p>
|
||||
<p class="text-sm text-neutral-800 mt-1">{{ dbInfoByEnvId[env.id!].activeConnections }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-neutral-400">{{ t('environments.database.cacheHitRatio') }}</p>
|
||||
<p class="text-sm text-neutral-800 mt-1">{{ dbInfoByEnvId[env.id!].cacheHitRatio }}%</p>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="dbInfoByEnvId[env.id!].largestTable && dbInfoByEnvId[env.id!].largestTable !== '-'" class="text-xs text-neutral-500 mt-2">
|
||||
{{ t('environments.database.largestTable') }} : <span class="font-mono">{{ dbInfoByEnvId[env.id!].largestTable }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center gap-4 mt-4">
|
||||
<MalioButton
|
||||
:label="t('environments.editButton')"
|
||||
@@ -577,6 +641,12 @@ onMounted(loadApplication)
|
||||
:label="t('environments.form.appUrl')"
|
||||
groupClass="mt-0"
|
||||
/>
|
||||
<MalioInputText
|
||||
v-model="envForm.databaseName"
|
||||
:label="t('environments.database.formLabel')"
|
||||
:hint="t('environments.database.formHint')"
|
||||
groupClass="mt-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Log files -->
|
||||
|
||||
Reference in New Issue
Block a user