From 731504ae8283d7a47d1915c9d115df6f80e65245 Mon Sep 17 00:00:00 2001 From: Sense T Date: Thu, 11 Apr 2024 22:05:58 +0800 Subject: [PATCH] tsx used - stage 2 --- .../components/domains/DomainEditModal.tsx | 219 ++++++++++++++++++ .../components/domains/DomainEditModal.vue | 217 ----------------- web/src/components/domains/DomainOps.tsx | 2 +- .../components/domains/DomainRemoveModal.tsx | 20 +- web/src/components/records/RecordOps.tsx | 47 ++++ web/src/components/records/RecordOps.vue | 51 ---- web/src/views/DomainsView.vue | 2 +- web/src/views/RecordsView.vue | 7 +- 8 files changed, 282 insertions(+), 283 deletions(-) create mode 100644 web/src/components/domains/DomainEditModal.tsx delete mode 100644 web/src/components/domains/DomainEditModal.vue create mode 100644 web/src/components/records/RecordOps.tsx delete mode 100644 web/src/components/records/RecordOps.vue diff --git a/web/src/components/domains/DomainEditModal.tsx b/web/src/components/domains/DomainEditModal.tsx new file mode 100644 index 0000000..fff210f --- /dev/null +++ b/web/src/components/domains/DomainEditModal.tsx @@ -0,0 +1,219 @@ +import { + NModal, + NCard, + NForm, + NFormItem, + NFlex, + NIcon, + NButton, + NInput, + NInputNumber, + type FormRules, + type FormItemRule, + createDiscreteApi +} from 'naive-ui' +import { getErrorInfo } from '@/apis/api'; +import { useDomainStore, type Domain } from '@/stores/domains'; +import { Check, Times } from '@vicons/fa'; +import i18n from '@/locale/i18n' +import { ref, type SetupContext } from 'vue'; + +const { t } = i18n.global +const domainStore = useDomainStore() +const { notification } = createDiscreteApi(['notification']) +const enum validFlags { + domainNameValid = 1, + mainNsValid = domainNameValid << 1, + adminEmailValid = mainNsValid << 1 +} +const allFlags = validFlags.adminEmailValid | validFlags.mainNsValid | validFlags.domainNameValid +const rules = { + domain_name: [{ + required: true, + trigger: 'blur', + validator: (_rule: FormItemRule, value: string) => { + return validate( + value, + /^([\w-]+\.)+[\w-]+$/, + 'domains.errors.domainName', + validFlags.domainNameValid + ) + } + }], + main_dns: [{ + required: true, + trigger: 'blur', + validator: (_rule: FormItemRule, value: string) => { + return validate( + value, + /^([\w-]+\.)+[\w-]+$/, + 'domains.errors.domainName', + validFlags.mainNsValid, + ) + } + }], + admin_email: [{ + required: true, + trigger: 'blur', + validator: (_rule: FormItemRule, value: string) => { + return validate( + value, + /^[\w-.]+@([\w-]+\.)+[\w-]+$/, + 'domains.errors.mail', + validFlags.adminEmailValid + ) + } + }], + refresh_interval: [{ + required: true, + trigger: 'blur', + type: 'number', + }], + retry_interval: [{ + required: true, + trigger: 'blur', + type: 'number', + }], + expiry_period: [{ + required: true, + trigger: 'blur', + type: 'number', + }], + negative_ttl: [{ + required: true, + trigger: 'blur', + type: 'number' + }] +} as FormRules + + +type Props = { + domain: Domain + show: boolean +} + +type Events = { + 'update:show': (v: boolean) => void + 'update:value': (v: string | number | null) => void +} + +const loading = ref(false) +const invalidData = ref(0) + +function validate(value: string, reg: RegExp, msg: string, flag: validFlags): Promise { + return new Promise((resolve, reject) => { + if (!value) { + invalidData.value &= ~flag + reject(Error(t('common.mandatory'))) + } else if (!reg.test(value)) { + invalidData.value &= ~flag + reject(Error(t(msg))) + } else { + invalidData.value |= flag + resolve() + } + }) +} + +async function confirm(domain: Domain) { + loading.value = true; + try { + if (!domain.id || domain.id < 1) { + await domainStore.addDomain(domain) + } else { + await domainStore.updateDomain(domain) + } + } catch (e) { + const msg = getErrorInfo(e) + notification.error(msg) + console.error(e) + } finally { + loading.value = false + } +} + +function easyInput(domain_name: string, domain: Domain) { + domain.admin_email = `admin@${domain_name}` + domain.main_dns = `ns1.${domain_name}` +} + +function modalHeader({ domain }: Props) { + return ( + <> + {(!domain || !domain.id || domain.id < 1) ? {t('common.new')} : {t('common.edit')}} + {t('domains._')} + + ) +} + +function modalInputNumbers({ value, label, path }: { value: number, label: string, path: string }, { emit }: SetupContext) { + return ( + + emit('update:value', v)} showButton={false}> + {{ + suffix: () => t('common.unitForSecond') + }} + + + ) +} + +function modalBody({ domain }: Props) { + return ( + <> + + + domain.domain_name = v} onInput={v => easyInput(v, domain)} /> + + + domain.main_dns = v} /> + + + domain.admin_email = v} inputProps={{ type: 'email' }} /> + + + + domain.refresh_interval = v} path='refresh_interval' label='records.refresh' /> + domain.retry_interval = v} path='retry_interval' label='records.retry' /> + domain.expiry_period = v} path='expiry_period' label='records.expire' /> + domain.negative_ttl = v} path='negative_ttl' label='records.ttl' /> + + + ) +} + +function modalActions({ domain }: Props, { emit }: SetupContext) { + return ( + + emit("update:show", false)} > + {{ + default: () => t('common.cancel'), + icon: () => + }} + + + confirm(domain).then(() => emit('update:show', false))} attrType='submit'> + {{ + default: () => t('common.confirm'), + icon: () => + }} + + + ) +} + +function DomainEditModal({ domain, show }: Props, { emit }: SetupContext) { + return ( + + + {{ + headler: () => , + default: () => , + action: () => { emit("update:show", v) }} /> + }} + + + ) +} + +export default DomainEditModal \ No newline at end of file diff --git a/web/src/components/domains/DomainEditModal.vue b/web/src/components/domains/DomainEditModal.vue deleted file mode 100644 index 7318fa5..0000000 --- a/web/src/components/domains/DomainEditModal.vue +++ /dev/null @@ -1,217 +0,0 @@ - - - \ No newline at end of file diff --git a/web/src/components/domains/DomainOps.tsx b/web/src/components/domains/DomainOps.tsx index 3a71d01..ccdff4e 100644 --- a/web/src/components/domains/DomainOps.tsx +++ b/web/src/components/domains/DomainOps.tsx @@ -4,7 +4,7 @@ import { type Domain } from "../../stores/domains" import router from '@/router'; import i18n from '@/locale/i18n' import type { SetupContext } from 'vue'; -const t = i18n.global.t +const { t } = i18n.global type Props = { domain: Domain diff --git a/web/src/components/domains/DomainRemoveModal.tsx b/web/src/components/domains/DomainRemoveModal.tsx index 0372ba1..f7cc50c 100644 --- a/web/src/components/domains/DomainRemoveModal.tsx +++ b/web/src/components/domains/DomainRemoveModal.tsx @@ -1,15 +1,15 @@ import './DomainRemoveModal.css' import { useDomainStore, type Domain } from '@/stores/domains'; -import { NModal, NCard, NFlex, NButton, NIcon, NInput, useNotification } from 'naive-ui' +import { NModal, NCard, NFlex, NButton, NIcon, NInput, createDiscreteApi } from 'naive-ui' import { Times, TrashAlt, QuestionCircle } from '@vicons/fa'; import { getErrorInfo } from '@/apis/api'; import i18n from '@/locale/i18n'; -import type { EmitsOptions, ObjectEmitsOptions, SetupContext } from 'vue'; +import { ref, type EmitsOptions, type ObjectEmitsOptions, type SetupContext } from 'vue'; const t = i18n.global.t const domainStore = useDomainStore() -const notification = useNotification() +const { notification } = createDiscreteApi(['notification']) type Props = { domain: Domain @@ -20,12 +20,12 @@ type Events = { 'update:show': (value: boolean) => void } -let domain_name = '' -let loading = false +const domain_name = ref('') +const loading = ref(false) async function confirm(domain: Domain) { - domain_name = '' - loading = true + domain_name.value = '' + loading.value = true try { if (domain) @@ -35,7 +35,7 @@ async function confirm(domain: Domain) { notification.error(msg) console.error(e) } finally { - loading = false + loading.value = false } } @@ -47,7 +47,7 @@ function modalBody({ domain }: Props) {

{t('domains.confirm1')} {domain.domain_name} {t('domains.confirm2')}


- domain_name = v} placeholder={domain.domain_name} /> + domain_name.value = v} placeholder={domain.domain_name} />

) @@ -63,7 +63,7 @@ function modalActions({ domain }: Props, { emit }: SetupContext) { }} - confirm(domain)}> + confirm(domain).then(() => emit('update:show', false))}> {{ icon: () => , default: () => t('common.confirm') diff --git a/web/src/components/records/RecordOps.tsx b/web/src/components/records/RecordOps.tsx new file mode 100644 index 0000000..6d0f023 --- /dev/null +++ b/web/src/components/records/RecordOps.tsx @@ -0,0 +1,47 @@ +import { NButton, NButtonGroup, NTooltip, NIcon, NPopconfirm, NFlex } from 'naive-ui' +import { TrashAlt, EditRegular } from '@vicons/fa' +import type { Record } from '@/stores/records' +import i18n from '@/locale/i18n' +import type { SetupContext } from 'vue' +const { t } = i18n.global + +type Props = { + record: Record + domain: string +} + +type Events = { + recordDelete(domain: string, record: Record): void + editRecord(domain: string, record: Record): void +} + +function RecordOps({ record, domain }: Props, { emit }: SetupContext) { + return ( + + + + {{ + trigger: () => emit('editRecord', domain, record)}> + {{ + icon: () => + }} + , + default: () => t("common.edit") + }} + + emit('recordDelete', domain, record)}> + {{ + trigger: () => + {{ + icon: () => + }} + , + default: () => t("common.deleteConfirm") + }} + + + + ) +} + +export default RecordOps \ No newline at end of file diff --git a/web/src/components/records/RecordOps.vue b/web/src/components/records/RecordOps.vue deleted file mode 100644 index 9d8212b..0000000 --- a/web/src/components/records/RecordOps.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - \ No newline at end of file diff --git a/web/src/views/DomainsView.vue b/web/src/views/DomainsView.vue index e9f526f..de75802 100644 --- a/web/src/views/DomainsView.vue +++ b/web/src/views/DomainsView.vue @@ -7,7 +7,7 @@ import { getErrorInfo } from '@/apis/api' import DomainInfo from '@/components/domains/DomainInfo' import DomainOps from '@/components/domains/DomainOps' import DomainRemoveModal from '@/components/domains/DomainRemoveModal' -import DomainEditModal from '@/components/domains/DomainEditModal.vue' +import DomainEditModal from '@/components/domains/DomainEditModal' const domainStore = useDomainStore() const notification = useNotification() diff --git a/web/src/views/RecordsView.vue b/web/src/views/RecordsView.vue index 6816f70..a69cec5 100644 --- a/web/src/views/RecordsView.vue +++ b/web/src/views/RecordsView.vue @@ -11,7 +11,7 @@ import { useRecordStore, type Record, type SOARecord, RecordTypes } from '@/stor import { getErrorInfo } from '@/apis/api' import { PlusSquare, RedoAlt, CheckCircle, Clock, Cogs, Search } from '@vicons/fa' import router from '@/router'; -import RecordOps from '@/components/records/RecordOps.vue' +import RecordOps from '@/components/records/RecordOps' import RecordEditModal from '@/components/records/RecordEditModal.vue' import { useI18n } from 'vue-i18n'; const { t } = useI18n() @@ -58,7 +58,7 @@ const columns = [ const recordStore = useRecordStore() const notification = useNotification() -const records = ref([]as Record[]); +const records = ref([] as Record[]); const soa = ref({} as SOARecord) const editModalShow = ref(false) const editingRecord = ref({} as Record) @@ -131,7 +131,8 @@ function newRecord() {