Skip to content

Commit

Permalink
21560: MINOR Added support for purposes to FeatureAttributes fields (#22
Browse files Browse the repository at this point in the history
)
  • Loading branch information
lancegliser authored Sep 23, 2024
1 parent 11fceb4 commit 7f48f98
Show file tree
Hide file tree
Showing 59 changed files with 363 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const meta: Meta<typeof FeatureAttributesConfiguration> = {
},
decorators: [
getFormProviderDecorator<InferFeatureAttributeFormValues>(),
getFeaturesAttributesContextDecorator(),
getFeaturesAttributesContextDecorator({ purposes: ["core", "synthesis"] }),
withPadding,
],
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const meta: Meta<typeof FeaturesAttributesCompact> = {
decorators: [withPadding],
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
args: {},
args: {
purposes: ["core"],
},
};

const sampleFeatureAttributesIndex: FeatureAttributesIndex = {
Expand Down Expand Up @@ -166,6 +168,24 @@ Default.args!.timeFeatureAtom = getInferFeatureAttributesParamsTimeFeatureAtom({
runRequiredAtom: defaultRunRequiredAtom,
});

const synthesisRunRequiredAtom = getInferFeatureAttributesRunRequiredFields();
export const Synthesis: Story = {
args: {
activeFeatureAtom:
getFeatureAttributesActiveFeatureAtom(defaultActiveFeature),
paramsAtom: getInferFeatureAttributesParamsAtom({
features: sampleFeatureAttributesIndex,
}),
purposes: ["core", "synthesis"],
runRequiredAtom: synthesisRunRequiredAtom,
},
};
Synthesis.args!.timeFeatureAtom =
getInferFeatureAttributesParamsTimeFeatureAtom({
paramsAtom: Synthesis.args!.paramsAtom!,
runRequiredAtom: synthesisRunRequiredAtom,
});

const noFeaturesRunRequiredAtom = getInferFeatureAttributesRunRequiredFields();
export const NoFeatures: Story = {
args: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ describe("FeaturesAttributesCompact", () => {
<FeaturesAttributesCompact
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom()}
paramsAtom={paramsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down Expand Up @@ -100,6 +101,7 @@ describe("FeaturesAttributesCompact", () => {
<FeaturesAttributesCompact
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom(firstFeature)}
paramsAtom={paramsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down Expand Up @@ -143,6 +145,7 @@ describe("FeaturesAttributesCompact", () => {
<FeaturesAttributesCompact
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom()}
paramsAtom={paramsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down Expand Up @@ -195,6 +198,7 @@ describe("FeaturesAttributesCompact", () => {
<FeaturesAttributesCompact
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom()}
paramsAtom={paramsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
InferFeatureAttributesRunRequiredFieldsAtom,
useFeatureAttributesForm,
} from "../hooks";
import { IFeatureAttributePurposes } from "../types";
import {
getFeatureAttributeConfigurationIssues,
getInferFeatureAttributeParamsFormValuesOnSubmit,
Expand All @@ -44,7 +45,7 @@ import {
} from "../utils";
import { FeaturesAttributesCompactI18nBundle as i18n } from "./FeaturesAttributesCompact.i18n";

export type FeaturesAttributesCompactProps = {
export type FeaturesAttributesCompactProps = IFeatureAttributePurposes & {
activeFeatureAtom: FeatureAttributesActiveFeatureAtom;
paramsAtom: InferFeatureAttributesParamsAtom;
runRequiredAtom: InferFeatureAttributesRunRequiredFieldsAtom;
Expand All @@ -56,9 +57,10 @@ export type FeaturesAttributesCompactProps = {
*
* ⚠️ This component relies heavily on Modal components, and is unsuited to Jupyter Notebook integrations.
**/
export const FeaturesAttributesCompact: FC<FeaturesAttributesCompactProps> = (
props,
) => {
export const FeaturesAttributesCompact: FC<FeaturesAttributesCompactProps> = ({
purposes,
...props
}) => {
const { t } = useTranslation(i18n.namespace);
const { activeFeatureAtom, paramsAtom, timeFeatureAtom } = props;
const activeFeature = useAtomValue(activeFeatureAtom);
Expand All @@ -70,7 +72,7 @@ export const FeaturesAttributesCompact: FC<FeaturesAttributesCompactProps> = (
const [isCompact, setIsCompact] = useState(true);

return (
<FeaturesAttributesContextProvider compact={isCompact}>
<FeaturesAttributesContextProvider compact={isCompact} purposes={purposes}>
<Header
activeFeatureAtom={activeFeatureAtom}
areConfigurationsDirty={areConfigurationsDirty}
Expand Down Expand Up @@ -225,6 +227,7 @@ const Configuration: FC<ConfigurationProps> = (props) => {

const { t } = useTranslation(i18n.namespace);
const theme = getTheme();
const { purposes } = useContext(FeaturesAttributesContext);
const activeFeature = useAtomValue(activeFeatureAtom);
const params = useAtomValue(inferFeatureAttributesParamsAtom);
const attributes = activeFeature
Expand All @@ -233,7 +236,9 @@ const Configuration: FC<ConfigurationProps> = (props) => {
if (!attributes) {
throw new Error(`attributes are not defined for ${activeFeature}`);
}
const issues = getFeatureAttributeConfigurationIssues(attributes);
const issues = getFeatureAttributeConfigurationIssues(attributes, {
purposes,
});

return (
<section data-testid="configuration-container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import {
} from "./FeaturesAttributesContext";

export const getFeaturesAttributesContextDecorator =
(props?: FeaturesAttributesContextProviderProps): Decorator =>
(
props?: Omit<FeaturesAttributesContextProviderProps, "children">,
): Decorator =>
(Story) => {
return (
<FeaturesAttributesContextProvider {...props}>
<FeaturesAttributesContextProvider purposes={["core"]} {...props}>
<Story />
</FeaturesAttributesContextProvider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {
ErrorBoundary,
FieldCheckboxProps,
FieldRadiosProps,
FieldSelectProps,
FieldTextAreaProps,
FieldTextProps,
FieldCheckboxProps,
} from "@howso/react-tailwind-flowbite-components";
import { ButtonProps } from "flowbite-react";
import {
ComponentProps,
Context,
Expand All @@ -16,9 +17,9 @@ import {
} from "react";
import { twMerge } from "tailwind-merge";
import { FeatureAttributesGroupBaseProps } from "../groups";
import { ButtonProps } from "flowbite-react";
import { IFeatureAttributePurposes } from "../types";

export type IFeaturesAttributesContext = {
export type IFeaturesAttributesContext = IFeatureAttributePurposes & {
buttonProps?: Partial<ButtonProps>;
fieldCheckboxProps?: Partial<FieldCheckboxProps>;
fieldRadiosProps?: Pick<FieldRadiosProps, "labelInline" | "labelProps">;
Expand All @@ -34,16 +35,18 @@ export type IFeaturesAttributesContext = {
>;
};

const defaultContext = { purposes: ["core"] } as IFeaturesAttributesContext;
export const FeaturesAttributesContext: Context<IFeaturesAttributesContext> =
createContext({});
createContext(defaultContext);

export type FeaturesAttributesContextProviderProps = {
children: ReactNode;
compact?: boolean;
};
export type FeaturesAttributesContextProviderProps =
IFeatureAttributePurposes & {
children: ReactNode;
compact?: boolean;
};
export const FeaturesAttributesContextProvider: FC<
FeaturesAttributesContextProviderProps
> = ({ children, compact }) => {
> = ({ children, compact, purposes }) => {
const buttonProps: IFeaturesAttributesContext["buttonProps"] = useMemo(
() => ({ size: compact ? "sm" : undefined }),
[compact],
Expand Down Expand Up @@ -138,6 +141,7 @@ export const FeaturesAttributesContextProvider: FC<
fieldStackProps,
fieldTextAreaProps,
groupBaseProps,
purposes,
}}
>
<ErrorBoundary>{children}</ErrorBoundary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ const meta: Meta<typeof FeaturesAttributesRows> = {
decorators: [withPadding],
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
args: {},
args: {
purposes: ["core"],
},
};

const sampleFeatureAttributesIndex: FeatureAttributesIndex = {
Expand Down Expand Up @@ -166,6 +168,24 @@ Default.args!.timeFeatureAtom = getInferFeatureAttributesParamsTimeFeatureAtom({
runRequiredAtom: defaultRunRequiredAtom,
});

const synthesisRunRequiredAtom = getInferFeatureAttributesRunRequiredFields();
export const Synthesis: Story = {
args: {
activeFeatureAtom: getFeatureAttributesActiveFeatureAtom(),
optionsAtom: getFeatureAttributesOptionsAtom({}),
paramsAtom: getInferFeatureAttributesParamsAtom({
features: sampleFeatureAttributesIndex,
}),
purposes: ["core", "synthesis"],
runRequiredAtom: synthesisRunRequiredAtom,
},
};
Synthesis.args!.timeFeatureAtom =
getInferFeatureAttributesParamsTimeFeatureAtom({
paramsAtom: Synthesis.args!.paramsAtom!,
runRequiredAtom: synthesisRunRequiredAtom,
});

const noFeaturesRunRequiredAtom = getInferFeatureAttributesRunRequiredFields();
export const NoFeatures: Story = {
args: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ describe("FeaturesAttributesRows", () => {
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom()}
optionsAtom={getFeatureAttributesOptionsAtom({})}
paramsAtom={inferFeatureAttributesParamsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down Expand Up @@ -101,6 +102,7 @@ describe("FeaturesAttributesRows", () => {
activeFeatureAtom={getFeatureAttributesActiveFeatureAtom()}
optionsAtom={getFeatureAttributesOptionsAtom({})}
paramsAtom={inferFeatureAttributesParamsAtom}
purposes={["core", "synthesis"]}
runRequiredAtom={runRequiredAtom}
timeFeatureAtom={timeFeatureAtom}
/>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ import {
} from "@howso/react-tailwind-flowbite-components";
import { Alert, Button, getTheme, Modal, Table, Tooltip } from "flowbite-react";
import { useAtom, useAtomValue, useSetAtom } from "jotai/react";
import { ChangeEvent, FC, useCallback, useEffect, useState } from "react";
import {
ChangeEvent,
FC,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { twMerge } from "tailwind-merge";
import { MapDependentFeatureAttributesIcon } from "../../Icons";
import { FeatureAttributeSample } from "../FeatureAttributeSample";
import { FeatureAttributesConfiguration } from "../FeatureAttributesConfiguration";
import { FeatureAttributesConfigurationIssues } from "../FeatureAttributesConfigurationIssues";
import { FeaturesAttributesContextProvider } from "../FeaturesAttributesContext";
import {
FeaturesAttributesContext,
FeaturesAttributesContextProvider,
} from "../FeaturesAttributesContext";
import { FeaturesAttributesDependencies } from "../FeaturesAttributesDependencies";
import {
FeatureAttributeTypeField,
Expand All @@ -33,6 +43,7 @@ import {
InferFeatureAttributesRunRequiredFieldsAtom,
useFeatureAttributesForm,
} from "../hooks";
import { IFeatureAttributePurposes } from "../types";
import {
getFeatureAttributeConfigurationIssues,
getInferFeatureAttributeParamsFormValuesOnSubmit,
Expand All @@ -42,7 +53,7 @@ import {
} from "../utils";
import { FeaturesAttributesRowsI18nBundle as i18n } from "./FeaturesAttributesRows.i18n";

export type FeaturesAttributesRowsProps = {
export type FeaturesAttributesRowsProps = IFeatureAttributePurposes & {
activeFeatureAtom: FeatureAttributesActiveFeatureAtom;
runRequiredAtom: InferFeatureAttributesRunRequiredFieldsAtom;
paramsAtom: InferFeatureAttributesParamsAtom;
Expand All @@ -55,9 +66,10 @@ export type FeaturesAttributesRowsProps = {
*
* ⚠️ This component relies heavily on Modal components, and is unsuited to Jupyter Notebook integrations.
**/
export const FeaturesAttributesRows: FC<FeaturesAttributesRowsProps> = (
props,
) => {
export const FeaturesAttributesRows: FC<FeaturesAttributesRowsProps> = ({
purposes,
...props
}) => {
const { t } = useTranslation(i18n.namespace);
const { activeFeatureAtom, paramsAtom, optionsAtom, timeFeatureAtom } = props;
const activeFeature = useAtomValue(activeFeatureAtom);
Expand All @@ -74,7 +86,7 @@ export const FeaturesAttributesRows: FC<FeaturesAttributesRowsProps> = (
};

return (
<FeaturesAttributesContextProvider>
<FeaturesAttributesContextProvider purposes={purposes}>
<div className="relative overflow-x-auto rounded-lg shadow-md">
<Table striped>
<Table.Head>
Expand Down Expand Up @@ -144,6 +156,7 @@ const FeatureFields: FC<FeatureFieldsProps> = ({
}) => {
const { t } = useTranslation(i18n.namespace);
const theme = getTheme();
const { purposes } = useContext(FeaturesAttributesContext);
const setActiveFeature = useSetAtom(activeFeatureAtom);
const setRunRequired = useSetAtom(runRequiredAtom);
const [params, setParams] = useAtom(paramsAtom);
Expand All @@ -162,7 +175,9 @@ const FeatureFields: FC<FeatureFieldsProps> = ({
},
[setRunRequired, setParams, params, feature],
);
const issues = getFeatureAttributeConfigurationIssues(attributes);
const issues = getFeatureAttributeConfigurationIssues(attributes, {
purposes,
});

return (
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { render, screen, within } from "@testing-library/react";
import "@testing-library/jest-dom";
import { FeatureAttributeAllowNullsField } from "./FeatureAttributeAllowNullsField";
import { featureAttributeAllowNullsFieldName } from "./constants";
import { useForm, FormProvider, UseFormProps } from "react-hook-form";
import { render, screen, within } from "@testing-library/react";
import { FC, ReactNode } from "react";
import { FormProvider, useForm, UseFormProps } from "react-hook-form";
import { FeaturesAttributesContextProvider } from "../../FeaturesAttributesContext";
import { FeatureAttributeAllowNullsField } from "./FeatureAttributeAllowNullsField";
import { featureAttributeAllowNullsFieldName } from "./constants";

describe("AllowNullsField", () => {
it("should be rendered with a default value of true if not in form context", async () => {
Expand Down Expand Up @@ -58,7 +58,7 @@ const Wrapper: FC<{ children: ReactNode; formProps?: UseFormProps }> = ({
}) => {
const form = useForm(formProps);
return (
<FeaturesAttributesContextProvider>
<FeaturesAttributesContextProvider purposes={["core"]}>
<FormProvider {...form}>{children}</FormProvider>
</FeaturesAttributesContextProvider>
);
Expand Down
Loading

0 comments on commit 7f48f98

Please sign in to comment.