mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
feat(web): mobile UI improvements (#359)
* enhancement: improved alerts component contrast enhancement: simplified and improved radio switch group look fix: fixed inconsistent spacing in input components (there's still some work left to be done) fix: made slideover panel display on full width on mobile devices enhancement: made forms more accessible to mobile users, adapter changes in accordance with the previous input components fix fix: fixed misspelling in NotificationForms filename chore: cleaned up code fix: made filter table top edges less round and improved look fix: fixed a bug where when a modal/slideover component was opened, a 1px white bar would be shown in one of the modal parent elements (for the fix see L89 in screens/settings/DwonloadClient.tsx) enhancement: improved responsiveness for irc network list * Fixed 2 small comma warnings from ESLint Co-authored-by: anonymous <anonymous>
This commit is contained in:
parent
f961115dac
commit
3da594ec75
26 changed files with 758 additions and 640 deletions
|
@ -96,7 +96,7 @@ function FilterAddForm({ isOpen, toggle }: filterAddFormProps) {
|
|||
<div
|
||||
className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<div
|
||||
className="space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
className="space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="name"
|
||||
|
|
|
@ -50,24 +50,31 @@ function FormFieldsDefault() {
|
|||
} = useFormikContext<InitialValues>();
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TextFieldWide name="host" label="Host" help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd:port"/>
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="host"
|
||||
label="Host"
|
||||
help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd:port"
|
||||
/>
|
||||
|
||||
<NumberFieldWide name="port" label="Port" help="WebUI port for qBittorrent and daemon port for Deluge"/>
|
||||
<NumberFieldWide
|
||||
name="port"
|
||||
label="Port"
|
||||
help="WebUI port for qBittorrent and daemon port for Deluge"
|
||||
/>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:divide-gray-700">
|
||||
<SwitchGroupWide name="tls" label="TLS"/>
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
|
||||
{tls && (
|
||||
<Fragment>
|
||||
<SwitchGroupWide name="tls_skip_verify" label="Skip TLS verification (insecure)"/>
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
{tls && (
|
||||
<SwitchGroupWide
|
||||
name="tls_skip_verify"
|
||||
label="Skip TLS verification (insecure)"
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextFieldWide name="username" label="Username"/>
|
||||
<PasswordFieldWide name="password" label="Password"/>
|
||||
</Fragment>
|
||||
<TextFieldWide name="username" label="Username" />
|
||||
<PasswordFieldWide name="password" label="Password" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -77,22 +84,24 @@ function FormFieldsArr() {
|
|||
} = useFormikContext<InitialValues>();
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TextFieldWide name="host" label="Host" help="Full url http(s)://domain.ltd and/or subdomain/subfolder"/>
|
||||
<div className="flex flex-col space-y-4 px-1 mb-4 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="host"
|
||||
label="Host"
|
||||
help="Full url http(s)://domain.ltd and/or subdomain/subfolder"
|
||||
/>
|
||||
|
||||
<PasswordFieldWide name="settings.apikey" label="API key"/>
|
||||
<PasswordFieldWide name="settings.apikey" label="API key" />
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="settings.basic.auth" label="Basic auth"/>
|
||||
</div>
|
||||
<SwitchGroupWide name="settings.basic.auth" label="Basic auth" />
|
||||
|
||||
{settings.basic?.auth === true && (
|
||||
<Fragment>
|
||||
<TextFieldWide name="settings.basic.username" label="Username"/>
|
||||
<PasswordFieldWide name="settings.basic.password" label="Password"/>
|
||||
</Fragment>
|
||||
<>
|
||||
<TextFieldWide name="settings.basic.username" label="Username" />
|
||||
<PasswordFieldWide name="settings.basic.password" label="Password" />
|
||||
</>
|
||||
)}
|
||||
</Fragment>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -102,37 +111,42 @@ function FormFieldsQbit() {
|
|||
} = useFormikContext<InitialValues>();
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TextFieldWide name="host" label="Host" help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd:port" />
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="host"
|
||||
label="Host"
|
||||
help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd:port"
|
||||
/>
|
||||
|
||||
{port > 0 && (
|
||||
<NumberFieldWide name="port" label="Port" help="WebUI port for qBittorrent" />
|
||||
<NumberFieldWide
|
||||
name="port"
|
||||
label="Port"
|
||||
help="WebUI port for qBittorrent"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:divide-gray-700">
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
|
||||
{tls && (
|
||||
<Fragment>
|
||||
<SwitchGroupWide name="tls_skip_verify" label="Skip TLS verification (insecure)" />
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
{tls && (
|
||||
<SwitchGroupWide
|
||||
name="tls_skip_verify"
|
||||
label="Skip TLS verification (insecure)"
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextFieldWide name="username" label="Username" />
|
||||
<PasswordFieldWide name="password" label="Password" />
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="settings.basic.auth" label="Basic auth" />
|
||||
</div>
|
||||
<SwitchGroupWide name="settings.basic.auth" label="Basic auth" />
|
||||
|
||||
{settings.basic?.auth === true && (
|
||||
<Fragment>
|
||||
<>
|
||||
<TextFieldWide name="settings.basic.username" label="Username" />
|
||||
<PasswordFieldWide name="settings.basic.password" label="Password" />
|
||||
</Fragment>
|
||||
</>
|
||||
)}
|
||||
</Fragment>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -142,24 +156,27 @@ function FormFieldsTransmission() {
|
|||
} = useFormikContext<InitialValues>();
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TextFieldWide name="host" label="Host" help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd"/>
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="host"
|
||||
label="Host"
|
||||
help="Eg. client.domain.ltd, domain.ltd/client, domain.ltd"
|
||||
/>
|
||||
|
||||
<NumberFieldWide name="port" label="Port" help="Port for Transmission"/>
|
||||
<NumberFieldWide name="port" label="Port" help="Port for Transmission" />
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:divide-gray-700">
|
||||
<SwitchGroupWide name="tls" label="TLS"/>
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
|
||||
{tls && (
|
||||
<Fragment>
|
||||
<SwitchGroupWide name="tls_skip_verify" label="Skip TLS verification (insecure)"/>
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
{tls && (
|
||||
<SwitchGroupWide
|
||||
name="tls_skip_verify"
|
||||
label="Skip TLS verification (insecure)"
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextFieldWide name="username" label="Username"/>
|
||||
<PasswordFieldWide name="password" label="Password"/>
|
||||
</Fragment>
|
||||
<TextFieldWide name="username" label="Username" />
|
||||
<PasswordFieldWide name="password" label="Password" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -186,21 +203,17 @@ function FormFieldsRulesBasic() {
|
|||
return (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
|
||||
<div className="px-6 space-y-1">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Rules</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Manage max downloads.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="settings.rules.enabled" label="Enabled"/>
|
||||
</div>
|
||||
<SwitchGroupWide name="settings.rules.enabled" label="Enabled"/>
|
||||
|
||||
{settings && settings.rules?.enabled === true && (
|
||||
<Fragment>
|
||||
<NumberFieldWide name="settings.rules.max_active_downloads" label="Max active downloads"/>
|
||||
</Fragment>
|
||||
<NumberFieldWide name="settings.rules.max_active_downloads" label="Max active downloads"/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -212,34 +225,38 @@ function FormFieldsRules() {
|
|||
} = useFormikContext<InitialValues>();
|
||||
|
||||
return (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
|
||||
<div className="px-6 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Rules</Dialog.Title>
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5 px-2">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">
|
||||
Rules
|
||||
</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Manage max downloads etc.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="settings.rules.enabled" label="Enabled"/>
|
||||
</div>
|
||||
<SwitchGroupWide name="settings.rules.enabled" label="Enabled" />
|
||||
|
||||
{settings.rules?.enabled === true && (
|
||||
<Fragment>
|
||||
<NumberFieldWide name="settings.rules.max_active_downloads" label="Max active downloads"/>
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="settings.rules.ignore_slow_torrents" label="Ignore slow torrents"/>
|
||||
</div>
|
||||
<>
|
||||
<NumberFieldWide
|
||||
name="settings.rules.max_active_downloads"
|
||||
label="Max active downloads"
|
||||
/>
|
||||
<SwitchGroupWide
|
||||
name="settings.rules.ignore_slow_torrents"
|
||||
label="Ignore slow torrents"
|
||||
/>
|
||||
|
||||
{settings.rules?.ignore_slow_torrents === true && (
|
||||
<Fragment>
|
||||
<NumberFieldWide name="settings.rules.download_speed_threshold" label="Download speed threshold"
|
||||
placeholder="in KB/s"
|
||||
help="If download speed is below this when max active downloads is hit, download anyways. KB/s"/>
|
||||
</Fragment>
|
||||
<NumberFieldWide
|
||||
name="settings.rules.download_speed_threshold"
|
||||
label="Download speed threshold"
|
||||
placeholder="in KB/s"
|
||||
help="If download speed is below this when max active downloads is hit, download anyways. KB/s"
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -248,7 +265,7 @@ function FormFieldsRules() {
|
|||
export const rulesComponentMap: componentMapType = {
|
||||
DELUGE_V1: <FormFieldsRulesBasic/>,
|
||||
DELUGE_V2: <FormFieldsRulesBasic/>,
|
||||
QBITTORRENT: <FormFieldsRules/>,
|
||||
QBITTORRENT: <FormFieldsRules/>
|
||||
};
|
||||
|
||||
interface formButtonsProps {
|
||||
|
@ -490,20 +507,14 @@ export function DownloadClientAddForm({ isOpen, toggle }: formProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y dark:divide-gray-700">
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide name="name" label="Name"/>
|
||||
|
||||
<div
|
||||
className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:divide-gray-700">
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
</div>
|
||||
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
<RadioFieldsetWide
|
||||
name="type"
|
||||
legend="Type"
|
||||
options={DownloadClientTypeOptions}
|
||||
/>
|
||||
|
||||
<div>{componentMap[values.type]}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -697,17 +708,12 @@ export function DownloadClientUpdateForm({ client, isOpen, toggle }: updateFormP
|
|||
|
||||
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y dark:divide-gray-700">
|
||||
<TextFieldWide name="name" label="Name"/>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
</div>
|
||||
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
<RadioFieldsetWide
|
||||
name="type"
|
||||
legend="Type"
|
||||
options={DownloadClientTypeOptions}
|
||||
/>
|
||||
|
||||
<div>{componentMap[values.type]}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -116,7 +116,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
|
|||
|
||||
<div className="space-y-4 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div
|
||||
className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="type"
|
||||
|
|
|
@ -63,7 +63,7 @@ const IrcSettingFields = (ind: IndexerDefinition, indexer: string) => {
|
|||
<Fragment>
|
||||
{ind && ind.irc && ind.irc.settings && (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
<div className="px-6 space-y-1">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">IRC</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-200">
|
||||
Networks, channels and invite commands are configured automatically.
|
||||
|
@ -94,7 +94,7 @@ const FeedSettingFields = (ind: IndexerDefinition, indexer: string) => {
|
|||
<Fragment>
|
||||
{ind && ind.torznab && ind.torznab.settings && (
|
||||
<div className="">
|
||||
<div className="px-6 space-y-1">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Torznab</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-200">
|
||||
Torznab feed
|
||||
|
@ -329,13 +329,13 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) {
|
|||
</div>
|
||||
|
||||
<div className="py-6 space-y-4 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="identifier"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Indexer
|
||||
Indexer
|
||||
</label>
|
||||
</div>
|
||||
<div className="sm:col-span-2">
|
||||
|
@ -391,9 +391,7 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
</div>
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
|
||||
{SettingFields(indexer, values.identifier)}
|
||||
|
||||
|
@ -504,7 +502,7 @@ export function IndexerUpdateForm({ isOpen, toggle, indexer }: UpdateProps) {
|
|||
...o,
|
||||
[obj.name]: obj.value
|
||||
} as Record<string, string>),
|
||||
{} as Record<string, string>
|
||||
{} as Record<string, string>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -519,16 +517,14 @@ export function IndexerUpdateForm({ isOpen, toggle, indexer }: UpdateProps) {
|
|||
initialValues={initialValues}
|
||||
>
|
||||
{() => (
|
||||
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white sm:mt-px sm:pt-2"
|
||||
>
|
||||
Name
|
||||
</label>
|
||||
</div>
|
||||
<div className="py-2 space-y-6 sm:py-0 sm:space-y-0 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="space-y-1 p-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4">
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white sm:mt-px sm:pt-2"
|
||||
>
|
||||
Name
|
||||
</label>
|
||||
<Field name="name">
|
||||
{({ field, meta }: FieldProps) => (
|
||||
<div className="sm:col-span-2">
|
||||
|
@ -542,11 +538,7 @@ export function IndexerUpdateForm({ isOpen, toggle, indexer }: UpdateProps) {
|
|||
)}
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:sm:divide-gray-700">
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
</div>
|
||||
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
{renderSettingFields(indexer.settings)}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -24,7 +24,7 @@ const ChannelsFieldArray = ({ channels }: ChannelsFieldArrayProps) => (
|
|||
<div className="p-6">
|
||||
<FieldArray name="channels">
|
||||
{({ remove, push }) => (
|
||||
<div className="flex flex-col border-2 border-dashed dark:border-gray-700 p-4">
|
||||
<div className="flex flex-col space-y-2 border-2 border-dashed dark:border-gray-700 p-4">
|
||||
{channels && channels.length > 0 ? (
|
||||
channels.map((_channel: IrcChannel, index: number) => (
|
||||
<div key={index} className="flex justify-between">
|
||||
|
@ -68,7 +68,7 @@ const ChannelsFieldArray = ({ channels }: ChannelsFieldArrayProps) => (
|
|||
))
|
||||
) : (
|
||||
<span className="text-center text-sm text-grey-darker dark:text-white">
|
||||
No channels!
|
||||
No channels!
|
||||
</span>
|
||||
)}
|
||||
<button
|
||||
|
@ -76,7 +76,7 @@ const ChannelsFieldArray = ({ channels }: ChannelsFieldArrayProps) => (
|
|||
className="border dark:border-gray-600 dark:bg-gray-700 my-4 px-4 py-2 text-sm text-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-600 rounded self-center text-center"
|
||||
onClick={() => push({ name: "", password: "" })}
|
||||
>
|
||||
Add Channel
|
||||
Add Channel
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -159,34 +159,47 @@ export function IrcNetworkAddForm({ isOpen, toggle }: AddFormProps) {
|
|||
validate={validate}
|
||||
>
|
||||
{(values) => (
|
||||
<>
|
||||
<TextFieldWide name="name" label="Name" placeholder="Name" required={true} />
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="name"
|
||||
label="Name"
|
||||
placeholder="Name"
|
||||
required={true}
|
||||
/>
|
||||
|
||||
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y dark:divide-gray-700">
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200 dark:sm:divide-gray-700">
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<TextFieldWide name="server" label="Server" placeholder="Address: Eg irc.server.net" required={true} />
|
||||
<NumberFieldWide name="port" label="Port" placeholder="Eg 6667" required={true} />
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
</div>
|
||||
|
||||
<PasswordFieldWide name="pass" label="Password" help="Network password" />
|
||||
|
||||
<TextFieldWide name="nickserv.account" label="NickServ Account" placeholder="NickServ Account" required={true} />
|
||||
<PasswordFieldWide name="nickserv.password" label="NickServ Password" />
|
||||
|
||||
<PasswordFieldWide name="invite_command" label="Invite command" />
|
||||
</div>
|
||||
</div>
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
<TextFieldWide
|
||||
name="server"
|
||||
label="Server"
|
||||
placeholder="Address: Eg irc.server.net"
|
||||
required={true}
|
||||
/>
|
||||
<NumberFieldWide
|
||||
name="port"
|
||||
label="Port"
|
||||
placeholder="Eg 6667"
|
||||
required={true}
|
||||
/>
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
<PasswordFieldWide
|
||||
name="pass"
|
||||
label="Password"
|
||||
help="Network password"
|
||||
/>
|
||||
<TextFieldWide
|
||||
name="nickserv.account"
|
||||
label="NickServ Account"
|
||||
placeholder="NickServ Account"
|
||||
required={true}
|
||||
/>
|
||||
<PasswordFieldWide
|
||||
name="nickserv.password"
|
||||
label="NickServ Password"
|
||||
/>
|
||||
<PasswordFieldWide name="invite_command" label="Invite command" />
|
||||
|
||||
<ChannelsFieldArray channels={values.channels} />
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
);
|
||||
|
@ -290,34 +303,51 @@ export function IrcNetworkUpdateForm({
|
|||
validate={validate}
|
||||
>
|
||||
{(values) => (
|
||||
<>
|
||||
<TextFieldWide name="name" label="Name" placeholder="Name" required={true} />
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="name"
|
||||
label="Name"
|
||||
placeholder="Name"
|
||||
required={true}
|
||||
/>
|
||||
|
||||
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y dark:divide-gray-700">
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
<TextFieldWide
|
||||
name="server"
|
||||
label="Server"
|
||||
placeholder="Address: Eg irc.server.net"
|
||||
required={true}
|
||||
/>
|
||||
<NumberFieldWide
|
||||
name="port"
|
||||
label="Port"
|
||||
placeholder="Eg 6667"
|
||||
required={true}
|
||||
/>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0">
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
</div>
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
|
||||
<div>
|
||||
<TextFieldWide name="server" label="Server" placeholder="Address: Eg irc.server.net" required={true} />
|
||||
<NumberFieldWide name="port" label="Port" placeholder="Eg 6667" required={true} />
|
||||
<PasswordFieldWide
|
||||
name="pass"
|
||||
label="Password"
|
||||
help="Network password"
|
||||
/>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="tls" label="TLS" />
|
||||
</div>
|
||||
<TextFieldWide
|
||||
name="nickserv.account"
|
||||
label="NickServ Account"
|
||||
placeholder="NickServ Account"
|
||||
required={true}
|
||||
/>
|
||||
<PasswordFieldWide
|
||||
name="nickserv.password"
|
||||
label="NickServ Password"
|
||||
/>
|
||||
|
||||
<PasswordFieldWide name="pass" label="Password" help="Network password" />
|
||||
|
||||
<TextFieldWide name="nickserv.account" label="NickServ Account" placeholder="NickServ Account" required={true} />
|
||||
<PasswordFieldWide name="nickserv.password" label="NickServ Password" />
|
||||
|
||||
<PasswordFieldWide name="invite_command" label="Invite command" />
|
||||
</div>
|
||||
</div>
|
||||
<PasswordFieldWide name="invite_command" label="Invite command" />
|
||||
|
||||
<ChannelsFieldArray channels={values.channels} />
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
);
|
||||
|
|
|
@ -62,11 +62,11 @@ const Option = (props: OptionProps) => {
|
|||
|
||||
function FormFieldsDiscord() {
|
||||
return (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
<div className="px-6 space-y-1">
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-4">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Settings</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Create a <a href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks" rel="noopener noreferrer" target="_blank" className="font-medium text-blue-500">webhook integration</a> in your server.
|
||||
Create a <a href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks" rel="noopener noreferrer" target="_blank" className="font-medium text-blue-500 underline underline-offset-1 hover:text-blue-400">webhook integration</a> in your server.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -82,11 +82,11 @@ function FormFieldsDiscord() {
|
|||
|
||||
function FormFieldsTelegram() {
|
||||
return (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
<div className="px-6 space-y-1">
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-4">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Settings</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Read how to <a href="https://core.telegram.org/bots#3-how-do-i-create-a-bot" rel="noopener noreferrer" target="_blank" className="font-medium text-blue-500">create a bot</a>.
|
||||
Read how to <a href="https://core.telegram.org/bots#3-how-do-i-create-a-bot" rel="noopener noreferrer" target="_blank" className="font-medium text-blue-500 underline underline-offset-1 hover:text-blue-400">create a bot</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -161,9 +161,15 @@ export function NotificationAddForm({ isOpen, toggle }: AddProps) {
|
|||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" static className="fixed inset-0 overflow-hidden" open={isOpen} onClose={toggle}>
|
||||
<Dialog
|
||||
as="div"
|
||||
static
|
||||
className="fixed inset-0 overflow-hidden"
|
||||
open={isOpen}
|
||||
onClose={toggle}
|
||||
>
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
<Dialog.Overlay className="absolute inset-0"/>
|
||||
<Dialog.Overlay className="absolute inset-0" />
|
||||
|
||||
<div className="fixed inset-y-0 right-0 pl-10 max-w-full flex sm:pl-16">
|
||||
<Transition.Child
|
||||
|
@ -208,16 +214,20 @@ export function NotificationAddForm({ isOpen, toggle }: AddProps) {
|
|||
onClick={toggle}
|
||||
>
|
||||
<span className="sr-only">Close panel</span>
|
||||
<XIcon className="h-6 w-6" aria-hidden="true"/>
|
||||
<XIcon className="h-6 w-6" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TextFieldWide name="name" label="Name" required={true}/>
|
||||
<div className="flex flex-col space-y-4 px-1 py-6 sm:py-0 sm:space-y-0">
|
||||
<TextFieldWide
|
||||
name="name"
|
||||
label="Name"
|
||||
required={true}
|
||||
/>
|
||||
|
||||
<div className="space-y-4 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div className="flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="type"
|
||||
|
@ -232,10 +242,16 @@ export function NotificationAddForm({ isOpen, toggle }: AddProps) {
|
|||
field,
|
||||
form: { setFieldValue, resetForm }
|
||||
}: FieldProps) => (
|
||||
<Select {...field}
|
||||
<Select
|
||||
{...field}
|
||||
isClearable={true}
|
||||
isSearchable={true}
|
||||
components={{ Input, Control, Menu, Option }}
|
||||
components={{
|
||||
Input,
|
||||
Control,
|
||||
Menu,
|
||||
Option
|
||||
}}
|
||||
placeholder="Choose a type"
|
||||
styles={{
|
||||
singleValue: (base) => ({
|
||||
|
@ -257,39 +273,39 @@ export function NotificationAddForm({ isOpen, toggle }: AddProps) {
|
|||
|
||||
const opt = option as SelectOption;
|
||||
// setFieldValue("name", option?.label ?? "")
|
||||
setFieldValue(field.name, opt.value ?? "");
|
||||
setFieldValue(
|
||||
field.name,
|
||||
opt.value ?? ""
|
||||
);
|
||||
}}
|
||||
options={NotificationTypeOptions}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
</div>
|
||||
<SwitchGroupWide name="enabled" label="Enabled" />
|
||||
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
<div className="px-6 space-y-1">
|
||||
<Dialog.Title
|
||||
className="text-lg font-medium text-gray-900 dark:text-white">Events</Dialog.Title>
|
||||
<div className="border-t mt-2 border-gray-200 dark:border-gray-700 py-4">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">
|
||||
Events
|
||||
</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Select what events to trigger on
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1 px-4 sm:space-y-0 sm:grid sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div className="space-y-1 px-4 sm:space-y-0 sm:grid sm:gap-4 sm:py-4">
|
||||
<EventCheckBoxes />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{componentMap[values.type]}
|
||||
</div>
|
||||
|
||||
<div className="flex-shrink-0 px-4 border-t border-gray-200 dark:border-gray-700 py-5 sm:px-6">
|
||||
<div className="flex-shrink-0 px-4 border-t border-gray-200 dark:border-gray-700 py-4 sm:px-6">
|
||||
<div className="space-x-3 flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
|
@ -314,12 +330,11 @@ export function NotificationAddForm({ isOpen, toggle }: AddProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<DEBUG values={values}/>
|
||||
<DEBUG values={values} />
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -432,8 +447,8 @@ export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateP
|
|||
<div>
|
||||
<TextFieldWide name="name" label="Name" required={true}/>
|
||||
|
||||
<div className="space-y-4 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div className="space-y-2 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="py-4 flex items-center justify-between space-y-1 px-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="type"
|
||||
|
@ -477,13 +492,9 @@ export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateP
|
|||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="py-6 px-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-5">
|
||||
<div className="px-6 space-y-1">
|
||||
<SwitchGroupWide name="enabled" label="Enabled"/>
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-4">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title
|
||||
className="text-lg font-medium text-gray-900 dark:text-white">Events</Dialog.Title>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
|
@ -491,7 +502,7 @@ export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateP
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1 px-4 sm:space-y-0 sm:grid sm:gap-4 sm:px-6 sm:py-5">
|
||||
<div className="space-y-1 px-4 sm:space-y-0 sm:grid sm:gap-4 sm:py-2">
|
||||
<EventCheckBoxes />
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue