refactor: move functions

This commit is contained in:
Maël Gangloff 2024-08-21 02:01:20 +02:00
parent 723ef3e883
commit a3c4a4e196
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
15 changed files with 208 additions and 183 deletions

View File

@ -1,4 +1,4 @@
import {ItemType, MenuItemType} from "antd/lib/menu/interface"; import {ItemType} from "antd/lib/menu/interface";
import {t} from "ttag"; import {t} from "ttag";
import { import {
AimOutlined, AimOutlined,
@ -22,8 +22,7 @@ import {useNavigate} from "react-router-dom";
export function Sider({isAuthenticated}: { isAuthenticated: boolean }) { export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
const navigate = useNavigate() const navigate = useNavigate()
const menuItems: ItemType[] = [
const menuItems: ItemType<MenuItemType>[] = [
{ {
key: 'home', key: 'home',
label: t`Home`, label: t`Home`,
@ -64,7 +63,8 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
icon: <CloudServerOutlined/>, icon: <CloudServerOutlined/>,
label: t`Nameserver`, label: t`Nameserver`,
title: t`Nameserver Finder`, title: t`Nameserver Finder`,
disabled: true disabled: true,
onClick: () => navigate('/search/nameserver')
} }
] ]
}, },
@ -103,7 +103,6 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
key: 'account', key: 'account',
icon: <UserOutlined/>, icon: <UserOutlined/>,
label: t`My Account`, label: t`My Account`,
disabled: !isAuthenticated,
onClick: () => navigate('/user') onClick: () => navigate('/user')
}, { }, {
key: 'logout', key: 'logout',
@ -122,7 +121,6 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
} }
return <Menu return <Menu
defaultSelectedKeys={['home']}
defaultOpenKeys={['search', 'info', 'tracking', 'doc']} defaultOpenKeys={['search', 'info', 'tracking', 'doc']}
mode="inline" mode="inline"
theme="dark" theme="dark"

View File

