Skip to content
Snippets Groups Projects
Commit 2480fb7a authored by mateusz-winiarczyk's avatar mateusz-winiarczyk
Browse files

feat(overlays): add loading indicators for overlays

parent a85733a9
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!102feat(overlays): add loading indicators for overlays
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.2427 1.75736L9.2998 2.70017C8.45533 1.85567 7.28867 1.33333 6 1.33333C3.42267 1.33333 1.33333 3.42267 1.33333 6C1.33333 8.57733 3.42267 10.6667 6 10.6667C8.57733 10.6667 10.6667 8.57733 10.6667 6H12C12 9.31373 9.31373 12 6 12C2.68629 12 0 9.31373 0 6C0 2.68629 2.68629 0 6 0C7.65687 0 9.15687 0.671574 10.2427 1.75736Z" fill="black"/>
</svg>
......@@ -95,6 +95,20 @@ describe('OverlayListItem - component', () => {
expect(store.getState().overlayBioEntity.data).toEqual([]);
expect(store.getState().overlayBioEntity.overlaysId).toEqual([]);
});
it('should display spinner icon if overlay is loading', () => {
const OVERLAY_ID = 21;
renderComponent({
overlayBioEntity: {
data: {
[OVERLAY_ID]: {},
},
overlaysId: [OVERLAY_ID],
},
});
expect(screen.getByAltText('spinner icon')).toBeVisible();
expect(screen.getByText('Disable')).toBeVisible();
});
});
// TODO implement when connecting logic to component
......
import { Button } from '@/shared/Button';
import Image from 'next/image';
import spinnerIcon from '@/assets/vectors/icons/spinner.svg';
import { useOverlay } from './hooks/useOverlay';
interface OverlayListItemProps {
......@@ -8,14 +10,27 @@ interface OverlayListItemProps {
export const OverlayListItem = ({ name, overlayId }: OverlayListItemProps): JSX.Element => {
const onDownloadOverlay = (): void => {};
const { toggleOverlay, isOverlayActive } = useOverlay(overlayId);
const { toggleOverlay, isOverlayActive, isOverlayLoading } = useOverlay(overlayId);
return (
<li className="flex flex-row flex-nowrap justify-between pl-5 [&:not(:last-of-type)]:mb-4">
<span>{name}</span>
<div className="flex flex-row flex-nowrap">
<Button variantStyles="ghost" className="mr-4 max-h-8" onClick={toggleOverlay}>
{isOverlayActive ? 'Disable' : 'View'}
<Button
variantStyles="ghost"
className="mr-4 max-h-8 flex-none gap-1.5"
onClick={toggleOverlay}
>
{isOverlayLoading && (
<Image
src={spinnerIcon}
alt="spinner icon"
height={12}
width={12}
className="animate-spin"
/>
)}
{isOverlayActive || isOverlayActive ? 'Disable' : 'View'}
</Button>
<Button className="max-h-8" variantStyles="ghost" onClick={onDownloadOverlay}>
Download
......
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { isOverlayActiveSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import {
isOverlayActiveSelector,
isOverlayLoadingSelector,
} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { removeOverlayBioEntityForGivenOverlay } from '@/redux/overlayBioEntity/overlayBioEntity.slice';
import { getOverlayBioEntityForAllModels } from '@/redux/overlayBioEntity/overlayBioEntity.thunk';
import { useEmptyBackground } from './useEmptyBackground';
......@@ -8,11 +11,13 @@ import { useEmptyBackground } from './useEmptyBackground';
type UseOverlay = {
toggleOverlay: () => void;
isOverlayActive: boolean;
isOverlayLoading: boolean;
};
export const useOverlay = (overlayId: number): UseOverlay => {
const dispatch = useAppDispatch();
const isOverlayActive = useAppSelector(state => isOverlayActiveSelector(state, overlayId));
const isOverlayLoading = useAppSelector(state => isOverlayLoadingSelector(state, overlayId));
const { setBackgroundtoEmptyIfAvailable } = useEmptyBackground();
const toggleOverlay = (): void => {
......@@ -24,5 +29,5 @@ export const useOverlay = (overlayId: number): UseOverlay => {
}
};
return { toggleOverlay, isOverlayActive };
return { toggleOverlay, isOverlayActive, isOverlayLoading };
};
......@@ -42,6 +42,12 @@ export const isOverlayActiveSelector = createSelector(
(overlaysId, overlayId) => overlaysId.includes(overlayId),
);
export const isOverlayLoadingSelector = createSelector(
[overlayBioEntitySelector, (_, overlayId: number): number => overlayId],
({ overlaysId, data }, overlayId) =>
overlaysId.includes(overlayId) && data[overlayId] && !Object.keys(data[overlayId]).length,
);
export const activeOverlaysSelector = createSelector(
rootSelector,
overlaysDataSelector,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment