feat: user can enable/disable a watchlist

This commit is contained in:
Maël Gangloff
2025-10-25 19:23:15 +02:00
parent 5243b3c2dd
commit 24e3bc19ff
13 changed files with 212 additions and 37 deletions

View File

@@ -0,0 +1,59 @@
import {Button, Drawer, Form} from 'antd'
import {t} from 'ttag'
import {WatchlistForm} from './WatchlistForm'
import React, {useState} from 'react'
import type {Connector} from '../../../utils/api/connectors'
import useBreakpoint from "../../../hooks/useBreakpoint"
export function CreateWatchlistButton({onUpdateWatchlist, connectors}: {
onUpdateWatchlist: (values: {
domains: string[],
trackedEvents: string[],
trackedEppStatus: string[],
token: string
}) => Promise<void>
connectors: Array<Connector & { id: string }>
}) {
const [form] = Form.useForm()
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
const sm = useBreakpoint('sm')
const showDrawer = () => setOpen(true)
const onClose = () => {
setOpen(false)
setLoading(false)
}
return (
<>
<Button type='default' block onClick={() => {
showDrawer()
}}>{t`Create a Watchlist`}</Button>
<Drawer
title={t`Create a Watchlist`}
width={sm ? '100%' : '80%'}
onClose={onClose}
open={open}
loading={loading}
styles={{
body: {
paddingBottom: 80
}
}}
extra={<Button onClick={onClose}>{t`Cancel`}</Button>}
>
<WatchlistForm
form={form}
onFinish={values => {
setLoading(true)
onUpdateWatchlist(values).then(onClose).catch(() => setLoading(false))
}}
connectors={connectors}
isCreation
/>
</Drawer>
</>
)
}

View File

@@ -0,0 +1,33 @@
import {Popconfirm, theme, Typography} from 'antd'
import {t} from 'ttag'
import type { Watchlist} from '../../../utils/api'
import {patchWatchlist} from '../../../utils/api'
import {PauseCircleOutlined, PlayCircleOutlined} from '@ant-design/icons'
import React from 'react'
export function DisableWatchlistButton({watchlist, onChange, enabled}: {
watchlist: Watchlist,
onChange: () => void,
enabled: boolean
}) {
const {token} = theme.useToken()
return (
enabled ?
<Popconfirm
title={t`Disable the Watchlist`}
description={t`Are you sure to disable this Watchlist?`}
onConfirm={async () => await patchWatchlist(watchlist.token, {enabled: !enabled}).then(onChange)}
okText={t`Yes`}
cancelText={t`No`}
okButtonProps={{danger: true}}
>
<Typography.Link>
<PauseCircleOutlined style={{color: token.colorText}} title={t`Disable the Watchlist`}/>
</Typography.Link>
</Popconfirm> : <Typography.Link>
<PlayCircleOutlined style={{color: token.colorWarning}} title={t`Enable the Watchlist`}
onClick={async () => await patchWatchlist(watchlist.token, {enabled: !enabled}).then(onChange)}/>
</Typography.Link>
)
}

View File

@@ -5,6 +5,7 @@ import React, {useState} from 'react'
import {EditOutlined} from '@ant-design/icons'
import type {Connector} from '../../../utils/api/connectors'
import type {Watchlist} from '../../../utils/api'
import useBreakpoint from "../../../hooks/useBreakpoint"
export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}: {
watchlist: Watchlist
@@ -14,10 +15,9 @@ export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}
const [form] = Form.useForm()
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
const sm = useBreakpoint('sm')
const showDrawer = () => {
setOpen(true)
}
const showDrawer = () => setOpen(true)
const onClose = () => {
setOpen(false)
@@ -44,7 +44,7 @@ export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}
</Typography.Link>
<Drawer
title={t`Update a Watchlist`}
width='80%'
width={sm ? '100%' : '80%'}
onClose={onClose}
open={open}
loading={loading}

View File

@@ -17,8 +17,9 @@ import {actionToColor} from '../../../utils/functions/actionToColor'
import {DomainToTag} from '../../../utils/functions/DomainToTag'
import type {Watchlist} from '../../../utils/api'
import {eppStatusCodeToColor} from "../../../utils/functions/eppStatusCodeToColor"
import {DisableWatchlistButton} from "./DisableWatchlistButton"
export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelete}: {
export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onChange}: {
watchlist: Watchlist
onUpdateWatchlist: (values: {
domains: string[],
@@ -27,7 +28,7 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
token: string
}) => Promise<void>
connectors: Array<Connector & { id: string }>
onDelete: () => void
onChange: () => void
}) {
const rdapEventNameTranslated = rdapEventNameTranslation()
const rdapEventDetailTranslated = rdapEventDetailTranslation()
@@ -36,7 +37,14 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
return (
<>
<Card
aria-disabled={true}
type='inner'
style={{
width: '100%',
opacity: watchlist.enabled ? 1 : 0.5,
filter: watchlist.enabled ? 'none' : 'grayscale(0.7)',
transition: 'all 0.3s ease',
}}
title={<>
{
(watchlist.connector != null)
@@ -52,7 +60,6 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
</Tooltip>
</>}
size='small'
style={{width: '100%'}}
extra={
<Space size='middle'>
<ViewDiagramWatchlistButton token={watchlist.token}/>
@@ -65,7 +72,9 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet
connectors={connectors}
/>
<DeleteWatchlistButton watchlist={watchlist} onDelete={onDelete}/>
<DisableWatchlistButton watchlist={watchlist} onChange={onChange}
enabled={watchlist.enabled}/>
<DeleteWatchlistButton watchlist={watchlist} onDelete={onChange}/>
</Space>
}
>

View File

@@ -3,21 +3,21 @@ import type {Connector} from '../../../utils/api/connectors'
import {WatchlistCard} from './WatchlistCard'
import type {Watchlist} from '../../../utils/api'
export function WatchlistsList({watchlists, onDelete, onUpdateWatchlist, connectors}: {
export function WatchlistsList({watchlists, onChange, onUpdateWatchlist, connectors}: {
watchlists: Watchlist[]
onDelete: () => void
onChange: () => void
onUpdateWatchlist: (values: { domains: string[], trackedEvents: string[], trackedEppStatus: string[], token: string }) => Promise<void>
connectors: Array<Connector & { id: string }>
}) {
return (
<>
{watchlists.map(watchlist =>
{[...watchlists.filter(w => w.enabled), ...watchlists.filter(w => !w.enabled)].map(watchlist =>
<WatchlistCard
key={watchlist.token}
watchlist={watchlist}
onUpdateWatchlist={onUpdateWatchlist}
connectors={connectors}
onDelete={onDelete}
onChange={onChange}
/>
)}
</>