feat: add Webhook support on frontend

This commit is contained in:
Maël Gangloff
2024-08-16 23:57:52 +02:00
parent 8667644da5
commit 64aba20a93
5 changed files with 72 additions and 14 deletions

View File

@@ -8,7 +8,7 @@ import {Connector} from "../../../utils/api/connectors";
export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}: { export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}: {
watchlist: Watchlist, watchlist: Watchlist,
onUpdateWatchlist: (values: { domains: string[], emailTriggers: string[], token: string }) => Promise<void>, onUpdateWatchlist: (values: { domains: string[], triggers: string[], token: string }) => Promise<void>,
connectors: (Connector & { id: string })[] connectors: (Connector & { id: string })[]
}) { }) {
@@ -35,7 +35,8 @@ export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}
{name: 'name', value: watchlist.name}, {name: 'name', value: watchlist.name},
{name: 'connector', value: watchlist.connector?.id}, {name: 'connector', value: watchlist.connector?.id},
{name: 'domains', value: watchlist.domains.map(d => d.ldhName)}, {name: 'domains', value: watchlist.domains.map(d => d.ldhName)},
{name: 'emailTriggers', value: watchlist.triggers?.map(t => t.event)}, {name: 'triggers', value: watchlist.triggers?.map(t => t.event)},
{name: 'dsn', value: watchlist.dsn}
]) ])
}}/> }}/>
</Typography.Link> </Typography.Link>

View File

@@ -28,7 +28,7 @@ const formItemLayoutWithOutLabel = {
export function WatchlistForm({form, connectors, onFinish, isCreation}: { export function WatchlistForm({form, connectors, onFinish, isCreation}: {
form: FormInstance, form: FormInstance,
connectors: (Connector & { id: string })[] connectors: (Connector & { id: string })[]
onFinish: (values: { domains: string[], emailTriggers: string[], token: string }) => void onFinish: (values: { domains: string[], triggers: string[], token: string }) => void
isCreation: boolean isCreation: boolean
}) { }) {
const domainEventTranslated = domainEvent() const domainEventTranslated = domainEvent()
@@ -56,7 +56,7 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: {
{...formItemLayoutWithOutLabel} {...formItemLayoutWithOutLabel}
form={form} form={form}
onFinish={onFinish} onFinish={onFinish}
initialValues={{emailTriggers: ['last changed', 'transfer', 'expiration', 'deletion']}} initialValues={{triggers: ['last changed', 'transfer', 'expiration', 'deletion']}}
> >
<Form.Item name='token' hidden> <Form.Item name='token' hidden>
@@ -140,7 +140,7 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: {
)} )}
</Form.List> </Form.List>
<Form.Item label={t`Tracked events`} <Form.Item label={t`Tracked events`}
name='emailTriggers' name='triggers'
rules={[{required: true, message: t`At least one trigger`, type: 'array'}]} rules={[{required: true, message: t`At least one trigger`, type: 'array'}]}
labelCol={{ labelCol={{
xs: {span: 24}, xs: {span: 24},
@@ -186,6 +186,53 @@ export function WatchlistForm({form, connectors, onFinish, isCreation}: {
}))} }))}
/> />
</Form.Item> </Form.Item>
<Form.List
name="dsn">
{(fields, {add, remove}, {errors}) => (
<>
{fields.map((field, index) => (
<Form.Item
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
label={index === 0 ? t`DSN` : ''}
required={true}
key={field.key}
>
<Form.Item
{...field}
validateTrigger={['onChange', 'onBlur']}
rules={[{
required: true,
message: t`Required`
}, {
pattern: /:\/\//,
message: t`This DSN does not appear to be valid`
}]}
noStyle
>
<Input placeholder={t`Data Source Name`} style={{width: '60%'}} autoComplete='off'/>
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => remove(field.name)}
/>
) : null}
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
style={{width: '60%'}}
icon={<PlusOutlined/>}
>
{t`Add a Webhook`}
</Button>
<Form.ErrorList errors={errors}/>
</Form.Item>
</>
)}
</Form.List>
<Form.Item> <Form.Item>
<Space> <Space>
<Button type="primary" htmlType="submit"> <Button type="primary" htmlType="submit">

View File

