From 4b1414a251c2b400a71f26de93bd41aed68f0453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Mon, 29 Jul 2024 18:41:36 +0200 Subject: [PATCH] refactor: split components Domain Finder --- assets/components/search/DomainSearchBar.tsx | 35 ++++ assets/components/search/EntitiesList.tsx | 53 ++++++ assets/components/search/EventTimeline.tsx | 70 ++++++++ assets/pages/search/DomainSearchPage.tsx | 171 +------------------ translations/translations.pot | 148 ++++++++-------- 5 files changed, 240 insertions(+), 237 deletions(-) create mode 100644 assets/components/search/DomainSearchBar.tsx create mode 100644 assets/components/search/EntitiesList.tsx create mode 100644 assets/components/search/EventTimeline.tsx diff --git a/assets/components/search/DomainSearchBar.tsx b/assets/components/search/DomainSearchBar.tsx new file mode 100644 index 0000000..8efa025 --- /dev/null +++ b/assets/components/search/DomainSearchBar.tsx @@ -0,0 +1,35 @@ +import {Form, Input} from "antd"; +import {t} from "ttag"; +import {SearchOutlined} from "@ant-design/icons"; +import React from "react"; + +export type FieldType = { + ldhName: string +} + +export function DomainSearchBar({onFinish}: { onFinish: any }) { + + return
+ + name="ldhName" + rules={[{ + required: true, + message: t`Required` + }, { + pattern: /^(?=.*\.)\S*[^.\s]$/, + message: t`This domain name does not appear to be valid`, + max: 63, + min: 2 + }]} + > + } placeholder="example.com" autoFocus={true} + autoComplete='off'/> + + +} \ No newline at end of file diff --git a/assets/components/search/EntitiesList.tsx b/assets/components/search/EntitiesList.tsx new file mode 100644 index 0000000..c0ee08d --- /dev/null +++ b/assets/components/search/EntitiesList.tsx @@ -0,0 +1,53 @@ +import vCard from "vcf"; +import {Avatar, List} from "antd"; +import {BankOutlined, IdcardOutlined, SignatureOutlined, ToolOutlined, UserOutlined} from "@ant-design/icons"; +import React from "react"; +import {Domain} from "../../utils/api"; +import {t} from "ttag"; + +export function EntitiesList({domain}: { domain: Domain }) { + const domainRole = { + registrant: t`Registrant`, + technical: t`Technical`, + administrative: t`Administrative`, + abuse: t`Abuse`, + billing: t`Billing`, + registrar: t`Registrar`, + reseller: t`Reseller`, + sponsor: t`Sponsor`, + proxy: t`Proxy`, + notifications: t`Notifications`, + noc: t`Noc` + } + + return { + const p = (r: string[]) => r.includes('registrant') ? 4 : r.includes('administrative') ? 3 : r.includes('billing') ? 2 : 1 + return p(e2.roles) - p(e1.roles) + })} + renderItem={(e) => { + const jCard = vCard.fromJSON(e.entity.jCard) + let name = '' + if (jCard.data.fn !== undefined && !Array.isArray(jCard.data.fn)) name = jCard.data.fn.valueOf() + + return + : e.roles.includes('registrar') ? + : + e.roles.includes('technical') ? + : + e.roles.includes('administrative') ? + : + }/>} + title={e.entity.handle} + description={name} + /> +
{e.roles.map((r) => Object.keys(domainRole).includes(r) ? domainRole[r as keyof typeof domainRole] : r).join(', ')}
+
+ }} + /> +} \ No newline at end of file diff --git a/assets/components/search/EventTimeline.tsx b/assets/components/search/EventTimeline.tsx new file mode 100644 index 0000000..d04a142 --- /dev/null +++ b/assets/components/search/EventTimeline.tsx @@ -0,0 +1,70 @@ +import { + ClockCircleOutlined, + DeleteOutlined, + ReloadOutlined, + ShareAltOutlined, + SignatureOutlined, + SyncOutlined +} from "@ant-design/icons"; +import {Timeline} from "antd"; +import React from "react"; +import {Domain} from "../../utils/api"; +import {t} from "ttag"; + +export function EventTimeline({domain}: { domain: Domain }) { + + const domainEvent = { + registration: t`Registration`, + reregistration: t`Reregistration`, + 'last changed': t`Last changed`, + expiration: t`Expiration`, + deletion: t`Deletion`, + reinstantiation: t`Reinstantiation`, + transfer: t`Transfer`, + locked: t`Locked`, + unlocked: t`Unlocked`, + 'registrar expiration': t`Registrar expiration`, + 'enum validation expiration': t`ENUM validation expiration` + } + + const locale = navigator.language.split('-')[0] + + return new Date(e2.date).getTime() - new Date(e1.date).getTime()) + .map(({action, date}) => { + + let color, dot + if (action === 'registration') { + color = 'green' + dot = + } else if (action === 'expiration') { + color = 'red' + dot = + } else if (action === 'transfer') { + color = 'orange' + dot = + } else if (action === 'last changed') { + color = 'blue' + dot = + } else if (action === 'deletion') { + color = 'red' + dot = + } else if (action === 'reregistration') { + color = 'green' + dot = + } + + return { + label: new Date(date).toLocaleString(locale), + children: Object.keys(domainEvent).includes(action) ? domainEvent[action as keyof typeof domainEvent] : action, + color, + dot, + pending: new Date(date).getTime() > new Date().getTime() + } + } + ) + } + /> +} \ No newline at end of file diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 26bc9d5..43526e2 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -1,77 +1,14 @@ import React, {useState} from "react"; -import { - Avatar, - Badge, - Card, - Divider, - Empty, - Flex, - Form, - FormProps, - Input, - List, - message, - Skeleton, - Space, - Tag, - Timeline, - Typography -} from "antd"; -import { - BankOutlined, - ClockCircleOutlined, - DeleteOutlined, - IdcardOutlined, - ReloadOutlined, - SearchOutlined, - ShareAltOutlined, - SignatureOutlined, - SyncOutlined, - ToolOutlined, - UserOutlined -} from "@ant-design/icons"; +import {Badge, Card, Divider, Empty, Flex, FormProps, message, Skeleton, Space, Tag} from "antd"; import {Domain, getDomain} from "../../utils/api"; import {AxiosError} from "axios" -import vCard from 'vcf' import {t} from 'ttag' +import {DomainSearchBar, FieldType} from "../../components/search/DomainSearchBar"; +import {EventTimeline} from "../../components/search/EventTimeline"; +import {EntitiesList} from "../../components/search/EntitiesList"; -type FieldType = { - ldhName: string -} - - -const locale = navigator.language.split('-')[0] - export default function DomainSearchPage() { - const domainRole = { - registrant: t`Registrant`, - technical: t`Technical`, - administrative: t`Administrative`, - abuse: t`Abuse`, - billing: t`Billing`, - registrar: t`Registrar`, - reseller: t`Reseller`, - sponsor: t`Sponsor`, - proxy: t`Proxy`, - notifications: t`Notifications`, - noc: t`Noc` - } - - const domainEvent = { - registration: t`Registration`, - reregistration: t`Reregistration`, - 'last changed': t`Last changed`, - expiration: t`Expiration`, - deletion: t`Deletion`, - reinstantiation: t`Reinstantiation`, - transfer: t`Transfer`, - locked: t`Locked`, - unlocked: t`Unlocked`, - 'registrar expiration': t`Registrar expiration`, - 'enum validation expiration': t`ENUM validation expiration` - } - const [domain, setDomain] = useState() const [messageApi, contextHolder] = message.useMessage() @@ -90,29 +27,7 @@ export default function DomainSearchPage() { return {contextHolder} -
- - name="ldhName" - rules={[{ - required: true, - message: t`Required` - }, { - pattern: /^(?=.*\.)\S*[^.\s]$/, - message: t`This domain name does not appear to be valid`, - max: 63, - min: 2 - }]} - > - } placeholder="example.com" autoFocus={true} - autoComplete='off'/> - - + { @@ -140,89 +55,19 @@ export default function DomainSearchPage() { } {t`Timeline`} - new Date(e2.date).getTime() - new Date(e1.date).getTime()) - .map(({action, date}) => { - - let color, dot - if (action === 'registration') { - color = 'green' - dot = - } else if (action === 'expiration') { - color = 'red' - dot = - } else if (action === 'transfer') { - color = 'orange' - dot = - } else if (action === 'last changed') { - color = 'blue' - dot = - } else if (action === 'deletion') { - color = 'red' - dot = - } else if (action === 'reregistration') { - color = 'green' - dot = - } - - return { - label: new Date(date).toLocaleString(locale), - children: Object.keys(domainEvent).includes(action) ? domainEvent[action as keyof typeof domainEvent] : action, - color, - dot, - pending: new Date(date).getTime() > new Date().getTime() - } - } - ) - } - /> + { domain.entities.length > 0 && <> {t`Entities`} - { - const p = (r: string[]) => r.includes('registrant') ? 4 : r.includes('administrative') ? 3 : r.includes('billing') ? 2 : 1 - return p(e2.roles) - p(e1.roles) - })} - renderItem={(e) => { - const jCard = vCard.fromJSON(e.entity.jCard) - let name = '' - if (jCard.data.fn !== undefined && !Array.isArray(jCard.data.fn)) name = jCard.data.fn.valueOf() - - return - : e.roles.includes('registrar') ? - : - e.roles.includes('technical') ? - : - e.roles.includes('administrative') ? - : - }/>} - title={e.entity.handle} - description={name} - /> -
{e.roles.map((r) => Object.keys(domainRole).includes(r) ? domainRole[r as keyof typeof domainRole] : r).join(', ')}
-
- }} - /> + }
: - {t`Although the domain exists in my database, it has been deleted from the WHOIS by its registrar.`} - - }/>) + description={t`Although the domain exists in my database, it has been deleted from the WHOIS by its registrar.`}/>) } diff --git a/translations/translations.pot b/translations/translations.pot index 66a3ddf..ec0541f 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -3,134 +3,134 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -#: assets/pages/search/DomainSearchPage.tsx:48 -msgid "Registrant" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:49 -msgid "Technical" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:50 -msgid "Administrative" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:51 -msgid "Abuse" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:52 -msgid "Billing" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:53 -msgid "Registrar" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:54 -msgid "Reseller" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:55 -msgid "Sponsor" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:56 -msgid "Proxy" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:57 -msgid "Notifications" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:58 -msgid "Noc" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:62 +#: assets/components/search/EventTimeline.tsx:17 msgid "Registration" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:63 +#: assets/components/search/EventTimeline.tsx:18 msgid "Reregistration" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:64 +#: assets/components/search/EventTimeline.tsx:19 msgid "Last changed" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:65 +#: assets/components/search/EventTimeline.tsx:20 msgid "Expiration" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:66 +#: assets/components/search/EventTimeline.tsx:21 msgid "Deletion" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:67 +#: assets/components/search/EventTimeline.tsx:22 msgid "Reinstantiation" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:68 +#: assets/components/search/EventTimeline.tsx:23 msgid "Transfer" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:69 +#: assets/components/search/EventTimeline.tsx:24 msgid "Locked" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:70 +#: assets/components/search/EventTimeline.tsx:25 msgid "Unlocked" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:71 +#: assets/components/search/EventTimeline.tsx:26 msgid "Registrar expiration" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:72 +#: assets/components/search/EventTimeline.tsx:27 msgid "ENUM validation expiration" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:82 -msgid "Found !" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:86 -#: assets/pages/tracking/WatchlistPage.tsx:91 -msgid "An error occurred" -msgstr "" - -#: assets/pages/search/DomainSearchPage.tsx:91 -msgid "Domain finder" -msgstr "" - +#: assets/components/search/DomainSearchBar.tsx:23 #: assets/pages/LoginPage.tsx:53 #: assets/pages/LoginPage.tsx:61 -#: assets/pages/search/DomainSearchPage.tsx:104 #: assets/pages/tracking/WatchlistPage.tsx:137 #: assets/pages/tracking/WatchlistPage.tsx:197 #: assets/pages/tracking/WatchlistPage.tsx:207 msgid "Required" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:107 +#: assets/components/search/DomainSearchBar.tsx:26 #: assets/pages/tracking/WatchlistPage.tsx:140 msgid "This domain name does not appear to be valid" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:132 +#: assets/components/search/EntitiesList.tsx:10 +msgid "Registrant" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:11 +msgid "Technical" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:12 +msgid "Administrative" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:13 +msgid "Abuse" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:14 +msgid "Billing" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:15 +msgid "Registrar" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:16 +msgid "Reseller" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:17 +msgid "Sponsor" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:18 +msgid "Proxy" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:19 +msgid "Notifications" +msgstr "" + +#: assets/components/search/EntitiesList.tsx:20 +msgid "Noc" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:19 +msgid "Found !" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:23 +#: assets/pages/tracking/WatchlistPage.tsx:91 +msgid "An error occurred" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:28 +msgid "Domain finder" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:47 msgid "EPP Status Codes" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:142 +#: assets/pages/search/DomainSearchPage.tsx:57 msgid "Timeline" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:184 +#: assets/pages/search/DomainSearchPage.tsx:62 msgid "Entities" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:223 +#: assets/pages/search/DomainSearchPage.tsx:70 msgid "" "Although the domain exists in my database, it has been deleted from the " "WHOIS by its registrar."