Skip to content

Commit

Permalink
Implement system settings data flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mairas committed Feb 2, 2024
1 parent 6b73e0d commit 50cedb3
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 47 deletions.
46 changes: 46 additions & 0 deletions web/mock/api-config.mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { JsonObject } from 'common/jsonTypes';
import { defineMock } from 'vite-plugin-mock-dev-server'

let hostname = "localhost";
let authenticationSettings: JsonObject = {
"authEnabled": false,
"username": "",
"password": ""
};

export default defineMock(
[
{
Expand Down Expand Up @@ -29,6 +37,44 @@ export default defineMock(
},
delay: 600,
},
{
url: '/api/config/system/hostname',
response(req, resp) {
if (req.method === 'GET') {
const doc = {
"config": {
"value": hostname
},
"schema": {},
"description": "The hostname of the device."
};
resp.end(JSON.stringify(doc));
} else if (req.method === 'POST') {
const doc = req.body;
console.log(doc);
hostname = doc.value;
resp.end();
}
}
},
{
url: '/api/config/system/authentication',
response(req, resp) {
if (req.method === 'GET') {
const doc = {
"config": authenticationSettings,
"schema": {},
"description": "Auth."
};
resp.end(JSON.stringify(doc));
} else if (req.method === 'POST') {
const doc = req.body;
console.log(doc);
authenticationSettings = doc;
resp.end();
}
}
},
{
url: '/api/config/System/WiFi Settings',
method: 'GET',
Expand Down
5 changes: 4 additions & 1 deletion web/src/common/configAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export async function saveConfigData(
data: string,
errorHandler: (e: Error) => void,
contentType: string = "application/json",
): Promise<void> {
): Promise<boolean> {
try {
const response = await fetch(APP_CONFIG.config_path + path, {
method: "POST",
Expand All @@ -59,8 +59,11 @@ export async function saveConfigData(
});
if (!response.ok) {
errorHandler(Error(`HTTP Error ${response.status} ${response.statusText}`));
return false;
}
} catch (e) {
errorHandler(Error(`Error saving config data to server: ${e.message}`));
return false;
}
return true;
}
29 changes: 3 additions & 26 deletions web/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ interface FormInputProps {
step?: number;
disabled?: boolean;
checked?: boolean;
onchange?: (e: JSX.TargetedEvent<HTMLInputElement, Event>) => void;
onInput?: (e: JSX.TargetedEvent<HTMLInputElement|HTMLTextAreaElement, Event>) => void;
}

export function FormInput(props: FormInputProps): JSX.Element {
const { isInputDirty, setInputDirty } =
useContext<InputDirtyContextType>(InputDirtyContext);

return (
<div>
<label className="form-label" htmlFor={props.id}>
Expand All @@ -31,13 +30,11 @@ export function FormInput(props: FormInputProps): JSX.Element {
{props.as === "textarea" ? (
<textarea
className="form-control"
onChange={() => setInputDirty(true)}
{...props}
/>
) : (
<input
className="form-control"
onChange={() => setInputDirty(true)}
{...props}
/>
)}
Expand All @@ -51,14 +48,11 @@ interface FormFloatInputProps {
}

export function FormFloatInput(props: FormFloatInputProps): JSX.Element {
const { isInputDirty, setInputDirty } =
useContext<InputDirtyContextType>(InputDirtyContext);

return (
<div className="form-floating mb-3">
<input
className="form-control"
onChange={() => setInputDirty(true)}
{...props}
/>
<label className="form-label" htmlFor={props.id}>
Expand All @@ -75,8 +69,6 @@ interface FormSelectProps {
}

export function FormSelect(props: FormSelectProps): JSX.Element {
const { isInputDirty, setInputDirty } =
useContext<InputDirtyContextType>(InputDirtyContext);

return (
<div className="mb-3">
Expand All @@ -85,7 +77,6 @@ export function FormSelect(props: FormSelectProps): JSX.Element {
</label>
<select
className="form-select"
onChange={() => setInputDirty(true)}
{...props}
/>
{props.children}
Expand All @@ -99,18 +90,15 @@ interface FormCheckProps {
type: string;
checked: boolean;
label: string;
onchange: (e: JSX.TargetedEvent<HTMLInputElement, Event>) => void;
handleValueChange: (value: string) => void;
}

export function FormCheck(props: FormCheckProps): JSX.Element {
const { isInputDirty, setInputDirty } =
useContext<InputDirtyContextType>(InputDirtyContext);

return (
<div className="form-check">
<input
className="form-check-input"
onChange={() => setInputDirty(true)}
{...props}
/>
<label className="form-check-label" htmlFor={props.id}>
Expand All @@ -123,17 +111,6 @@ export function FormCheck(props: FormCheckProps): JSX.Element {
export function FormSwitch(
props: JSX.IntrinsicAttributes & JSX.HTMLAttributes<HTMLInputElement>,
): JSX.Element {
const { isInputDirty, setInputDirty } =
useContext<InputDirtyContextType>(InputDirtyContext);

// Extend props.onChange (if it exists) to set the dirty flag
if (props.onChange) {
const onChange = props.onChange;
props.onChange = (e) => {
setInputDirty(true);
onChange(e);
};
}

return (
<div className="form-check form-switch mb-3">
Expand Down
6 changes: 3 additions & 3 deletions web/src/pages/Configuration/ConfigCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@ export function ConfigCard({ path }: ConfigCardProps): JSX.Element | null {
}
}, [config, path]);

async function handleSave(e): Promise<void> {
async function handleSave(e: MouseEvent): Promise<void> {
e.preventDefault();
setSaving(true);
await saveConfigData(path, JSON.stringify(config), (e) => {
console.log("Error saving config data", e);
setIsDirty(true);
setHttpErrorText(e);
setHttpErrorText(e.message);
});
setIsDirty(false);
setSaving(false);
Expand Down Expand Up @@ -214,7 +214,7 @@ export function ConfigCard({ path }: ConfigCardProps): JSX.Element | null {
<button
className="btn btn-primary"
type="submit"
onClick={(e) => {
onClick={(e: MouseEvent): void => {
void handleSave(e);
}}
disabled={saving || !isDirty}
Expand Down
Loading

0 comments on commit 50cedb3

Please sign in to comment.