/* * Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors. * SPDX-License-Identifier: GPL-2.0-or-later */ import { Fragment } from "react"; import { Field, FieldProps } from "formik"; import { Listbox, ListboxButton, Label, ListboxOption, ListboxOptions, Transition } from "@headlessui/react"; import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/solid"; import { MultiSelect as RMSC } from "react-multi-select-component"; import { classNames, COL_WIDTHS } from "@utils"; import { DocsTooltip } from "@components/tooltips/DocsTooltip"; export interface MultiSelectOption { value: string | number; label: string; key?: string; disabled?: boolean; } interface MultiSelectProps { name: string; label?: string; options: MultiSelectOption[]; columns?: COL_WIDTHS; creatable?: boolean; disabled?: boolean; tooltip?: JSX.Element; } export const MultiSelect = ({ name, label, options, columns, creatable, tooltip, disabled }: MultiSelectProps) => { const handleNewField = (value: string) => ({ value: value.toUpperCase(), label: value.toUpperCase(), key: value }); return (
{({ field, form: { setFieldValue } }: FieldProps) => ( ({ value: item.value ? item.value : item, label: item.label ? item.label : item }))} onChange={(values: Array) => { const am = values && values.map((i) => i.value); setFieldValue(field.name, am); }} /> )}
); }; interface IndexerMultiSelectOption { id: number; name: string; } export const IndexerMultiSelect = ({ name, label, options, columns }: MultiSelectProps) => (
{({ field, meta, form: { setFieldValue } }: FieldProps) => ( <> ({ value: item.id, label: item.name }))} onChange={(values: MultiSelectOption[]) => { const item = values && values.map((i) => ({ id: i.value, name: i.label })); setFieldValue(field.name, item); }} /> {meta.touched && meta.error && (

* {meta.error}

)} )}
); interface DownloadClientSelectProps { name: string; action: Action; clients: DownloadClient[]; } export function DownloadClientSelect({ name, action, clients }: DownloadClientSelectProps) { return (
{({ field, meta, form: { setFieldValue } }: FieldProps) => ( setFieldValue(field?.name, value)} > {({ open }) => ( <>
{field.value ? clients.find((c) => c.id === field.value)?.name : "Choose a client"} {clients .filter((c) => c.type === action.type) .map((client) => ( classNames( active ? "text-white dark:text-gray-100 bg-blue-600 dark:bg-gray-950" : "text-gray-900 dark:text-gray-300", "cursor-default select-none relative py-2 pl-3 pr-9" )} value={client.id} > {({ selected, active }) => ( <> {client.name} {selected ? ( ) : null} )} ))} {meta.touched && meta.error && (

* {meta.error}

)}
)}
)}
); } export interface SelectFieldOption { label: string; value: string | number | null; } export interface SelectFieldProps { name: string; label: string; optionDefaultText: string; options: SelectFieldOption[]; columns?: COL_WIDTHS; tooltip?: JSX.Element; className?: string; } export const Select = ({ name, label, tooltip, optionDefaultText, options, columns = 6, className }: SelectFieldProps) => { return (
{({ field, form: { setFieldValue } }: FieldProps) => ( setFieldValue(field.name, value)} > {({ open }) => (
{field.value ? options.find((c) => c.value === field.value)?.label : optionDefaultText } {options.map((opt) => ( classNames( selected ? "font-bold text-black dark:text-white bg-gray-300 dark:bg-gray-950" : ( hovered ? "text-black dark:text-gray-100 font-normal" : "text-gray-700 dark:text-gray-300 font-normal" ), hovered ? "bg-gray-200 dark:bg-gray-800" : "", "transition-colors cursor-default select-none relative py-2 pl-3 pr-9" ) } value={opt.value} > {({ selected }) => ( <> {opt.label} )} ))}
)}
)}
); }; export const SelectWide = ({ name, label, optionDefaultText, options }: SelectFieldProps) => { return (
{({ field, form: { setFieldValue } }: FieldProps) => ( setFieldValue(field?.name, value)} > {({ open }) => (
{field.value ? options.find((c) => c.value === field.value)?.label : optionDefaultText } {options.map((opt) => ( classNames( active ? "text-white dark:text-gray-100 bg-blue-600 dark:bg-gray-800" : "text-gray-900 dark:text-gray-300", "cursor-default select-none relative py-2 pl-3 pr-9" ) } value={opt.value} > {({ selected, active }) => ( <> {opt.label} {selected ? ( ) : null} )} ))}
)}
)}
); }; export const AgeSelect = ({ duration, setDuration, setParsedDuration, columns = 6 }: { duration: string; setDuration: (value: string) => void; setParsedDuration: (value: number) => void; columns?: number; }) => { const options = [ { value: '1', label: '1 hour' }, { value: '12', label: '12 hours' }, { value: '24', label: '1 day' }, { value: '168', label: '1 week' }, { value: '720', label: '1 month' }, { value: '2160', label: '3 months' }, { value: '4320', label: '6 months' }, { value: '8760', label: '1 year' }, { value: '0', label: 'Delete everything' } ]; return (
{ const parsedValue = parseInt(value, 10); setParsedDuration(parsedValue); setDuration(value); }}> {({ open }) => ( <>
{duration ? options.find(opt => opt.value === duration)?.label : 'Select...'} {options.map((option) => ( `relative cursor-default select-none py-2 pl-3 pr-9 ${selected ? "font-bold text-black dark:text-white bg-gray-300 dark:bg-gray-950" : active ? "text-black dark:text-gray-100 font-normal bg-gray-200 dark:bg-gray-800" : "text-gray-700 dark:text-gray-300 font-normal" }` } value={option.value} > {({ selected }) => ( <> {option.label} {selected && ( )} )} ))}
)}
); };