diff --git a/server/src/modules/api/lib/plextvApi.ts b/server/src/modules/api/lib/plextvApi.ts index 46ec519b..8be2bf23 100644 --- a/server/src/modules/api/lib/plextvApi.ts +++ b/server/src/modules/api/lib/plextvApi.ts @@ -167,9 +167,7 @@ export class PlexTvApi extends ExternalApiService { responseType: 'text', }); - const parsedXml = (await parseStringPromise( - response, - )) as UsersResponse; + const parsedXml = (await parseStringPromise(response)) as UsersResponse; return parsedXml; } diff --git a/ui/src/components/Collection/index.tsx b/ui/src/components/Collection/index.tsx index 421fe156..99afb99f 100644 --- a/ui/src/components/Collection/index.tsx +++ b/ui/src/components/Collection/index.tsx @@ -6,6 +6,7 @@ import CollectionDetail from './CollectionDetail' import CollectionOverview from './CollectionOverview' import { EPlexDataType } from '../../utils/PlexDataType-enum' import { IPlexMetadata } from '../Overview/Content' +import { useToasts } from 'react-toast-notifications' export interface ICollection { id?: number @@ -47,6 +48,7 @@ const Collection = () => { }>({ open: false, collection: undefined }) const [library, setLibrary] = useState() const [collections, setCollections] = useState() + const { addToast } = useToasts() useEffect(() => { document.title = 'Maintainerr - Collections' @@ -74,6 +76,13 @@ const Collection = () => { const doActions = () => { PostApiHandler('/collections/handle', {}) + addToast( + 'Initiated collection handling in the background, Consult the logs for status updates.', + { + autoDismiss: true, + appearance: 'success', + }, + ) } const openDetail = (collection: ICollection) => { diff --git a/ui/src/components/Common/AddButton/index.tsx b/ui/src/components/Common/AddButton/index.tsx index edd1d579..b9df78de 100644 --- a/ui/src/components/Common/AddButton/index.tsx +++ b/ui/src/components/Common/AddButton/index.tsx @@ -11,8 +11,8 @@ const AddButton = (props: IAddButton) => { className="add-button bg-amber-600 hover:bg-amber-500 flex m-auto h-9 rounded text-zinc-200 shadow-md" onClick={props.onClick} > - {} -

{props.text}

+ {} +

{props.text}

) } diff --git a/ui/src/components/Common/ExecuteButton/index.tsx b/ui/src/components/Common/ExecuteButton/index.tsx index 4f9d6c9b..3a308469 100644 --- a/ui/src/components/Common/ExecuteButton/index.tsx +++ b/ui/src/components/Common/ExecuteButton/index.tsx @@ -1,4 +1,6 @@ import { PlayIcon } from '@heroicons/react/solid' +import { useEffect, useState } from 'react' +import { SmallLoadingSpinner } from '../LoadingSpinner' interface IExecuteButton { text: string @@ -6,13 +8,30 @@ interface IExecuteButton { } const ExecuteButton = (props: IExecuteButton) => { + const [clicked, setClicked] = useState(false) + + useEffect(() => { + setTimeout(() => { + setClicked(false) + }, 10000) + }, [clicked]) + const onClick = () => { + setClicked(true) + props.onClick() + } + return ( ) } diff --git a/ui/src/components/Common/LoadingSpinner/index.tsx b/ui/src/components/Common/LoadingSpinner/index.tsx index ad94ff0e..55d34d4f 100644 --- a/ui/src/components/Common/LoadingSpinner/index.tsx +++ b/ui/src/components/Common/LoadingSpinner/index.tsx @@ -1,33 +1,41 @@ -import React from 'react'; +import React from 'react' -export const SmallLoadingSpinner: React.FC = () => { +interface SmallLoadingSpinnerProps { + className?: string +} + +export const SmallLoadingSpinner: React.FC = ( + props: SmallLoadingSpinnerProps, +) => { return ( -
- - - - - - - +
+
+ + + + + + + + - - + +
- ); -}; + ) +} const LoadingSpinner: React.FC = () => { return ( @@ -55,7 +63,7 @@ const LoadingSpinner: React.FC = () => {
- ); -}; + ) +} -export default LoadingSpinner; \ No newline at end of file +export default LoadingSpinner diff --git a/ui/src/components/Rules/index.tsx b/ui/src/components/Rules/index.tsx index 90c2dbb7..045c562a 100644 --- a/ui/src/components/Rules/index.tsx +++ b/ui/src/components/Rules/index.tsx @@ -1,8 +1,5 @@ -import { RefreshIcon } from '@heroicons/react/outline' -import { PlayIcon } from '@heroicons/react/solid' import { debounce } from 'lodash' -import React, { useContext, useEffect, useState } from 'react' -import LibrariesContext from '../../contexts/libraries-context' +import React, { useEffect, useState } from 'react' import GetApiHandler, { PostApiHandler } from '../../utils/ApiHandler' import AddButton from '../Common/AddButton' import ExecuteButton from '../Common/ExecuteButton' @@ -10,15 +7,16 @@ import LibrarySwitcher from '../Common/LibrarySwitcher' import LoadingSpinner from '../Common/LoadingSpinner' import RuleGroup, { IRuleGroup } from './RuleGroup' import AddModal from './RuleGroup/AddModal' +import { useToasts } from 'react-toast-notifications' const Rules: React.FC = () => { const [addModalActive, setAddModal] = useState(false) const [editModalActive, setEditModal] = useState(false) const [data, setData] = useState() const [editData, setEditData] = useState() - const LibrariesCtx = useContext(LibrariesContext) const [selectedLibrary, setSelectedLibrary] = useState(9999) const [isLoading, setIsLoading] = useState(true) + const { addToast } = useToasts() const fetchData = async () => { if (selectedLibrary === 9999) return await GetApiHandler('/rules') @@ -58,6 +56,13 @@ const Rules: React.FC = () => { const sync = () => { PostApiHandler(`/rules/execute`, {}) + addToast( + 'Initiated rule execution in the background. Consult the logs for status updates.', + { + autoDismiss: true, + appearance: 'success', + }, + ) } if (!data || isLoading) {