@ -19,9 +19,9 @@ export function DomainResult({domain}: { domain: Domain }) {
domain.tld.type === 'gTLD' ? "green" domain.tld.type === 'gTLD' ? "green"
: "cyan" : "cyan"
}> }>
<Card title={<> <Card title={<Space>
{domain.ldhName}{domain.handle && <Typography.Text code>{domain.handle}</Typography.Text>} {domain.ldhName}{domain.handle && <Typography.Text code>{domain.handle}</Typography.Text>}
</>} </Space>}
size="small"> size="small">
{domain.status.length > 0 && {domain.status.length > 0 &&
<> <>

View File

@ -10,7 +10,6 @@ export type FieldType = {
export function DomainSearchBar({onFinish}: { onFinish: (values: FieldType) => void }) { export function DomainSearchBar({onFinish}: { onFinish: (values: FieldType) => void }) {
return <Form return <Form
name="basic"
labelCol={{span: 8}} labelCol={{span: 8}}
wrapperCol={{span: 16}} wrapperCol={{span: 16}}
onFinish={onFinish} onFinish={onFinish}

View File

@ -1,49 +1,33 @@
import vCard from "vcf"; import {List, Tag, Tooltip} from "antd";
import {Avatar, List, Tag, Tooltip} from "antd";
import {BankOutlined, IdcardOutlined, SignatureOutlined, ToolOutlined, UserOutlined} from "@ant-design/icons";
import React from "react"; import React from "react";
import {Domain} from "../../utils/api"; import {Domain} from "../../utils/api";
import {rdapRoleDetailTranslation, rdapRoleTranslation} from "./rdapTranslation"; import {rdapRoleDetailTranslation, rdapRoleTranslation} from "./rdapTranslation";
import {rolesToColor} from "../tracking/watchlist/diagram/watchlistToEdges"; import {entityToName, rolesToColor, roleToAvatar, sortDomainEntities} from "../../utils";
export function EntitiesList({domain}: { domain: Domain }) { export function EntitiesList({domain}: { domain: Domain }) {
const rdapRoleTranslated = rdapRoleTranslation() const rdapRoleTranslated = rdapRoleTranslation()
const rdapRoleDetailTranslated = rdapRoleDetailTranslation() const rdapRoleDetailTranslated = rdapRoleDetailTranslation()
const roleToTag = (r: string) => <Tooltip
title={r in rdapRoleDetailTranslated ? rdapRoleDetailTranslated[r as keyof typeof rdapRoleDetailTranslated] : undefined}>
<Tag
color={rolesToColor([r])}>{rdapRoleTranslated[r as keyof typeof rdapRoleTranslated]}</Tag>
</Tooltip>
return <List return <List
className="demo-loadmore-list" className="demo-loadmore-list"
itemLayout="horizontal" itemLayout="horizontal"
dataSource={domain.entities.sort((e1, e2) => { dataSource={sortDomainEntities(domain)}
const p = (r: string[]) => r.includes('registrant') ? 4 : r.includes('administrative') ? 3 : r.includes('billing') ? 2 : 1 renderItem={(e) =>
return p(e2.roles) - p(e1.roles) <List.Item>
})}
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 <List.Item>
<List.Item.Meta <List.Item.Meta
avatar={<Avatar style={{backgroundColor: '#87d068'}} avatar={roleToAvatar(e)}
icon={e.roles.includes('registrant') ?
<SignatureOutlined/> : e.roles.includes('registrar') ?
<BankOutlined/> :
e.roles.includes('technical') ?
<ToolOutlined/> :
e.roles.includes('administrative') ?
<IdcardOutlined/> :
<UserOutlined/>}/>}
title={e.entity.handle} title={e.entity.handle}
description={name} description={entityToName(e)}
/> />
{e.roles.map((r) => {e.roles.map(roleToTag)}
<Tooltip
title={r in rdapRoleDetailTranslated ? rdapRoleDetailTranslated[r as keyof typeof rdapRoleDetailTranslated] : undefined}>
<Tag
color={rolesToColor([r])}>{rdapRoleTranslated[r as keyof typeof rdapRoleTranslated]}</Tag>
</Tooltip>)}
</List.Item> </List.Item>
}} }
/> />
} }

View File

@ -1,26 +1,9 @@
import { import {Timeline, Tooltip, Typography} from "antd";
ClockCircleOutlined,
DeleteOutlined,
ReloadOutlined,
ShareAltOutlined,
SignatureOutlined,
SyncOutlined
} from "@ant-design/icons";
import {Timeline, Tooltip} from "antd";
import React from "react"; import React from "react";
import {Domain, EventAction} from "../../utils/api"; import {Domain} from "../../utils/api";
import useBreakpoint from "../../hooks/useBreakpoint"; import useBreakpoint from "../../hooks/useBreakpoint";
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "./rdapTranslation"; import {rdapEventDetailTranslation, rdapEventNameTranslation} from "./rdapTranslation";
import {actionToColor, actionToIcon} from "../../utils";
export function actionToColor(a: EventAction) {
return a === 'registration' ? 'green' :
a === 'reregistration' ? 'cyan' :
a === 'expiration' ? 'red' :
a === 'deletion' ? 'magenta' :
a === 'transfer' ? 'orange' :
a === 'last changed' ? 'blue' : 'default'
}
export function EventTimeline({domain}: { domain: Domain }) { export function EventTimeline({domain}: { domain: Domain }) {
const sm = useBreakpoint('sm') const sm = useBreakpoint('sm')
@ -30,29 +13,22 @@ export function EventTimeline({domain}: { domain: Domain }) {
const rdapEventDetailTranslated = rdapEventDetailTranslation() const rdapEventDetailTranslated = rdapEventDetailTranslation()
const domainEvents = domain.events.sort((e1, e2) => new Date(e2.date).getTime() - new Date(e1.date).getTime()) const domainEvents = domain.events.sort((e1, e2) => new Date(e2.date).getTime() - new Date(e1.date).getTime())
const expirationEvents = domainEvents.filter(e => e.action === 'expiration')
return <Timeline return <Timeline
mode={sm ? "left" : "right"} mode={sm ? "left" : "right"}
items={domainEvents.map(({action, date}) => { items={domainEvents.map(e => {
let dot const sameEvents = domainEvents.filter(se => se.action === e.action)
if (action === 'registration') { const isRelevant = !(sameEvents.length > 1 && sameEvents.indexOf(e) !== 0)
dot = <SignatureOutlined style={{fontSize: '16px'}}/>
} else if (action === 'expiration') {
dot = <ClockCircleOutlined style={{fontSize: '16px'}}/>
} else if (action === 'transfer') {
dot = <ShareAltOutlined style={{fontSize: '16px'}}/>
} else if (action === 'last changed') {
dot = <SyncOutlined style={{fontSize: '16px'}}/>
} else if (action === 'deletion') {
dot = <DeleteOutlined style={{fontSize: '16px'}}/>
} else if (action === 'reregistration') {
dot = <ReloadOutlined style={{fontSize: '16px'}}/>
}
const eventName = action in rdapEventNameTranslated ? rdapEventNameTranslated[action as keyof typeof rdapEventNameTranslated] : action const eventName = <Typography.Text style={{color: isRelevant ? 'default' : 'grey'}}>
const dateStr = new Date(date).toLocaleString(locale) {e.action in rdapEventNameTranslated ? rdapEventNameTranslated[e.action as keyof typeof rdapEventNameTranslated] : e.action}
const eventDetail = action in rdapEventDetailTranslated ? rdapEventDetailTranslated[action as keyof typeof rdapEventDetailTranslated] : undefined </Typography.Text>
const dateStr = <Typography.Text
style={{color: isRelevant ? 'default' : 'grey'}}>{new Date(e.date).toLocaleString(locale)}
</Typography.Text>
const eventDetail = e.action in rdapEventDetailTranslated ? rdapEventDetailTranslated[e.action as keyof typeof rdapEventDetailTranslated] : undefined
const text = sm ? { const text = sm ? {
children: <Tooltip placement='bottom' title={eventDetail}> children: <Tooltip placement='bottom' title={eventDetail}>
@ -64,9 +40,9 @@ export function EventTimeline({domain}: { domain: Domain }) {
} }
return { return {
color: (action === 'expiration' ? (expirationEvents.length > 0 && domainEvents[0].date === date) : true) ? actionToColor(action) : 'grey', color: isRelevant ? actionToColor(e.action) : 'grey',
dot, dot: actionToIcon(e.action),
pending: new Date(date).getTime() > new Date().getTime(), pending: new Date(e.date).getTime() > new Date().getTime(),
...text ...text
} }
} }

View File

@ -16,7 +16,7 @@ const formItemLayoutWithOutLabel = {
xs: {span: 24, offset: 0}, xs: {span: 24, offset: 0},
sm: {span: 20, offset: 4}, sm: {span: 20, offset: 4},
}, },
}; }
export function ConnectorForm({form, onCreate}: { form: FormInstance, onCreate: (values: Connector) => void }) { export function ConnectorForm({form, onCreate}: { form: FormInstance, onCreate: (values: Connector) => void }) {
const [provider, setProvider] = useState<string>() const [provider, setProvider] = useState<string>()

View File

@ -5,13 +5,13 @@ import {ViewDiagramWatchlistButton} from "./diagram/ViewDiagramWatchlistButton";
import {UpdateWatchlistButton} from "./UpdateWatchlistButton"; import {UpdateWatchlistButton} from "./UpdateWatchlistButton";
import {DeleteWatchlistButton} from "./DeleteWatchlistButton"; import {DeleteWatchlistButton} from "./DeleteWatchlistButton";
import punycode from "punycode/punycode"; import punycode from "punycode/punycode";
import {actionToColor} from "../../search/EventTimeline";
import React from "react"; import React from "react";
import {Watchlist} from "../../../pages/tracking/WatchlistPage"; import {Watchlist} from "../../../pages/tracking/WatchlistPage";
import {Connector} from "../../../utils/api/connectors"; import {Connector} from "../../../utils/api/connectors";
import useBreakpoint from "../../../hooks/useBreakpoint"; import useBreakpoint from "../../../hooks/useBreakpoint";
import {CalendarWatchlistButton} from "./CalendarWatchlistButton"; import {CalendarWatchlistButton} from "./CalendarWatchlistButton";
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation"; import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation";
import {actionToColor, actionToIcon} from "../../../utils";
export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelete}: { export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelete}: {
watchlist: Watchlist, watchlist: Watchlist,
@ -78,7 +78,7 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
events: watchlist.triggers?.filter(t => t.action === 'email') events: watchlist.triggers?.filter(t => t.action === 'email')
.map(t => <Tooltip .map(t => <Tooltip
title={t.event in rdapEventDetailTranslated ? rdapEventDetailTranslated[t.event as keyof typeof rdapEventDetailTranslated] : undefined}> title={t.event in rdapEventDetailTranslated ? rdapEventDetailTranslated[t.event as keyof typeof rdapEventDetailTranslated] : undefined}>
<Tag color={actionToColor(t.event)}> <Tag color={actionToColor(t.event)} icon={actionToIcon(t.event)}>
{rdapEventNameTranslated[t.event as keyof typeof rdapEventNameTranslated]} {rdapEventNameTranslated[t.event as keyof typeof rdapEventNameTranslated]}
</Tag> </Tag>
</Tooltip> </Tooltip>

View File

@ -3,8 +3,8 @@ import {t} from "ttag";
import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from "@ant-design/icons"; import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from "@ant-design/icons";
import React from "react"; import React from "react";
import {Connector} from "../../../utils/api/connectors"; import {Connector} from "../../../utils/api/connectors";
import {actionToColor} from "../../search/EventTimeline";
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation"; import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation";
import {actionToColor, actionToIcon} from "../../../utils";
type TagRender = SelectProps['tagRender']; type TagRender = SelectProps['tagRender'];
@ -44,6 +44,7 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: {
return (<Tooltip return (<Tooltip
title={value in rdapEventDetailTranslated ? rdapEventDetailTranslated[value as keyof typeof rdapEventDetailTranslated] : undefined}> title={value in rdapEventDetailTranslated ? rdapEventDetailTranslated[value as keyof typeof rdapEventDetailTranslated] : undefined}>
<Tag <Tag
icon={actionToIcon(value)}
color={actionToColor(value)} color={actionToColor(value)}
onMouseDown={onPreventMouseDown} onMouseDown={onPreventMouseDown}
closable={closable} closable={closable}

View File

@ -1,13 +1,7 @@
import {Domain, Watchlist} from "../../../../utils/api"; import {Domain, Watchlist} from "../../../../utils/api";
import {rdapRoleTranslation} from "../../../search/rdapTranslation"; import {rdapRoleTranslation} from "../../../search/rdapTranslation";
import {t} from "ttag"; import {t} from "ttag";
import {rolesToColor} from "../../../../utils";
export const rolesToColor = (roles: string[]) => roles.includes('registrant') ? 'green' :
roles.includes('administrative') ? 'blue' :
roles.includes('technical') ? 'orange' :
roles.includes('registrar') ? 'magenta' :
roles.includes('sponsor') ? 'purple' :
roles.includes('billing') ? 'cyan' : 'default'
export function domainEntitiesToEdges(d: Domain, withRegistrar = false) { export function domainEntitiesToEdges(d: Domain, withRegistrar = false) {
const rdapRoleTranslated = rdapRoleTranslation() const rdapRoleTranslated = rdapRoleTranslation()

View File

@ -1,7 +1,7 @@
import {Domain, Nameserver, Tld, Watchlist} from "../../../../utils/api"; import {Domain, Nameserver, Tld, Watchlist} from "../../../../utils/api";
import vCard from "vcf";
import React from "react"; import React from "react";
import {t} from 'ttag' import {t} from 'ttag'
import {entityToName} from "../../../../utils";
export const domainToNode = (d: Domain) => ({ export const domainToNode = (d: Domain) => ({
id: d.ldhName, id: d.ldhName,
@ -14,14 +14,10 @@ export const domainToNode = (d: Domain) => ({
export const domainEntitiesToNode = (d: Domain, withRegistrar = false) => d.entities export const domainEntitiesToNode = (d: Domain, withRegistrar = false) => d.entities
.filter(e => !withRegistrar ? !e.roles.includes('registrar') : true) .filter(e => !withRegistrar ? !e.roles.includes('registrar') : true)
.map(e => { .map(e => {
const jCard = vCard.fromJSON(e.entity.jCard)
let label = e.entity.handle
if (jCard.data.fn !== undefined && !Array.isArray(jCard.data.fn)) label = jCard.data.fn.valueOf()
return { return {
id: e.entity.handle, id: e.entity.handle,
type: e.roles.includes('registrant') || e.roles.includes('registrar') ? 'input' : 'output', type: e.roles.includes('registrant') || e.roles.includes('registrar') ? 'input' : 'output',
data: {label}, data: {label: entityToName(e)},
style: { style: {
width: 200 width: 200
} }

View File

@ -7,11 +7,6 @@ import {getConfiguration, InstanceConfig} from "../utils/api";
import {RegisterForm} from "../components/RegisterForm"; import {RegisterForm} from "../components/RegisterForm";
const gridStyle: React.CSSProperties = {
width: '50%',
textAlign: 'center',
}
export const AuthenticatedContext = createContext<any>(null) export const AuthenticatedContext = createContext<any>(null)
export default function LoginPage() { export default function LoginPage() {
@ -28,7 +23,7 @@ export default function LoginPage() {
}, []) }, [])
return <Card title={wantRegister ? t`Register` : t`Log in`} style={{width: '100%'}}> return <Card title={wantRegister ? t`Register` : t`Log in`} style={{width: '100%'}}>
<Card.Grid style={gridStyle} hoverable={false}> <Card.Grid style={{width: '50%', textAlign: 'center'}} hoverable={false}>
{wantRegister ? <RegisterForm/> : <LoginForm ssoLogin={configuration?.ssoLogin}/>} {wantRegister ? <RegisterForm/> : <LoginForm ssoLogin={configuration?.ssoLogin}/>}
{ {
configuration?.registerEnabled && configuration?.registerEnabled &&

View File

@ -54,11 +54,10 @@ export default function WatchlistPage() {
const [form] = Form.useForm() const [form] = Form.useForm()
const [messageApi, contextHolder] = message.useMessage() const [messageApi, contextHolder] = message.useMessage()
const [watchlists, setWatchlists] = useState<Watchlist[] | null>() const [watchlists, setWatchlists] = useState<Watchlist[]>()
const [connectors, setConnectors] = useState<(Connector & { id: string })[] | null>() const [connectors, setConnectors] = useState<(Connector & { id: string })[]>()
const onCreateWatchlist = (values: FormValuesType) => { const onCreateWatchlist = (values: FormValuesType) => {
postWatchlist(getRequestDataFromForm(values)).then((w) => { postWatchlist(getRequestDataFromForm(values)).then((w) => {
form.resetFields() form.resetFields()
refreshWatchlists() refreshWatchlists()
@ -98,9 +97,10 @@ export default function WatchlistPage() {
return <Flex gap="middle" align="center" justify="center" vertical> return <Flex gap="middle" align="center" justify="center" vertical>
{contextHolder} {contextHolder}
{ {
connectors && <Card loading={connectors === undefined} title={t`Create a Watchlist`} style={{width: '100%'}}>
<Card title={t`Create a Watchlist`} style={{width: '100%'}}> {connectors &&
<WatchlistForm form={form} onFinish={onCreateWatchlist} connectors={connectors} isCreation={true}/> <WatchlistForm form={form} onFinish={onCreateWatchlist} connectors={connectors} isCreation={true}/>
}
</Card> </Card>
} }
<Divider/> <Divider/>

View File

@ -1,27 +0,0 @@
import {MessageInstance, MessageType} from "antd/lib/message/interface";
import {AxiosError, AxiosResponse} from "axios";
import {t} from "ttag";
export function showErrorAPI(e: AxiosError, messageApi: MessageInstance): MessageType | undefined {
const response = e.response as AxiosResponse
const data = response.data
if ('message' in data) {
return messageApi.error(data.message as string)
}
if (!('detail' in data)) return
const detail = data.detail as string
if (response.status === 429) {
const duration = response.headers['retry-after']
return messageApi.error(t`Please retry after ${duration} seconds`)
}
if (response.status.toString()[0] === '4') {
return messageApi.warning(detail !== '' ? detail : t`An error occurred`)
}
return messageApi.error(detail !== '' ? detail : t`An error occurred`)
}

109
assets/utils/index.tsx Normal file
View File

@ -0,0 +1,109 @@
import {MessageInstance, MessageType} from "antd/lib/message/interface";
import {AxiosError, AxiosResponse} from "axios";
import {t} from "ttag";
import {Avatar} from "antd";
import {
BankOutlined,
ClockCircleOutlined,
DeleteOutlined,
DollarOutlined,
IdcardOutlined,
LockOutlined,
ReloadOutlined,
ShareAltOutlined,
SignatureOutlined,
SyncOutlined,
ToolOutlined,
UnlockOutlined,
UserOutlined
} from "@ant-design/icons";
import {Domain, Entity, EventAction} from "./api";
import vCard from "vcf";
import React from "react";
export const roleToAvatar = (e: { roles: string[] }) => <Avatar style={{backgroundColor: rolesToColor(e.roles)}}
icon={e.roles.includes('registrant') ?
<SignatureOutlined/> : e.roles.includes('registrar') ?
<BankOutlined/> :
e.roles.includes('technical') ?
<ToolOutlined/> :
e.roles.includes('administrative') ?
<IdcardOutlined/> :
e.roles.includes('billing') ?
<DollarOutlined/> :
<UserOutlined/>}/>
export const rolesToColor = (roles: string[]) => roles.includes('registrant') ? 'green' :
roles.includes('administrative') ? 'blue' :
roles.includes('technical') ? 'orange' :
roles.includes('registrar') ? 'purple' :
roles.includes('sponsor') ? 'magenta' :
roles.includes('billing') ? 'cyan' : 'default'
export const actionToColor = (a: EventAction) => a === 'registration' ? 'green' :
a === 'reregistration' ? 'cyan' :
a === 'expiration' ? 'red' :
a === 'deletion' ? 'magenta' :
a === 'transfer' ? 'orange' :
a === 'last changed' ? 'blue' :
a === 'registrar expiration' ? 'red' :
a === 'reinstantiation' ? 'purple' :
a === 'enum validation expiration' ? 'red' : 'default'
export const actionToIcon = (a: EventAction) => a === 'registration' ?
<SignatureOutlined style={{fontSize: '16px'}}/> : a === 'expiration' ?
<ClockCircleOutlined style={{fontSize: '16px'}}/> : a === 'transfer' ?
<ShareAltOutlined style={{fontSize: '16px'}}/> : a === 'last changed' ?
<SyncOutlined style={{fontSize: '16px'}}/> : a === 'deletion' ?
<DeleteOutlined style={{fontSize: '16px'}}/> : a === 'reregistration' ?
<ReloadOutlined style={{fontSize: '16px'}}/> : a === 'locked' ?
<LockOutlined style={{fontSize: '16px'}}/> : a === 'unlocked' ?
<UnlockOutlined style={{fontSize: '16px'}}/> : a === 'registrar expiration' ?
<ClockCircleOutlined
style={{fontSize: '16px'}}/> : a === 'enum validation expiration' ?
<ClockCircleOutlined style={{fontSize: '16px'}}/> : a === 'reinstantiation' ?
<ReloadOutlined style={{fontSize: '16px'}}/> : undefined
export const entityToName = (e: { entity: Entity }): string => {
const jCard = vCard.fromJSON(e.entity.jCard)
let name = e.entity.handle
if (jCard.data.fn && !Array.isArray(jCard.data.fn) && jCard.data.fn.valueOf() !== '') name = jCard.data.fn.valueOf()
return name
}
export const sortDomainEntities = (domain: Domain) => domain.entities.sort((e1, e2) => {
const p = (r: string[]) => r.includes('registrant') ? 5 :
r.includes('administrative') ? 4 :
r.includes('billing') ? 3 :
r.includes('registrar') ? 2 : 1
return p(e2.roles) - p(e1.roles)
})
export function showErrorAPI(e: AxiosError, messageApi: MessageInstance): MessageType | undefined {
const response = e.response as AxiosResponse
const data = response.data
if ('message' in data) {
return messageApi.error(data.message as string)
}
if (!('detail' in data)) return
const detail = data.detail as string
if (response.status === 429) {
const duration = response.headers['retry-after']
return messageApi.error(t`Please retry after ${duration} seconds`)
}
if (response.status.toString()[0] === '4') {
return messageApi.warning(detail !== '' ? detail : t`An error occurred`)
}
return messageApi.error(detail !== '' ? detail : t`An error occurred`)
}

View File

@ -12,7 +12,7 @@ msgstr ""
#: assets/components/LoginForm.tsx:61 #: assets/components/LoginForm.tsx:61
#: assets/components/RegisterForm.tsx:40 #: assets/components/RegisterForm.tsx:40
#: assets/components/RegisterForm.tsx:48 #: assets/components/RegisterForm.tsx:48
#: assets/components/search/DomainSearchBar.tsx:23 #: assets/components/search/DomainSearchBar.tsx:22
#: assets/components/tracking/connector/ConnectorForm.tsx:43 #: assets/components/tracking/connector/ConnectorForm.tsx:43
#: assets/components/tracking/connector/ConnectorForm.tsx:69 #: assets/components/tracking/connector/ConnectorForm.tsx:69
#: assets/components/tracking/connector/ConnectorForm.tsx:77 #: assets/components/tracking/connector/ConnectorForm.tsx:77
@ -22,8 +22,8 @@ msgstr ""
#: assets/components/tracking/connector/ConnectorForm.tsx:142 #: assets/components/tracking/connector/ConnectorForm.tsx:142
#: assets/components/tracking/connector/ConnectorForm.tsx:156 #: assets/components/tracking/connector/ConnectorForm.tsx:156
#: assets/components/tracking/connector/ConnectorForm.tsx:165 #: assets/components/tracking/connector/ConnectorForm.tsx:165
#: assets/components/tracking/watchlist/WatchlistForm.tsx:113 #: assets/components/tracking/watchlist/WatchlistForm.tsx:114
#: assets/components/tracking/watchlist/WatchlistForm.tsx:210 #: assets/components/tracking/watchlist/WatchlistForm.tsx:211
msgid "Required" msgid "Required"
msgstr "" msgstr ""
@ -468,8 +468,8 @@ msgstr ""
msgid "Entities" msgid "Entities"
msgstr "" msgstr ""
#: assets/components/search/DomainSearchBar.tsx:26 #: assets/components/search/DomainSearchBar.tsx:25
#: assets/components/tracking/watchlist/WatchlistForm.tsx:116 #: assets/components/tracking/watchlist/WatchlistForm.tsx:117
msgid "This domain name does not appear to be valid" msgid "This domain name does not appear to be valid"
msgstr "" msgstr ""
@ -544,12 +544,12 @@ msgid ""
msgstr "" msgstr ""
#: assets/components/tracking/connector/ConnectorForm.tsx:176 #: assets/components/tracking/connector/ConnectorForm.tsx:176
#: assets/components/tracking/watchlist/WatchlistForm.tsx:250 #: assets/components/tracking/watchlist/WatchlistForm.tsx:251
msgid "Create" msgid "Create"
msgstr "" msgstr ""
#: assets/components/tracking/connector/ConnectorForm.tsx:179 #: assets/components/tracking/connector/ConnectorForm.tsx:179
#: assets/components/tracking/watchlist/WatchlistForm.tsx:253 #: assets/components/tracking/watchlist/WatchlistForm.tsx:254
msgid "Reset" msgid "Reset"
msgstr "" msgstr ""
@ -582,72 +582,72 @@ msgstr ""
msgid "No" msgid "No"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:70 #: assets/components/tracking/watchlist/WatchlistForm.tsx:71
msgid "Name" msgid "Name"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:81 #: assets/components/tracking/watchlist/WatchlistForm.tsx:82
msgid "Watchlist Name" msgid "Watchlist Name"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:82 #: assets/components/tracking/watchlist/WatchlistForm.tsx:83
msgid "Naming the Watchlist makes it easier to find in the list below." msgid "Naming the Watchlist makes it easier to find in the list below."
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:93 #: assets/components/tracking/watchlist/WatchlistForm.tsx:94
msgid "At least one domain name" msgid "At least one domain name"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistCard.tsx:28 #: assets/components/tracking/watchlist/WatchlistCard.tsx:28
#: assets/components/tracking/watchlist/WatchlistForm.tsx:104 #: assets/components/tracking/watchlist/WatchlistForm.tsx:105
msgid "Domain names" msgid "Domain names"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:122 #: assets/components/tracking/watchlist/WatchlistForm.tsx:123
msgid "Domain name" msgid "Domain name"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:139 #: assets/components/tracking/watchlist/WatchlistForm.tsx:140
msgid "Add a Domain name" msgid "Add a Domain name"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistCard.tsx:32 #: assets/components/tracking/watchlist/WatchlistCard.tsx:32
#: assets/components/tracking/watchlist/WatchlistForm.tsx:146 #: assets/components/tracking/watchlist/WatchlistForm.tsx:147
msgid "Tracked events" msgid "Tracked events"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:148 #: assets/components/tracking/watchlist/WatchlistForm.tsx:149
msgid "At least one trigger" msgid "At least one trigger"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:171 #: assets/components/tracking/watchlist/WatchlistForm.tsx:172
#: assets/components/tracking/watchlist/WatchlistForm.tsx:185 #: assets/components/tracking/watchlist/WatchlistForm.tsx:186
msgid "Connector" msgid "Connector"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:181 #: assets/components/tracking/watchlist/WatchlistForm.tsx:182
msgid "" msgid ""
"Please make sure the connector information is valid to purchase a domain " "Please make sure the connector information is valid to purchase a domain "
"that may be available soon." "that may be available soon."
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:201 #: assets/components/tracking/watchlist/WatchlistForm.tsx:202
msgid "DSN" msgid "DSN"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:213 #: assets/components/tracking/watchlist/WatchlistForm.tsx:214
msgid "This DSN does not appear to be valid" msgid "This DSN does not appear to be valid"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:231 #: assets/components/tracking/watchlist/WatchlistForm.tsx:232
msgid "Check out this link to the Symfony documentation to help you build the DSN" msgid "Check out this link to the Symfony documentation to help you build the DSN"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:240 #: assets/components/tracking/watchlist/WatchlistForm.tsx:241
msgid "Add a Webhook" msgid "Add a Webhook"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/WatchlistForm.tsx:250 #: assets/components/tracking/watchlist/WatchlistForm.tsx:251
msgid "Update" msgid "Update"
msgstr "" msgstr ""
@ -671,11 +671,11 @@ msgstr ""
msgid "Watchlist Entity Diagram" msgid "Watchlist Entity Diagram"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/diagram/watchlistToEdges.tsx:42 #: assets/components/tracking/watchlist/diagram/watchlistToEdges.tsx:36
msgid "Registry" msgid "Registry"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/diagram/watchlistToNodes.tsx:33 #: assets/components/tracking/watchlist/diagram/watchlistToNodes.tsx:29
#, javascript-format #, javascript-format
msgid ".${ tld.tld } Registry" msgid ".${ tld.tld } Registry"
msgstr "" msgstr ""
@ -705,44 +705,44 @@ msgstr ""
msgid "Watchlist" msgid "Watchlist"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:29 #: assets/components/Sider.tsx:28
msgid "Home" msgid "Home"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:35 #: assets/components/Sider.tsx:34
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:41 #: assets/components/Sider.tsx:40
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:42 #: assets/components/Sider.tsx:41
msgid "Domain Finder" msgid "Domain Finder"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:49 #: assets/components/Sider.tsx:48
#: assets/pages/info/TldPage.tsx:79 #: assets/pages/info/TldPage.tsx:79
msgid "TLD" msgid "TLD"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:50 #: assets/components/Sider.tsx:49
msgid "TLD list" msgid "TLD list"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:57 #: assets/components/Sider.tsx:56
msgid "Entity" msgid "Entity"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:58 #: assets/components/Sider.tsx:57
msgid "Entity Finder" msgid "Entity Finder"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:65 #: assets/components/Sider.tsx:64
msgid "Nameserver" msgid "Nameserver"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:66 #: assets/components/Sider.tsx:65
msgid "Nameserver Finder" msgid "Nameserver Finder"
msgstr "" msgstr ""
@ -767,18 +767,18 @@ msgstr ""
msgid "My Account" msgid "My Account"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:111 #: assets/components/Sider.tsx:110
msgid "Log out" msgid "Log out"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:119 #: assets/components/Sider.tsx:118
#: assets/pages/LoginPage.tsx:30 #: assets/pages/LoginPage.tsx:25
#: assets/pages/LoginPage.tsx:38 #: assets/pages/LoginPage.tsx:33
msgid "Log in" msgid "Log in"
msgstr "" msgstr ""
#: assets/components/RegisterForm.tsx:55 #: assets/components/RegisterForm.tsx:55
#: assets/pages/LoginPage.tsx:30 #: assets/pages/LoginPage.tsx:25
msgid "Register" msgid "Register"
msgstr "" msgstr ""
@ -881,15 +881,15 @@ msgstr ""
msgid "Create a Connector" msgid "Create a Connector"
msgstr "" msgstr ""
#: assets/pages/tracking/WatchlistPage.tsx:65 #: assets/pages/tracking/WatchlistPage.tsx:64
msgid "Watchlist created !" msgid "Watchlist created !"
msgstr "" msgstr ""
#: assets/pages/tracking/WatchlistPage.tsx:77 #: assets/pages/tracking/WatchlistPage.tsx:76
msgid "Watchlist updated !" msgid "Watchlist updated !"
msgstr "" msgstr ""
#: assets/pages/tracking/WatchlistPage.tsx:102 #: assets/pages/tracking/WatchlistPage.tsx:100
msgid "Create a Watchlist" msgid "Create a Watchlist"
msgstr "" msgstr ""
@ -897,7 +897,7 @@ msgstr ""
msgid "Sorry, the page you visited does not exist." msgid "Sorry, the page you visited does not exist."
msgstr "" msgstr ""
#: assets/pages/LoginPage.tsx:38 #: assets/pages/LoginPage.tsx:33
msgid "Create an account" msgid "Create an account"
msgstr "" msgstr ""