diff --git a/assets/pages/info/StatisticsPage.tsx b/assets/pages/info/StatisticsPage.tsx index 9bc6956..d7ae8d6 100644 --- a/assets/pages/info/StatisticsPage.tsx +++ b/assets/pages/info/StatisticsPage.tsx @@ -2,6 +2,6 @@ import React from "react"; export default function StatisticsPage() { return

- Statistics Page + Not implemented

} \ No newline at end of file diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 02f4a35..37f3018 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -34,7 +34,6 @@ import {Domain, getDomain} from "../../utils/api"; import {AxiosError} from "axios" import vCard from 'vcf' -const {Title} = Typography type FieldType = { ldhName: string @@ -58,13 +57,12 @@ export default function DomainSearchPage() { } return - + {contextHolder}
diff --git a/assets/pages/tracking/WatchlistPage.tsx b/assets/pages/tracking/WatchlistPage.tsx index 02b9594..d88cf75 100644 --- a/assets/pages/tracking/WatchlistPage.tsx +++ b/assets/pages/tracking/WatchlistPage.tsx @@ -1,7 +1,232 @@ -import React from "react"; +import React, {useEffect, useState} from "react"; +import {Button, Card, Divider, Flex, Form, Input, message, Select, Skeleton, Space} from "antd"; + +import {CloseOutlined, DeleteFilled, MinusCircleOutlined, PlusOutlined, ThunderboltFilled} from "@ant-design/icons"; +import {deleteWatchlist, EventAction, getWatchlists, postWatchlist} from "../../utils/api"; +import {AxiosError} from "axios"; + + +const formItemLayout = { + labelCol: { + xs: {span: 24}, + sm: {span: 4}, + }, + wrapperCol: { + xs: {span: 24}, + sm: {span: 20}, + }, +}; + +const formItemLayoutWithOutLabel = { + wrapperCol: { + xs: {span: 24, offset: 0}, + sm: {span: 20, offset: 4}, + }, +}; + +const triggerEventItems: { label: string, value: EventAction }[] = [ + { + label: 'When the domain is expired', + value: 'expiration' + }, + { + label: 'When the domain is updated', + value: 'last changed' + }, + { + label: 'When the domain is deleted', + value: 'deletion' + }, + { + label: 'When the domain is transferred', + value: 'transfer' + }, + { + label: 'When the domain is locked', + value: 'locked' + }, + { + label: 'When the domain is unlocked', + value: 'unlocked' + }, + { + label: 'When the domain is reregistered', + value: 'reregistration' + }, + { + label: 'When the domain is reinstantiated', + value: 'reinstantiation' + } +] + +const trigerActionItems = [ + { + label: 'Send me an email', + value: 'email' + } +] export default function WatchlistPage() { - return

- Not implemented -

+ const [form] = Form.useForm() + const [messageApi, contextHolder] = message.useMessage() + const [watchlists, setWatchlists] = useState<{ token: string }[] | null>() + + const onCreateWatchlist = (values: { domains: string[], triggers: { event: string, action: string }[] }) => { + const domainsURI = values.domains.map(d => '/api/domains/' + d) + + postWatchlist(domainsURI, values.triggers).then((w) => { + form.resetFields() + refreshWatchlists() + messageApi.success('Watchlist created !') + }).catch((e: AxiosError) => { + const data = e?.response?.data as { detail: string } + messageApi.error(data.detail ?? 'An error occurred') + }) + } + + const refreshWatchlists = () => getWatchlists().then(w => { + setWatchlists(w['hydra:member']) + }).catch(() => setWatchlists(undefined)) + + useEffect(() => { + refreshWatchlists() + }, []) + + return + + {contextHolder} + + { + if (!domains || domains.length < 1) { + return Promise.reject(new Error('At least one domain name')); + } + }, + }, + ]} + > + {(fields, {add, remove}, {errors}) => ( + <> + {fields.map((field, index) => ( + + + + + {fields.length > 1 ? ( + remove(field.name)} + /> + ) : null} + + ))} + + + + + + )} + + + {(fields, {add, remove}) => ( + <> + {fields.map((field) => ( + { + remove(field.name); + }} + /> + } + > + + + + + ))} + + + + + + )} + + + + + + + + + + + + + {watchlists && watchlists.map(watchlist => + <> + + { + deleteWatchlist(watchlist.token).then(refreshWatchlists) + }}/>}> + + + )} + + +
} \ No newline at end of file diff --git a/assets/utils/api/index.ts b/assets/utils/api/index.ts index c96a8d5..5148bd9 100644 --- a/assets/utils/api/index.ts +++ b/assets/utils/api/index.ts @@ -1,7 +1,7 @@ import axios, {AxiosRequestConfig, AxiosResponse} from "axios"; -type EventAction = +export type EventAction = 'registration' | 'reregistration' | 'last changed' diff --git a/assets/utils/api/watchlist.ts b/assets/utils/api/watchlist.ts index 0a244a6..fcc0a67 100644 --- a/assets/utils/api/watchlist.ts +++ b/assets/utils/api/watchlist.ts @@ -1,7 +1,7 @@ -import {Event, request, Watchlist} from "./index"; +import {Event, EventAction, request, Watchlist} from "./index"; export async function getWatchlists() { - const response = await request<{ token: string }[]>({ + const response = await request({ url: 'watchlists' }) return response.data @@ -14,7 +14,7 @@ export async function getWatchlist(token: string) { return response.data } -export async function postWatchlist(domains: string[], triggers: Event[]) { +export async function postWatchlist(domains: string[], triggers: { action: string, event: EventAction }[]) { const response = await request<{ token: string }>({ method: 'POST', url: 'watchlists', diff --git a/src/Entity/WatchList.php b/src/Entity/WatchList.php index bda060e..9567a60 100644 --- a/src/Entity/WatchList.php +++ b/src/Entity/WatchList.php @@ -21,7 +21,8 @@ use Symfony\Component\Uid\Uuid; shortName: 'Watchlist', operations: [ new GetCollection( - routeName: 'watchlist_get_all_mine', normalizationContext: ['groups' => 'watchlist:list'], + routeName: 'watchlist_get_all_mine', + normalizationContext: ['groups' => 'watchlist:list'], name: 'get_all_mine', ), new Get(