feat: add an interpretation to the table of tracked domains

This commit is contained in:
Maël Gangloff
2024-12-25 22:43:34 +01:00
parent d8aafdedad
commit f97c1132b9
3 changed files with 111 additions and 42 deletions

View File

@@ -1,26 +1,45 @@
import React, {useEffect, useState} from "react"; import React, {ReactElement, useEffect, useState} from "react";
import {Domain, getTrackedDomainList} from "../../../utils/api"; import {Domain, getTrackedDomainList} from "../../../utils/api";
import {Table, Tag, Tooltip} from "antd"; import {Button, Empty, Result, Skeleton, Table, Tag, Tooltip} from "antd";
import {t} from "ttag"; import {t} from "ttag";
import useBreakpoint from "../../../hooks/useBreakpoint";
import {ColumnType} from "antd/es/table"; import {ColumnType} from "antd/es/table";
import {rdapStatusCodeDetailTranslation} from "../../../utils/functions/rdapTranslation"; import {rdapStatusCodeDetailTranslation} from "../../../utils/functions/rdapTranslation";
import {eppStatusCodeToColor} from "../../../utils/functions/eppStatusCodeToColor"; import {eppStatusCodeToColor} from "../../../utils/functions/eppStatusCodeToColor";
import {Link} from "react-router-dom";
import {ExceptionOutlined, MonitorOutlined} from '@ant-design/icons'
export function TrackedDomainTable() { export function TrackedDomainTable() {
const sm = useBreakpoint('sm') const REDEMPTION_NOTICE = <Tooltip
const [dataTable, setDataTable] = useState<Domain[]>([]) title={t`At least one domain name is in redemption period and will potentially be deleted soon`}>
const [total, setTotal] = useState() <Tag color={eppStatusCodeToColor('redemption period')}>redemption period</Tag>
</Tooltip>
const PENDING_DELETE_NOTICE = <Tooltip
title={t`At least one domain name is pending deletion and will soon become available for registration again`}>
<Tag color={eppStatusCodeToColor('pending delete')}>pending delete</Tag>
</Tooltip>
const [dataTable, setDataTable] = useState<(Domain & { domain: Domain })[]>([])
const [total, setTotal] = useState<number>()
const [specialNotice, setSpecialNotice] = useState<ReactElement[]>([])
const rdapStatusCodeDetailTranslated = rdapStatusCodeDetailTranslation() const rdapStatusCodeDetailTranslated = rdapStatusCodeDetailTranslation()
const fetchData = (params: { page: number, itemsPerPage: number }) => { const fetchData = (params: { page: number, itemsPerPage: number }) => {
getTrackedDomainList(params).then(data => { getTrackedDomainList(params).then(data => {
setTotal(data['hydra:totalItems']) setTotal(data['hydra:totalItems'])
const notices: ReactElement[] = []
setDataTable(data['hydra:member'].map((d: Domain) => { setDataTable(data['hydra:member'].map((d: Domain) => {
const expirationDate = d.events.find(e => e.action === 'expiration' && !e.deleted)?.date const expirationDate = d.events.find(e => e.action === 'expiration' && !e.deleted)?.date
if (d.status.includes('redemption period')) {
if (!notices.includes(REDEMPTION_NOTICE)) notices.push(REDEMPTION_NOTICE)
} else if (d.status.includes('pending delete')) {
if (!notices.includes(PENDING_DELETE_NOTICE)) notices.push(PENDING_DELETE_NOTICE)
}
return { return {
key: d.ldhName, key: d.ldhName,
ldhName: d.ldhName, ldhName: d.ldhName,
@@ -35,6 +54,7 @@ export function TrackedDomainTable() {
domain: d domain: d
} }
})) }))
setSpecialNotice(notices)
}) })
} }
@@ -42,6 +62,7 @@ export function TrackedDomainTable() {
fetchData({page: 1, itemsPerPage: 30}) fetchData({page: 1, itemsPerPage: 30})
}, []) }, [])
const columns: ColumnType<any>[] = [ const columns: ColumnType<any>[] = [
{ {
title: t`Domain`, title: t`Domain`,
@@ -59,6 +80,14 @@ export function TrackedDomainTable() {
return new Date(expirationDate1).getTime() - new Date(expirationDate2).getTime() return new Date(expirationDate1).getTime() - new Date(expirationDate2).getTime()
} }
}, },
{
title: t`Updated at`,
dataIndex: 'updatedAt',
sorter: (a: { domain: Domain }, b: {
domain: Domain
}) => new Date(a.domain.updatedAt).getTime() - new Date(b.domain.updatedAt).getTime()
},
{ {
title: t`Status`, title: t`Status`,
dataIndex: 'status', dataIndex: 'status',
@@ -72,29 +101,48 @@ export function TrackedDomainTable() {
value: s, value: s,
})), })),
onFilter: (value, record: { domain: Domain }) => record.domain.status.includes(value as string) onFilter: (value, record: { domain: Domain }) => record.domain.status.includes(value as string)
},
{
title: t`Updated at`,
dataIndex: 'updatedAt',
sorter: (a: { domain: Domain }, b: {
domain: Domain
}) => new Date(a.domain.updatedAt).getTime() - new Date(b.domain.updatedAt).getTime()
} }
] ]
return <>
{
total === 0 ? <Empty
description={t`No tracked domain names were found, please create your first Watchlist`}
>
<Link to='/tracking/watchlist'>
<Button type="primary">Create Now</Button>
</Link>
</Empty> : <Skeleton loading={total === undefined}>
<Result
style={{paddingTop: 0}}
subTitle={t`Please note that this table does not include domain names marked as expired or those with an unknown expiration date`}
{...(specialNotice.length > 0 ? {
icon: <ExceptionOutlined/>,
status: 'warning',
title: t`At least one domain name you are tracking requires special attention`,
extra: specialNotice
} : {
icon: <MonitorOutlined/>,
status: 'info',
title: t`The domain names below are subject to special monitoring`,
})}
/>
return <Table <Table
loading={total === undefined} loading={total === undefined}
columns={columns} columns={columns}
dataSource={dataTable} dataSource={dataTable}
pagination={{ pagination={{
total, total,
hideOnSinglePage: true, hideOnSinglePage: true,
defaultPageSize: 30, defaultPageSize: 30,
onChange: (page, itemsPerPage) => { onChange: (page, itemsPerPage) => {
fetchData({page, itemsPerPage}) fetchData({page, itemsPerPage})
} }
}} }}
scroll={{y: '60vh'}} scroll={{y: '50vh'}}
/> />
</Skeleton>
}
</>
} }

