mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
enhancement(web): layout improvements (#1095)
* minor style fixes fix: removed not-allowed button-in-button in IRCLogsDropdown, removed unnecessary inner div as well fix: removed shadow from 'remove releases older than X?' modal in settings on the light theme. (told soup about this long ago) * added tips for searching releases, improved overall look enhancement: made title page headings have a smaller vertical margin (almost by half) chore: moved title page headings from <header> to some less-obtuse screen-reader element enhancement: added documentation to the search engine on the releases table page enhancement: made StatsItem cards more compact (WIP - to be coupled with more stats items) enhancement: made WarningAlert be more contrastful on the light theme, made it more compact and added a border as well. * better wording for search tips * bad merge resolve, fixed now
This commit is contained in:
parent
6a4d96f988
commit
d187daa566
10 changed files with 205 additions and 126 deletions
|
@ -7,10 +7,8 @@ import { Stats } from "./dashboard/Stats";
|
|||
import { ActivityTable } from "./dashboard/ActivityTable";
|
||||
|
||||
export const Dashboard = () => (
|
||||
<main className="py-10">
|
||||
<div className="max-w-screen-xl mx-auto pb-6 px-4 sm:px-6 lg:pb-16 lg:px-8">
|
||||
<Stats />
|
||||
<ActivityTable />
|
||||
</div>
|
||||
</main>
|
||||
<div className="my-6 max-w-screen-xl mx-auto pb-6 px-4 sm:px-6 lg:pb-16 lg:px-8">
|
||||
<Stats />
|
||||
<ActivityTable />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -102,11 +102,9 @@ export const Logs = () => {
|
|||
|
||||
return (
|
||||
<main>
|
||||
<header className="pt-10 pb-5">
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Logs</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="my-6 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Logs</h1>
|
||||
</div>
|
||||
|
||||
<div className="max-w-screen-xl mx-auto pb-12 px-2 sm:px-4 lg:px-8">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg px-2 sm:px-4 pt-3 sm:pt-4 pb-3 sm:pb-4">
|
||||
|
|
|
@ -3,17 +3,93 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import { ChevronUpIcon, ChevronDownIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
import { ReleaseTable } from "./releases/ReleaseTable";
|
||||
|
||||
export const Releases = () => (
|
||||
<main>
|
||||
<header className="py-10">
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Releases</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="max-w-screen-xl mx-auto pb-6 px-4 sm:px-6 lg:pb-16 lg:px-8">
|
||||
<ReleaseTable />
|
||||
</div>
|
||||
</main>
|
||||
const Code = ({ children }: { children: React.ReactNode }) => (
|
||||
<code className="rounded-md inline-block mb-1 px-1 py-0.5 border bg-gray-100 border-gray-300 dark:bg-gray-800 dark:border-gray-700">
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
|
||||
export const Releases = () => {
|
||||
const [isHintOpen, setIsHintOpen] = useState(false);
|
||||
return (
|
||||
<main>
|
||||
<div className="mt-6 mb-4 mx-auto flex flex-col max-w-screen-xl px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Releases</h1>
|
||||
|
||||
<p className="flex mt-1 text-sm text-gray-800 dark:text-gray-200">
|
||||
The search engine uses a special pattern-matching engine to filter out results.
|
||||
Please
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setIsHintOpen((state) => !state);
|
||||
}}
|
||||
className="flex items-center shadow-md border rounded-md mx-1 px-1 text-black bg-lime-100 hover:bg-lime-200 border-lime-500 dark:text-white dark:bg-lime-950 dark:hover:bg-lime-900 dark:border-lime-800"
|
||||
>
|
||||
click here
|
||||
{isHintOpen ? (
|
||||
<ChevronUpIcon className="ml-1 h-3 w-3" />
|
||||
) : (
|
||||
<ChevronDownIcon className="ml-1 h-3 w-3" />
|
||||
)}
|
||||
</button>
|
||||
to get tips on how to get relevant results.
|
||||
</p>
|
||||
{isHintOpen ? (
|
||||
<div className="rounded-md text-sm mt-2 border border-gray-300 text-black shadow-lg dark:text-white dark:border-gray-700 dark:shadow-2xl">
|
||||
<div className="flex justify-between items-center text-base font-medium pl-2 py-1 border-b border-gray-300 bg-gray-100 dark:border-gray-700 dark:bg-gray-800 rounded-t-md">
|
||||
Search tips
|
||||
</div>
|
||||
<div className={"rounded-t-md py-1 px-2 rounded-b-md bg-white dark:bg-gray-900"}>
|
||||
You can use <b>2</b> special <span className="underline decoration-2 underline-offset-2 decoration-amber-500">wildcard characters</span> for the purpose of pattern matching.
|
||||
<br />
|
||||
- Percent (<Code>%</Code>) - for matching any <i>sequence</i> of characters (equivalent to <Code>*</Code> in Regex)
|
||||
<br />
|
||||
- Underscore (<Code>_</Code>) - for matching any <i>single</i> character (equivalent to <Code>.</Code> in Regex)
|
||||
<br /><br />
|
||||
|
||||
Additionally, autobrr supports <span className="underline decoration-2 underline-offset-2 decoration-lime-500">keyword faceting</span>.
|
||||
The supported keywords are:{" "}
|
||||
<b>category</b>, <b>codec</b>, <b>episode</b>, <b>filter</b>, <b>group</b>,{" "}
|
||||
<b>hdr</b>, <b>resolution</b>, <b>season</b>, <b>source</b>, <b>title</b> and <b>year</b>.
|
||||
<br /><br />
|
||||
|
||||
<b>Examples:</b><br />
|
||||
|
||||
<Code>year:2022 resolution:1080p</Code> (all 1080p from the year 2022)
|
||||
<br />
|
||||
<Code>group:framestor hdr:DV</Code> (all Dolby Vision releases by a certain group, e.g. Framestor)
|
||||
<br />
|
||||
<Code>Movie Title resolution:1080p</Code> (all releases starting with "Movie Title" in 1080p)
|
||||
<br />
|
||||
<Code>The Show season:05 episode:03</Code> (all releases starting with "The Show" related to S05E03)
|
||||
<br />
|
||||
<Code>%collection hd%</Code> (all releases containing "collection hd" - in the same order - and with a space!)
|
||||
<br />
|
||||
<Code>%collection_hd%</Code> (all releases containing "collection" <b>AND</b> "hd" - in the same order - but with a wildcard character in between, e.g. a space <b>OR</b> a dot <b>OR</b> any other character)
|
||||
|
||||
<br /><br />
|
||||
|
||||
As always, please refer to our <a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://autobrr.com/usage/search/"
|
||||
className="text-gray-700 dark:text-gray-200 underline font-semibold underline-offset-2 decoration-purple-500 decoration-2 hover:text-black hover:dark:text-gray-100"
|
||||
>
|
||||
Search function usage
|
||||
</a> documentation page to keep up with the latest examples and information.
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="max-w-screen-xl mx-auto pb-6 px-4 sm:px-6 lg:pb-16 lg:px-8">
|
||||
<ReleaseTable />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ function SidebarNav({ subNavigation }: SidebarNavProps) {
|
|||
<aside className="py-2 lg:col-span-3">
|
||||
<nav className="space-y-1">
|
||||
{subNavigation.map((item) => (
|
||||
<SubNavLink item={item} key={item.href}/>
|
||||
<SubNavLink item={item} key={item.href} />
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
|
@ -88,11 +88,9 @@ function SidebarNav({ subNavigation }: SidebarNavProps) {
|
|||
export function Settings() {
|
||||
return (
|
||||
<main>
|
||||
<header className="py-10">
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Settings</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="my-6 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Settings</h1>
|
||||
</div>
|
||||
|
||||
<div className="max-w-screen-xl mx-auto pb-6 px-4 sm:px-6 lg:pb-16 lg:px-8">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg">
|
||||
|
|
|
@ -15,11 +15,11 @@ interface StatsItemProps {
|
|||
|
||||
const StatsItem = ({ name, placeholder, value }: StatsItemProps) => (
|
||||
<div
|
||||
className="relative px-4 py-5 overflow-hidden bg-white rounded-lg shadow-lg dark:bg-gray-800"
|
||||
className="relative px-4 py-3 overflow-hidden bg-white rounded-lg shadow-lg dark:bg-gray-800"
|
||||
title="All time"
|
||||
>
|
||||
<dt>
|
||||
<p className="pb-1 text-sm font-medium text-gray-500 truncate">{name}</p>
|
||||
<p className="pb-0.5 text-sm font-medium text-gray-500 truncate">{name}</p>
|
||||
</dt>
|
||||
|
||||
<dd className="flex items-baseline">
|
||||
|
@ -53,4 +53,4 @@ export const Stats = () => {
|
|||
</dl>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -312,17 +312,15 @@ export function FilterDetails() {
|
|||
|
||||
return (
|
||||
<main>
|
||||
<header className="py-10">
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">
|
||||
<NavLink to="/filters">
|
||||
Filters
|
||||
</NavLink>
|
||||
</h1>
|
||||
<ChevronRightIcon className="h-6 w-6 text-gray-500" aria-hidden="true" />
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white truncate" title={filter.name}>{filter.name}</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="my-6 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">
|
||||
<NavLink to="/filters">
|
||||
Filters
|
||||
</NavLink>
|
||||
</h1>
|
||||
<ChevronRightIcon className="h-6 w-6 text-gray-500" aria-hidden="true" />
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white truncate" title={filter.name}>{filter.name}</h1>
|
||||
</div>
|
||||
<div className="max-w-screen-xl mx-auto pb-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow">
|
||||
<div className="pt-1 px-4 pb-6 block">
|
||||
|
@ -584,7 +582,7 @@ export function Advanced({ values }: AdvancedProps) {
|
|||
<div>
|
||||
<CollapsableSection defaultOpen={true} title="Releases" subtitle="Match only certain release names and/or ignore other release names.">
|
||||
<div className="grid col-span-12 gap-6">
|
||||
<WarningAlert text="autobrr has extensive filtering built-in - only use this if nothing else works. If you need help please ask." />
|
||||
<WarningAlert text="autobrr has extensive filtering built-in - only use this if nothing else works. If you need help, please ask." />
|
||||
|
||||
<RegexTextAreaField name="match_releases" label="Match releases" useRegex={values.use_regex} columns={6} placeholder="eg. *some?movie*,*some?show*s01*" tooltip={<div><p>This field has full regex support (Golang flavour).</p><a href='https://autobrr.com/filters#advanced' className='text-blue-400 visited:text-blue-400' target='_blank'>https://autobrr.com/filters#advanced</a><br /><br /><p>Remember to tick <b>Use Regex</b> below if using more than <code>*</code> and <code>?</code>.</p></div>} />
|
||||
<RegexTextAreaField name="except_releases" label="Except releases" useRegex={values.use_regex} columns={6} placeholder="eg. *bad?movie*,*bad?show*s03*" tooltip={<div><p>This field has full regex support (Golang flavour).</p><a href='https://autobrr.com/filters#advanced' className='text-blue-400 visited:text-blue-400' target='_blank'>https://autobrr.com/filters#advanced</a><br /><br /><p>Remember to tick <b>Use Regex</b> below if using more than <code>*</code> and <code>?</code>.</p></div>} />
|
||||
|
@ -688,8 +686,8 @@ function WarningAlert({ text, alert, colors }: WarningAlertProps) {
|
|||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"col-span-12 flex p-4 text-sm rounded-lg",
|
||||
colors ?? "text-yellow-700 bg-yellow-100 dark:bg-yellow-200 dark:text-yellow-800"
|
||||
"col-span-12 flex items-center px-4 py-3 text-md font-medium rounded-lg",
|
||||
colors ?? "text-amber-800 bg-amber-100 border border-amber-700 dark:border-none dark:bg-amber-200 dark:text-amber-800"
|
||||
)}
|
||||
role="alert">
|
||||
<svg aria-hidden="true" className="flex-shrink-0 inline w-5 h-5 mr-3" fill="currentColor"
|
||||
|
@ -700,7 +698,7 @@ function WarningAlert({ text, alert, colors }: WarningAlertProps) {
|
|||
</svg>
|
||||
<span className="sr-only">Info</span>
|
||||
<div>
|
||||
<span className="font-bold">{alert ?? "Warning!"}</span>
|
||||
<span className="font-extrabold">{alert ?? "Warning!"}</span>
|
||||
{" "}{text}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -139,61 +139,58 @@ export function Filters() {
|
|||
return (
|
||||
<main>
|
||||
<FilterAddForm isOpen={createFilterIsOpen} toggle={toggleCreateFilter} />
|
||||
<header className="py-10">
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Filters</h1>
|
||||
<div className="relative">
|
||||
<Menu>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<button
|
||||
className="relative inline-flex items-center px-4 py-2 shadow-sm text-sm font-medium rounded-l-md text-white bg-blue-600 dark:bg-blue-600 hover:bg-blue-700 dark:hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500"
|
||||
onClick={(e: { stopPropagation: () => void; }) => {
|
||||
if (!open) {
|
||||
e.stopPropagation();
|
||||
toggleCreateFilter();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 mr-1" />
|
||||
Add Filter
|
||||
</button>
|
||||
<Menu.Button className="relative inline-flex items-center px-2 py-2 border-l border-spacing-1 dark:border-black shadow-sm text-sm font-medium rounded-r-md text-white bg-blue-600 dark:bg-blue-600 hover:bg-blue-700 dark:hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500">
|
||||
<ChevronDownIcon className="h-5 w-5" />
|
||||
</Menu.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition ease-out duration-100 transform"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75 transform"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 mt-0.5 w-46 bg-white dark:bg-gray-700 rounded-md shadow-lg">
|
||||
<Menu.Item>
|
||||
{({ active }) => (
|
||||
<button
|
||||
type="button"
|
||||
className={`${
|
||||
active
|
||||
? "bg-gray-50 dark:bg-gray-600"
|
||||
: ""
|
||||
<div className="my-6 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between">
|
||||
<h1 className="text-3xl font-bold text-black dark:text-white">Filters</h1>
|
||||
<div className="relative">
|
||||
<Menu>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<button
|
||||
className="relative inline-flex items-center px-4 py-2 shadow-sm text-sm font-medium rounded-l-md text-white bg-blue-600 dark:bg-blue-600 hover:bg-blue-700 dark:hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500"
|
||||
onClick={(e: { stopPropagation: () => void; }) => {
|
||||
if (!open) {
|
||||
e.stopPropagation();
|
||||
toggleCreateFilter();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 mr-1" />
|
||||
Add Filter
|
||||
</button>
|
||||
<Menu.Button className="relative inline-flex items-center px-2 py-2 border-l border-spacing-1 dark:border-black shadow-sm text-sm font-medium rounded-r-md text-white bg-blue-600 dark:bg-blue-600 hover:bg-blue-700 dark:hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500">
|
||||
<ChevronDownIcon className="h-5 w-5" />
|
||||
</Menu.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition ease-out duration-100 transform"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75 transform"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 mt-0.5 w-46 bg-white dark:bg-gray-700 rounded-md shadow-lg">
|
||||
<Menu.Item>
|
||||
{({ active }) => (
|
||||
<button
|
||||
type="button"
|
||||
className={`${active
|
||||
? "bg-gray-50 dark:bg-gray-600"
|
||||
: ""
|
||||
} w-full text-left py-2 px-4 text-sm font-medium text-gray-700 dark:text-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500`}
|
||||
onClick={() => setShowImportModal(true)}
|
||||
>
|
||||
Import Filter
|
||||
</button>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
</div>
|
||||
onClick={() => setShowImportModal(true)}
|
||||
>
|
||||
Import Filter
|
||||
</button>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
{showImportModal && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
|
@ -212,14 +209,14 @@ export function Filters() {
|
|||
className="bg-white dark:bg-gray-700 py-2 px-4 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-blue-500"
|
||||
onClick={() => setShowImportModal(false)}
|
||||
>
|
||||
Cancel
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="ml-4 relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 dark:bg-blue-600 hover:bg-blue-700 dark:hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
onClick={handleImportJson}
|
||||
>
|
||||
Import
|
||||
Import
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -351,7 +348,8 @@ interface FilterItemDropdownProps {
|
|||
const FilterItemDropdown = ({ filter, onToggle }: FilterItemDropdownProps) => {
|
||||
|
||||
// This function handles the export of a filter to a JSON string
|
||||
const handleExportJson = useCallback(async (discordFormat = false) => { try {
|
||||
const handleExportJson = useCallback(async (discordFormat = false) => {
|
||||
try {
|
||||
type CompleteFilterType = {
|
||||
id: number;
|
||||
name: string;
|
||||
|
@ -449,10 +447,10 @@ const FilterItemDropdown = ({ filter, onToggle }: FilterItemDropdownProps) => {
|
|||
copyTextToClipboard(finalJson);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.custom((t) => <Toast type="error" body="Failed to get filter data." t={t} />);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.custom((t) => <Toast type="error" body="Failed to get filter data." t={t} />);
|
||||
}
|
||||
}, [filter]);
|
||||
|
||||
const cancelModalButtonRef = useRef(null);
|
||||
|
@ -858,7 +856,7 @@ const ListboxFilter = ({
|
|||
// a unique option from a list
|
||||
const IndexerSelectFilter = ({ dispatch }: any) => {
|
||||
const { data, isSuccess } = useQuery({
|
||||
queryKey: ["filters","indexers_options"],
|
||||
queryKey: ["filters", "indexers_options"],
|
||||
queryFn: () => APIClient.indexers.getOptions(),
|
||||
keepPreviousData: true,
|
||||
staleTime: Infinity
|
||||
|
|
|
@ -408,8 +408,8 @@ export const ReleaseTable = () => {
|
|||
{headerGroup.headers.map((column) => {
|
||||
const { key: columnKey, ...columnRest } = column.getHeaderProps(column.getSortByToggleProps());
|
||||
return (
|
||||
// Add the sorting props to control sorting. For this example
|
||||
// we can add them into the header props
|
||||
// Add the sorting props to control sorting. For this example
|
||||
// we can add them into the header props
|
||||
<th
|
||||
key={`${rowKey}-${columnKey}`}
|
||||
scope="col"
|
||||
|
|
|
@ -721,12 +721,26 @@ const IRCLogsDropdown = () => {
|
|||
[key]: newValue
|
||||
}));
|
||||
|
||||
//
|
||||
// FIXME: Warning: Function components cannot be given refs. Attempts to access this ref will fail.
|
||||
// Did you mean to use React.forwardRef()?
|
||||
//
|
||||
// Check the render method of `Pe2`.
|
||||
// at Checkbox (http://localhost:3000/src/components/Checkbox.tsx:14:28)
|
||||
// at Pe2 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:2164:12)
|
||||
// at div
|
||||
// at Ee (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:2106:12)
|
||||
// at c5 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:592:22)
|
||||
// at De4 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:3016:22)
|
||||
// at He5 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:3053:15)
|
||||
// at div
|
||||
// at c5 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:592:22)
|
||||
// at Me2 (http://localhost:3000/node_modules/.vite/deps/@headlessui_react.js?v=e8629745:2062:21)
|
||||
// at IRCLogsDropdown (http://localhost:3000/src/screens/settings/Irc.tsx?t=1694269937935:1354:53)
|
||||
return (
|
||||
<Menu as="div" className="relative">
|
||||
<Menu.Button>
|
||||
<button className="flex items-center text-gray-800 dark:text-gray-400 p-1 px-2 rounded shadow bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600">
|
||||
<span className="flex items-center">Options <Cog6ToothIcon className="ml-1 w-4 h-4"/></span>
|
||||
</button>
|
||||
<Menu.Button className="flex items-center text-gray-800 dark:text-gray-400 p-1 px-2 rounded shadow bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600">
|
||||
<span className="flex items-center">Options <Cog6ToothIcon className="ml-1 w-4 h-4"/></span>
|
||||
</Menu.Button>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
|
@ -738,21 +752,20 @@ const IRCLogsDropdown = () => {
|
|||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
className="absolute z-10 right-0 mt-2 bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-10 focus:outline-none"
|
||||
className="absolute z-10 right-0 mt-2 px-3 py-2 bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-10 focus:outline-none"
|
||||
>
|
||||
<div className="p-3">
|
||||
<Menu.Item>
|
||||
{() => (
|
||||
<Checkbox
|
||||
label="Scroll to bottom on new message"
|
||||
value={settings.scrollOnNewLog}
|
||||
setValue={(newValue) => onSetValue("scrollOnNewLog", newValue)}
|
||||
/>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</div>
|
||||
<Menu.Item>
|
||||
{() => (
|
||||
<Checkbox
|
||||
label="Scroll to bottom on new message"
|
||||
value={settings.scrollOnNewLog}
|
||||
setValue={(newValue) => onSetValue("scrollOnNewLog", newValue)}
|
||||
/>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</Transition>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ function DeleteReleases() {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="flex justify-between items-center rounded-md shadow-sm">
|
||||
<div className="flex justify-between items-center rounded-md">
|
||||
<DeleteModal
|
||||
isOpen={deleteModalIsOpen}
|
||||
isLoading={deleteOlderMutation.isLoading}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue