fix(blacklist): merge back CopyButton changes, disable button when there's nothing to copy
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import Modal from '@app/components/Common/Modal';
|
||||
import Tooltip from '@app/components/Common/Tooltip';
|
||||
import CopyButton from '@app/components/Settings/CopyButton';
|
||||
import { encodeURIExtraParams } from '@app/hooks/useDiscover';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { Transition } from '@headlessui/react';
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
ClipboardDocumentIcon,
|
||||
} from '@heroicons/react/24/solid';
|
||||
import { ArrowDownIcon } from '@heroicons/react/24/solid';
|
||||
import type { TmdbKeywordSearchResponse } from '@server/api/themoviedb/interfaces';
|
||||
import type { Keyword } from '@server/models/common';
|
||||
import { useFormikContext } from 'formik';
|
||||
@@ -22,12 +20,11 @@ import { useIntl } from 'react-intl';
|
||||
import type { ClearIndicatorProps, GroupBase, MultiValue } from 'react-select';
|
||||
import { components } from 'react-select';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useClipboard from 'react-use-clipboard';
|
||||
|
||||
const messages = defineMessages('components.Settings', {
|
||||
copyBlacklistedTags: 'Copied blacklisted tags to clipboard.',
|
||||
copyBlacklistedTagsTip: 'Copy blacklisted tags configuration',
|
||||
copyBlacklistedTagsTip: 'Copy blacklisted tag configuration',
|
||||
copyBlacklistedTagsEmpty: 'Nothing to copy',
|
||||
importBlacklistedTagsTip: 'Import blacklisted tag configuration',
|
||||
clearBlacklistedTagsConfirm:
|
||||
'Are you sure you want to clear the blacklisted tags?',
|
||||
@@ -58,6 +55,7 @@ const BlacklistedTagsSelector = ({
|
||||
}: BlacklistedTagsSelectorProps) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
const [value, setValue] = useState<string | undefined>(defaultValue);
|
||||
const intl = useIntl();
|
||||
const [selectorValue, setSelectorValue] =
|
||||
useState<MultiValue<SingleVal> | null>(null);
|
||||
|
||||
@@ -71,6 +69,8 @@ const BlacklistedTagsSelector = ({
|
||||
[setSelectorValue, setValue, setFieldValue]
|
||||
);
|
||||
|
||||
const copyDisabled = value === null || value?.length === 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ControlledKeywordSelector
|
||||
@@ -84,7 +84,17 @@ const BlacklistedTagsSelector = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
<BlacklistedTagsCopyButton value={value ?? ''} />
|
||||
<CopyButton
|
||||
textToCopy={value ?? ''}
|
||||
disabled={copyDisabled}
|
||||
toastMessage={intl.formatMessage(messages.copyBlacklistedTags)}
|
||||
tooltipContent={intl.formatMessage(
|
||||
copyDisabled
|
||||
? messages.copyBlacklistedTagsEmpty
|
||||
: messages.copyBlacklistedTagsTip
|
||||
)}
|
||||
tooltipConfig={{ followCursor: false }}
|
||||
/>
|
||||
<BlacklistedTagsImportButton setSelector={update} />
|
||||
</>
|
||||
);
|
||||
@@ -170,54 +180,13 @@ const ControlledKeywordSelector = ({
|
||||
);
|
||||
};
|
||||
|
||||
type BlacklistedTagsCopyButtonProps = {
|
||||
value: string;
|
||||
};
|
||||
|
||||
const BlacklistedTagsCopyButton = ({
|
||||
value,
|
||||
}: BlacklistedTagsCopyButtonProps) => {
|
||||
const intl = useIntl();
|
||||
const [isCopied, setCopied] = useClipboard(value, {
|
||||
successDuration: 1000,
|
||||
});
|
||||
const { addToast } = useToasts();
|
||||
|
||||
useEffect(() => {
|
||||
if (isCopied) {
|
||||
addToast(intl.formatMessage(messages.copyBlacklistedTags), {
|
||||
appearance: 'info',
|
||||
autoDismiss: true,
|
||||
});
|
||||
}
|
||||
}, [isCopied, addToast, intl]);
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={intl.formatMessage(messages.copyBlacklistedTagsTip)}
|
||||
tooltipConfig={{ followCursor: false }}
|
||||
>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setCopied();
|
||||
}}
|
||||
className="input-action"
|
||||
type="button"
|
||||
>
|
||||
<ClipboardDocumentIcon />
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
type BlacklistedTagsImportButton = {
|
||||
type BlacklistedTagsImportButtonProps = {
|
||||
setSelector: (value: MultiValue<SingleVal>) => void;
|
||||
};
|
||||
|
||||
const BlacklistedTagsImportButton = ({
|
||||
setSelector,
|
||||
}: BlacklistedTagsImportButton) => {
|
||||
}: BlacklistedTagsImportButtonProps) => {
|
||||
const [show, setShow] = useState(false);
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
const intl = useIntl();
|
||||
@@ -269,7 +238,7 @@ const BlacklistedTagsImportButton = ({
|
||||
);
|
||||
};
|
||||
|
||||
type BlacklistedTagImportFormProps = BlacklistedTagsImportButton;
|
||||
type BlacklistedTagImportFormProps = BlacklistedTagsImportButtonProps;
|
||||
|
||||
const BlacklistedTagImportForm = forwardRef<
|
||||
Partial<HTMLFormElement>,
|
||||
|
||||
@@ -1,41 +1,54 @@
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import Tooltip from '@app/components/Common/Tooltip';
|
||||
import { ClipboardDocumentIcon } from '@heroicons/react/24/solid';
|
||||
import { useEffect } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import React, { useEffect } from 'react';
|
||||
import type { Config } from 'react-popper-tooltip';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useClipboard from 'react-use-clipboard';
|
||||
|
||||
const messages = defineMessages('components.Settings', {
|
||||
copied: 'Copied API key to clipboard.',
|
||||
});
|
||||
type CopyButtonProps = {
|
||||
textToCopy: string;
|
||||
disabled?: boolean;
|
||||
toastMessage?: string;
|
||||
|
||||
const CopyButton = ({ textToCopy }: { textToCopy: string }) => {
|
||||
const intl = useIntl();
|
||||
tooltipContent?: React.ReactNode;
|
||||
tooltipConfig?: Partial<Config>;
|
||||
};
|
||||
|
||||
const CopyButton = ({
|
||||
textToCopy,
|
||||
disabled,
|
||||
toastMessage,
|
||||
tooltipContent,
|
||||
tooltipConfig,
|
||||
}: CopyButtonProps) => {
|
||||
const [isCopied, setCopied] = useClipboard(textToCopy, {
|
||||
successDuration: 1000,
|
||||
});
|
||||
const { addToast } = useToasts();
|
||||
|
||||
useEffect(() => {
|
||||
if (isCopied) {
|
||||
addToast(intl.formatMessage(messages.copied), {
|
||||
if (isCopied && toastMessage) {
|
||||
addToast(toastMessage, {
|
||||
appearance: 'info',
|
||||
autoDismiss: true,
|
||||
});
|
||||
}
|
||||
}, [isCopied, addToast, intl]);
|
||||
}, [isCopied, addToast, toastMessage]);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setCopied();
|
||||
}}
|
||||
className="input-action"
|
||||
type="button"
|
||||
>
|
||||
<ClipboardDocumentIcon />
|
||||
</button>
|
||||
<Tooltip content={tooltipContent} tooltipConfig={tooltipConfig}>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setCopied();
|
||||
}}
|
||||
className="input-action"
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
>
|
||||
<ClipboardDocumentIcon />
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ const messages = defineMessages('components.Settings.SettingsMain', {
|
||||
generalsettingsDescription:
|
||||
'Configure global and default settings for Jellyseerr.',
|
||||
apikey: 'API Key',
|
||||
apikeyCopied: 'Copied API key to clipboard.',
|
||||
applicationTitle: 'Application Title',
|
||||
applicationurl: 'Application URL',
|
||||
discoverRegion: 'Discover Region',
|
||||
@@ -232,6 +233,9 @@ const SettingsMain = () => {
|
||||
/>
|
||||
<CopyButton
|
||||
textToCopy={data?.apiKey ?? ''}
|
||||
toastMessage={intl.formatMessage(
|
||||
messages.apikeyCopied
|
||||
)}
|
||||
key={data?.apiKey}
|
||||
/>
|
||||
<button
|
||||
|
||||
@@ -917,6 +917,7 @@
|
||||
"components.Settings.SettingsLogs.time": "Timestamp",
|
||||
"components.Settings.SettingsLogs.viewdetails": "View Details",
|
||||
"components.Settings.SettingsMain.apikey": "API Key",
|
||||
"components.Settings.SettingsMain.apikeyCopied": "Copied API key to clipboard.",
|
||||
"components.Settings.SettingsMain.applicationTitle": "Application Title",
|
||||
"components.Settings.SettingsMain.applicationurl": "Application URL",
|
||||
"components.Settings.SettingsMain.blacklistedTags": "Blacklist Content with Tags",
|
||||
@@ -1055,11 +1056,12 @@
|
||||
"components.Settings.apiKey": "API key",
|
||||
"components.Settings.blacklistedTagImportInstructions": "Paste blacklist tag configuration below.",
|
||||
"components.Settings.blacklistedTagImportTitle": "Import Blacklisted Tag Configuration",
|
||||
"components.Settings.blacklistedTagsText": "Blacklisted Tags",
|
||||
"components.Settings.cancelscan": "Cancel Scan",
|
||||
"components.Settings.clearBlacklistedTagsConfirm": "Are you sure you want to clear the blacklisted tags?",
|
||||
"components.Settings.copied": "Copied API key to clipboard.",
|
||||
"components.Settings.copyBlacklistedTags": "Copied blacklisted tags to clipboard.",
|
||||
"components.Settings.copyBlacklistedTagsTip": "Copy blacklisted tags configuration",
|
||||
"components.Settings.copyBlacklistedTagsEmpty": "Nothing to copy",
|
||||
"components.Settings.copyBlacklistedTagsTip": "Copy blacklisted tag configuration",
|
||||
"components.Settings.currentlibrary": "Current Library: {name}",
|
||||
"components.Settings.default": "Default",
|
||||
"components.Settings.default4k": "Default 4K",
|
||||
|
||||
@@ -342,7 +342,15 @@
|
||||
}
|
||||
|
||||
button.input-action {
|
||||
@apply relative -ml-px inline-flex items-center border border-gray-500 bg-indigo-600 bg-opacity-80 px-3 py-2 text-sm font-medium leading-5 text-white transition duration-150 ease-in-out last:rounded-r-md hover:bg-opacity-100 active:bg-gray-100 active:text-gray-700 sm:px-3.5;
|
||||
@apply relative -ml-px inline-flex items-center border border-gray-500 bg-indigo-600 bg-opacity-80 px-3 py-2 text-sm font-medium leading-5 text-white last:rounded-r-md sm:px-3.5;
|
||||
}
|
||||
|
||||
button.input-action[disabled] {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
button.input-action:not([disabled]) {
|
||||
@apply transition duration-150 ease-in-out hover:bg-opacity-100 active:bg-gray-100 active:text-gray-700;
|
||||
}
|
||||
|
||||
.button-md :where(svg),
|
||||
|
||||
Reference in New Issue
Block a user