2024-08-15 03:04:31 +02:00
|
|
|
import {Button, Card, Divider, Drawer, Form, Popconfirm, Space, Table, Tag, theme, Typography} from "antd";
|
2024-07-29 18:54:28 +02:00
|
|
|
import {t} from "ttag";
|
2024-08-02 17:23:27 +02:00
|
|
|
import {deleteWatchlist} from "../../utils/api";
|
2024-08-15 03:04:31 +02:00
|
|
|
import {CalendarFilled, DeleteFilled, DisconnectOutlined, EditOutlined, LinkOutlined} from "@ant-design/icons";
|
|
|
|
|
import React, {useState} from "react";
|
2024-08-02 17:23:27 +02:00
|
|
|
import useBreakpoint from "../../hooks/useBreakpoint";
|
2024-08-03 02:21:11 +02:00
|
|
|
import {actionToColor, domainEvent} from "../search/EventTimeline";
|
2024-08-02 17:23:27 +02:00
|
|
|
import {Watchlist} from "../../pages/tracking/WatchlistPage";
|
2024-08-03 19:16:58 +02:00
|
|
|
import punycode from "punycode/punycode";
|
2024-08-15 03:04:31 +02:00
|
|
|
import {WatchlistForm} from "./WatchlistForm";
|
|
|
|
|
import {Connector} from "../../utils/api/connectors";
|
2024-07-29 18:54:28 +02:00
|
|
|
|
2024-07-31 12:37:43 +02:00
|
|
|
const {useToken} = theme;
|
2024-07-31 02:55:20 +02:00
|
|
|
|
2024-08-15 03:04:31 +02:00
|
|
|
export function WatchlistsList({watchlists, onDelete, onUpdateWatchlist, connectors}: {
|
|
|
|
|
watchlists: Watchlist[],
|
|
|
|
|
onDelete: () => void,
|
2024-08-15 04:06:35 +02:00
|
|
|
onUpdateWatchlist: (values: { domains: string[], emailTriggers: string[], token: string }) => Promise<void>,
|
2024-08-15 03:04:31 +02:00
|
|
|
connectors: (Connector & { id: string })[]
|
|
|
|
|
}) {
|
2024-07-31 12:37:43 +02:00
|
|
|
const {token} = useToken()
|
2024-08-02 17:23:27 +02:00
|
|
|
const sm = useBreakpoint('sm')
|
2024-08-03 02:21:11 +02:00
|
|
|
const domainEventTranslated = domainEvent()
|
2024-08-15 03:04:31 +02:00
|
|
|
const [form] = Form.useForm()
|
2024-08-03 02:21:11 +02:00
|
|
|
|
2024-08-02 17:23:27 +02:00
|
|
|
const columns = [
|
|
|
|
|
{
|
|
|
|
|
title: t`Domain names`,
|
|
|
|
|
dataIndex: 'domains'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: t`Tracked events`,
|
|
|
|
|
dataIndex: 'events'
|
|
|
|
|
}
|
|
|
|
|
]
|
2024-07-31 02:55:20 +02:00
|
|
|
|
2024-08-15 04:06:35 +02:00
|
|
|
const [open, setOpen] = useState(false)
|
|
|
|
|
const [loading, setLoading] = useState(false)
|
2024-08-15 03:04:31 +02:00
|
|
|
|
|
|
|
|
const showDrawer = () => {
|
|
|
|
|
setOpen(true)
|
2024-08-15 17:40:09 +02:00
|
|
|
}
|
2024-08-15 03:04:31 +02:00
|
|
|
|
|
|
|
|
const onClose = () => {
|
|
|
|
|
setOpen(false)
|
2024-08-15 04:06:35 +02:00
|
|
|
setLoading(false)
|
2024-08-15 17:40:09 +02:00
|
|
|
}
|
2024-08-15 03:04:31 +02:00
|
|
|
|
2024-07-29 18:54:28 +02:00
|
|
|
return <>
|
|
|
|
|
{watchlists.map(watchlist =>
|
|
|
|
|
<>
|
2024-08-02 17:23:27 +02:00
|
|
|
<Card
|
2024-08-08 14:00:21 +02:00
|
|
|
hoverable
|
2024-08-04 17:16:00 +02:00
|
|
|
title={<>
|
|
|
|
|
{
|
|
|
|
|
watchlist.connector ?
|
|
|
|
|
<Tag icon={<LinkOutlined/>} color="lime-inverse" title={watchlist.connector.id}/> :
|
|
|
|
|
<Tag icon={<DisconnectOutlined/>} color="default"
|
|
|
|
|
title={t`This Watchlist is not linked to a Connector.`}/>
|
|
|
|
|
}
|
|
|
|
|
<Typography.Text title={new Date(watchlist.createdAt).toLocaleString()}>
|
|
|
|
|
{t`Watchlist` + (watchlist.name ? ` (${watchlist.name})` : '')}
|
|
|
|
|
</Typography.Text>
|
|
|
|
|
</>
|
|
|
|
|
}
|
2024-08-02 17:23:27 +02:00
|
|
|
size='small'
|
2024-08-04 17:16:00 +02:00
|
|
|
style={{width: '100%'}}
|
2024-08-07 15:31:29 +02:00
|
|
|
extra={<Space size='middle'>
|
2024-08-15 03:04:31 +02:00
|
|
|
<Typography.Link>
|
2024-08-07 15:31:29 +02:00
|
|
|
<CalendarFilled title={t`Export events to iCalendar format`}/>
|
|
|
|
|
</Typography.Link>
|
2024-08-15 03:04:31 +02:00
|
|
|
<Typography.Link>
|
|
|
|
|
<EditOutlined title={t`Edit the Watchlist`} onClick={() => {
|
|
|
|
|
showDrawer()
|
|
|
|
|
form.setFields([
|
|
|
|
|
{name: 'token', value: watchlist.token},
|
|
|
|
|
{name: 'name', value: watchlist.name},
|
|
|
|
|
{name: 'connector', value: watchlist.connector?.id},
|
|
|
|
|
{name: 'domains', value: watchlist.domains.map(d => d.ldhName)},
|
|
|
|
|
{name: 'emailTriggers', value: watchlist.triggers?.map(t => t.event)},
|
|
|
|
|
])
|
|
|
|
|
}}/>
|
|
|
|
|
</Typography.Link>
|
|
|
|
|
|
|
|
|
|
<Drawer
|
|
|
|
|
title={t`Update a Watchlist`}
|
2024-08-15 03:11:19 +02:00
|
|
|
width='80%'
|
2024-08-15 03:04:31 +02:00
|
|
|
onClose={onClose}
|
|
|
|
|
open={open}
|
2024-08-15 04:06:35 +02:00
|
|
|
loading={loading}
|
2024-08-15 03:04:31 +02:00
|
|
|
styles={{
|
|
|
|
|
body: {
|
|
|
|
|
paddingBottom: 80,
|
|
|
|
|
}
|
|
|
|
|
}}
|
2024-08-15 17:40:09 +02:00
|
|
|
extra={<Button onClick={onClose}>{t`Cancel`}</Button>}
|
2024-08-15 03:04:31 +02:00
|
|
|
>
|
|
|
|
|
<WatchlistForm
|
|
|
|
|
form={form}
|
|
|
|
|
onFinish={values => {
|
2024-08-15 04:06:35 +02:00
|
|
|
setLoading(true)
|
|
|
|
|
onUpdateWatchlist(values).then(onClose).catch(() => setLoading(false))
|
2024-08-15 03:04:31 +02:00
|
|
|
}}
|
|
|
|
|
connectors={connectors}
|
|
|
|
|
isCreation={false}
|
|
|
|
|
/>
|
|
|
|
|
</Drawer>
|
|
|
|
|
|
2024-08-07 15:31:29 +02:00
|
|
|
<Popconfirm
|
|
|
|
|
title={t`Delete the Watchlist`}
|
|
|
|
|
description={t`Are you sure to delete this Watchlist?`}
|
|
|
|
|
onConfirm={() => deleteWatchlist(watchlist.token).then(onDelete)}
|
|
|
|
|
okText={t`Yes`}
|
|
|
|
|
cancelText={t`No`}
|
|
|
|
|
okButtonProps={{danger: true}}>
|
2024-08-15 03:04:31 +02:00
|
|
|
<Typography.Link>
|
|
|
|
|
<DeleteFilled style={{color: token.colorError}} title={t`Delete the Watchlist`}/>
|
|
|
|
|
</Typography.Link>
|
2024-08-07 15:31:29 +02:00
|
|
|
</Popconfirm>
|
|
|
|
|
</Space>}
|
2024-08-02 21:32:24 +02:00
|
|
|
>
|
2024-07-31 12:37:43 +02:00
|
|
|
<Card.Meta description={watchlist.token} style={{marginBottom: '1em'}}/>
|
2024-08-02 17:23:27 +02:00
|
|
|
<Table
|
2024-08-03 02:08:30 +02:00
|
|
|
size='small'
|
2024-08-02 17:23:27 +02:00
|
|
|
columns={columns}
|
|
|
|
|
pagination={false}
|
2024-08-04 17:16:00 +02:00
|
|
|
style={{width: '100%'}}
|
2024-08-02 17:23:27 +02:00
|
|
|
dataSource={[{
|
2024-08-03 19:16:58 +02:00
|
|
|
domains: watchlist.domains.map(d => <Tag>{punycode.toUnicode(d.ldhName)}</Tag>),
|
2024-08-02 17:23:27 +02:00
|
|
|
events: watchlist.triggers?.filter(t => t.action === 'email')
|
2024-08-03 02:21:11 +02:00
|
|
|
.map(t => <Tag color={actionToColor(t.event)}>
|
|
|
|
|
{domainEventTranslated[t.event as keyof typeof domainEventTranslated]}
|
|
|
|
|
</Tag>
|
|
|
|
|
)
|
2024-08-02 17:23:27 +02:00
|
|
|
}]}
|
|
|
|
|
{...(sm ? {scroll: {y: 'max-content'}} : {scroll: {y: 240}})}
|
|
|
|
|
/>
|
2024-07-29 18:54:28 +02:00
|
|
|
</Card>
|
|
|
|
|
<Divider/>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
}
|