View File

@@ -1,14 +1,6 @@
import {Card, Flex} from "antd";
import {t} from "ttag";
import {TrackedDomainTable} from "../../components/tracking/watchlist/TrackedDomainTable"; import {TrackedDomainTable} from "../../components/tracking/watchlist/TrackedDomainTable";
import React from "react"; import React from "react";
export default function TrackedDomainPage() { export default function TrackedDomainPage() {
return <TrackedDomainTable/>
return <Flex gap="middle" align="center" justify="center" vertical>
<Card title={t`Tracked domain names`}
style={{width: '100%', height: '80vh'}}>
<TrackedDomainTable/>
</Card>
</Flex>
} }

View File

@@ -123,7 +123,7 @@ msgid "Search"
msgstr "" msgstr ""
#: assets/components/Sider.tsx:39 #: assets/components/Sider.tsx:39
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:47 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:68
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
@@ -150,7 +150,6 @@ msgstr ""
#: assets/components/Sider.tsx:87 #: assets/components/Sider.tsx:87
#: assets/pages/StatisticsPage.tsx:68 #: assets/pages/StatisticsPage.tsx:68
#: assets/pages/tracking/TrackedDomainPage.tsx:9
msgid "Tracked domain names" msgid "Tracked domain names"
msgstr "" msgstr ""
@@ -377,16 +376,46 @@ msgstr ""
msgid ".${ tld.tld } Registry" msgid ".${ tld.tld } Registry"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:51 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:14
msgid ""
"At least one domain name is in redemption period and will potentially be "
"deleted soon"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:19
msgid ""
"At least one domain name is pending deletion and will soon become available "
"for registration again"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:72
msgid "Expiration date" msgid "Expiration date"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:63 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:85
msgid "Updated at"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:92
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:77 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:110
msgid "Updated at" msgid "No tracked domain names were found, please create your first Watchlist"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:118
msgid ""
"Please note that this table does not include domain names marked as expired "
"or those with an unknown expiration date"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:122
msgid "At least one domain name you are tracking requires special attention"
msgstr ""
#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:127
msgid "The domain names below are subject to special monitoring"
msgstr "" msgstr ""
#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:31 #: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:31