From 1385e0a3d179d58c8316e6167c7b7cfc13d545b5 Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Wed, 29 Nov 2023 20:36:33 +0100 Subject: [PATCH] Add loader to service filter in Assets Update styles --- src/components/Assets/FilterMenu/index.tsx | 53 ++++++++++++++-------- src/components/Assets/FilterMenu/styles.ts | 8 ++++ src/components/Assets/FilterMenu/types.ts | 1 + src/components/Assets/index.tsx | 48 +++++++++++++++----- src/components/Assets/styles.ts | 1 + 5 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/components/Assets/FilterMenu/index.tsx b/src/components/Assets/FilterMenu/index.tsx index aac59eebd..26c902a31 100644 --- a/src/components/Assets/FilterMenu/index.tsx +++ b/src/components/Assets/FilterMenu/index.tsx @@ -1,5 +1,6 @@ import { ChangeEvent, useState } from "react"; import { Checkbox } from "../../common/Checkbox"; +import { NewCircleLoader } from "../../common/NewCircleLoader"; import { Tooltip } from "../../common/Tooltip"; import { CrossIcon } from "../../common/icons/CrossIcon"; import { MagnifierIcon } from "../../common/icons/MagnifierIcon"; @@ -27,24 +28,17 @@ export const FilterMenu = (props: FilterMenuProps) => { const selectedItems = props.items.filter((x) => x.selected); - return ( - - - {props.title} - - - - - - - - - - - + const renderContent = () => { + if (props.isLoading) { + return ( + + + + ); + } + + return ( + <> {selectedItems.length > 0 && ( {selectedItems.map((x) => ( @@ -74,7 +68,28 @@ export const FilterMenu = (props: FilterMenuProps) => { ))} - + + ); + }; + + return ( + + + {props.title} + + + + + + + + + + + {renderContent()} ); }; diff --git a/src/components/Assets/FilterMenu/styles.ts b/src/components/Assets/FilterMenu/styles.ts index 0cbfa920e..e7200da55 100644 --- a/src/components/Assets/FilterMenu/styles.ts +++ b/src/components/Assets/FilterMenu/styles.ts @@ -153,6 +153,7 @@ export const ContentContainer = styled.div` flex-direction: column; overflow: auto; gap: 8px; + flex-grow: 1; `; export const TagsContainer = styled.div` @@ -193,3 +194,10 @@ export const ListItem = styled.li` box-sizing: border-box; list-style-type: none; `; + +export const EmptyStateContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + flex-grow: 1; +`; diff --git a/src/components/Assets/FilterMenu/types.ts b/src/components/Assets/FilterMenu/types.ts index e50778c73..0ecbc6e75 100644 --- a/src/components/Assets/FilterMenu/types.ts +++ b/src/components/Assets/FilterMenu/types.ts @@ -9,4 +9,5 @@ export interface FilterMenuProps { items: MenuItem[]; onItemClick: (value: string) => void; onClose: () => void; + isLoading: boolean; } diff --git a/src/components/Assets/index.tsx b/src/components/Assets/index.tsx index cc0fbd45c..b2c888684 100644 --- a/src/components/Assets/index.tsx +++ b/src/components/Assets/index.tsx @@ -36,12 +36,14 @@ export const Assets = () => { const [selectedAssetTypeId, setSelectedAssetTypeId] = useState( null ); - const [services, setServices] = useState([]); + const [services, setServices] = useState(); + const [areServicesLoading, setAreServicesLoading] = useState(false); const [lastSetDataTimeStamp, setLastSetDataTimeStamp] = useState(); const [selectedServices, setSelectedServices] = useState([]); const previousSelectedServices = usePrevious(selectedServices); const [isServiceMenuOpen, setIsServiceMenuOpen] = useState(false); const config = useContext(ConfigContext); + const previousEnvironment = usePrevious(config.environment); const backendVersion = config.backendInfo?.applicationVersion; @@ -57,17 +59,25 @@ export const Assets = () => { window.sendMessageToDigma({ action: actions.GET_SERVICES }); + setAreServicesLoading(true); const handleServicesData = (data: unknown, timeStamp: number) => { - const services = (data as ServiceData).services; - setServices(services); + const serviceData = data as ServiceData; setLastSetDataTimeStamp(timeStamp); - if (lastSetDataTimeStamp === undefined) { - const selectedServices = services.filter((x) => - preselectedServices.includes(x) - ); - setSelectedServices(selectedServices); + if (services === undefined) { + setSelectedServices((selectedServices) => { + const oldSelectedServices = Array.isArray(selectedServices) + ? selectedServices + : preselectedServices; + + const newSelectedServices = serviceData.services.filter((x) => + oldSelectedServices.includes(x) + ); + return newSelectedServices; + }); } + setServices(serviceData.services); + setAreServicesLoading(false); }; dispatcher.addActionListener(actions.SET_SERVICES, handleServicesData); @@ -77,6 +87,19 @@ export const Assets = () => { }; }, []); + useEffect(() => { + if ( + isString(previousEnvironment) && + previousEnvironment !== config.environment + ) { + setServices(undefined); + window.sendMessageToDigma({ + action: actions.GET_SERVICES + }); + setAreServicesLoading(true); + } + }, [previousEnvironment, config.environment, services]); + useEffect(() => { const timerId = window.setTimeout(() => { window.sendMessageToDigma({ @@ -120,7 +143,7 @@ export const Assets = () => { } }; - const filterMenuItems = services.map((x) => ({ + const filterMenuItems = (services || []).map((x) => ({ label: x, value: x, selected: selectedServices.includes(x) @@ -165,17 +188,20 @@ export const Assets = () => { items={filterMenuItems} onItemClick={handleServiceMenuItemClick} onClose={handleServiceMenuClose} + isLoading={areServicesLoading} /> } onOpenChange={setIsServiceMenuOpen} isOpen={isServiceMenuOpen} - placement={"bottom-start"} + placement={"bottom-end"} > Services - {selectedServices.length > 0 ? ( + {selectedServices && + selectedServices.length > 0 && + !areServicesLoading ? ( {selectedServices.length} ) : ( diff --git a/src/components/Assets/styles.ts b/src/components/Assets/styles.ts index 414034c22..b41025276 100644 --- a/src/components/Assets/styles.ts +++ b/src/components/Assets/styles.ts @@ -20,6 +20,7 @@ export const Header = styled.div` display: flex; gap: 8px; align-items: center; + justify-content: space-between; font-size: 16px; flex-shrink: 0; height: 36px;