Browse Source

Add override button to form

Malte Grimm 3 years ago
parent
commit
0501276855
  1. 34
      src/components/Form/DynamicForm.tsx
  2. 17
      src/components/Form/FormWrapper.tsx
  3. 17
      src/components/PageComponents/Config/Device.tsx
  4. 2
      src/components/PageComponents/Config/Position.tsx
  5. 1
      src/core/stores/appStore.ts
  6. 11
      src/core/stores/deviceStore.ts

34
src/components/Form/DynamicForm.tsx

@ -11,6 +11,12 @@ import { Subtle } from "@components/UI/Typography/Subtle.js";
import { DynamicFormField, FieldProps } from "./DynamicFormField.js";
import { FieldWrapper } from "./FormWrapper.js";
import { Button } from "../UI/Button.js";
import { useState } from "react";
export interface EnableSwitchData {
getEnabled: (name: string) => boolean;
setEnabled: (name: string, value: boolean) => void;
}
interface DisabledBy<T> {
fieldName: Path<T>;
@ -37,6 +43,7 @@ export interface DynamicFormProps<T extends FieldValues> {
submitType?: "onChange" | "onSubmit";
hasSubmitButton?: boolean;
defaultValues?: DeepPartial<T>;
enableSwitch?: EnableSwitchData;
fieldGroups: {
label: string;
description: string;
@ -49,6 +56,7 @@ export function DynamicForm<T extends FieldValues>({
submitType = "onChange",
hasSubmitButton,
defaultValues,
enableSwitch,
fieldGroups
}: DynamicFormProps<T>) {
const { handleSubmit, control, getValues } = useForm<T>({
@ -89,16 +97,22 @@ export function DynamicForm<T extends FieldValues>({
<Subtle>{fieldGroup.description}</Subtle>
</div>
{fieldGroup.fields.map((field, index) => (
<FieldWrapper label={field.label} description={field.description}>
<DynamicFormField
key={index}
field={field}
control={control}
disabled={isDisabled(field.disabledBy)}
/>
</FieldWrapper>
))}
{fieldGroup.fields.map((field, index) => {
const [ enableSwitchState, setEnableSwitchState ] = useState(enableSwitch?.getEnabled(field.name));
return (
<FieldWrapper label={field.label} description={field.description} enableSwitchEnabled={enableSwitchState} onEnableSwitchChanged={(value) => {
enableSwitch?.setEnabled(field.name, value);
setEnableSwitchState(value);
}}>
<DynamicFormField
key={index}
field={field}
control={control}
disabled={isDisabled(field.disabledBy) || enableSwitchState == false}
/>
</FieldWrapper>
);
})}
</div>
))}
{hasSubmitButton && <Button type="submit">Submit</Button>}

17
src/components/Form/FormWrapper.tsx

@ -1,22 +1,37 @@
import { Label } from "../UI/Label.js";
import { ErrorMessage } from "@hookform/error-message";
import { Switch } from "../UI/Switch.js";
export interface FieldWrapperProps {
label: string;
description?: string;
disabled?: boolean;
enableSwitchEnabled?: boolean;
onEnableSwitchChanged?: (value: boolean) => void;
children?: React.ReactNode;
}
export const FieldWrapper = ({
label,
description,
enableSwitchEnabled,
onEnableSwitchChanged,
children
}: FieldWrapperProps): JSX.Element => (
<div className="pt-6 sm:pt-5">
<div role="group" aria-labelledby="label-notifications">
<div className="sm:grid sm:grid-cols-3 sm:items-baseline sm:gap-4">
<Label>{label}</Label>
<div className="sm:col-span-1">
<Label>{label}</Label>
{enableSwitchEnabled !== undefined && (
<div className="mt-4 space-y-4">
<Switch
defaultChecked={enableSwitchEnabled}
onCheckedChange={onEnableSwitchChanged}
/>
</div>
)}
</div>
<div className="sm:col-span-2">
<div className="max-w-lg">
<p className="text-sm text-gray-500">{description}</p>

17
src/components/PageComponents/Config/Device.tsx

@ -1,11 +1,21 @@
import type { DeviceValidation } from "@app/validation/config/device.js";
import { useConfig, useDevice } from "@core/stores/deviceStore.js";
import { Protobuf } from "@meshtastic/meshtasticjs";
import { DynamicForm } from "@components/Form/DynamicForm.js";
import { DynamicForm, EnableSwitchData } from "@components/Form/DynamicForm.js";
export const Device = (): JSX.Element => {
//const { config, setWorkingConfig } = useDevice();
const config = useConfig();
const config = useConfig();
debugger;
const enableSwitch: EnableSwitchData | undefined = config.overrideValues ? {
getEnabled(name) {
return config.overrideValues![name] ?? false;
},
setEnabled(name, value) {
config.overrideValues![name] = value;
},
} : undefined;
const onSubmit = (data: DeviceValidation) => {
// setWorkingConfig(
@ -21,7 +31,8 @@ export const Device = (): JSX.Element => {
return (
<DynamicForm<DeviceValidation>
onSubmit={onSubmit}
defaultValues={config.device}
defaultValues={config.config.device}
enableSwitch={enableSwitch}
fieldGroups={[
{
label: "Device Settings",

2
src/components/PageComponents/Config/Position.tsx

@ -21,7 +21,7 @@ export const Position = (): JSX.Element => {
return (
<DynamicForm<PositionValidation>
onSubmit={onSubmit}
defaultValues={config.position}
defaultValues={config.config.position}
fieldGroups={[
{
label: "Position settings",

1
src/core/stores/appStore.ts

@ -22,6 +22,7 @@ export type accentColor =
export class ConfigPreset {
public children: ConfigPreset[] = [];
public count: number = 0;
public overrideValues: {[fieldName: string]: boolean} = {};
public constructor(public name: string, public parent?: ConfigPreset, public config : Protobuf.LocalConfig = new Protobuf.LocalConfig()) {
if(config.device === undefined)

11
src/core/stores/deviceStore.ts

@ -596,7 +596,12 @@ export const useDevice = (): Device => {
return context;
};
export const useConfig = (): Protobuf.LocalConfig => {
interface ConfigProvider {
config: Protobuf.LocalConfig;
overrideValues?: {[fieldName: string]: boolean};
}
export const useConfig = (): ConfigProvider => {
const context = useContext(DeviceContext);
if(context == undefined) {
const {configPresetRoot, configPresetSelected } = useAppStore();
@ -606,7 +611,7 @@ export const useConfig = (): Protobuf.LocalConfig => {
}
else
console.log(`No preset selected; Displaying root preset. (${configPresetRoot.config.device?.buttonGpio})`);
return (configPresetSelected ?? configPresetRoot).config; // TEMP
return (configPresetSelected ?? configPresetRoot); // TEMP
}
return context.config;
return context;
};
Loading…
Cancel
Save