From 618343d4d25a1c96c022bc7d911593ef651f5b23 Mon Sep 17 00:00:00 2001 From: Ben Beauchamp Date: Thu, 6 Feb 2025 20:01:18 -0600 Subject: [PATCH] fix(blacklist): merge back CopyButton changes, disable button when there's nothing to copy --- .../BlacklistedTagsSelector/index.tsx | 73 ++++++------------- src/components/Settings/CopyButton.tsx | 55 ++++++++------ .../Settings/SettingsMain/index.tsx | 4 + src/i18n/locale/en.json | 6 +- src/styles/globals.css | 10 ++- 5 files changed, 72 insertions(+), 76 deletions(-) diff --git a/src/components/BlacklistedTagsSelector/index.tsx b/src/components/BlacklistedTagsSelector/index.tsx index c51c381d..d0fe45dc 100644 --- a/src/components/BlacklistedTagsSelector/index.tsx +++ b/src/components/BlacklistedTagsSelector/index.tsx @@ -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(defaultValue); + const intl = useIntl(); const [selectorValue, setSelectorValue] = useState | null>(null); @@ -71,6 +69,8 @@ const BlacklistedTagsSelector = ({ [setSelectorValue, setValue, setFieldValue] ); + const copyDisabled = value === null || value?.length === 0; + return ( <> - + ); @@ -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 ( - - - - ); -}; - -type BlacklistedTagsImportButton = { +type BlacklistedTagsImportButtonProps = { setSelector: (value: MultiValue) => void; }; const BlacklistedTagsImportButton = ({ setSelector, -}: BlacklistedTagsImportButton) => { +}: BlacklistedTagsImportButtonProps) => { const [show, setShow] = useState(false); const formRef = useRef(null); const intl = useIntl(); @@ -269,7 +238,7 @@ const BlacklistedTagsImportButton = ({ ); }; -type BlacklistedTagImportFormProps = BlacklistedTagsImportButton; +type BlacklistedTagImportFormProps = BlacklistedTagsImportButtonProps; const BlacklistedTagImportForm = forwardRef< Partial, diff --git a/src/components/Settings/CopyButton.tsx b/src/components/Settings/CopyButton.tsx index a53acada..3314a20b 100644 --- a/src/components/Settings/CopyButton.tsx +++ b/src/components/Settings/CopyButton.tsx @@ -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; +}; + +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 ( - + + + ); }; diff --git a/src/components/Settings/SettingsMain/index.tsx b/src/components/Settings/SettingsMain/index.tsx index d29304b5..7398b7cb 100644 --- a/src/components/Settings/SettingsMain/index.tsx +++ b/src/components/Settings/SettingsMain/index.tsx @@ -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 = () => { />