@@ -14,7 +14,7 @@ import {ViewDiagramWatchlistButton} from "../diagram/ViewDiagramWatchlistButton"
export function WatchlistsList({watchlists, onDelete, onUpdateWatchlist, connectors}: { export function WatchlistsList({watchlists, onDelete, onUpdateWatchlist, connectors}: {
watchlists: Watchlist[], watchlists: Watchlist[],
onDelete: () => void, onDelete: () => void,
onUpdateWatchlist: (values: { domains: string[], emailTriggers: string[], token: string }) => Promise<void>, onUpdateWatchlist: (values: { domains: string[], triggers: string[], token: string }) => Promise<void>,
connectors: (Connector & { id: string })[] connectors: (Connector & { id: string })[]
}) { }) {
const sm = useBreakpoint('sm') const sm = useBreakpoint('sm')

View File

@@ -14,6 +14,7 @@ export type Watchlist = {
token: string, token: string,
domains: { ldhName: string }[], domains: { ldhName: string }[],
triggers?: { event: EventAction, action: string }[], triggers?: { event: EventAction, action: string }[],
dsn?: string[]
connector?: { connector?: {
id: string id: string
provider: string provider: string
@@ -32,15 +33,20 @@ export default function WatchlistPage() {
const onCreateWatchlist = (values: { const onCreateWatchlist = (values: {
name?: string name?: string
domains: string[], domains: string[],
emailTriggers: string[] triggers: string[]
connector?: string connector?: string,
dsn?: string[]
}) => { }) => {
const domainsURI = values.domains.map(d => '/api/domains/' + d) const domainsURI = values.domains.map(d => '/api/domains/' + d)
let triggers = values.triggers.map(t => ({event: t, action: 'email'}))
if(values.dsn !== undefined) triggers = [...triggers, ...values.triggers.map(t => ({event: t, action: 'chat'}))]
postWatchlist({ postWatchlist({
name: values.name, name: values.name,
domains: domainsURI, domains: domainsURI,
triggers: values.emailTriggers.map(t => ({event: t, action: 'email'})), triggers,
connector: values.connector !== undefined ? ('/api/connectors/' + values.connector) : undefined connector: values.connector !== undefined ? ('/api/connectors/' + values.connector) : undefined,
dsn: values.dsn
}).then((w) => { }).then((w) => {
form.resetFields() form.resetFields()
refreshWatchlists() refreshWatchlists()
@@ -54,8 +60,9 @@ export default function WatchlistPage() {
token: string token: string
name?: string name?: string
domains: string[], domains: string[],
emailTriggers: string[] triggers: string[]
connector?: string connector?: string,
dsn?: string[]
}) => { }) => {
const domainsURI = values.domains.map(d => '/api/domains/' + d) const domainsURI = values.domains.map(d => '/api/domains/' + d)
@@ -63,8 +70,9 @@ export default function WatchlistPage() {
token: values.token, token: values.token,
name: values.name, name: values.name,
domains: domainsURI, domains: domainsURI,
triggers: values.emailTriggers.map(t => ({event: t, action: 'email'})), triggers: values.triggers.map(t => ({event: t, action: 'email'})),
connector: values.connector !== undefined ? ('/api/connectors/' + values.connector) : undefined connector: values.connector !== undefined ? ('/api/connectors/' + values.connector) : undefined,
dsn: values.dsn
}).then((w) => { }).then((w) => {
refreshWatchlists() refreshWatchlists()
messageApi.success(t`Watchlist updated !`) messageApi.success(t`Watchlist updated !`)

View File

@@ -69,6 +69,7 @@ export interface WatchlistRequest {
domains: string[], domains: string[],
triggers: { event: EventAction, action: TriggerAction }[], triggers: { event: EventAction, action: TriggerAction }[],
connector?: string connector?: string
dsn?: string[]
} }
export interface Watchlist { export interface Watchlist {
@@ -78,6 +79,7 @@ export interface Watchlist {
triggers: { event: EventAction, action: TriggerAction }[], triggers: { event: EventAction, action: TriggerAction }[],
connector?: string connector?: string
createdAt: string createdAt: string
dsn?: string[]
} }
export interface InstanceConfig { export interface InstanceConfig {