base UI
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>This is an about page</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@media (min-width: 1024px) {
|
||||
.about {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
51
web/src/views/DomainsView.vue
Normal file
51
web/src/views/DomainsView.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import { NSpin, NFlex, NCard, NButton, NIcon, useNotification } from 'naive-ui'
|
||||
import { PlusSquare } from "@vicons/fa"
|
||||
import { onMounted } from 'vue'
|
||||
import { useDomainStore } from '@/stores/domains'
|
||||
import { getErrorInfo } from '@/apis/api'
|
||||
import DomainInfo from '@/components/domains/DomainInfo.vue'
|
||||
import DomainOps from '@/components/domains/DomainOps.vue'
|
||||
|
||||
const loading = defineModel<boolean>({ default: true });
|
||||
const domainStore = useDomainStore()
|
||||
const notification = useNotification()
|
||||
|
||||
onMounted(() => {
|
||||
try {
|
||||
domainStore.loadDomains()
|
||||
loading.value = false
|
||||
} catch (error) {
|
||||
const msg = getErrorInfo(error)
|
||||
notification.error(msg)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NSpin size="large" v-if="loading" />
|
||||
<NFlex v-else id="domains" vertical>
|
||||
<NCard v-for="domain in domainStore.domains" :title="domain.domain_name" v-bind:key="domain.id" size="large"
|
||||
hoverable>
|
||||
<DomainInfo :domain="domain" />
|
||||
<template #action>
|
||||
<DomainOps :domain="domain" />
|
||||
</template>
|
||||
</NCard>
|
||||
<NCard hoverable>
|
||||
<NButton block quaternary size="large">
|
||||
<template #icon>
|
||||
<NIcon :component="PlusSquare" :depth="5" />
|
||||
</template>
|
||||
</NButton>
|
||||
</NCard>
|
||||
</NFlex>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.n-card {
|
||||
width: 32vw;
|
||||
}
|
||||
</style>
|
@@ -1,9 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import TheWelcome from '../components/TheWelcome.vue'
|
||||
import router from '@/router';
|
||||
router.push("/domains")
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<TheWelcome />
|
||||
</main>
|
||||
</template>
|
||||
|
126
web/src/views/RecordsView.vue
Normal file
126
web/src/views/RecordsView.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<script setup lang="ts">
|
||||
import { NSpin, NPageHeader, useNotification, NFlex, NButton, NIcon, NGrid, NGi, NStatistic, NDataTable, NInput } from 'naive-ui'
|
||||
import { onMounted } from 'vue'
|
||||
import { useRecordStore, type Record, type SOARecord, RecordTypes } from '@/stores/records'
|
||||
import { getErrorInfo } from '@/apis/api'
|
||||
import { PlusSquare, RedoAlt, CheckCircle, Clock, Cogs, Search } from '@vicons/fa'
|
||||
import router from '@/router';
|
||||
|
||||
const props = defineProps<{
|
||||
domain: string
|
||||
}>()
|
||||
const loading = defineModel<boolean>('loading', { default: true });
|
||||
const records = defineModel<Record[]>('records');
|
||||
const search = defineModel<string>('search', { default: '' })
|
||||
const soa = defineModel<SOARecord | undefined>('soa')
|
||||
|
||||
const recordStore = useRecordStore()
|
||||
const notification = useNotification()
|
||||
onMounted(() => {
|
||||
try {
|
||||
refreshRecords()
|
||||
} catch (err) {
|
||||
const msg = getErrorInfo(err)
|
||||
notification.error(msg)
|
||||
}
|
||||
})
|
||||
|
||||
function refreshRecords() {
|
||||
recordStore.loadRecords(props.domain)
|
||||
records.value = recordStore.records
|
||||
soa.value = records.value?.find(e => e.record_type === RecordTypes.RecordTypeSOA)?.content as SOARecord
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
router.push('/domains')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="records">
|
||||
<NSpin size="large" v-if="loading" />
|
||||
<NPageHeader v-else title="DNS 记录" :subtitle="domain" @back="goBack">
|
||||
<template #extra>
|
||||
<NFlex :wrap="false" justify="end" inline>
|
||||
<NButton type="primary">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<PlusSquare />
|
||||
</NIcon>
|
||||
</template>
|
||||
新增
|
||||
</NButton>
|
||||
<NInput v-model:value="search" placeholder="搜索...">
|
||||
<template #prefix>
|
||||
<NIcon :component="Search" />
|
||||
</template>
|
||||
</NInput>
|
||||
</NFlex>
|
||||
</template>
|
||||
<NGrid :cols="4">
|
||||
<NGi>
|
||||
<NStatistic :value="soa?.refresh">
|
||||
<template #suffix>
|
||||
s
|
||||
</template>
|
||||
<template #label>
|
||||
<NIcon class="icon">
|
||||
<RedoAlt />
|
||||
</NIcon>
|
||||
刷新时间
|
||||
</template>
|
||||
</NStatistic>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NStatistic :value="soa?.retry">
|
||||
<template #suffix>
|
||||
s
|
||||
</template>
|
||||
<template #label>
|
||||
<NIcon class="icon">
|
||||
<CheckCircle />
|
||||
</NIcon>
|
||||
重试间隔
|
||||
</template>
|
||||
</NStatistic>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NStatistic :value="soa?.expire">
|
||||
<template #suffix>
|
||||
s
|
||||
</template>
|
||||
<template #label>
|
||||
<NIcon class="icon">
|
||||
<Clock />
|
||||
</NIcon>
|
||||
超期时间
|
||||
</template>
|
||||
</NStatistic>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<NStatistic :value="soa?.minttl">
|
||||
<template #suffix>
|
||||
s
|
||||
</template>
|
||||
<template #label>
|
||||
<NIcon class="icon">
|
||||
<Cogs />
|
||||
</NIcon>
|
||||
缓存时间
|
||||
</template>
|
||||
</NStatistic>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
</NPageHeader>
|
||||
<NDataTable :data="records">
|
||||
|
||||
</NDataTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
transform: translateY(2px);
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user