Skip to content

Commit

Permalink
additional functionality on quick filters, fix tab auto naming
Browse files Browse the repository at this point in the history
  • Loading branch information
heswell authored and keikeicheung committed Aug 20, 2024
1 parent 36741c0 commit 547e905
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { ColumnDescriptor } from "@finos/vuu-table-types";
import { VuuInput, VuuTypeaheadInput } from "@finos/vuu-ui-controls";
import {
VuuDatePicker,
VuuInput,
VuuTypeaheadInput,
} from "@finos/vuu-ui-controls";
import { SuggestionProvider, TableSchemaTable } from "@finos/vuu-data-types";
import { CommitHandler } from "@finos/vuu-utils";
import { CommitHandler, isDateTimeColumn } from "@finos/vuu-utils";

export interface DataItemEditControlProps {
column: ColumnDescriptor;
Expand All @@ -16,7 +20,13 @@ export const getDataItemEditControl = ({
suggestionProvider,
table,
}: DataItemEditControlProps) => {
if (column.serverDataType === "string" && suggestionProvider && table) {
if (isDateTimeColumn(column)) {
return <VuuDatePicker onCommit={onCommit as any} />;
} else if (
column.serverDataType === "string" &&
suggestionProvider &&
table
) {
return (
<VuuTypeaheadInput
column={column.name}
Expand Down
4 changes: 4 additions & 0 deletions vuu-ui/packages/vuu-filters/src/filter-bar/FilterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {
onFilterRenamed?: (filter: Filter, name: string) => void;
onFilterStateChanged?: (state: FilterState) => void;
suggestionProvider?: SuggestionProvider;
/**
* TableSchema is used both to populate list of available columns and to
* provide table in call to Typeahead service
*/
tableSchema?: TableSchema;
variant?: FilterBarVariant;
}
Expand Down
18 changes: 11 additions & 7 deletions vuu-ui/packages/vuu-filters/src/quick-filters/QuickFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface QuickFilterProps
FilterBarProps,
"onApplyFilter" | "suggestionProvider" | "tableSchema"
> {
allowAddColumn?: boolean;
allowFind?: boolean;
availableColumns: ColumnDescriptor[];
onChangeQuickFilterColumns?: (columns: string[]) => void;
Expand All @@ -31,6 +32,7 @@ export interface QuickFilterProps
}

export const QuickFilters = ({
allowAddColumn = true,
allowFind = true,
availableColumns,
onApplyFilter,
Expand Down Expand Up @@ -106,13 +108,15 @@ export const QuickFilters = ({
<div className={`${classBase}-filter-container`}>
{getFilterControls()}
</div>
<ColumnPicker
columns={availableColumnNames}
icon="more-horiz"
iconSize={16}
onSelectionChange={onColumnsSelectionChange}
selected={quickFilterColumns}
/>
{allowAddColumn ? (
<ColumnPicker
columns={availableColumnNames}
icon="more-horiz"
iconSize={16}
onSelectionChange={onColumnsSelectionChange}
selected={quickFilterColumns}
/>
) : null}
</div>
);
};
23 changes: 15 additions & 8 deletions vuu-ui/packages/vuu-filters/src/quick-filters/useQuickFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import type { Filter } from "@finos/vuu-filter-types";
import type { VuuRowDataItemType } from "@finos/vuu-protocol-types";
import type { ColumnDescriptor } from "@finos/vuu-table-types";
import { MultiSelectionHandler } from "@finos/vuu-ui-controls";
import { CommitHandler, filterAsQuery, queryClosest } from "@finos/vuu-utils";
import {
CommitHandler,
NoFilter,
filterAsQuery,
queryClosest,
} from "@finos/vuu-utils";
import {
ChangeEventHandler,
RefCallback,
Expand Down Expand Up @@ -49,7 +54,7 @@ const createFilterClause = (
const buildFilterStruct = (
quickFilters: QuickFilterValues,
availableColumns: ColumnDescriptor[],
): Filter => {
): Filter | undefined => {
const entries = Object.entries(quickFilters);
if (entries.length === 1) {
return createFilterClause(entries[0], availableColumns);
Expand All @@ -61,8 +66,6 @@ const buildFilterStruct = (
availableColumns,
),
};
} else {
throw Error("What no filter");
}
};

Expand All @@ -71,10 +74,14 @@ const buildFilter = (
availableColumns: ColumnDescriptor[],
): DataSourceFilter => {
const filterStruct = buildFilterStruct(quickFilters, availableColumns);
return {
filter: filterAsQuery(filterStruct),
filterStruct,
};
if (filterStruct) {
return {
filter: filterAsQuery(filterStruct),
filterStruct,
};
} else {
return NoFilter;
}
};

export type QuickFilterHookProps = Pick<
Expand Down
47 changes: 25 additions & 22 deletions vuu-ui/packages/vuu-layout/src/layout-reducer/layoutUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface ComponentWithId {
}

export const getManagedDimension = (
style: CSSProperties
style: CSSProperties,
): [dimension, dimension] =>
style.flexDirection === "column" ? ["height", "width"] : ["width", "height"];

Expand All @@ -33,7 +33,7 @@ export const applyLayoutProps = (component: ReactElement, path = "0") => {
const [layoutProps, children] = getChildLayoutProps(
typeOf(component) as string,
component.props,
path
path,
);
return React.cloneElement(component, layoutProps, children);
};
Expand All @@ -58,30 +58,30 @@ export interface LayoutProps extends ComponentWithId {
*/
export const cloneElementAddLayoutProps = (
layoutElement: ReactElement,
previousLayout?: ReactElement
previousLayout?: ReactElement,
): ReactElement => {
const type = typeOf(layoutElement) as string;
const [layoutProps, children] = getChildLayoutProps(
type,
layoutElement.props,
"0",
undefined,
previousLayout
previousLayout,
);
return cloneElement(layoutElement, layoutProps, children);
};

export const applyLayout = (
type: layoutType,
props: LayoutProps,
previousLayout?: LayoutModel
previousLayout?: LayoutModel,
): LayoutModel => {
const [layoutProps, children] = getChildLayoutProps(
type,
props,
"0",
undefined,
previousLayout
previousLayout,
);
return {
...props,
Expand All @@ -96,7 +96,7 @@ function getLayoutProps(
props: LayoutProps,
path = "0",
parentType: string | null = null,
previousLayout?: LayoutModel
previousLayout?: LayoutModel,
): LayoutProps {
const {
active: prevActive = 0,
Expand All @@ -107,8 +107,8 @@ function getLayoutProps(
} = getProps(previousLayout);

const prevMatch = typeOf(previousLayout) === type && path === prevPath;
const id = prevMatch ? prevId : props.id ?? uuid();
const active = type === "Stack" ? props.active ?? prevActive : undefined;
const id = prevMatch ? prevId : (props.id ?? uuid());
const active = type === "Stack" ? (props.active ?? prevActive) : undefined;

const key = id;
const style = prevMatch ? prevStyle : getStyle(type, props, parentType);
Expand All @@ -122,14 +122,14 @@ function getChildLayoutProps(
props: LayoutProps,
path: string,
parentType: string | null = null,
previousLayout?: LayoutModel
previousLayout?: LayoutModel,
): [LayoutProps, ReactElement[]] {
const layoutProps = getLayoutProps(
type,
props,
path,
parentType,
previousLayout
previousLayout,
);

if (props.layout && !previousLayout) {
Expand All @@ -149,13 +149,13 @@ function getLayoutChildren(
type: string,
children?: ReactElement[],
path = "0",
previousChildren?: ReactElement[]
previousChildren?: ReactElement[],
) {
const kids = Array.isArray(children)
? children
: React.isValidElement(children)
? [children]
: [];
? [children]
: [];
return isContainer(type)
? kids.map((child, i) => {
const childType = typeOf(child) as string;
Expand All @@ -167,7 +167,7 @@ function getLayoutChildren(
child.props,
`${path}.${i}`,
type,
previousChildren?.[i]
previousChildren?.[i],
);
return React.cloneElement(child, layoutProps, children);
}
Expand All @@ -180,7 +180,7 @@ function getLayoutChildren(
const getStyle = (
type: string,
props: LayoutProps,
parentType?: string | null
parentType?: string | null,
) => {
let { style = theKidHasNoStyle } = props;
if (type === "Flexbox") {
Expand Down Expand Up @@ -220,13 +220,13 @@ const getStyle = (

export function layoutFromJson(
{ id = uuid(), type, children, props, state }: LayoutJSON,
path: string
path: string,
): ReactElement {
const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);

if (componentType === undefined) {
throw Error(
`layoutUtils unable to create component from JSON, unknown type ${type}`
`layoutUtils unable to create component from JSON, unknown type ${type}`,
);
}

Expand All @@ -244,7 +244,7 @@ export function layoutFromJson(
},
children
? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))
: undefined
: undefined,
);
}

Expand Down Expand Up @@ -303,7 +303,7 @@ export type LayoutQuery = "PARENT_CONTAINER";
export const layoutQuery = (
query: LayoutQuery,
path?: string,
layoutRoot?: ReactElement
layoutRoot?: ReactElement,
) => {
if (path && layoutRoot) {
const parentElement = followPathToParent(layoutRoot, path);
Expand All @@ -325,9 +325,12 @@ export const layoutQuery = (
export const getDefaultTabLabel: TabLabelFactory = (
component,
tabIndex,
existingLabels = []
existingLabels = [],
): string => {
let label = component.props?.title ?? component.props?.["data-tab-title"];
let label =
component.props?.title ??
component.props?.["data-tab-title"] ??
existingLabels[tabIndex];
if (label) {
return label;
} else {
Expand Down
18 changes: 11 additions & 7 deletions vuu-ui/packages/vuu-layout/src/stack/Stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const classBase = "vuuTabs";
const getDefaultTabIcon = () => undefined;

const getChildElements = <T extends ReactElement = ReactElement>(
children: ReactNode
children: ReactNode,
): T[] => {
const elements: T[] = [];
React.Children.forEach(children, (child) => {
Expand Down Expand Up @@ -59,7 +59,7 @@ export const Stack = forwardRef(function Stack(
showTabs = "top",
style,
}: StackProps,
ref: ForwardedRef<HTMLDivElement>
ref: ForwardedRef<HTMLDivElement>,
) {
const targetWindow = useWindow();
useComponentCssInjection({
Expand All @@ -69,7 +69,7 @@ export const Stack = forwardRef(function Stack(
});

const id = useId(idProp);
const tabLabels = useRef<string[]>([]);
const tabLabelsRef = useRef<string[]>([]);
const {
allowCloseTab,
allowRenameTab,
Expand All @@ -81,11 +81,11 @@ export const Stack = forwardRef(function Stack(
_oldText: string,
newText: string,
_allowDeactivation: boolean,
tabIndex: number
tabIndex: number,
) => {
onTabEdit?.(tabIndex, newText);
},
[onTabEdit]
[onTabEdit],
);

const activeChild = () => {
Expand All @@ -101,15 +101,19 @@ export const Stack = forwardRef(function Stack(
return null;
};

// The list of existing Tab Labels is required only when assigning a default label
// to a new Tab. We rebuild on each render
tabLabelsRef.current.length = 0;

const renderTabs = () =>
getChildElements(children).map((child, idx) => {
const {
closeable = allowCloseTab,
id: childId = `${id}-${idx}`,
"data-tab-location": tabLocation,
} = child.props;
const label = getTabLabel(child, idx, tabLabels.current);
tabLabels.current.push(label);
const label = getTabLabel(child, idx, tabLabelsRef.current);
tabLabelsRef.current.push(label);
return (
<Tab
ariaControls={childId}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vuuColumnPicker {
z-index: 100;
}
Loading

0 comments on commit 547e905

Please sign in to comment.