mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-29 16:15:04 +00:00
refactor: move functions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {ItemType, MenuItemType} from "antd/lib/menu/interface";
|
||||
import {ItemType} from "antd/lib/menu/interface";
|
||||
import {t} from "ttag";
|
||||
import {
|
||||
AimOutlined,
|
||||
@@ -22,8 +22,7 @@ import {useNavigate} from "react-router-dom";
|
||||
export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
|
||||
const navigate = useNavigate()
|
||||
|
||||
|
||||
const menuItems: ItemType<MenuItemType>[] = [
|
||||
const menuItems: ItemType[] = [
|
||||
{
|
||||
key: 'home',
|
||||
label: t`Home`,
|
||||
@@ -64,7 +63,8 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
|
||||
icon: <CloudServerOutlined/>,
|
||||
label: t`Nameserver`,
|
||||
title: t`Nameserver Finder`,
|
||||
disabled: true
|
||||
disabled: true,
|
||||
onClick: () => navigate('/search/nameserver')
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -103,7 +103,6 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
|
||||
key: 'account',
|
||||
icon: <UserOutlined/>,
|
||||
label: t`My Account`,
|
||||
disabled: !isAuthenticated,
|
||||
onClick: () => navigate('/user')
|
||||
}, {
|
||||
key: 'logout',
|
||||
@@ -122,7 +121,6 @@ export function Sider({isAuthenticated}: { isAuthenticated: boolean }) {
|
||||
}
|
||||
|
||||
return <Menu
|
||||
defaultSelectedKeys={['home']}
|
||||
defaultOpenKeys={['search', 'info', 'tracking', 'doc']}
|
||||
mode="inline"
|
||||
theme="dark"
|
||||
|
||||
@@ -19,9 +19,9 @@ export function DomainResult({domain}: { domain: Domain }) {
|
||||
domain.tld.type === 'gTLD' ? "green"
|
||||
: "cyan"
|
||||
}>
|
||||
<Card title={<>
|
||||
<Card title={<Space>
|
||||
{domain.ldhName}{domain.handle && <Typography.Text code>{domain.handle}</Typography.Text>}
|
||||
</>}
|
||||
</Space>}
|
||||
size="small">
|
||||
{domain.status.length > 0 &&
|
||||
<>
|
||||
|
||||
@@ -10,7 +10,6 @@ export type FieldType = {
|
||||
export function DomainSearchBar({onFinish}: { onFinish: (values: FieldType) => void }) {
|
||||
|
||||
return <Form
|
||||
name="basic"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 16}}
|
||||
onFinish={onFinish}
|
||||
|
||||
@@ -1,49 +1,33 @@
|
||||
import vCard from "vcf";
|
||||
import {Avatar, List, Tag, Tooltip} from "antd";
|
||||
import {BankOutlined, IdcardOutlined, SignatureOutlined, ToolOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import {List, Tag, Tooltip} from "antd";
|
||||
import React from "react";
|
||||
import {Domain} from "../../utils/api";
|
||||
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 }) {
|
||||
const rdapRoleTranslated = rdapRoleTranslation()
|
||||
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
|
||||
className="demo-loadmore-list"
|
||||
itemLayout="horizontal"
|
||||
dataSource={domain.entities.sort((e1, e2) => {
|
||||
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 <List.Item>
|
||||
dataSource={sortDomainEntities(domain)}
|
||||
renderItem={(e) =>
|
||||
<List.Item>
|
||||
<List.Item.Meta
|
||||
avatar={<Avatar style={{backgroundColor: '#87d068'}}
|
||||
icon={e.roles.includes('registrant') ?
|
||||
<SignatureOutlined/> : e.roles.includes('registrar') ?
|
||||
<BankOutlined/> :
|
||||
e.roles.includes('technical') ?
|
||||
<ToolOutlined/> :
|
||||
e.roles.includes('administrative') ?
|
||||
<IdcardOutlined/> :
|
||||
<UserOutlined/>}/>}
|
||||
avatar={roleToAvatar(e)}
|
||||
title={e.entity.handle}
|
||||
description={name}
|
||||
description={entityToName(e)}
|
||||
/>
|
||||
{e.roles.map((r) =>
|
||||
<Tooltip
|
||||
title={r in rdapRoleDetailTranslated ? rdapRoleDetailTranslated[r as keyof typeof rdapRoleDetailTranslated] : undefined}>
|
||||
<Tag
|
||||
color={rolesToColor([r])}>{rdapRoleTranslated[r as keyof typeof rdapRoleTranslated]}</Tag>
|
||||
</Tooltip>)}
|
||||
{e.roles.map(roleToTag)}
|
||||
</List.Item>
|
||||
}}
|
||||
}
|
||||
/>
|
||||
}
|
||||
@@ -1,26 +1,9 @@
|
||||
import {
|
||||
ClockCircleOutlined,
|
||||
DeleteOutlined,
|
||||
ReloadOutlined,
|
||||
ShareAltOutlined,
|
||||
SignatureOutlined,
|
||||
SyncOutlined
|
||||
} from "@ant-design/icons";
|
||||
import {Timeline, Tooltip} from "antd";
|
||||
import {Timeline, Tooltip, Typography} from "antd";
|
||||
import React from "react";
|
||||
import {Domain, EventAction} from "../../utils/api";
|
||||
import {Domain} from "../../utils/api";
|
||||
import useBreakpoint from "../../hooks/useBreakpoint";
|
||||
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "./rdapTranslation";
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
import {actionToColor, actionToIcon} from "../../utils";
|
||||
|
||||
export function EventTimeline({domain}: { domain: Domain }) {
|
||||
const sm = useBreakpoint('sm')
|
||||
@@ -30,29 +13,22 @@ export function EventTimeline({domain}: { domain: Domain }) {
|
||||
const rdapEventDetailTranslated = rdapEventDetailTranslation()
|
||||
|
||||
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
|
||||
mode={sm ? "left" : "right"}
|
||||
items={domainEvents.map(({action, date}) => {
|
||||
let dot
|
||||
if (action === 'registration') {
|
||||
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'}}/>
|
||||
}
|
||||
items={domainEvents.map(e => {
|
||||
const sameEvents = domainEvents.filter(se => se.action === e.action)
|
||||
const isRelevant = !(sameEvents.length > 1 && sameEvents.indexOf(e) !== 0)
|
||||
|
||||
const eventName = action in rdapEventNameTranslated ? rdapEventNameTranslated[action as keyof typeof rdapEventNameTranslated] : action
|
||||
const dateStr = new Date(date).toLocaleString(locale)
|
||||
const eventDetail = action in rdapEventDetailTranslated ? rdapEventDetailTranslated[action as keyof typeof rdapEventDetailTranslated] : undefined
|
||||
const eventName = <Typography.Text style={{color: isRelevant ? 'default' : 'grey'}}>
|
||||
{e.action in rdapEventNameTranslated ? rdapEventNameTranslated[e.action as keyof typeof rdapEventNameTranslated] : e.action}
|
||||
</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 ? {
|
||||
children: <Tooltip placement='bottom' title={eventDetail}>
|
||||
@@ -64,9 +40,9 @@ export function EventTimeline({domain}: { domain: Domain }) {
|
||||
}
|
||||
|
||||
return {
|
||||
color: (action === 'expiration' ? (expirationEvents.length > 0 && domainEvents[0].date === date) : true) ? actionToColor(action) : 'grey',
|
||||
dot,
|
||||
pending: new Date(date).getTime() > new Date().getTime(),
|
||||
color: isRelevant ? actionToColor(e.action) : 'grey',
|
||||
dot: actionToIcon(e.action),
|
||||
pending: new Date(e.date).getTime() > new Date().getTime(),
|
||||
...text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ const formItemLayoutWithOutLabel = {
|
||||
xs: {span: 24, offset: 0},
|
||||
sm: {span: 20, offset: 4},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function ConnectorForm({form, onCreate}: { form: FormInstance, onCreate: (values: Connector) => void }) {
|
||||
const [provider, setProvider] = useState<string>()
|
||||
|
||||
@@ -5,13 +5,13 @@ import {ViewDiagramWatchlistButton} from "./diagram/ViewDiagramWatchlistButton";
|
||||
import {UpdateWatchlistButton} from "./UpdateWatchlistButton";
|
||||
import {DeleteWatchlistButton} from "./DeleteWatchlistButton";
|
||||
import punycode from "punycode/punycode";
|
||||
import {actionToColor} from "../../search/EventTimeline";
|
||||
import React from "react";
|
||||
import {Watchlist} from "../../../pages/tracking/WatchlistPage";
|
||||
import {Connector} from "../../../utils/api/connectors";
|
||||
import useBreakpoint from "../../../hooks/useBreakpoint";
|
||||
import {CalendarWatchlistButton} from "./CalendarWatchlistButton";
|
||||
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation";
|
||||
import {actionToColor, actionToIcon} from "../../../utils";
|
||||
|
||||
export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelete}: {
|
||||
watchlist: Watchlist,
|
||||
@@ -78,7 +78,7 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
|
||||
events: watchlist.triggers?.filter(t => t.action === 'email')
|
||||
.map(t => <Tooltip
|
||||
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]}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
|
||||
@@ -3,8 +3,8 @@ import {t} from "ttag";
|
||||
import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from "@ant-design/icons";
|
||||
import React from "react";
|
||||
import {Connector} from "../../../utils/api/connectors";
|
||||
import {actionToColor} from "../../search/EventTimeline";
|
||||
import {rdapEventDetailTranslation, rdapEventNameTranslation} from "../../search/rdapTranslation";
|
||||
import {actionToColor, actionToIcon} from "../../../utils";
|
||||
|
||||
type TagRender = SelectProps['tagRender'];
|
||||
|
||||
@@ -44,6 +44,7 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: {
|
||||
return (<Tooltip
|
||||
title={value in rdapEventDetailTranslated ? rdapEventDetailTranslated[value as keyof typeof rdapEventDetailTranslated] : undefined}>
|
||||
<Tag
|
||||
icon={actionToIcon(value)}
|
||||
color={actionToColor(value)}
|
||||
onMouseDown={onPreventMouseDown}
|
||||
closable={closable}
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import {Domain, Watchlist} from "../../../../utils/api";
|
||||
import {rdapRoleTranslation} from "../../../search/rdapTranslation";
|
||||
import {t} from "ttag";
|
||||
|
||||
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'
|
||||
import {rolesToColor} from "../../../../utils";
|
||||
|
||||
export function domainEntitiesToEdges(d: Domain, withRegistrar = false) {
|
||||
const rdapRoleTranslated = rdapRoleTranslation()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {Domain, Nameserver, Tld, Watchlist} from "../../../../utils/api";
|
||||
import vCard from "vcf";
|
||||
import React from "react";
|
||||
import {t} from 'ttag'
|
||||
import {entityToName} from "../../../../utils";
|
||||
|
||||
export const domainToNode = (d: Domain) => ({
|
||||
id: d.ldhName,
|
||||
@@ -14,14 +14,10 @@ export const domainToNode = (d: Domain) => ({
|
||||
export const domainEntitiesToNode = (d: Domain, withRegistrar = false) => d.entities
|
||||
.filter(e => !withRegistrar ? !e.roles.includes('registrar') : true)
|
||||
.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 {
|
||||
id: e.entity.handle,
|
||||
type: e.roles.includes('registrant') || e.roles.includes('registrar') ? 'input' : 'output',
|
||||
data: {label},
|
||||
data: {label: entityToName(e)},
|
||||
style: {
|
||||
width: 200
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@ import {getConfiguration, InstanceConfig} from "../utils/api";
|
||||
import {RegisterForm} from "../components/RegisterForm";
|
||||
|
||||
|
||||
const gridStyle: React.CSSProperties = {
|
||||
width: '50%',
|
||||
textAlign: 'center',
|
||||
}
|
||||
|
||||
export const AuthenticatedContext = createContext<any>(null)
|
||||
|
||||
export default function LoginPage() {
|
||||
@@ -28,7 +23,7 @@ export default function LoginPage() {
|
||||
}, [])
|
||||
|
||||
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}/>}
|
||||
{
|
||||
configuration?.registerEnabled &&
|
||||
|
||||
@@ -54,11 +54,10 @@ export default function WatchlistPage() {
|
||||
|
||||
const [form] = Form.useForm()
|
||||
const [messageApi, contextHolder] = message.useMessage()
|
||||
const [watchlists, setWatchlists] = useState<Watchlist[] | null>()
|
||||
const [connectors, setConnectors] = useState<(Connector & { id: string })[] | null>()
|
||||
const [watchlists, setWatchlists] = useState<Watchlist[]>()
|
||||
const [connectors, setConnectors] = useState<(Connector & { id: string })[]>()
|
||||
|
||||
const onCreateWatchlist = (values: FormValuesType) => {
|
||||
|
||||
postWatchlist(getRequestDataFromForm(values)).then((w) => {
|
||||
form.resetFields()
|
||||
refreshWatchlists()
|
||||
@@ -98,9 +97,10 @@ export default function WatchlistPage() {
|
||||
return <Flex gap="middle" align="center" justify="center" vertical>
|
||||
{contextHolder}
|
||||
{
|
||||
connectors &&
|
||||
<Card title={t`Create a Watchlist`} style={{width: '100%'}}>
|
||||
<WatchlistForm form={form} onFinish={onCreateWatchlist} connectors={connectors} isCreation={true}/>
|
||||
<Card loading={connectors === undefined} title={t`Create a Watchlist`} style={{width: '100%'}}>
|
||||
{connectors &&
|
||||
<WatchlistForm form={form} onFinish={onCreateWatchlist} connectors={connectors} isCreation={true}/>
|
||||
}
|
||||
</Card>
|
||||
}
|
||||
<Divider/>
|
||||
|
||||
@@ -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
109
assets/utils/index.tsx
Normal 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`)
|
||||
}
|
||||
Reference in New Issue
Block a user