mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
feat: overhaul webui (#135)
feat: Added Inter Variable as the default font feat: Added a pattern to the page background. fix(react-multi-select-component): Made the multiselect components theme-agnostic, so it works properly with the light theme now. fix(react-select): Made the components fix the default 30px height of the rest of the input components. fix(useToggle): Fixed a bug where the toggle didn't work due to useCallback memoizing a callback with the old value. refactor(Base): - Added small theme-primary gradient to the beginning of the header. - Made the splitter border theme-agnostic. - Increased logo size a bit. - Moved the links a bit closer to the logo. - Updated the default link style to look more stylish. - Added a link to the autobrr Docs section (currently defaults to the Indexers sections, but this should lead to an "Overview" page for configuring autobrr) - Adapted the user dropdown to match the other header links' stylesheets and removed the annoying ring focus. - Adapted the header for theme-agnostic mobile usage. - Removed the negative padding/margin hacks. refactor(StatsItem): Increased shadow size/strength and made the description text a bit lighter on the dark theme. refactor(Dashboard): Increased the heading text sizes. refactor(Logs, Releases, Settings, Login, filters/details, filters/list): Adapted to match the previous changes and improved theme compatibility with regards to text. refactor(RegexPlayground): Fixed match highlight for JS regex.
This commit is contained in:
parent
c3687b8fa5
commit
ac37bd4d9c
17 changed files with 371 additions and 342 deletions
|
@ -1,9 +1,11 @@
|
|||
import { Fragment } from "react";
|
||||
import { MultiSelect as RMSC} from "react-multi-select-component";
|
||||
import { Transition, Listbox } from "@headlessui/react";
|
||||
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
||||
import { classNames, COL_WIDTHS } from "../../utils";
|
||||
import { Field } from "formik";
|
||||
import { Transition, Listbox } from "@headlessui/react";
|
||||
import { CheckIcon, SelectorIcon } from "@heroicons/react/solid";
|
||||
import { MultiSelect as RMSC } from "react-multi-select-component";
|
||||
|
||||
import { classNames, COL_WIDTHS } from "../../utils";
|
||||
import { SettingsContext } from "../../utils/Context";
|
||||
|
||||
interface MultiSelectProps {
|
||||
label?: string;
|
||||
|
@ -17,80 +19,87 @@ export const MultiSelect = ({
|
|||
label,
|
||||
options,
|
||||
columns,
|
||||
}: MultiSelectProps) => (
|
||||
<div
|
||||
className={classNames(
|
||||
columns ? `col-span-${columns}` : "col-span-12"
|
||||
)}
|
||||
>
|
||||
<label
|
||||
className="block mb-2 text-xs font-bold tracking-wide text-gray-700 uppercase dark:text-gray-200"
|
||||
htmlFor={label}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<Field name={name} type="select" multiple={true}>
|
||||
{({
|
||||
field,
|
||||
form: { setFieldValue },
|
||||
}: any) => (
|
||||
<RMSC
|
||||
{...field}
|
||||
type="select"
|
||||
options={options}
|
||||
labelledBy={name}
|
||||
value={field.value && field.value.map((item: any) => options.find((o: any) => o.value === item))}
|
||||
onChange={(values: any) => {
|
||||
const am = values && values.map((i: any) => i.value);
|
||||
setFieldValue(field.name, am);
|
||||
}}
|
||||
className="dark:bg-gray-700 dark"
|
||||
/>
|
||||
}: MultiSelectProps) => {
|
||||
const settingsContext = SettingsContext.useValue();
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
columns ? `col-span-${columns}` : "col-span-12"
|
||||
)}
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
>
|
||||
<label
|
||||
className="block mb-2 text-xs font-bold tracking-wide text-gray-700 uppercase dark:text-gray-200"
|
||||
htmlFor={label}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<Field name={name} type="select" multiple={true}>
|
||||
{({
|
||||
field,
|
||||
form: { setFieldValue },
|
||||
}: any) => (
|
||||
<RMSC
|
||||
{...field}
|
||||
type="select"
|
||||
options={options}
|
||||
labelledBy={name}
|
||||
value={field.value && field.value.map((item: any) => options.find((o: any) => o.value === item))}
|
||||
onChange={(values: any) => {
|
||||
const am = values && values.map((i: any) => i.value);
|
||||
setFieldValue(field.name, am);
|
||||
}}
|
||||
className={settingsContext.darkTheme ? "dark" : ""}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const IndexerMultiSelect = ({
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
columns,
|
||||
}: MultiSelectProps) => (
|
||||
<div
|
||||
className={classNames(
|
||||
columns ? `col-span-${columns}` : "col-span-12"
|
||||
)}
|
||||
>
|
||||
<label
|
||||
className="block mb-2 text-xs font-bold tracking-wide text-gray-700 uppercase dark:text-gray-200"
|
||||
htmlFor={label}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
}: MultiSelectProps) => {
|
||||
const settingsContext = SettingsContext.useValue();
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
columns ? `col-span-${columns}` : "col-span-12"
|
||||
)}
|
||||
>
|
||||
<label
|
||||
className="block mb-2 text-xs font-bold tracking-wide text-gray-700 uppercase dark:text-gray-200"
|
||||
htmlFor={label}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<Field name={name} type="select" multiple={true}>
|
||||
{({
|
||||
field,
|
||||
form: { setFieldValue },
|
||||
}: any) => (
|
||||
<RMSC
|
||||
{...field}
|
||||
type="select"
|
||||
options={options}
|
||||
labelledBy={name}
|
||||
value={field.value && field.value.map((item: any) => options.find((o: any) => o.value?.id === item.id))}
|
||||
onChange={(values: any) => {
|
||||
const am = values && values.map((i: any) => i.value);
|
||||
setFieldValue(field.name, am);
|
||||
}}
|
||||
className="dark:bg-gray-700 dark"
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
<Field name={name} type="select" multiple={true}>
|
||||
{({
|
||||
field,
|
||||
form: { setFieldValue },
|
||||
}: any) => (
|
||||
<RMSC
|
||||
{...field}
|
||||
type="select"
|
||||
options={options}
|
||||
labelledBy={name}
|
||||
value={field.value && field.value.map((item: any) => options.find((o: any) => o.value?.id === item.id))}
|
||||
onChange={(values: any) => {
|
||||
const am = values && values.map((i: any) => i.value);
|
||||
setFieldValue(field.name, am);
|
||||
}}
|
||||
className={settingsContext.darkTheme ? "dark" : ""}
|
||||
itemHeight={50}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface DownloadClientSelectProps {
|
||||
name: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue