web done
This commit is contained in:
parent
65bf461d44
commit
9465bb885d
@ -25,28 +25,28 @@
|
||||
<NFormItem :label="t('records.refresh')" path="refresh_interval">
|
||||
<NInputNumber v-model:value="domain.refresh_interval" :show-button="false">
|
||||
<template #suffix>
|
||||
{{ t('domains.form.unitForSecond') }}
|
||||
{{ t('common.unitForSecond') }}
|
||||
</template>
|
||||
</NInputNumber>
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.retry')" path="retry_interval">
|
||||
<NInputNumber v-model:value="domain.retry_interval" :show-button="false">
|
||||
<template #suffix>
|
||||
{{ t('domains.form.unitForSecond') }}
|
||||
{{ t('common.unitForSecond') }}
|
||||
</template>
|
||||
</NInputNumber>
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.expire')" path="expiry_period">
|
||||
<NInputNumber v-model:value="domain.expiry_period" :show-button="false">
|
||||
<template #suffix>
|
||||
{{ t('domains.form.unitForSecond') }}
|
||||
{{ t('common.unitForSecond') }}
|
||||
</template>
|
||||
</NInputNumber>
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.ttl')" path="negative_ttl">
|
||||
<NInputNumber v-model:value="domain.negative_ttl" :show-button="false">
|
||||
<template #suffix>
|
||||
{{ t('domains.form.unitForSecond') }}
|
||||
{{ t('common.unitForSecond') }}
|
||||
</template>
|
||||
</NInputNumber>
|
||||
</NFormItem>
|
||||
@ -62,16 +62,16 @@
|
||||
</template>
|
||||
{{ t('common.cancel') }}
|
||||
</NButton>
|
||||
<NSpin :show="loading">
|
||||
<NButton size="small" type="primary" :disabled="loading || invalidData !== allFlags" @click="confirm" attr-type="submit">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<Check />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</NSpin>
|
||||
|
||||
<NButton size="small" type="primary" :disabled="invalidData !== allFlags" :loading="loading"
|
||||
@click="confirm" attr-type="submit">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<Check />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NCard>
|
||||
@ -92,12 +92,11 @@ import {
|
||||
NButton,
|
||||
NInput,
|
||||
NInputNumber,
|
||||
NSpin,
|
||||
useNotification,
|
||||
type FormRules,
|
||||
type FormItemRule
|
||||
} from 'naive-ui'
|
||||
import { ref, watch } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const enum validFlags {
|
||||
@ -105,7 +104,7 @@ const enum validFlags {
|
||||
mainNsValid = domainNameValid << 1,
|
||||
adminEmailValid = mainNsValid << 1
|
||||
}
|
||||
const allFlags = validFlags.adminEmailValid|validFlags.mainNsValid|validFlags.domainNameValid
|
||||
const allFlags = validFlags.adminEmailValid | validFlags.mainNsValid | validFlags.domainNameValid
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -133,7 +132,6 @@ const rules = {
|
||||
main_dns: [{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
|
||||
validator: (_rule: FormItemRule, value: string) => {
|
||||
return validate(
|
||||
value,
|
||||
@ -173,6 +171,7 @@ const rules = {
|
||||
negative_ttl: [{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
type: 'number'
|
||||
}]
|
||||
} as FormRules
|
||||
|
||||
@ -197,7 +196,7 @@ async function confirm() {
|
||||
}
|
||||
|
||||
function validate(value: string, reg: RegExp, msg: string, flag: validFlags): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if (!value) {
|
||||
invalidData.value &= ~flag
|
||||
reject(Error(t('common.mandatory')))
|
||||
|
@ -24,17 +24,16 @@
|
||||
</template>
|
||||
{{ t('common.cancel') }}
|
||||
</NButton>
|
||||
<NSpin :show="loading">
|
||||
<NButton size="small" type="error" :disabled="(domain_name !== domain?.domain_name) || loading"
|
||||
@click="confirm">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<TrashAlt />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</NSpin>
|
||||
|
||||
<NButton size="small" type="error" :disabled="domain_name !== domain?.domain_name"
|
||||
:loading="loading" @click="confirm">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<TrashAlt />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NCard>
|
||||
@ -43,7 +42,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDomainStore, type Domain } from '@/stores/domains';
|
||||
import { NModal, NCard, NFlex, NButton, NIcon, NInput, NSpin, useNotification } from 'naive-ui'
|
||||
import { NModal, NCard, NFlex, NButton, NIcon, NInput, useNotification } from 'naive-ui'
|
||||
import { Times, TrashAlt, QuestionCircle } from '@vicons/fa';
|
||||
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<NModal :mask-closable="false" :show="show">
|
||||
<NCard style="width: 640px" role="dialog" aria-modal="true">
|
||||
<template #header>
|
||||
<span v-if="!record || !record.id || record.id < 1">{{ t('common.new') }}</span><span v-else>{{
|
||||
t('common.edit') }}</span><span>{{ t('records._') }}</span>
|
||||
</template>
|
||||
|
||||
<NForm :model="record" inline :rules="rules">
|
||||
<NFormItem :label="t('records.recordType')">
|
||||
<NSelect v-model:value="record.record_type" :options="recordTypeOptions" />
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.name')" path="name">
|
||||
<NInput v-model:value="record.name" />
|
||||
</NFormItem>
|
||||
<NFormItem label="TTL" path="ttl">
|
||||
<NInputNumber v-model:value="record.ttl" :show-button="false">
|
||||
<template #suffix>
|
||||
{{ t('common.unitForSecond') }}
|
||||
</template>
|
||||
</NInputNumber>
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
<NForm :model="record" inline>
|
||||
<NFormItem :label="t('records.content')"
|
||||
v-if="[RecordTypes.RecordTypeA, RecordTypes.RecordTypeAAAA].indexOf(record.record_type) > -1">
|
||||
<NInput v-model:value="(record.content as ARecord | AAAARecord).ip" placeholder="IP" />
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.content')"
|
||||
v-if="[RecordTypes.RecordTypeCNAME, RecordTypes.RecordTypeNS].indexOf(record.record_type) > -1">
|
||||
<NInput v-model:value="(record.content as CNAMERecord | NSRecord).host"
|
||||
:placeholder="t('records.form.host')" />
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.content')" v-if="RecordTypes.RecordTypeTXT === record.record_type">
|
||||
<NInput v-model:value="(record.content as TXTRecord).text" :placeholder="t('records.form.text')" />
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.content')" v-if="RecordTypes.RecordTypeMX === record.record_type">
|
||||
<NInputGroup>
|
||||
<NInput :placeholder="t('records.form.host')" v-model:value="(record.content as MXRecord).host"
|
||||
style="width: 75%;" />
|
||||
<NInputNumber :placeholder="t('records.form.preference')"
|
||||
v-model:value="(record.content as MXRecord).preference" style="width: 25%;" />
|
||||
</NInputGroup>
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.content')" v-if="RecordTypes.RecordTypeSRV === record.record_type">
|
||||
<NInputGroup>
|
||||
<NInputNumber :placeholder="t('records.form.priority')"
|
||||
v-model:value="(record.content as SRVRecord).priority" style="width: 25%;" />
|
||||
<NInputNumber :placeholder="t('records.form.weight')"
|
||||
v-model:value="(record.content as SRVRecord).weight" style="width: 25%;" />
|
||||
<NInputNumber :placeholder="t('records.form.port')"
|
||||
v-model:value="(record.content as SRVRecord).port" style="width: 25%;" :min="0"
|
||||
:max="65535" />
|
||||
<NInput :placeholder="t('records.form.target')"
|
||||
v-model:value="(record.content as SRVRecord).target" style="width: 25%;" />
|
||||
</NInputGroup>
|
||||
</NFormItem>
|
||||
<NFormItem :label="t('records.content')" v-if="RecordTypes.RecordTypeCAA === record.record_type">
|
||||
<NInputGroup>
|
||||
<NInputNumber :placeholder="t('records.form.flag')"
|
||||
v-model:value="(record.content as CAARecord).flag" style="width: 20%;" />
|
||||
<NInput :placeholder="t('records.form.tag')" v-model:value="(record.content as CAARecord).tag"
|
||||
style="width: 40%;" />
|
||||
<NInput :placeholder="t('records.form.value')"
|
||||
v-model:value="(record.content as CAARecord).value" style="width: 40%;" />
|
||||
</NInputGroup>
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
|
||||
<template #action>
|
||||
<NFlex justify="end">
|
||||
<NButton size="small" @click="show = false">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<Times />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.cancel') }}
|
||||
</NButton>
|
||||
|
||||
<NButton size="small" type="primary" :loading="loading" @click="confirm" attr-type="submit">
|
||||
<template #icon>
|
||||
<NIcon>
|
||||
<Check />
|
||||
</NIcon>
|
||||
</template>
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NCard>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
NModal,
|
||||
NCard,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NFlex,
|
||||
NButton,
|
||||
NInput,
|
||||
NInputNumber,
|
||||
NInputGroup,
|
||||
NSelect,
|
||||
useNotification,
|
||||
type FormRules,
|
||||
type SelectOption
|
||||
} from 'naive-ui'
|
||||
import { getErrorInfo } from '@/apis/api';
|
||||
import {
|
||||
useRecordStore,
|
||||
RecordTypes,
|
||||
type Record,
|
||||
type ARecord,
|
||||
type AAAARecord,
|
||||
type CAARecord,
|
||||
type CNAMERecord,
|
||||
type NSRecord,
|
||||
type SRVRecord,
|
||||
type TXTRecord,
|
||||
type MXRecord,
|
||||
} from '@/stores/records';
|
||||
import { Check, Times } from '@vicons/fa';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
const { t } = useI18n()
|
||||
const props = defineProps<{
|
||||
record: Record,
|
||||
domain: string,
|
||||
}>()
|
||||
|
||||
const show = defineModel<boolean>('show', { default: false })
|
||||
const loading = ref(false)
|
||||
const notification = useNotification()
|
||||
const recordStore = useRecordStore()
|
||||
const recordTypeOptions = Object.entries(RecordTypes).filter(
|
||||
e => e[1] !== RecordTypes.RecordTypeSOA
|
||||
).map(e => {
|
||||
return {
|
||||
label: e[1],
|
||||
value: e[1]
|
||||
} as SelectOption
|
||||
})
|
||||
const rules = {
|
||||
name: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: t('common.mandatory')
|
||||
}
|
||||
} as FormRules
|
||||
|
||||
async function confirm() {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (!props.record.id || props.record.id < 1) {
|
||||
await recordStore.addRecord(props.domain, props.record)
|
||||
} else {
|
||||
await recordStore.updateRecord(props.domain, props.record)
|
||||
}
|
||||
show.value = false
|
||||
} catch (e) {
|
||||
const msg = getErrorInfo(e)
|
||||
notification.error(msg)
|
||||
console.error(e)
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
</script>
|
@ -11,7 +11,7 @@
|
||||
</template>
|
||||
{{ $t("common.edit") }}
|
||||
</NTooltip>
|
||||
<NPopconfirm>
|
||||
<NPopconfirm @positive-click="confirm">
|
||||
<template #trigger>
|
||||
<NButton type="error" size="tiny">
|
||||
<template #icon>
|
||||
@ -26,12 +26,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NButton, NButtonGroup, NTooltip, NIcon, NPopconfirm, NFlex } from 'naive-ui'
|
||||
import { NButton, NButtonGroup, NTooltip, NIcon, NPopconfirm, NFlex, useNotification } from 'naive-ui'
|
||||
import { TrashAlt, EditRegular } from '@vicons/fa'
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { Record } from '@/stores/records';
|
||||
import { useRecordStore, type Record } from '@/stores/records';
|
||||
import { getErrorInfo } from '@/apis/api';
|
||||
const { t } = useI18n()
|
||||
const recordStore = useRecordStore()
|
||||
const notification = useNotification()
|
||||
const props = defineProps<{
|
||||
record: Record
|
||||
domain: string
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['record-delete'])
|
||||
|
||||
function confirm() {
|
||||
emit('record-delete', props.domain, props.record)
|
||||
}
|
||||
</script>
|
@ -9,7 +9,8 @@ export default {
|
||||
new: 'New',
|
||||
cancel: 'Cancel',
|
||||
confirm: 'OK',
|
||||
mandatory: 'This field is mandatory'
|
||||
mandatory: 'This field is mandatory',
|
||||
unitForSecond: 'Second(s)'
|
||||
},
|
||||
api: {
|
||||
error400: {
|
||||
@ -48,7 +49,6 @@ export default {
|
||||
form: {
|
||||
adminMail: 'Admin Email',
|
||||
mainDNS: 'Main DNS',
|
||||
unitForSecond: 'Second(s)'
|
||||
},
|
||||
|
||||
errors: {
|
||||
@ -67,5 +67,18 @@ export default {
|
||||
retry: 'Retry Interval',
|
||||
expire: 'Expiry Period',
|
||||
ttl: 'Negative TTL',
|
||||
|
||||
form: {
|
||||
text: 'Text',
|
||||
host: 'Host',
|
||||
preference: 'Preference',
|
||||
priority: 'Priority',
|
||||
weight: 'Weight',
|
||||
port: 'Port',
|
||||
target: 'Target',
|
||||
flag: 'Flag',
|
||||
tag: 'Tag',
|
||||
value: 'Value'
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,8 @@ export default {
|
||||
new: '新增',
|
||||
cancel: '取消',
|
||||
confirm: '确定',
|
||||
mandatory: '此项必填'
|
||||
mandatory: '此项必填',
|
||||
unitForSecond: '秒'
|
||||
},
|
||||
api: {
|
||||
error400: {
|
||||
@ -48,7 +49,6 @@ export default {
|
||||
form: {
|
||||
adminMail: '管理员邮箱',
|
||||
mainDNS: '主 DNS 服务器',
|
||||
unitForSecond: '秒'
|
||||
},
|
||||
|
||||
errors: {
|
||||
@ -67,5 +67,18 @@ export default {
|
||||
retry: '重试间隔',
|
||||
expire: '超期时间',
|
||||
ttl: '缓存时间',
|
||||
|
||||
form: {
|
||||
text: '文本',
|
||||
host: '主机',
|
||||
preference: '优先级',
|
||||
priority: '优先级',
|
||||
weight: '权重',
|
||||
port: '端口',
|
||||
target: '目标',
|
||||
flag: '标志',
|
||||
tag: '标签',
|
||||
value: '值'
|
||||
}
|
||||
}
|
||||
}
|
@ -232,5 +232,5 @@ export const useRecordStore = defineStore('records', () => {
|
||||
records.value = records.value?.filter(e => e.id !== record.id)
|
||||
}
|
||||
|
||||
return { records, recordsGetter, loadRecords }
|
||||
return { records, recordsGetter, loadRecords, addRecord, updateRecord, removeRecord }
|
||||
})
|
||||
|
@ -49,7 +49,7 @@ const columns = [
|
||||
{
|
||||
key: '',
|
||||
render(row: Record) {
|
||||
return <RecordOps record={row} />
|
||||
return <RecordOps record={row} domain={props.domain} onRecord-delete={deleteRecord} />
|
||||
}
|
||||
}
|
||||
] as DataTableColumns<Record>
|
||||
@ -70,11 +70,18 @@ onMounted(() => {
|
||||
}
|
||||
})
|
||||
|
||||
function refreshRecords() {
|
||||
recordStore.loadRecords(props.domain)
|
||||
records.value = recordStore.records?.filter(e => e.record_type !== RecordTypes.RecordTypeSOA)
|
||||
soa.value = recordStore.records?.find(e => e.record_type === RecordTypes.RecordTypeSOA)?.content as SOARecord
|
||||
loading.value = false;
|
||||
async function refreshRecords() {
|
||||
try {
|
||||
await recordStore.loadRecords(props.domain)
|
||||
records.value = recordStore.records?.filter(e => e.record_type !== RecordTypes.RecordTypeSOA)
|
||||
soa.value = recordStore.records?.find(e => e.record_type === RecordTypes.RecordTypeSOA)?.content as SOARecord
|
||||
} catch (err) {
|
||||
const msg = getErrorInfo(err)
|
||||
notification.error(msg)
|
||||
console.error(err)
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
@ -91,6 +98,17 @@ function searchRecord(value: string) {
|
||||
filter(e => e.record_type !== RecordTypes.RecordTypeSOA)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRecord(domain: string, record: Record) {
|
||||
try {
|
||||
await recordStore.removeRecord(domain, record)
|
||||
records.value = recordStore.records?.filter(e => e.record_type !== RecordTypes.RecordTypeSOA)
|
||||
} catch (err) {
|
||||
const msg = getErrorInfo(err)
|
||||
notification.error(msg)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
Loading…
Reference in New Issue
Block a user