From 0888033bd87da18b4e2e10422d76c81e58c48bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 19 Oct 2025 21:37:52 +0200 Subject: [PATCH] feat: add trackedEppStatus field in Watchlist --- .../watchlist/UpdateWatchlistButton.tsx | 3 +- .../tracking/watchlist/WatchlistCard.tsx | 73 +++- .../tracking/watchlist/WatchlistForm.tsx | 73 +++- .../tracking/watchlist/WatchlistsList.tsx | 2 +- assets/pages/tracking/WatchlistPage.tsx | 2 + assets/utils/api/index.ts | 2 + .../utils/functions/eppStatusCodeToColor.tsx | 17 +- assets/utils/functions/rdapTranslation.ts | 39 ++- migrations/Version20251019211214.php | 31 ++ src/Entity/WatchList.php | 21 ++ .../SendDomainEventNotifHandler.php | 83 ++++- .../DomainStatusUpdateNotification.php | 69 ++++ .../errors/connector_credentials.html.twig | 2 +- .../emails/errors/domain_deleted.html.twig | 4 +- .../emails/errors/domain_order.html.twig | 4 +- .../emails/errors/domain_update.html.twig | 4 +- .../success/confirmation_email.html.twig | 4 +- .../emails/success/domain_ordered.html.twig | 4 +- .../emails/success/domain_status_updated.twig | 23 ++ .../emails/success/domain_updated.html.twig | 4 +- tests/State/WatchListUpdateProcessorTest.php | 2 + translations/translations.pot | 324 +++++++++--------- 22 files changed, 565 insertions(+), 225 deletions(-) create mode 100644 migrations/Version20251019211214.php create mode 100644 src/Notifier/DomainStatusUpdateNotification.php create mode 100644 templates/emails/success/domain_status_updated.twig diff --git a/assets/components/tracking/watchlist/UpdateWatchlistButton.tsx b/assets/components/tracking/watchlist/UpdateWatchlistButton.tsx index 2ca47bb..419b06b 100644 --- a/assets/components/tracking/watchlist/UpdateWatchlistButton.tsx +++ b/assets/components/tracking/watchlist/UpdateWatchlistButton.tsx @@ -8,7 +8,7 @@ import type {Watchlist} from '../../../utils/api' export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}: { watchlist: Watchlist - onUpdateWatchlist: (values: { domains: string[], trackedEvents: string[], token: string }) => Promise + onUpdateWatchlist: (values: { domains: string[], trackedEvents: string[], trackedEppStatus: string[], token: string }) => Promise connectors: Array }) { const [form] = Form.useForm() @@ -36,6 +36,7 @@ export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors} {name: 'connector', value: watchlist.connector?.id}, {name: 'domains', value: watchlist.domains.map(d => d.ldhName)}, {name: 'trackedEvents', value: watchlist.trackedEvents}, + {name: 'trackedEppStatus', value: watchlist.trackedEppStatus}, {name: 'dsn', value: watchlist.dsn} ]) }} diff --git a/assets/components/tracking/watchlist/WatchlistCard.tsx b/assets/components/tracking/watchlist/WatchlistCard.tsx index 1798306..103495a 100644 --- a/assets/components/tracking/watchlist/WatchlistCard.tsx +++ b/assets/components/tracking/watchlist/WatchlistCard.tsx @@ -7,20 +7,31 @@ import {DeleteWatchlistButton} from './DeleteWatchlistButton' import React from 'react' import type {Connector} from '../../../utils/api/connectors' import {CalendarWatchlistButton} from './CalendarWatchlistButton' -import {rdapEventDetailTranslation, rdapEventNameTranslation} from '../../../utils/functions/rdapTranslation' +import { + rdapDomainStatusCodeDetailTranslation, + rdapEventDetailTranslation, + rdapEventNameTranslation +} from '../../../utils/functions/rdapTranslation' import {actionToColor} from '../../../utils/functions/actionToColor' import {DomainToTag} from '../../../utils/functions/DomainToTag' import type {Watchlist} from '../../../utils/api' +import {eppStatusCodeToColor} from "../../../utils/functions/eppStatusCodeToColor" export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelete}: { watchlist: Watchlist - onUpdateWatchlist: (values: { domains: string[], trackedEvents: string[], token: string }) => Promise + onUpdateWatchlist: (values: { + domains: string[], + trackedEvents: string[], + trackedEppStatus: string[], + token: string + }) => Promise connectors: Array onDelete: () => void }) { const rdapEventNameTranslated = rdapEventNameTranslation() const rdapEventDetailTranslated = rdapEventDetailTranslation() + const rdapDomainStatusCodeDetailTranslated = rdapDomainStatusCodeDetailTranslation() return ( <> @@ -61,18 +72,56 @@ export function WatchlistCard({watchlist, onUpdateWatchlist, connectors, onDelet - {watchlist.domains.map(d => )} + {watchlist.domains.map(d => ( + + ))} + - {watchlist.trackedEvents?.map(t => - - {rdapEventNameTranslated[t as keyof typeof rdapEventNameTranslated]} - - - )} + <> +
+ {t`Tracked events`} +
+
+ {watchlist.trackedEvents?.map(t => ( + + + {rdapEventNameTranslated[t as keyof typeof rdapEventNameTranslated]} + + + ))} +
+ + <> +
+ {t`Tracked EPP status`} +
+
+ {watchlist.trackedEppStatus?.map(t => ( + + + {t} + + + ))} +
+
diff --git a/assets/components/tracking/watchlist/WatchlistForm.tsx b/assets/components/tracking/watchlist/WatchlistForm.tsx index a2bddb0..33cdd49 100644 --- a/assets/components/tracking/watchlist/WatchlistForm.tsx +++ b/assets/components/tracking/watchlist/WatchlistForm.tsx @@ -4,11 +4,16 @@ import {t} from 'ttag' import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from '@ant-design/icons' import React from 'react' import type {Connector} from '../../../utils/api/connectors' -import {rdapEventDetailTranslation, rdapEventNameTranslation} from '../../../utils/functions/rdapTranslation' +import { + rdapDomainStatusCodeDetailTranslation, + rdapEventDetailTranslation, + rdapEventNameTranslation +} from '../../../utils/functions/rdapTranslation' import {actionToColor} from '../../../utils/functions/actionToColor' import {actionToIcon} from '../../../utils/functions/actionToIcon' import type {EventAction, Watchlist} from '../../../utils/api' import {formItemLayoutWithOutLabel} from "../../../utils/providers" +import {eppStatusCodeToColor} from "../../../utils/functions/eppStatusCodeToColor" type TagRender = SelectProps['tagRender'] @@ -26,14 +31,15 @@ const formItemLayout = { export function WatchlistForm({form, connectors, onFinish, isCreation}: { form: FormInstance connectors: Array - onFinish: (values: { domains: string[], trackedEvents: string[], token: string }) => void + onFinish: (values: { domains: string[], trackedEvents: string[], trackedEppStatus: string[], token: string }) => void isCreation: boolean, watchList?: Watchlist, }) { const rdapEventNameTranslated = rdapEventNameTranslation() const rdapEventDetailTranslated = rdapEventDetailTranslation() + const rdapDomainStatusCodeDetailTranslated = rdapDomainStatusCodeDetailTranslation() - const triggerTagRenderer: TagRender = ({value, closable, onClose}: { + const eventActionTagRenderer: TagRender = ({value, closable, onClose}: { value: EventAction closable: boolean onClose: () => void @@ -60,12 +66,41 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: { ) } + const domainStatusTagRenderer: TagRender = ({value, closable, onClose}: { + value: EventAction + closable: boolean + onClose: () => void + }) => { + const onPreventMouseDown = (event: React.MouseEvent) => { + event.preventDefault() + event.stopPropagation() + } + return ( + + + {value} + + + ) + } + return (