From 7c8fb24d67991323f711096b487c2e0c24c42bdd Mon Sep 17 00:00:00 2001 From: DrMint Date: Sat, 5 Mar 2022 13:15:43 +0100 Subject: [PATCH] More filtering options in Library --- .../Library/LibraryItemsPreview.tsx | 2 +- src/components/Select.tsx | 26 +++---- src/components/Switch.tsx | 26 +++++++ src/graphql/operation.graphql | 2 +- src/graphql/operations-types.ts | 1 + src/pages/library/index.tsx | 73 ++++++++++++++++--- 6 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 src/components/Switch.tsx diff --git a/src/components/Library/LibraryItemsPreview.tsx b/src/components/Library/LibraryItemsPreview.tsx index d4f97ef..3db4afd 100644 --- a/src/components/Library/LibraryItemsPreview.tsx +++ b/src/components/Library/LibraryItemsPreview.tsx @@ -30,7 +30,7 @@ export default function LibraryItemsPreview( {item.thumbnail.data ? ( ) : (
diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 5b256dc..da912e0 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -13,22 +13,22 @@ export type SelectOption = { label: string; }; -export function selectOptionsIncludes( - options: SelectOption[], - newOption: SelectOption -) { - options.map((option) => { - if (option.label === newOption.label) return true; - }); - return false; -} - export default function Select(props: SelectProps): JSX.Element { const [selected, setSelected] = useState( props.selected ? props.selected : props.allowEmpty ? -1 : 0 ); const [opened, setOpened] = useState(false); + useEffect(() => { + if (props.onChange) { + if (selected >= 0) { + props.onChange(props.options[selected].name); + } else { + props.onChange(""); + } + } + }, [props, selected]); + return (
{selected >= 0 && props.allowEmpty && ( { - setSelected(-1); - props.onChange && props.onChange(""); - }} + onClick={() => setSelected(-1)} className="material-icons !text-xs" > close @@ -73,7 +70,6 @@ export default function Select(props: SelectProps): JSX.Element { onClick={() => { setOpened(false); setSelected(index); - props.onChange && props.onChange(props.options[index].name); }} > {option.label} diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx new file mode 100644 index 0000000..6f33b96 --- /dev/null +++ b/src/components/Switch.tsx @@ -0,0 +1,26 @@ +import { Dispatch, SetStateAction } from "react"; + +export type SwitchProps = { + setState: Dispatch>; + state: boolean; + className?: string; +}; + +export default function Select(props: SwitchProps): JSX.Element { + return ( +
{ + props.setState(!props.state); + }} + > +
+
+ ); +} diff --git a/src/graphql/operation.graphql b/src/graphql/operation.graphql index a91da45..f83644f 100644 --- a/src/graphql/operation.graphql +++ b/src/graphql/operation.graphql @@ -126,7 +126,6 @@ query getChronologyItems($language_code: String) { query getLibraryItemsPreview($language_code: String) { libraryItems( - filters: { root_item: { eq: true } } pagination: { limit: -1 } ) { data { @@ -135,6 +134,7 @@ query getLibraryItemsPreview($language_code: String) { title subtitle slug + root_item thumbnail { data { attributes { diff --git a/src/graphql/operations-types.ts b/src/graphql/operations-types.ts index 57b4615..45392cf 100644 --- a/src/graphql/operations-types.ts +++ b/src/graphql/operations-types.ts @@ -238,6 +238,7 @@ export type GetLibraryItemsPreviewQuery = { title: string; subtitle: string; slug: string; + root_item: boolean; thumbnail: { __typename: "UploadFileEntityResponse"; data: { diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx index 32cd19c..be097cf 100644 --- a/src/pages/library/index.tsx +++ b/src/pages/library/index.tsx @@ -17,6 +17,7 @@ import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; import Select from "components/Select"; import { useEffect, useState } from "react"; import { prettyDate, prettyinlineTitle } from "queries/helpers"; +import Switch from "components/Switch"; type LibraryProps = { libraryItems: GetLibraryItemsPreviewQuery; @@ -31,21 +32,31 @@ type GroupLibraryItems = Map< export default function Library(props: LibraryProps): JSX.Element { const langui = props.langui.websiteInterfaces.data[0].attributes; + const [showSubitems, setShowSubitems] = useState(false); + const [sortingMethod, setSortingMethod] = useState("title"); + const [groupingMethod, setGroupingMethod] = useState(""); + + const [filteredItems, setFilteredItems] = useState< + LibraryProps["libraryItems"]["libraryItems"]["data"] + >(filterItems(showSubitems, props.libraryItems.libraryItems.data)); + const [sortedItems, setSortedItem] = useState< LibraryProps["libraryItems"]["libraryItems"]["data"] - >(sortBy("title", props.libraryItems.libraryItems.data)); - - const [sortingMethod, setSortingMethod] = useState("title"); + >(sortBy(groupingMethod, filteredItems)); const [groups, setGroups] = useState( getGroups("", sortedItems) ); - const [groupingMethod, setGroupingMethod] = useState(""); + useEffect(() => { + setFilteredItems( + filterItems(showSubitems, props.libraryItems.libraryItems.data) + ); + }, [showSubitems, props.libraryItems.libraryItems.data]); useEffect(() => { - setSortedItem(sortBy(sortingMethod, props.libraryItems.libraryItems.data)); - }, [props.libraryItems.libraryItems.data, sortingMethod]); + setSortedItem(sortBy(sortingMethod, filteredItems)); + }, [filteredItems, sortingMethod]); useEffect(() => { setGroups(getGroups(groupingMethod, sortedItems)); @@ -85,6 +96,11 @@ export default function Library(props: LibraryProps): JSX.Element { onChange={setSortingMethod} />
+ +
+

Show subitems:

+ +
); const contentPanel = ( @@ -93,10 +109,10 @@ export default function Library(props: LibraryProps): JSX.Element { <> {items.length > 0 && ( <> -

{name}

+

{name}

{items.map((item) => ( @@ -168,7 +184,26 @@ function getGroups( groupType.get("Video")?.push(item); break; case "ComponentMetadataOther": - groupType.get("Other")?.push(item); + switch ( + item.attributes.metadata[0].subtype.data.attributes.slug + ) { + case "audio-case": + groupType.get("Audio")?.push(item); + break; + + case "video-case": + groupType.get("Video")?.push(item); + break; + + case "game-case": + groupType.get("Game")?.push(item); + break; + + default: + groupType.get("Other")?.push(item); + break; + } + break; } } else { @@ -210,6 +245,26 @@ function getGroups( } } +function filterItems( + showSubitems: boolean, + items: LibraryProps["libraryItems"]["libraryItems"]["data"] +): LibraryProps["libraryItems"]["libraryItems"]["data"] { + return [...items].filter((item) => { + let result = true; + if (!showSubitems && !item.attributes.root_item) result = false; + if ( + item.attributes.metadata.length > 0 && + item.attributes.metadata[0].__typename === "ComponentMetadataOther" && + (item.attributes.metadata[0].subtype.data.attributes.slug === + "variant-set" || + item.attributes.metadata[0].subtype.data.attributes.slug === + "relation-set") + ) + result = false; + return result; + }); +} + function sortBy( orderByType: string, items: LibraryProps["libraryItems"]["libraryItems"]["data"]