mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-23 04:35:30 +00:00
refactor: move functions
This commit is contained in:
parent
723ef3e883
commit
a3c4a4e196
@ -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"
|
||||||
|
|||||||
@ -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 &&
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
return <List
|
const roleToTag = (r: string) => <Tooltip
|
||||||
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>
|
|
||||||
<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/>}/>}
|
|
||||||
title={e.entity.handle}
|
|
||||||
description={name}
|
|
||||||
/>
|
|
||||||
{e.roles.map((r) =>
|
|
||||||
<Tooltip
|
|
||||||
title={r in rdapRoleDetailTranslated ? rdapRoleDetailTranslated[r as keyof typeof rdapRoleDetailTranslated] : undefined}>
|
title={r in rdapRoleDetailTranslated ? rdapRoleDetailTranslated[r as keyof typeof rdapRoleDetailTranslated] : undefined}>
|
||||||
<Tag
|
<Tag
|
||||||
color={rolesToColor([r])}>{rdapRoleTranslated[r as keyof typeof rdapRoleTranslated]}</Tag>
|
color={rolesToColor([r])}>{rdapRoleTranslated[r as keyof typeof rdapRoleTranslated]}</Tag>
|
||||||
</Tooltip>)}
|
</Tooltip>
|
||||||
|
|
||||||
|
return <List
|
||||||
|
className="demo-loadmore-list"
|
||||||
|
itemLayout="horizontal"
|
||||||
|
dataSource={sortDomainEntities(domain)}
|
||||||
|
renderItem={(e) =>
|
||||||
|
<List.Item>
|
||||||
|
<List.Item.Meta
|
||||||
|
avatar={roleToAvatar(e)}
|
||||||
|
title={e.entity.handle}
|
||||||
|
description={entityToName(e)}
|
||||||
|
/>
|
||||||
|
{e.roles.map(roleToTag)}
|
||||||
</List.Item>
|
</List.Item>
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>()
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 &&
|
||||||
|
|||||||
@ -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/>
|
||||||
|
|||||||
@ -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`)
|
||||||
|
}
|
||||||
@ -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 ""
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user