From c5ff0245130bd942f5a77592ccf7b896b044aae8 Mon Sep 17 00:00:00 2001 From: Samuel Gratzl Date: Tue, 25 May 2021 11:24:30 -0400 Subject: [PATCH] feat: improve custom filter/sortby/groupby actions --- packages/_playground/src/App.tsx | 213 ++++++++++++------ packages/_playground/src/styles.css | 16 +- packages/hooks/src/grouping/baseGroupBy.ts | 22 +- .../src/grouping/columnSpecificGroupByFn.ts | 6 +- packages/hooks/src/grouping/histGroupBy.ts | 2 +- packages/hooks/src/grouping/textGroupBy.ts | 10 +- .../hooks/src/hooks/useGroupingOptions.ts | 2 +- packages/hooks/src/hooks/useSortingOptions.ts | 2 +- packages/table/src/components/LineUpLite.tsx | 9 +- .../table/src/components/LineUpLiteTH.tsx | 11 +- .../table/src/components/LineUpLiteTHead.tsx | 12 +- packages/table/src/components/interfaces.ts | 18 +- .../toolbar/LineUpLiteFilterAction.tsx | 52 +++-- .../toolbar/LineUpLiteGroupByAction.tsx | 54 +++-- .../toolbar/LineUpLiteHideAction.tsx | 35 +-- .../toolbar/LineUpLiteSortByAction.tsx | 63 +++--- .../components/toolbar/LineUpLiteToolbar.tsx | 43 +++- .../table/src/components/useLineUpLite.ts | 8 +- 18 files changed, 395 insertions(+), 183 deletions(-) diff --git a/packages/_playground/src/App.tsx b/packages/_playground/src/App.tsx index 34f1468..c3b596a 100644 --- a/packages/_playground/src/App.tsx +++ b/packages/_playground/src/App.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ /** * @lineup-lite/example-basic * https://github.com/sgratzl/lineup-lite @@ -10,23 +11,23 @@ import '@lineup-lite/components/src/style.css'; import '@lineup-lite/hooks/src/style.css'; import LineUpLite, { actionIconsRemixicon, - asTextColumn, + ActionLineUpProps, asDivergingNumberColumn, + asTextColumn, + featureFilterColumns, + featureFlexLayout, + featureRowRank, + featureRowSelect, + featureSortAndGroupBy, LineUpLiteColumn, LineUpLitePanel, LineUpLiteStateContextProvider, - ColumnInstance, - LineUpLiteFilterAction, UseFiltersColumnProps, - featureFlexLayout, - featureFilterColumns, - featureRowRank, - featureSortAndGroupBy, - featureRowSelect, - ActionIcons, + ColumnInstance, } from '@lineup-lite/table'; +import type { TextGroupByOptions } from '@lineup-lite/hooks'; import '@lineup-lite/table/src/style.css'; -import React, { useMemo, useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { data, Row } from './data'; import './styles.css'; @@ -35,59 +36,138 @@ function MyCheckBox({ indeterminate, ...rest }: any) { return ; } -function MyFilterAction(props: { col: ColumnInstance; icons: ActionIcons }) { - const col = props.col as unknown as ColumnInstance & UseFiltersColumnProps; +function useVisibleHelper() { + const [visible, setVisible] = useState([] as string[]); - const [visible, setVisible] = useState(false); - const showFilterDialog = useCallback(() => { - setVisible(!visible); - }, [visible, setVisible]); + const toggleVisibility = useCallback( + (col: { id: string }) => { + setVisible((v) => (v.indexOf(col.id) >= 0 ? v.filter((d) => d !== col.id) : [...v, col.id])); + }, + [setVisible] + ); + const isVisible = useCallback((col: { id: string }) => visible.indexOf(col.id) >= 0, [visible]); + return { toggleVisibility, isVisible }; +} - return ( - <> - - {visible && ( -
- {col.render('Summary')} - -
- )} - +function useFilterAction() { + const { toggleVisibility, isVisible } = useVisibleHelper(); + const r: ActionLineUpProps['actionFilter'] = useCallback( + (col: ColumnInstance & UseFiltersColumnProps) => { + if (!col.canFilter) { + return undefined; + } + const handler = () => toggleVisibility(col); + return { + handler, + children: isVisible(col) ? ( +
+ {col.render('Summary')} + +
+ ) : undefined, + }; + }, + [isVisible, toggleVisibility] ); + return r; } -// function MyGroupingOptionAction(props: { col: ColumnInstance; icons: ActionIcons }) { -// const col = props.col as unknown as ColumnInstance & UseFiltersColumnProps; +function TextGroupByOptionsBlock({ + setGroupingOptions, + groupingOptions, + onClose, +}: { + groupingOptions?: TextGroupByOptions; + setGroupingOptions(v: TextGroupByOptions | undefined): void; + onClose(): void; +}) { + const values = (groupingOptions?.values ?? []) as (RegExp | string)[]; + + const onSubmit = useCallback( + (e: React.FormEvent) => { + e.preventDefault(); + const fData = new FormData(e.currentTarget); + const type = fData.get('type') as TextGroupByOptions['type']; + if (!type) { + setGroupingOptions(undefined); + onClose(); + return; + } + + const currentValues = (fData.get('values') ?? '') + .toString() + .split('\n') + .map((d) => d.trim()) + .filter(Boolean); + if (type === 'regex') { + setGroupingOptions({ + type, + values: currentValues.map((d) => new RegExp(d)), + }); + } else { + setGroupingOptions({ + type, + values: currentValues, + }); + } + onClose(); + }, + [onClose, setGroupingOptions] + ); -// const [visible, setVisible] = useState(false); -// const showGroupingDialog = useCallback(() => { -// setVisible(!visible); -// }, [visible, setVisible]); + return ( +
+ + + +