Skip to content

Commit

Permalink
feat: powerbi improvements (#525)
Browse files Browse the repository at this point in the history
* feat: powerbi improvements

* refactor: refactor powerbi filters

* chore: 🔖 release
  • Loading branch information
Gustav-Eikaas authored Nov 20, 2023
1 parent 045d433 commit d6c1bfc
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 21 deletions.
2 changes: 1 addition & 1 deletion packages/power-bi/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@equinor/workspace-powerbi",
"version": "1.0.8",
"version": "1.0.9",
"type": "module",
"sideEffects": false,
"license": "MIT",
Expand Down
56 changes: 50 additions & 6 deletions packages/power-bi/src/lib/components/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 });

Expand All @@ -30,7 +33,7 @@ export interface FilterController {
setVisibleFilters: (visibleGroups: string[]) => void;
}

interface PowerBIFilterOptions {
export interface PowerBIFilterOptions {
defaultFilterGroupVisible?: string[];
}

Expand All @@ -42,7 +45,8 @@ type PowerBIFilterProps = {
export const PowerBIFilter = ({ report, options }: PowerBIFilterProps): JSX.Element | null => {
const [activeFilters, setActiveFilters] = useState<Record<string, ActiveFilter[]>>({});
const [slicerFilters, setSlicerFilters] = useState<PowerBiFilter[] | null>(null);
const [filterGroupVisible, setFilterGroupVisible] = useState<string[]>(options?.defaultFilterGroupVisible || []);
const [filterGroupVisible, setFilterGroupVisible] = useVisibleFilters(report, options);

const [isFilterExpanded, setIsFilterExpanded] = useState(false);

const handleChangeGroup = async (filter: PowerBiFilter) => {
Expand Down Expand Up @@ -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));
}
};
Expand All @@ -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 <QuickFilterLoading />;

const controller: FilterController = {
handleChangeGroup,
Expand All @@ -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 <PowerBIQuickFilter controller={controller} />;
};

function QuickFilterLoading() {
return (
<div
style={{
height: '48px',
width: '100%',
display: 'flex',
background: tokens.colors.ui.background__light.hex,
alignItems: 'center',
gap: '1em',
paddingLeft: '1em',
}}
>
<Skeleton height={24} width={160} />
<Skeleton height={24} width={160} />
<Skeleton height={24} width={160} />
<Skeleton height={24} width={160} />
<Skeleton height={24} width={160} />
<Skeleton height={24} width={160} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@ export function ExpandedFilter({ controller }: ExpandedFilterProps): JSX.Element
return (
<StyledExpandedFilterWrapper>
<StyledFilterItemsWrapper>
{slicerFilters
.filter((s) => visibleFilters.includes(s.type))
{visibleFilters
.map((s) => slicerFilters.find((x) => x.type === s))
.filter(Boolean)
.map((group) => (
<FilterItems
controller={controller}
handleOnChange={handleOnChange}
handleOnSelectAll={controller.handleOnSelectAll}
activeFilters={activeFilters}
group={group}
key={group.type}
group={group!}
key={group!.type}
/>
))}
</StyledFilterItemsWrapper>
Expand Down
30 changes: 30 additions & 0 deletions packages/power-bi/src/lib/components/skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -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;
}
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand All @@ -22,7 +25,9 @@ export const ToggleHideFilterPopover = ({
const [isOpen, setIsOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);

const [list, setList] = useState<SortObject<string>[]>(allFilters.map((s) => ({ id: s, item: s })));
const listRef = useRef<SortObject<string>[]>(
joinListWithPreservedOrder(visibleFilters, allFilters).map((s) => ({ id: s, item: s }))
);

const handleChange = (val: string) => {
if (visibleFilters.includes(val)) {
Expand All @@ -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 (
<>
Expand All @@ -53,11 +59,13 @@ export const ToggleHideFilterPopover = ({
<ReactSortable
animation={200}
handle={`.${DraggableHandleSelector}`}
list={list}
setList={setList}
list={listRef.current}
setList={(e) => {
listRef.current = e;
}}
onEnd={updateList}
>
{list.map(({ item }) => (
{listRef.current.map(({ item }) => (
<ItemWrapper className={DraggableHandleSelector} key={item}>
<Checkbox
size={2}
Expand Down
30 changes: 30 additions & 0 deletions packages/power-bi/src/lib/hooks/useVisibleFilterGroups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState } from 'react';
import { PowerBIFilterOptions } from '../components/Filter/Filter';
import { Report } from 'powerbi-client';

export const getVisibleFiltersFromLocalStorage = (reportId: string) => {
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<string[]>(
getVisibleFiltersFromLocalStorage(report.getId()) ?? options?.defaultFilterGroupVisible ?? []
);

return [
filterGroupVisible,
(e: Parameters<typeof setFilterGroupVisible>[0]) => {
const reportId = report.getId();
if (reportId) {
localStorage.setItem(`${reportId}-filters`, JSON.stringify(e));
}
setFilterGroupVisible(e);
},
] as const;
};
2 changes: 1 addition & 1 deletion packages/workspace-fusion/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@equinor/workspace-fusion",
"version": "6.0.2",
"version": "6.0.3",
"type": "module",
"sideEffects": false,
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const TabNavigation = () => {
{!!leftIcons.length && (
<>
{leftIcons.map(({ Icon, name, type }) => (
<>
<Fragment key={name}>
{pRef.current && (
<Fragment key={name}>
{type === 'button' ? (
Expand All @@ -34,7 +34,7 @@ export const TabNavigation = () => {
)}
</Fragment>
)}
</>
</Fragment>
))}
{(!!analyticsTabs.length || !!viewTabs.length || !!rightIcons.length) && <TabButtonDivider />}
</>
Expand Down Expand Up @@ -73,7 +73,7 @@ export const TabNavigation = () => {
{!!rightIcons.length && (
<>
{rightIcons.map(({ Icon, name, type }) => (
<>
<Fragment key={name}>
{pRef.current && (
<Fragment key={name}>
{type === 'button' ? (
Expand All @@ -87,7 +87,7 @@ export const TabNavigation = () => {
)}
</Fragment>
)}
</>
</Fragment>
))}
</>
)}
Expand Down

0 comments on commit d6c1bfc

Please sign in to comment.