200 lines
7.1 KiB
TypeScript
Raw Normal View History

2024-08-03 18:56:37 +02:00
import {Button, Form, FormInstance, Input, Select, SelectProps, Space, Tag} from "antd";
import {t} from "ttag";
2024-08-03 18:56:37 +02:00
import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from "@ant-design/icons";
2024-07-30 22:03:04 +02:00
import React from "react";
2024-07-30 00:55:36 +02:00
import {Connector} from "../../utils/api/connectors";
2024-08-03 18:56:37 +02:00
import {actionToColor, domainEvent} from "../search/EventTimeline";
2024-08-03 18:56:37 +02:00
type TagRender = SelectProps['tagRender'];
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},
},
};
2024-08-15 03:04:31 +02:00
export function WatchlistForm({form, connectors, onFinish, isCreation}: {
form: FormInstance,
2024-07-30 00:55:36 +02:00
connectors: (Connector & { id: string })[]
2024-08-15 03:04:31 +02:00
onFinish: (values: { domains: string[], emailTriggers: string[], token: string }) => void
isCreation: boolean
}) {
2024-08-03 18:56:37 +02:00
const domainEventTranslated = domainEvent()
2024-08-03 18:56:37 +02:00
const triggerTagRenderer: TagRender = (props) => {
const {value, closable, onClose} = props;
const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
2024-08-15 03:04:31 +02:00
event.preventDefault()
event.stopPropagation()
}
2024-08-03 18:56:37 +02:00
return (
<Tag
color={actionToColor(value)}
onMouseDown={onPreventMouseDown}
closable={closable}
onClose={onClose}
style={{marginInlineEnd: 4}}
>
{domainEventTranslated[value as keyof typeof domainEventTranslated]}
</Tag>
)
}
return <Form
{...formItemLayoutWithOutLabel}
form={form}
2024-08-15 03:04:31 +02:00
onFinish={onFinish}
2024-08-03 18:56:37 +02:00
initialValues={{emailTriggers: ['last changed', 'transfer', 'expiration', 'deletion']}}
>
2024-08-15 03:04:31 +02:00
<Form.Item name='token' hidden>
<Input hidden/>
</Form.Item>
2024-08-03 18:56:37 +02:00
<Form.Item label={t`Name`}
name='name'
labelCol={{
xs: {span: 24},
sm: {span: 4},
}}
wrapperCol={{
md: {span: 12},
sm: {span: 20},
}}
>
<Input placeholder={t`Watchlist Name`}
2024-08-03 18:59:13 +02:00
title={t`Naming the Watchlist makes it easier to find in the list below.`}
2024-08-03 18:56:37 +02:00
autoComplete='off'
autoFocus
2024-08-03 18:56:37 +02:00
/>
</Form.Item>
<Form.List
name="domains"
rules={[
{
validator: async (_, domains) => {
if (!domains || domains.length < 1) {
return Promise.reject(new Error(t`At least one domain name`));
}
},
},
]}
>
{(fields, {add, remove}, {errors}) => (
<>
{fields.map((field, index) => (
<Form.Item
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
label={index === 0 ? t`Domain names` : ''}
required={true}
key={field.key}
>
<Form.Item
{...field}
validateTrigger={['onChange', 'onBlur']}
rules={[{
required: true,
message: t`Required`
}, {
pattern: /^(?=.*\.)\S*[^.\s]$/,
message: t`This domain name does not appear to be valid`,
max: 63,
min: 2
}]}
noStyle
>
<Input placeholder={t`Domain 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 Domain name`}
</Button>
<Form.ErrorList errors={errors}/>
</Form.Item>
</>
)}
</Form.List>
2024-08-03 18:56:37 +02:00
<Form.Item label={t`Tracked events`}
name='emailTriggers'
rules={[{required: true, message: t`At least one trigger`, type: 'array'}]}
labelCol={{
xs: {span: 24},
sm: {span: 4},
}}
wrapperCol={{
md: {span: 12},
sm: {span: 20},
}}
required
>
2024-08-03 18:56:37 +02:00
<Select
mode="multiple"
tagRender={triggerTagRenderer}
style={{width: '100%'}}
options={Object.keys(domainEventTranslated).map(e => ({
value: e,
label: domainEventTranslated[e as keyof typeof domainEventTranslated]
}))}
/>
</Form.Item>
2024-07-30 22:03:04 +02:00
<Form.Item label={t`Connector`}
name='connector'
2024-07-31 02:22:36 +02:00
labelCol={{
2024-07-31 12:37:43 +02:00
xs: {span: 24},
sm: {span: 4},
2024-07-31 02:22:36 +02:00
}}
wrapperCol={{
2024-07-31 12:37:43 +02:00
md: {span: 12},
sm: {span: 20},
2024-07-31 02:22:36 +02:00
}}
2024-08-03 18:56:37 +02:00
help={t`Please make sure the connector information is valid to purchase a domain that may be available soon.`}
2024-07-30 22:03:04 +02:00
>
<Select showSearch
allowClear
placeholder={t`Connector`}
suffixIcon={<ApiOutlined/>}
optionFilterProp="label"
options={connectors.map(c => ({
label: `${c.provider} (${c.id})`,
value: c.id
}))}
/>
</Form.Item>
<Form.Item>
<Space>
<Button type="primary" htmlType="submit">
2024-08-15 03:04:31 +02:00
{isCreation ? t`Create` : t`Update`}
</Button>
<Button type="default" htmlType="reset">
{t`Reset`}
</Button>
</Space>
</Form.Item>
</Form>
}