From d6c1bfcd3ba31067ecbe341f3279cf535a59aaad Mon Sep 17 00:00:00 2001 From: Gustav-Eikaas <89254170+Gustav-Eikaas@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:41:12 +0100 Subject: [PATCH] feat: powerbi improvements (#525) * feat: powerbi improvements * refactor: refactor powerbi filters * chore: :bookmark: release --- packages/power-bi/package.json | 2 +- .../src/lib/components/Filter/Filter.tsx | 56 +++++++++++++++++-- .../expandedFilter/ExpandedFilter.tsx | 9 +-- .../src/lib/components/skeleton/Skeleton.tsx | 30 ++++++++++ .../ToggleHideFilterPopover.tsx | 18 ++++-- .../src/lib/hooks/useVisibleFilterGroups.ts | 30 ++++++++++ packages/workspace-fusion/package.json | 2 +- .../common/components/TabNavigation.tsx | 8 +-- 8 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 packages/power-bi/src/lib/components/skeleton/Skeleton.tsx create mode 100644 packages/power-bi/src/lib/hooks/useVisibleFilterGroups.ts diff --git a/packages/power-bi/package.json b/packages/power-bi/package.json index 92721f10e..7dddd1bf2 100644 --- a/packages/power-bi/package.json +++ b/packages/power-bi/package.json @@ -1,6 +1,6 @@ { "name": "@equinor/workspace-powerbi", - "version": "1.0.8", + "version": "1.0.9", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/power-bi/src/lib/components/Filter/Filter.tsx b/packages/power-bi/src/lib/components/Filter/Filter.tsx index 4afb744cb..180a6a30f 100644 --- a/packages/power-bi/src/lib/components/Filter/Filter.tsx +++ b/packages/power-bi/src/lib/components/Filter/Filter.tsx @@ -8,6 +8,9 @@ import { getActiveFilterValues } from '../../utils/getActiveFilterValues'; import { getFiltersAsync } from '../../utils/getFiltersAsync'; import { PowerBIQuickFilter } from '../QuickFilter/QuickFilter'; import { search, playlist_add, drag_handle } from '@equinor/eds-icons'; +import { tokens } from '@equinor/eds-tokens'; +import { Skeleton } from '../skeleton/Skeleton'; +import { getVisibleFiltersFromLocalStorage, useVisibleFilters } from '../../hooks/useVisibleFilterGroups'; Icon.add({ search, playlist_add, drag_handle }); @@ -30,7 +33,7 @@ export interface FilterController { setVisibleFilters: (visibleGroups: string[]) => void; } -interface PowerBIFilterOptions { +export interface PowerBIFilterOptions { defaultFilterGroupVisible?: string[]; } @@ -42,7 +45,8 @@ type PowerBIFilterProps = { export const PowerBIFilter = ({ report, options }: PowerBIFilterProps): JSX.Element | null => { const [activeFilters, setActiveFilters] = useState>({}); const [slicerFilters, setSlicerFilters] = useState(null); - const [filterGroupVisible, setFilterGroupVisible] = useState(options?.defaultFilterGroupVisible || []); + const [filterGroupVisible, setFilterGroupVisible] = useVisibleFilters(report, options); + const [isFilterExpanded, setIsFilterExpanded] = useState(false); const handleChangeGroup = async (filter: PowerBiFilter) => { @@ -161,7 +165,10 @@ export const PowerBIFilter = ({ report, options }: PowerBIFilterProps): JSX.Elem const defaultActiveFilters = await getActiveFilterValues(filters); setSlicerFilters(filters.sort((a, b) => a.type.localeCompare(b.type))); setActiveFilters(defaultActiveFilters); - if (!options?.defaultFilterGroupVisible) { + const state = getVisibleFiltersFromLocalStorage(report.getId()); + if (state) { + setFilterGroupVisible(state); + } else { setFilterGroupVisible(filters.map((s) => s.type)); } }; @@ -183,13 +190,21 @@ export const PowerBIFilter = ({ report, options }: PowerBIFilterProps): JSX.Elem setSlicerFilters(filters.sort((a, b) => a.type.localeCompare(b.type))); const filterGroupNames = getActiveFilterGroupArray(activeFilters); - setFilterGroupVisible((s) => [...s, ...filterGroupNames].filter((v, i, a) => a.indexOf(v) === i)); + + const reportId = report.getId(); + + const state = getVisibleFiltersFromLocalStorage(reportId); + if (state) { + setFilterGroupVisible(state); + } else { + setFilterGroupVisible((s) => [...s, ...filterGroupNames].filter((v, i, a) => a.indexOf(v) === i)); + } }; reCreateFilters(); } }, [activeFilters, Object.keys(activeFilters).length]); - if (!slicerFilters || Object.keys(activeFilters).length === 0) return null; + if (!slicerFilters || Object.keys(activeFilters).length === 0) return ; const controller: FilterController = { handleChangeGroup, @@ -203,8 +218,37 @@ export const PowerBIFilter = ({ report, options }: PowerBIFilterProps): JSX.Elem slicerFilters, activeFilters, visibleFilters: filterGroupVisible, - setVisibleFilters: setFilterGroupVisible, + setVisibleFilters: (e) => { + const reportId = report.getId(); + if (reportId) { + localStorage.setItem(`${reportId}-filters`, JSON.stringify(e)); + } + setFilterGroupVisible(e); + }, }; return ; }; + +function QuickFilterLoading() { + return ( +
+ + + + + + +
+ ); +} diff --git a/packages/power-bi/src/lib/components/expandedFilter/ExpandedFilter.tsx b/packages/power-bi/src/lib/components/expandedFilter/ExpandedFilter.tsx index ebf6cbf76..6f350a78e 100644 --- a/packages/power-bi/src/lib/components/expandedFilter/ExpandedFilter.tsx +++ b/packages/power-bi/src/lib/components/expandedFilter/ExpandedFilter.tsx @@ -25,16 +25,17 @@ export function ExpandedFilter({ controller }: ExpandedFilterProps): JSX.Element return ( - {slicerFilters - .filter((s) => visibleFilters.includes(s.type)) + {visibleFilters + .map((s) => slicerFilters.find((x) => x.type === s)) + .filter(Boolean) .map((group) => ( ))} diff --git a/packages/power-bi/src/lib/components/skeleton/Skeleton.tsx b/packages/power-bi/src/lib/components/skeleton/Skeleton.tsx new file mode 100644 index 000000000..fca120575 --- /dev/null +++ b/packages/power-bi/src/lib/components/skeleton/Skeleton.tsx @@ -0,0 +1,30 @@ +import styled from 'styled-components'; + +export const Skeleton = styled.div<{ height: number; width: number }>` + width: ${({ width }) => `${width}px`}; + height: ${({ height }) => `${height}px`}; + cursor: progress; + background: linear-gradient(0.25turn, transparent, #fff, transparent), linear-gradient(#eee, #eee); + background-repeat: no-repeat; + background-size: + 315px 250px, + 315px 180px, + 100px 100px, + 225px 30px; + background-position: + -315px 0, + 0 0, + 0px 190px, + 50px 195px; + border-radius: 5px; + animation: loading 1.5s infinite; + @keyframes loading { + to { + background-position: + 315px 0, + 0 0, + 0 190px, + 50px 195px; + } + } +`; diff --git a/packages/power-bi/src/lib/components/toggleHideFilterPopover.tsx/ToggleHideFilterPopover.tsx b/packages/power-bi/src/lib/components/toggleHideFilterPopover.tsx/ToggleHideFilterPopover.tsx index b4a26a213..90b2384ab 100644 --- a/packages/power-bi/src/lib/components/toggleHideFilterPopover.tsx/ToggleHideFilterPopover.tsx +++ b/packages/power-bi/src/lib/components/toggleHideFilterPopover.tsx/ToggleHideFilterPopover.tsx @@ -4,6 +4,9 @@ import { useState, useRef } from 'react'; import { ReactSortable } from 'react-sortablejs'; import styled from 'styled-components'; +const joinListWithPreservedOrder = (list1: string[], list2: string[]) => + list1.concat(list2).filter((v, i, a) => a.indexOf(v) === i); + interface ShowHideFilterButtonProps { allFilters: string[]; visibleFilters: string[]; @@ -22,7 +25,9 @@ export const ToggleHideFilterPopover = ({ const [isOpen, setIsOpen] = useState(false); const ref = useRef(null); - const [list, setList] = useState[]>(allFilters.map((s) => ({ id: s, item: s }))); + const listRef = useRef[]>( + joinListWithPreservedOrder(visibleFilters, allFilters).map((s) => ({ id: s, item: s })) + ); const handleChange = (val: string) => { if (visibleFilters.includes(val)) { @@ -33,7 +38,8 @@ export const ToggleHideFilterPopover = ({ }; const DraggableHandleSelector = 'globalDraggableHandle'; - const updateList = () => setVisibleFilters(list.map((s) => s.item).filter((s) => visibleFilters.includes(s))); + const updateList = () => + setVisibleFilters(listRef.current.map((s) => s.item).filter((s) => visibleFilters.includes(s))); return ( <> @@ -53,11 +59,13 @@ export const ToggleHideFilterPopover = ({ { + listRef.current = e; + }} onEnd={updateList} > - {list.map(({ item }) => ( + {listRef.current.map(({ item }) => ( { + const value = localStorage.getItem(`${reportId}-filters`); + if (!value) return null; + const parsedValue = JSON.parse(value); + if (Array.isArray(parsedValue) && parsedValue.every((s) => typeof s === 'string')) { + return parsedValue as string[]; + } + return null; +}; + +export const useVisibleFilters = (report: Report, options?: PowerBIFilterOptions) => { + const [filterGroupVisible, setFilterGroupVisible] = useState( + getVisibleFiltersFromLocalStorage(report.getId()) ?? options?.defaultFilterGroupVisible ?? [] + ); + + return [ + filterGroupVisible, + (e: Parameters[0]) => { + const reportId = report.getId(); + if (reportId) { + localStorage.setItem(`${reportId}-filters`, JSON.stringify(e)); + } + setFilterGroupVisible(e); + }, + ] as const; +}; diff --git a/packages/workspace-fusion/package.json b/packages/workspace-fusion/package.json index 72dfee909..72e3a90c5 100644 --- a/packages/workspace-fusion/package.json +++ b/packages/workspace-fusion/package.json @@ -1,6 +1,6 @@ { "name": "@equinor/workspace-fusion", - "version": "6.0.2", + "version": "6.0.3", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/workspace-fusion/src/lib/integrations/common/components/TabNavigation.tsx b/packages/workspace-fusion/src/lib/integrations/common/components/TabNavigation.tsx index 628de2672..8e0603245 100644 --- a/packages/workspace-fusion/src/lib/integrations/common/components/TabNavigation.tsx +++ b/packages/workspace-fusion/src/lib/integrations/common/components/TabNavigation.tsx @@ -20,7 +20,7 @@ export const TabNavigation = () => { {!!leftIcons.length && ( <> {leftIcons.map(({ Icon, name, type }) => ( - <> + {pRef.current && ( {type === 'button' ? ( @@ -34,7 +34,7 @@ export const TabNavigation = () => { )} )} - + ))} {(!!analyticsTabs.length || !!viewTabs.length || !!rightIcons.length) && } @@ -73,7 +73,7 @@ export const TabNavigation = () => { {!!rightIcons.length && ( <> {rightIcons.map(({ Icon, name, type }) => ( - <> + {pRef.current && ( {type === 'button' ? ( @@ -87,7 +87,7 @@ export const TabNavigation = () => { )} )} - + ))} )}