Skip to content

Commit

Permalink
add static features to featuresProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
chuchee authored and keikeicheung committed Aug 14, 2024
1 parent d1a7f12 commit a65192c
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 88 deletions.
40 changes: 35 additions & 5 deletions vuu-ui/packages/vuu-shell/src/feature-list/FeatureList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Palette, PaletteItem } from "@finos/vuu-layout";
import { Icon, ListProps } from "@finos/vuu-ui-controls";
import { FeatureProps } from "@finos/vuu-utils";
import {
FeatureProps,
StaticFeatures,
featureFromJson,
} from "@finos/vuu-utils";
import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
import cx from "clsx";
import { HTMLAttributes, useMemo } from "react";
import { HTMLAttributes, Key, useMemo } from "react";
import { Feature } from "../feature/Feature";

import featureListCss from "./FeatureList.css";
Expand All @@ -18,7 +22,8 @@ export type GroupedFeatureProps<P extends object | undefined = object> = Record<

export interface FeatureListProps<P extends object | undefined = object>
extends HTMLAttributes<HTMLDivElement> {
features: FeatureProps<P>[] | GroupedFeatureProps<P>;
features: FeatureProps<P>[] | GroupedFeatureProps<P> | StaticFeatures;
isStatic?: boolean;
}

const listPropsFullHeight: Partial<ListProps> = {
Expand All @@ -34,6 +39,7 @@ const listPropsAutoHeight: Partial<ListProps> = {
export const FeatureList = ({
features,
title = "VUU TABLES",
isStatic = false,
...htmlAttributes
}: FeatureListProps) => {
const targetWindow = useWindow();
Expand All @@ -44,6 +50,30 @@ export const FeatureList = ({
});

const content = useMemo<JSX.Element[]>(() => {
if (isStatic) {
return Object.entries(features).map(([heading, feature], index) => {
return (
<div className={`${classBase}-group`} key={index}>
<div className={`${classBase}-groupHeader`}>{heading}</div>
<PaletteItem
closeable
component={featureFromJson({
type: feature.type,
label: feature.label,
})}
// key={i}
label={feature.label}
resizeable
resize="defer"
header
>
<Icon name="draggable" size={18} />
<span className={`${classBase}-itemName`}>{feature.title}</span>
</PaletteItem>
</div>
);
});
}
if (Array.isArray(features)) {
return [
<div className={`${classBase}-standalone`} key={0}>
Expand Down Expand Up @@ -76,7 +106,7 @@ export const FeatureList = ({
<div className={`${classBase}-group`} key={index}>
<div className={`${classBase}-groupHeader`}>{heading}</div>
<Palette orientation="vertical" ListProps={listPropsAutoHeight}>
{featureList.map((featureProps, i) => (
{featureList.map((featureProps: FeatureProps<object>, i: Key) => (
<PaletteItem
closeable
component={<Feature {...featureProps} />}
Expand All @@ -96,7 +126,7 @@ export const FeatureList = ({
</div>
));
}
}, [features]);
}, [features, isStatic]);

return (
<div {...htmlAttributes} className={cx(classBase, "vuuScrollable")}>
Expand Down
64 changes: 41 additions & 23 deletions vuu-ui/packages/vuu-shell/src/feature-provider/FeatureProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,68 @@ import {
DynamicFeatures,
FeatureProps,
FilterTableFeatureProps,
StaticFeatureDescriptor,
StaticFeatures,
getCustomAndTableFeatures,
} from "@finos/vuu-utils";
import { ReactElement, ReactNode, createContext, useContext } from "react";
import { useVuuFeatures } from "./useVuuFeatures";
import {
ReactElement,
ReactNode,
createContext,
useContext,
useMemo,
} from "react";
import { useVuuTables } from "@finos/vuu-data-react";

export interface FeatureContextProps {
features: FeatureProps[];
dynamicFeatures: FeatureProps[];
tableFeatures: FeatureProps<FilterTableFeatureProps>[];
staticFeatures: StaticFeatureDescriptor[] | undefined;
staticFeatures?: StaticFeatures;
}

const NO_FEATURES: FeatureContextProps["features"] = [];
const NO_FEATURES: FeatureContextProps["dynamicFeatures"] = [];
const NO_TABLES: FeatureContextProps["tableFeatures"] = [];
const NO_STATICFEATURES: FeatureContextProps["staticFeatures"] = [];
const NO_STATICFEATURES: FeatureContextProps["staticFeatures"] = {};

const NO_FEATURES_VUU: {
dynamicFeatures: FeatureProps[];
tableFeatures: FeatureProps<FilterTableFeatureProps>[];
} = { dynamicFeatures: [], tableFeatures: [] };

const FeatureContext = createContext<FeatureContextProps>({
features: NO_FEATURES,
dynamicFeatures: NO_FEATURES,
tableFeatures: NO_TABLES,
staticFeatures: NO_STATICFEATURES,
});

export interface FeatureProviderProps extends Partial<FeatureContextProps> {
children: ReactNode;
dynamicFeatures: DynamicFeatures;
staticFeatures?: StaticFeatureDescriptor[];
features: DynamicFeatures;
staticFeatures?: StaticFeatures;
}

export const FeatureProvider = ({
children,
dynamicFeatures,
features: featuresProp,
tableFeatures: tableFeaturesProp,
features,
staticFeatures,
}: FeatureProviderProps): ReactElement => {
const [vuuFeatures, vuuTableFeatures, staticVuuFeatures] = useVuuFeatures({
staticFeatures,
features: dynamicFeatures,
});
const vuuTables = useVuuTables();
const { dynamicFeatures, tableFeatures } = useMemo<{
dynamicFeatures: FeatureProps[];
tableFeatures: FeatureProps<FilterTableFeatureProps>[];
}>(
() =>
vuuTables
? getCustomAndTableFeatures(features, vuuTables)
: NO_FEATURES_VUU,
[features, vuuTables]
);

return (
<FeatureContext.Provider
value={{
features: featuresProp ?? vuuFeatures,
tableFeatures: tableFeaturesProp ?? vuuTableFeatures,
staticFeatures: staticFeatures ?? staticVuuFeatures,
dynamicFeatures,
tableFeatures,
staticFeatures,
}}
>
{children}
Expand All @@ -57,18 +74,19 @@ export const FeatureProvider = ({
export type FeaturesHook = (
props?: Partial<FeatureContextProps>
) => FeatureContextProps;
export const useFeatures: FeaturesHook = (localFeatures) => {
export const useFeatures: FeaturesHook = (localFeatures?) => {
const contextFeatures = useContext(FeatureContext);
if (
localFeatures === undefined ||
(localFeatures.features === undefined &&
(localFeatures.dynamicFeatures === undefined &&
localFeatures.tableFeatures === undefined &&
localFeatures.staticFeatures === undefined)
) {
return contextFeatures;
} else {
return {
features: localFeatures.features ?? contextFeatures.features,
dynamicFeatures:
localFeatures.dynamicFeatures ?? contextFeatures.dynamicFeatures,
tableFeatures:
localFeatures.tableFeatures ?? contextFeatures.tableFeatures,
staticFeatures:
Expand Down
2 changes: 1 addition & 1 deletion vuu-ui/packages/vuu-shell/src/feature-provider/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./FeatureProvider";
export * from "./useVuuFeatures";
// export * from "./useVuuFeatures";
85 changes: 47 additions & 38 deletions vuu-ui/packages/vuu-shell/src/feature-provider/useVuuFeatures.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,51 @@
import { useVuuTables } from "@finos/vuu-data-react";
import {
DynamicFeatures,
FeatureProps,
FilterTableFeatureProps,
StaticFeatureDescriptor,
getCustomAndTableFeatures,
} from "@finos/vuu-utils";
import { useMemo } from "react";
// import { useVuuTables } from "@finos/vuu-data-react";
// import {
// DynamicFeatures,
// FeatureProps,
// FilterTableFeatureProps,
// getCustomAndTableFeatures,
// } from "@finos/vuu-utils";
// import { useMemo } from "react";
// import { FeatureContextProps } from "./FeatureProvider";

export interface FeaturesHookProps {
features: DynamicFeatures;
staticFeatures?: StaticFeatureDescriptor[];
}
// export interface FeaturesHookProps {
// dynamicFeatures: DynamicFeatures;
// }

const NO_FEATURES: ReturnType<typeof useVuuFeatures> = [[], [], []];
// const NO_FEATURES: {
// vuuFeatures: FeatureProps[];
// vuuTableFeatures: FeatureProps<FilterTableFeatureProps>[];
// } = { vuuFeatures: [], vuuTableFeatures: [] };

export const useVuuFeatures = ({
features,
staticFeatures,
}: FeaturesHookProps): [
FeatureProps[],
FeatureProps<FilterTableFeatureProps>[],
StaticFeatureDescriptor[] | undefined
] => {
const tables = useVuuTables();
const [customFeatures, tableFeatures, staticCustomFeatures] = useMemo<
[
FeatureProps[],
FeatureProps<FilterTableFeatureProps>[],
StaticFeatureDescriptor[] | undefined
]
>(
() =>
tables
? getCustomAndTableFeatures(features, tables, staticFeatures)
: NO_FEATURES,
[features, staticFeatures, tables]
);
// export const useVuuFeatures = ({
// dynamicFeatures: features,
// }: FeaturesHookProps): FeatureContextProps => {
// const tables = useVuuTables();
// const { vuuFeatures, vuuTableFeatures } = useMemo<{
// vuuFeatures: FeatureProps[];
// vuuTableFeatures: FeatureProps<FilterTableFeatureProps>[];
// }>(
// () => (tables ? getCustomAndTableFeatures(features, tables) : NO_FEATURES),
// [features, tables]
// );

return [customFeatures, tableFeatures, staticCustomFeatures];
};
// return {
// dynamicFeatures: vuuFeatures,
// tableFeatures: vuuTableFeatures,
// };
// };

// const vuuTables = useVuuTables();
// console.log("vuutable: ", vuuTables);
// const { vuuFeatures, vuuTableFeatures } = useMemo<{
// vuuFeatures: FeatureProps[];
// vuuTableFeatures: FeatureProps<FilterTableFeatureProps>[];
// }>(() => {
// console.log("vuutable");
// const a = vuuTables
// ? getCustomAndTableFeatures(features, vuuTables)
// : NO_FEATURES_VUU;
// return a;
// }, [features, vuuTables]);
// console.log("vuuFeature: ", vuuFeatures);
// console.log("table: ", vuuTableFeatures);
4 changes: 2 additions & 2 deletions vuu-ui/packages/vuu-shell/src/left-nav/LeftNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ export const LeftNav = (props: LeftNavProps) => {
window: targetWindow,
});

const { features, tableFeatures } = useFeatures({
features: featuresProp,
const { dynamicFeatures: features, tableFeatures } = useFeatures({
dynamicFeatures: featuresProp,
tableFeatures: tableFeaturesProp,
});

Expand Down
42 changes: 25 additions & 17 deletions vuu-ui/packages/vuu-utils/src/feature-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import type { VuuTable } from "@finos/vuu-protocol-types";
import { ListOption } from "@finos/vuu-table-types";
import { partition } from "./array-utils";
import { wordify } from "./text-utils";
import React, { ReactElement } from "react";
import { getLayoutComponent } from "./component-registry";

export type PathMap = {
[key: string]: Pick<DynamicFeatureConfig, "css" | "url">;
[key: string]: Pick<DynamicFeatureDescriptor, "css" | "url">;
};
export type Environment = "development" | "production";
export const env = process.env.NODE_ENV as Environment;
Expand Down Expand Up @@ -39,7 +41,7 @@ declare global {
const vuuConfig: Promise<VuuConfig>;
}

export interface DynamicFeatureConfig {
export interface DynamicFeatureDescriptor {
name: string;
title: string;
url: string;
Expand All @@ -63,21 +65,34 @@ export interface FilterTableFeatureProps {
}

export type DynamicFeatures = {
[key: string]: DynamicFeatureConfig;
[key: string]: DynamicFeatureDescriptor;
};

export type StaticFeatures = {
[key: string]: StaticFeatureDescriptor;
};

export function featureFromJson({
type,
label,
}: StaticFeatureDescriptor): 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}`
);
}
return React.createElement(componentType, { id: label, key: label });
}

export interface VuuConfig {
features: DynamicFeatures;
authUrl?: string;
websocketUrl: string;
ssl: boolean;
}

export const isCustomFeature = (feature: DynamicFeatureConfig) =>
export const isCustomFeature = (feature: DynamicFeatureDescriptor) =>
feature.leftNavLocation === "vuu-features";

export const isWildcardSchema = (schema?: "*" | VuuTable): schema is "*" =>
Expand Down Expand Up @@ -163,26 +178,19 @@ export const assertComponentsRegistered = (componentList: Component[]) => {

export const getCustomAndTableFeatures = (
features: DynamicFeatures,
vuuTables: Map<string, TableSchema>,
staticFeatures?: StaticFeatureDescriptor[]
): [
FeatureProps[],
FeatureProps<FilterTableFeatureProps>[],
StaticFeatureDescriptor[] | undefined
] => {
vuuTables: Map<string, TableSchema>
): {
dynamicFeatures: FeatureProps[];
tableFeatures: FeatureProps<FilterTableFeatureProps>[];
} => {
const [customFeatureConfig, tableFeaturesConfig] = partition(
Object.values(features),
isCustomFeature
);

// const staticFeatureDescriptors: StaticFeatureDescriptor[] = [];
const customFeatures: FeatureProps[] = [];
const tableFeatures: FeatureProps<FilterTableFeatureProps>[] = [];

// for (const descriptor of staticFeatures) {
// staticFeatureDescriptors.push(descriptor);
// }

for (const {
featureProps = {},
viewProps,
Expand Down Expand Up @@ -252,5 +260,5 @@ export const getCustomAndTableFeatures = (
customFeatures.push(feature);
}
}
return [customFeatures, tableFeatures, staticFeatures];
return { dynamicFeatures: customFeatures, tableFeatures: tableFeatures };
};
Loading

0 comments on commit a65192c

Please sign in to comment.