From 7962b356bee862e67e48c9fa529fb3c3604b1d1b Mon Sep 17 00:00:00 2001 From: Rohin <120430781+rohinp14@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:04:01 +1000 Subject: [PATCH 1/4] Application Settings Panel refactor --- .../ApplicationSettingsPanel.tsx | 186 +----------------- .../src/application-settings/SettingsForm.tsx | 178 +++++++++++++++++ .../applicationsettingsSchema.tsx | 39 ---- vuu-ui/showcase/index.html | 5 - 4 files changed, 180 insertions(+), 228 deletions(-) create mode 100644 vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx delete mode 100644 vuu-ui/packages/vuu-shell/src/application-settings/applicationsettingsSchema.tsx diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx index ceff7138f..c76a8f674 100644 --- a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx @@ -1,139 +1,10 @@ -import { queryClosest } from "@finos/vuu-utils"; -import { - Dropdown, - DropdownProps, - FormField, - FormFieldLabel, - Input, - Option, - Switch, - ToggleButton, - ToggleButtonGroup, - ToggleButtonGroupProps, -} from "@salt-ds/core"; import { useComponentCssInjection } from "@salt-ds/styles"; import { useWindow } from "@salt-ds/window"; -import { - FormEventHandler, - HTMLAttributes, - SyntheticEvent, - useCallback, -} from "react"; +import { HTMLAttributes } from "react"; +import { SettingsForm, SettingsSchema } from "./SettingsForm"; import applicationSettingsPanelCss from "./ApplicationSettingsPanel.css"; -export type Option = { label: string; value: T }; -// Schema type definitions -export const isOption = ( - value: Option | number | string -): value is Option => - typeof value === "object" && "label" in value && "label" in value; - -export interface BaseProperty { - name: string; - label: string; -} - -export interface StringProperty extends BaseProperty { - values?: string[] | Option[]; - defaultValue?: string; - type: "string"; -} -export interface NumericProperty extends BaseProperty { - values?: number[] | Option[]; - defaultValue?: number; - type: "number"; -} -export interface BooleanProperty extends BaseProperty { - defaultValue?: boolean; - type: "boolean"; -} - -export type SettingsProperty = - | StringProperty - | NumericProperty - | BooleanProperty; - -export const isBooleanProperty = ( - property: SettingsProperty -): property is BooleanProperty => property.type === "boolean"; - -export const isStringOrNumber = (value: unknown): value is string | number => - typeof value === "string" || typeof value === "number"; - -export interface SettingsSchema { - properties: SettingsProperty[]; -} - -const getValueAndLabel = (value: string | number | Option) => - isOption(value) ? [value.value, value.label] : [value, value]; - -// Determine the form control type to be displayed -export function getFormControl( - property: SettingsProperty, - changeHandler: FormEventHandler, - selectHandler: DropdownProps["onSelectionChange"], - currentValue?: string | boolean | number -) { - if (isBooleanProperty(property)) { - const checked = - typeof currentValue === "boolean" - ? currentValue - : property.defaultValue ?? false; - - return ( - - ); - } - // Toggle Box for 1 or 2 values - if (Array.isArray(property.values)) { - if (property.values.length <= 2) { - return ( - - {property.values.map((valueOrOption) => { - const [value, label] = getValueAndLabel(valueOrOption); - return ( - - {label} - - ); - })} - - ); - } else if (property.values.length > 2) { - return ( - - {property.values.map((valueOrOption) => { - const [value, label] = getValueAndLabel(valueOrOption); - return ( - - ); - })} - - ); - } - } else { - const value = isStringOrNumber(currentValue) - ? currentValue - : isStringOrNumber(property.defaultValue) - ? property.defaultValue - : ""; - return ; - } -} - // Props for Panel export interface ApplicatonSettingsPanelProps extends HTMLAttributes { @@ -145,57 +16,6 @@ export interface ApplicatonSettingsPanelProps ) => void; } -// Generates application settings form component -export const SettingsForm = ({ - applicationSettingsSchema, - applicationSettings, - onApplicationSettingChanged, -}: ApplicatonSettingsPanelProps) => { - const getFieldNameFromEventTarget = (evt: SyntheticEvent) => { - const fieldElement = queryClosest(evt.target, "[data-field]"); - if (fieldElement && fieldElement.dataset.field) { - return fieldElement.dataset.field; - } else { - throw Error("data-field attribute not defined"); - } - }; - - // Change Handler for toggle and input buttons - const changeHandler = useCallback( - (event) => { - const fieldName = getFieldNameFromEventTarget(event); - const { checked, value } = event.target as HTMLInputElement; - onApplicationSettingChanged(fieldName, checked ?? value); - }, - [onApplicationSettingChanged] - ); - - // Change handler for selection form controls - const selectHandler = useCallback( - (event: SyntheticEvent, [selected]: string[]) => { - const fieldName = getFieldNameFromEventTarget(event); - onApplicationSettingChanged(fieldName, selected); - }, - [onApplicationSettingChanged] - ); - - return ( -
- {applicationSettingsSchema.properties.map((property) => ( - - {property.label} - {getFormControl( - property, - changeHandler, - selectHandler, - applicationSettings[property.name] - )} - - ))} -
- ); -}; - const classBase = "vuuApplicationSettingsPanel"; export const ApplicationSettingsPanel = ({ @@ -222,5 +42,3 @@ export const ApplicationSettingsPanel = ({ ); }; - -export default ApplicationSettingsPanel; diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx new file mode 100644 index 000000000..877fb3165 --- /dev/null +++ b/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx @@ -0,0 +1,178 @@ +import { queryClosest } from "@finos/vuu-utils"; +import { + Dropdown, + DropdownProps, + FormField, + FormFieldLabel, + Input, + Option, + Switch, + ToggleButton, + ToggleButtonGroup, + ToggleButtonGroupProps, +} from "@salt-ds/core"; +import { FormEventHandler, SyntheticEvent, useCallback } from "react"; +import { ApplicatonSettingsPanelProps } from "./ApplicationSettingsPanel"; + +export type Option = { label: string; value: T }; +// Schema type definitions +export const isOption = ( + value: Option | number | string +): value is Option => + typeof value === "object" && "label" in value && "label" in value; + +export interface BaseProperty { + name: string; + label: string; +} + +export interface StringProperty extends BaseProperty { + values?: string[] | Option[]; + defaultValue?: string; + type: "string"; +} +export interface NumericProperty extends BaseProperty { + values?: number[] | Option[]; + defaultValue?: number; + type: "number"; +} +export interface BooleanProperty extends BaseProperty { + defaultValue?: boolean; + type: "boolean"; +} + +export type SettingsProperty = + | StringProperty + | NumericProperty + | BooleanProperty; + +export const isBooleanProperty = ( + property: SettingsProperty +): property is BooleanProperty => property.type === "boolean"; + +export const isStringOrNumber = (value: unknown): value is string | number => + typeof value === "string" || typeof value === "number"; + +export interface SettingsSchema { + properties: SettingsProperty[]; +} + +const getValueAndLabel = (value: string | number | Option) => + isOption(value) ? [value.value, value.label] : [value, value]; + +// Determine the form control type to be displayed +export function getFormControl( + property: SettingsProperty, + changeHandler: FormEventHandler, + selectHandler: DropdownProps["onSelectionChange"], + currentValue?: string | boolean | number +) { + if (isBooleanProperty(property)) { + const checked = + typeof currentValue === "boolean" + ? currentValue + : property.defaultValue ?? false; + + return ( + + ); + } + // Toggle Box for 1 or 2 values + if (Array.isArray(property.values)) { + if (property.values.length <= 2) { + return ( + + {property.values.map((valueOrOption) => { + const [value, label] = getValueAndLabel(valueOrOption); + return ( + + {label} + + ); + })} + + ); + } else if (property.values.length > 2) { + return ( + + {property.values.map((valueOrOption) => { + const [value, label] = getValueAndLabel(valueOrOption); + return ( + + ); + })} + + ); + } + } else { + const value = isStringOrNumber(currentValue) + ? currentValue + : isStringOrNumber(property.defaultValue) + ? property.defaultValue + : ""; + return ; + } +} + +// Generates application settings form component +export const SettingsForm = ({ + applicationSettingsSchema, + applicationSettings, + onApplicationSettingChanged, +}: ApplicatonSettingsPanelProps) => { + const getFieldNameFromEventTarget = (evt: SyntheticEvent) => { + const fieldElement = queryClosest(evt.target, "[data-field]"); + if (fieldElement && fieldElement.dataset.field) { + return fieldElement.dataset.field; + } else { + throw Error("data-field attribute not defined"); + } + }; + + // Change Handler for toggle and input buttons + const changeHandler = useCallback( + (event) => { + const fieldName = getFieldNameFromEventTarget(event); + const { checked, value } = event.target as HTMLInputElement; + onApplicationSettingChanged(fieldName, checked ?? value); + }, + [onApplicationSettingChanged] + ); + + // Change handler for selection form controls + const selectHandler = useCallback( + (event: SyntheticEvent, [selected]: string[]) => { + const fieldName = getFieldNameFromEventTarget(event); + onApplicationSettingChanged(fieldName, selected); + }, + [onApplicationSettingChanged] + ); + + return ( +
+ {applicationSettingsSchema.properties.map((property) => ( + + {property.label} + {getFormControl( + property, + changeHandler, + selectHandler, + applicationSettings[property.name] + )} + + ))} +
+ ); +}; diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/applicationsettingsSchema.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/applicationsettingsSchema.tsx deleted file mode 100644 index 7004c68ff..000000000 --- a/vuu-ui/packages/vuu-shell/src/application-settings/applicationsettingsSchema.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import type { SettingsSchema } from "@finos/vuu-shell"; - -export const applicationSettingsSchema: SettingsSchema = { - properties: [ - { - name: "themeMode", - label: "Mode", - values: ["light", "dark"], - defaultValue: "light", - type: "string", - }, - { - name: "dateFormatPattern", - label: "Date Formatting", - values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], - defaultValue: "dd/mm/yyyy", - type: "string", - }, - { - name: "region", - label: "Region", - values: [ - { value: "us", label: "US" }, - { value: "apac", label: "apac (Asia Pacific)" }, - { value: "emea", label: "emea (Europe, Middle East & Africa)" }, - ], - defaultValue: "apac", - type: "string", - }, - { - name: "greyscale", - label: "Greyscale", - defaultValue: false, - type: "boolean", - }, - ], -}; - -export default applicationSettingsSchema; diff --git a/vuu-ui/showcase/index.html b/vuu-ui/showcase/index.html index e8b8b2dc8..93aa3315c 100644 --- a/vuu-ui/showcase/index.html +++ b/vuu-ui/showcase/index.html @@ -11,10 +11,5 @@
- From f75096a527c856278b9b497a5d039571369d1396 Mon Sep 17 00:00:00 2001 From: Rohin <120430781+rohinp14@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:23:14 +1000 Subject: [PATCH 2/4] Update panel to consume props from provider --- .../ApplicationContext.tsx | 41 ++++++++++++++++++- .../ApplicationProvider.tsx | 28 ++++++++++--- .../ApplicationSettingsPanel.tsx | 11 ++--- vuu-ui/packages/vuu-shell/src/index.ts | 3 +- .../ApplicationSettingsForm.examples.tsx | 18 +++++--- 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx index ecf33a2ce..b4a041ea8 100644 --- a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx @@ -1,5 +1,6 @@ import type { ThemeMode, VuuUser } from "@finos/vuu-utils"; import { createContext } from "react"; +import { SettingsSchema } from "../application-settings/SettingsForm"; export interface CoreSettings { themeMode: ThemeMode; @@ -12,7 +13,8 @@ const Guest: VuuUser = { export interface ApplicationContextProps { changeSetting: (propertyName: string, value: unknown) => void; - settings: CoreSettings; + applicationSettings: CoreSettings; + applicationSettingsSchema?: SettingsSchema | undefined; user: VuuUser; } @@ -21,8 +23,43 @@ export const ApplicationContext = createContext({ console.log( `Cannot change setting '${propertyName}'.\nDid you forget to declare an ApplicationProvider ?` ), - settings: { + applicationSettings: { themeMode: "light", }, + applicationSettingsSchema: { + properties: [ + { + name: "themeMode", + label: "Mode", + values: ["light", "dark"], + defaultValue: "light", + type: "string", + }, + { + name: "dateFormatPattern", + label: "Date Formatting", + values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], + defaultValue: "dd/mm/yyyy", + type: "string", + }, + { + name: "region", + label: "Region", + values: [ + { value: "us", label: "US" }, + { value: "apac", label: "Asia Pacific" }, + { value: "emea", label: "Europe, Middle East & Africa" }, + ], + defaultValue: "apac", + type: "string", + }, + { + name: "greyscale", + label: "Greyscale", + defaultValue: false, + type: "boolean", + }, + ], + }, user: Guest, }); diff --git a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx index 33281ad1b..5ff84da47 100644 --- a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx @@ -18,11 +18,14 @@ export interface ApplicationProviderProps export const ApplicationProvider = ({ children, - settings: settingsProp, + applicationSettings: settingsProp, + applicationSettingsSchema, user, }: ApplicationProviderProps): ReactElement => { const context = useContext(ApplicationContext); - const [settings, setSettings] = useState(settingsProp ?? context.settings); + const [applicationSettings, setSettings] = useState( + settingsProp ?? context.applicationSettings + ); const changeSetting = useCallback((propertyName: string, value: unknown) => { setSettings((s) => ({ ...s, [propertyName]: value })); @@ -33,11 +36,16 @@ export const ApplicationProvider = ({ value={{ ...context, changeSetting, - settings, + applicationSettings, + applicationSettingsSchema, user: user ?? context.user, }} > - + {children} @@ -49,7 +57,15 @@ export const useApplicationUser = () => { return user; }; +//Setter method (only used within the shell) export const useApplicationSettings = () => { - const { changeSetting, settings } = useContext(ApplicationContext); - return { changeSetting, settings }; + const { changeSetting, applicationSettings, applicationSettingsSchema } = + useContext(ApplicationContext); + return { changeSetting, applicationSettings, applicationSettingsSchema }; +}; + +//Getter method (read only access to applicationSetting) +export const useApplicationSetting = () => { + const { applicationSettings } = useContext(ApplicationContext); + return { applicationSettings }; }; diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx index c76a8f674..17b38237b 100644 --- a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx @@ -4,11 +4,12 @@ import { HTMLAttributes } from "react"; import { SettingsForm, SettingsSchema } from "./SettingsForm"; import applicationSettingsPanelCss from "./ApplicationSettingsPanel.css"; +import { useApplicationSettings } from "../application-provider"; // Props for Panel export interface ApplicatonSettingsPanelProps extends HTMLAttributes { - applicationSettingsSchema: SettingsSchema; + applicationSettingsSchema: SettingsSchema | undefined; applicationSettings: Record; onApplicationSettingChanged: ( propertyName: string, @@ -19,13 +20,13 @@ export interface ApplicatonSettingsPanelProps const classBase = "vuuApplicationSettingsPanel"; export const ApplicationSettingsPanel = ({ - applicationSettingsSchema, - applicationSettings, - onApplicationSettingChanged, ...htmlAttributes }: ApplicatonSettingsPanelProps) => { const targetWindow = useWindow(); + const { changeSetting, applicationSettings, applicationSettingsSchema } = + useApplicationSettings(); + useComponentCssInjection({ testId: "vuu-application-settings-panel", css: applicationSettingsPanelCss, @@ -37,7 +38,7 @@ export const ApplicationSettingsPanel = ({ ); diff --git a/vuu-ui/packages/vuu-shell/src/index.ts b/vuu-ui/packages/vuu-shell/src/index.ts index b3d414cf8..f4c466df5 100644 --- a/vuu-ui/packages/vuu-shell/src/index.ts +++ b/vuu-ui/packages/vuu-shell/src/index.ts @@ -12,4 +12,5 @@ export * from "./shell-layouts/side-panel"; export * from "./ShellContextProvider"; export * from "./feature-list"; export * from "./theme-switch"; -export * from "./application-settings"; \ No newline at end of file +export * from "./application-settings"; +export * from "./application-provider" \ No newline at end of file diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx index c3a433df0..99c7d539f 100644 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx +++ b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx @@ -1,7 +1,9 @@ import { ApplicationSettingsPanel, - type SettingsSchema, + ApplicationProvider, } from "@finos/vuu-shell"; +import { SettingsSchema } from "packages/vuu-shell/src/application-settings/SettingsForm"; + import { useState } from "react"; let displaySequence = 1; @@ -63,11 +65,17 @@ export const DefaultApplicationSettingsForm = () => { }; return ( - + > + + ); }; DefaultApplicationSettingsForm.displaySequence = displaySequence++; From 4313b9f036a1d7894055ea30c1a941d3e939dd7e Mon Sep 17 00:00:00 2001 From: Rohin <120430781+rohinp14@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:49:52 +1000 Subject: [PATCH 3/4] Move showcase example to Shell --- .../ApplicationSettingsForm.examples.css | 0 .../ApplicationSettingsForm.examples.tsx | 81 ------------------ .../ApplicationSettingsForm/index.ts | 1 - .../ApplicationSettingsPanel.examples.css | 0 .../ApplicationSettingsPanel.examples.tsx | 29 ------- .../ApplicationSettingsPanel/index.ts | 1 - .../ApplicationSettingsSchemaExample.json | 33 -------- .../ApplicationSettingsTypesExamples.d.ts | 11 --- .../src/examples/ApplicationSettings/index.ts | 2 - .../Shell/ApplicationSettings.examples.tsx | 82 +++++++++++++++++++ vuu-ui/showcase/src/examples/Shell/index.ts | 1 + vuu-ui/showcase/src/examples/index.ts | 3 +- 12 files changed, 84 insertions(+), 160 deletions(-) delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.css delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/index.ts delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.css delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.tsx delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/index.ts delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsSchemaExample.json delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsTypesExamples.d.ts delete mode 100644 vuu-ui/showcase/src/examples/ApplicationSettings/index.ts create mode 100644 vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.css b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx deleted file mode 100644 index 99c7d539f..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/ApplicationSettingsForm.examples.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { - ApplicationSettingsPanel, - ApplicationProvider, -} from "@finos/vuu-shell"; -import { SettingsSchema } from "packages/vuu-shell/src/application-settings/SettingsForm"; - -import { useState } from "react"; - -let displaySequence = 1; - -export const DefaultApplicationSettingsForm = () => { - const initialSettings = { - themeMode: "light", - dateFormatPattern: "dd/mm/yyyy", - region: "US", - greyscale: false, - }; - - const applicationSettingsSchema: SettingsSchema = { - properties: [ - { - name: "themeMode", - label: "Mode", - values: ["light", "dark"], - defaultValue: "light", - type: "string", - }, - { - name: "dateFormatPattern", - label: "Date Formatting", - values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], - defaultValue: "dd/mm/yyyy", - type: "string", - }, - { - name: "region", - label: "Region", - values: [ - { value: "us", label: "US" }, - { value: "apac", label: "Asia Pacific" }, - { value: "emea", label: "Europe, Middle East & Africa" }, - ], - defaultValue: "apac", - type: "string", - }, - { - name: "greyscale", - label: "Greyscale", - defaultValue: false, - type: "boolean", - }, - ], - }; - const [applicationSettings, setApplicationSettings] = - useState(initialSettings); - - const handlePropertyChanged = ( - propertyName: string, - value: string | boolean | number - ) => { - setApplicationSettings((currentSettings) => ({ - ...currentSettings, - [propertyName]: value, - })); - }; - - return ( - - - - ); -}; -DefaultApplicationSettingsForm.displaySequence = displaySequence++; diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/index.ts b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/index.ts deleted file mode 100644 index e277371b6..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsForm/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as ApplicationSettingsForm from "./ApplicationSettingsForm.examples"; diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.css b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.tsx b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.tsx deleted file mode 100644 index 3463e22d2..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/ApplicationSettingsPanel.examples.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Shell } from "@finos/vuu-shell"; -import { CSSProperties } from "react"; - -const user = { username: "test-user", token: "test-token" }; - -let displaySequence = 1; - -export const ApplicationSettingsPanel = () => { - return ( - - ); -}; - -ApplicationSettingsPanel.displaySequence = displaySequence++; diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/index.ts b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/index.ts deleted file mode 100644 index e37020f47..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsPanel/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as ApplicationSettingsPanel from "./ApplicationSettingsPanel.examples"; \ No newline at end of file diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsSchemaExample.json b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsSchemaExample.json deleted file mode 100644 index 5af012f54..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsSchemaExample.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "properties": [ - { - "name": "themeMode", - "label": "Mode", - "values": ["light","dark"], - "defaultValue": "light", - "type": "string" - }, - { - "name": "dateFormatPattern", - "label": "Date Formatting", - "values": ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], - "defaultValue": "dd/mm/yyyy", - "type": "string" - }, - { - "name": "region", - "label": "Region", - "values": [{"value": "us", "label":"US"},{"value": "apac", "label": "Asia Pacific"},{"value": "emea", "label": "Europe, Middle East & Africa"}], - "defaultValue": "light", - "type": "string" - }, - { - "name": "greyscale", - "label": "Greyscale", - "values": ["true", "false"], - "defaultValue": "false", - "type": "boolean" - } - ] - } - \ No newline at end of file diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsTypesExamples.d.ts b/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsTypesExamples.d.ts deleted file mode 100644 index 15eaeabf2..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/ApplicationSettingsTypesExamples.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -type SettingsProperty = { - name: string; - label: string; - values?: T[]; - defaultValue: T; - type: 'string' | 'boolean' | 'number'; -} - -export interface SettingsSchema { - properties: SettingsProperty[]; -} diff --git a/vuu-ui/showcase/src/examples/ApplicationSettings/index.ts b/vuu-ui/showcase/src/examples/ApplicationSettings/index.ts deleted file mode 100644 index 43dac19ab..000000000 --- a/vuu-ui/showcase/src/examples/ApplicationSettings/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./ApplicationSettingsForm"; -export * from "./ApplicationSettingsPanel"; \ No newline at end of file diff --git a/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx b/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx new file mode 100644 index 000000000..31b1160b4 --- /dev/null +++ b/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx @@ -0,0 +1,82 @@ +import { + ApplicationSettingsPanel, + ApplicationProvider, + } from "@finos/vuu-shell"; + import { SettingsSchema } from "packages/vuu-shell/src/application-settings/SettingsForm"; + + import { useState } from "react"; + + let displaySequence = 1; + + export const DefaultApplicationSettingsForm = () => { + const initialSettings = { + themeMode: "light", + dateFormatPattern: "dd/mm/yyyy", + region: "US", + greyscale: false, + }; + + const applicationSettingsSchema: SettingsSchema = { + properties: [ + { + name: "themeMode", + label: "Mode", + values: ["light", "dark"], + defaultValue: "light", + type: "string", + }, + { + name: "dateFormatPattern", + label: "Date Formatting", + values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], + defaultValue: "dd/mm/yyyy", + type: "string", + }, + { + name: "region", + label: "Region", + values: [ + { value: "us", label: "US" }, + { value: "apac", label: "Asia Pacific" }, + { value: "emea", label: "Europe, Middle East & Africa" }, + ], + defaultValue: "apac", + type: "string", + }, + { + name: "greyscale", + label: "Greyscale", + defaultValue: false, + type: "boolean", + }, + ], + }; + const [applicationSettings, setApplicationSettings] = + useState(initialSettings); + + const handlePropertyChanged = ( + propertyName: string, + value: string | boolean | number + ) => { + setApplicationSettings((currentSettings) => ({ + ...currentSettings, + [propertyName]: value, + })); + }; + + return ( + + + + ); + }; + DefaultApplicationSettingsForm.displaySequence = displaySequence++; + \ No newline at end of file diff --git a/vuu-ui/showcase/src/examples/Shell/index.ts b/vuu-ui/showcase/src/examples/Shell/index.ts index 4e247149f..250a3b05a 100644 --- a/vuu-ui/showcase/src/examples/Shell/index.ts +++ b/vuu-ui/showcase/src/examples/Shell/index.ts @@ -1,4 +1,5 @@ export * as AppHeader from "./AppHeader.examples"; +export * as ApplicationSettings from "./ApplicationSettings.examples"; export * as ConnectionStatus from "./ConnectionStatus.examples"; export * as ConnectionMetrics from "./ConnectionMetrics.examples"; export * as Feature from "./Feature.examples"; diff --git a/vuu-ui/showcase/src/examples/index.ts b/vuu-ui/showcase/src/examples/index.ts index dfaae8d79..826fbcb7a 100644 --- a/vuu-ui/showcase/src/examples/index.ts +++ b/vuu-ui/showcase/src/examples/index.ts @@ -13,5 +13,4 @@ export * as Table from "./Table"; export * as UiControls from "./UiControls"; export * as VUU from "./VUU"; export * as VuuFeatures from "./VuuFeatures"; -export * as Performance from "./Performance"; -export * as ApplicationSettings from "./ApplicationSettings"; +export * as Performance from "./Performance"; \ No newline at end of file From 8124232b7458be14295f7b7991e2470ae8b59ed7 Mon Sep 17 00:00:00 2001 From: Rohin <120430781+rohinp14@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:16:04 +1000 Subject: [PATCH 4/4] Showcase examples + settings form value fix --- .../ApplicationContext.tsx | 17 +- .../ApplicationProvider.tsx | 24 ++- .../ApplicationSettingsPanel.tsx | 18 +- .../src/application-settings/SettingsForm.tsx | 36 ++-- .../Shell/ApplicationSettings.examples.tsx | 194 ++++++++++-------- 5 files changed, 172 insertions(+), 117 deletions(-) diff --git a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx index b4a041ea8..4667baa84 100644 --- a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationContext.tsx @@ -2,9 +2,9 @@ import type { ThemeMode, VuuUser } from "@finos/vuu-utils"; import { createContext } from "react"; import { SettingsSchema } from "../application-settings/SettingsForm"; -export interface CoreSettings { - themeMode: ThemeMode; -} +// export interface CoreSettings { +// themeMode: ThemeMode; +// } const Guest: VuuUser = { username: "unknown", @@ -12,19 +12,22 @@ const Guest: VuuUser = { }; export interface ApplicationContextProps { - changeSetting: (propertyName: string, value: unknown) => void; - applicationSettings: CoreSettings; - applicationSettingsSchema?: SettingsSchema | undefined; + onApplicationSettingChanged: (propertyName: string, value: unknown) => void; + applicationSettings: Record; + applicationSettingsSchema: SettingsSchema; user: VuuUser; } export const ApplicationContext = createContext({ - changeSetting: (propertyName: string) => + onApplicationSettingChanged: (propertyName: string) => console.log( `Cannot change setting '${propertyName}'.\nDid you forget to declare an ApplicationProvider ?` ), applicationSettings: { themeMode: "light", + dateFormatPattern: "dd MMMM yyyy", + region: "apac", + greyscale: false, }, applicationSettingsSchema: { properties: [ diff --git a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx index 5ff84da47..6b8bebebb 100644 --- a/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-provider/ApplicationProvider.tsx @@ -27,15 +27,18 @@ export const ApplicationProvider = ({ settingsProp ?? context.applicationSettings ); - const changeSetting = useCallback((propertyName: string, value: unknown) => { - setSettings((s) => ({ ...s, [propertyName]: value })); - }, []); + const onApplicationSettingChanged = useCallback( + (propertyName: string, value: unknown) => { + setSettings((s) => ({ ...s, [propertyName]: value })); + }, + [] + ); return ( { //Setter method (only used within the shell) export const useApplicationSettings = () => { - const { changeSetting, applicationSettings, applicationSettingsSchema } = - useContext(ApplicationContext); - return { changeSetting, applicationSettings, applicationSettingsSchema }; + const { + onApplicationSettingChanged, + applicationSettings, + applicationSettingsSchema, + } = useContext(ApplicationContext); + return { + onApplicationSettingChanged, + applicationSettings, + applicationSettingsSchema, + }; }; //Getter method (read only access to applicationSetting) diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx index 17b38237b..5122df23b 100644 --- a/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-settings/ApplicationSettingsPanel.tsx @@ -8,14 +8,7 @@ import { useApplicationSettings } from "../application-provider"; // Props for Panel export interface ApplicatonSettingsPanelProps - extends HTMLAttributes { - applicationSettingsSchema: SettingsSchema | undefined; - applicationSettings: Record; - onApplicationSettingChanged: ( - propertyName: string, - value: string | number | boolean - ) => void; -} + extends HTMLAttributes {} const classBase = "vuuApplicationSettingsPanel"; @@ -24,8 +17,11 @@ export const ApplicationSettingsPanel = ({ }: ApplicatonSettingsPanelProps) => { const targetWindow = useWindow(); - const { changeSetting, applicationSettings, applicationSettingsSchema } = - useApplicationSettings(); + const { + onApplicationSettingChanged, + applicationSettings, + applicationSettingsSchema, + } = useApplicationSettings(); useComponentCssInjection({ testId: "vuu-application-settings-panel", @@ -38,7 +34,7 @@ export const ApplicationSettingsPanel = ({ ); diff --git a/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx b/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx index 877fb3165..3e03aea75 100644 --- a/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx +++ b/vuu-ui/packages/vuu-shell/src/application-settings/SettingsForm.tsx @@ -11,8 +11,24 @@ import { ToggleButtonGroup, ToggleButtonGroupProps, } from "@salt-ds/core"; -import { FormEventHandler, SyntheticEvent, useCallback } from "react"; -import { ApplicatonSettingsPanelProps } from "./ApplicationSettingsPanel"; +import { + FormEventHandler, + HTMLAttributes, + SyntheticEvent, + useCallback, +} from "react"; +// import { ApplicatonSettingsPanelProps } from "./ApplicationSettingsPanel"; + +//Props for Form +export interface ApplicatonSettingsPanelProps + extends HTMLAttributes { + applicationSettingsSchema: SettingsSchema; + applicationSettings: Record; + onApplicationSettingChanged: ( + propertyName: string, + value: string | number | boolean + ) => void; +} export type Option = { label: string; value: T }; // Schema type definitions @@ -73,13 +89,7 @@ export function getFormControl( ? currentValue : property.defaultValue ?? false; - return ( - - ); + return ; } // Toggle Box for 1 or 2 values if (Array.isArray(property.values)) { @@ -108,9 +118,11 @@ export function getFormControl( {property.values.map((valueOrOption) => { const [value, label] = getValueAndLabel(valueOrOption); return ( - + ); })} diff --git a/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx b/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx index 31b1160b4..79c001e73 100644 --- a/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx +++ b/vuu-ui/showcase/src/examples/Shell/ApplicationSettings.examples.tsx @@ -1,82 +1,116 @@ import { - ApplicationSettingsPanel, - ApplicationProvider, - } from "@finos/vuu-shell"; - import { SettingsSchema } from "packages/vuu-shell/src/application-settings/SettingsForm"; - - import { useState } from "react"; - - let displaySequence = 1; - - export const DefaultApplicationSettingsForm = () => { - const initialSettings = { - themeMode: "light", - dateFormatPattern: "dd/mm/yyyy", - region: "US", - greyscale: false, - }; - - const applicationSettingsSchema: SettingsSchema = { - properties: [ - { - name: "themeMode", - label: "Mode", - values: ["light", "dark"], - defaultValue: "light", - type: "string", - }, - { - name: "dateFormatPattern", - label: "Date Formatting", - values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], - defaultValue: "dd/mm/yyyy", - type: "string", - }, - { - name: "region", - label: "Region", - values: [ - { value: "us", label: "US" }, - { value: "apac", label: "Asia Pacific" }, - { value: "emea", label: "Europe, Middle East & Africa" }, - ], - defaultValue: "apac", - type: "string", - }, - { - name: "greyscale", - label: "Greyscale", - defaultValue: false, - type: "boolean", - }, - ], - }; - const [applicationSettings, setApplicationSettings] = - useState(initialSettings); - - const handlePropertyChanged = ( - propertyName: string, - value: string | boolean | number - ) => { - setApplicationSettings((currentSettings) => ({ - ...currentSettings, - [propertyName]: value, - })); - }; - - return ( - - - - ); + ApplicationSettingsPanel, + ApplicationProvider, +} from "@finos/vuu-shell"; +import { SettingsSchema } from "packages/vuu-shell/src/application-settings/SettingsForm"; + +import { useState } from "react"; + +let displaySequence = 1; + +// Showcase example showing the current default settings form +export const DefaultApplicationSettingsForm = () => { + const initialSettings = { + themeMode: "light", }; - DefaultApplicationSettingsForm.displaySequence = displaySequence++; - \ No newline at end of file + + const applicationSettingsSchema: SettingsSchema = { + properties: [ + { + name: "themeMode", + label: "Mode", + values: ["light", "dark"], + defaultValue: "light", + type: "string", + }, + ], + }; + const [applicationSettings, setApplicationSettings] = + useState(initialSettings); + + const handlePropertyChanged = (propertyName: string, value: unknown) => { + setApplicationSettings((currentSettings) => ({ + ...currentSettings, + [propertyName]: value, + })); + }; + + return ( + + + + ); +}; +DefaultApplicationSettingsForm.displaySequence = displaySequence++; + + +// Showcase example showing different form controls +export const VariedFormControlApplicationSettingsForm = () => { + const initialSettings = { + themeMode: "light", + dateFormatPattern: "dd/mm/yyyy", + region: "US", + greyscale: false, + }; + + const applicationSettingsSchema: SettingsSchema = { + properties: [ + { + name: "themeMode", + label: "Mode", + values: ["light", "dark"], + defaultValue: "light", + type: "string", + }, + { + name: "dateFormatPattern", + label: "Date Formatting", + values: ["dd/mm/yyyy", "mm/dd/yyyy", "dd MMMM yyyy"], + defaultValue: "dd/mm/yyyy", + type: "string", + }, + { + name: "region", + label: "Region", + values: [ + { value: "us", label: "US" }, + { value: "apac", label: "Asia Pacific" }, + { value: "emea", label: "Europe, Middle East & Africa" }, + ], + defaultValue: "apac", + type: "string", + }, + { + name: "greyscale", + label: "Greyscale", + defaultValue: false, + type: "boolean", + }, + ], + }; + const [applicationSettings, setApplicationSettings] = + useState(initialSettings); + + const handlePropertyChanged = (propertyName: string, value: unknown) => { + setApplicationSettings((currentSettings) => ({ + ...currentSettings, + [propertyName]: value, + })); + }; + + return ( + + + + ); +}; +VariedFormControlApplicationSettingsForm.displaySequence = displaySequence++; +