Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"dependencies": {
"@mantine/dates": "^8.0.1",
"@mantine/notifications": "^7.17.3",
"@next/swc-darwin-arm64": "15.3.4",
"esbuild": "^0.23.0",
"uuid": "^11.0.5"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import type I_PIS from "@/objects/PIS/PIS.interface";

function BottomInformationContainer() {
const { currentAppState, setCurrentAppState } = useAppState();
const { battery, motor, mppt } = usePIS();
const dataArray = [battery, motor, mppt].filter(
const { battery, mbms, motor, mppt } = usePIS();
const dataArray = [battery, motor, mppt, mbms].filter(
(data) => data !== undefined,
) as I_PIS[];
const lookupTable = useFavouriteLookupTable(dataArray);
Expand All @@ -28,6 +28,18 @@ function BottomInformationContainer() {
[currentAppState, favourites],
);

const formatPathLabel = (path: string) =>
path
.split(".")
.map(
(segment) =>
segment
.replace(/([a-z])([A-Z])/g, "$1 $2") // lowerUpper → lower Upper
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2") // ABCDef → ABC Def
.replace(/([a-zA-Z])(\d)/g, "$1 $2"), // Unit3 → Unit 3
)
.join(" "); // use " " or " →" or " / " if preferred

return (
<div className="align-middle">
<div className="flex h-full flex-row flex-wrap justify-evenly gap-4 pt-1 text-center text-base md:gap-2 2xl:text-xl">
Expand All @@ -37,7 +49,7 @@ function BottomInformationContainer() {
className="text-xs hover:cursor-pointer 2xl:text-sm"
onClick={() => handleRemoveFavourite(favourite)}
>
{favourite}
{formatPathLabel(favourite)}
</div>
<div className="text-helios">
{/*Search for the value associated with the favourite name string in the lookupTable */
Expand Down
49 changes: 33 additions & 16 deletions packages/client/src/components/transformers/PISTransformer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,31 @@ function FieldDataFormatter(props: FieldDataFormatterProps): JSX.Element {

type FieldPrinterProps = {
field: I_PISField;
fieldPath: string;
};

function FieldPrinter(props: FieldPrinterProps): JSX.Element {
const { setCurrentAppState } = useAppState();
const { field } = props;
const { field, fieldPath } = props;

const handleAddToFavourites = useCallback(() => {
const storedFavourites = localStorage.getItem("favourites");
const parsedFavourites: string[] = storedFavourites
? (JSON.parse(storedFavourites) as string[])
: [];

if (
!parsedFavourites.some((fav) => fav === field.name) &&
typeof field.name === "string"
) {
if (parsedFavourites.length === 8 && typeof field.name === "string") {
if (!parsedFavourites.includes(fieldPath)) {
if (parsedFavourites.length === 8) {
parsedFavourites.shift();
}
parsedFavourites.push(field.name);
parsedFavourites.push(fieldPath);
setCurrentAppState((prev) => ({
...prev,
favourites: parsedFavourites,
}));
localStorage.setItem("favourites", JSON.stringify(parsedFavourites));
}
}, [field.name, setCurrentAppState]);
}, [fieldPath, setCurrentAppState]);

if (
field.fstring !== undefined &&
Expand Down Expand Up @@ -151,10 +149,11 @@ function FieldPrinter(props: FieldPrinterProps): JSX.Element {
type FieldsPrinterProps = {
fields: I_PISField[];
depth?: number;
basePath: string; // NEW
};

function FieldsPrinter(props: FieldsPrinterProps): JSX.Element {
const { depth = 0, fields } = props;
const { basePath, depth = 0, fields } = props;
const isFullscreen = useFullscreen();

// get the max height class based on depth, but only do this if not in fullscreen
Expand All @@ -170,30 +169,39 @@ function FieldsPrinter(props: FieldsPrinterProps): JSX.Element {
className={`block overflow-x-hidden md:grid md:grid-cols-3 md:gap-x-2 lg:block lg:overflow-x-hidden ${getMaxHeightClass()}`}
>
{fields.map((field, index) => (
<FieldPrinter field={field} key={index} />
<FieldPrinter
field={field}
fieldPath={`${basePath}.${field.name}`}
key={index}
/>
))}
</div>
);
}

type PIStransformerProps = {
root: I_PIS;
depth?: number;
path?: string[];
};

function PISTransformer(props: PIStransformerProps): JSX.Element {
const { depth = 0, root } = props;
const { depth = 0, path = [], root } = props;

const formatKey = (key: string): string => {
return key
.replace(/([a-z])([A-Z])/g, "$1 $2") // Add space between lowercase and uppercase
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2") // Add space between consecutive uppercase followed by lowercase
.replace(/([a-zA-Z])(\d)/g, "$1 $2"); // Add space between letters and numbers
.replace(/([a-z])([A-Z])/g, "$1 $2")
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
.replace(/([a-zA-Z])(\d)/g, "$1 $2");
};

return (
root && (
<div className="flex size-full flex-col gap-x-2 lg:h-[375px] lg:flex-wrap xl:h-[350px]">
{Object.keys(root).map((key, index) => {
const value = root[key];
const newPath = [...path, key]; // Track path

return (
<div className={`flex flex-col`} id={key} key={index}>
<div className="flex w-full items-center justify-evenly border-b-2 border-helios">
Expand All @@ -205,10 +213,19 @@ function PISTransformer(props: PIStransformerProps): JSX.Element {
{formatKey(key)}
</p>
</div>

{Array.isArray(value) ? (
<FieldsPrinter depth={depth + 1} fields={value} />
<FieldsPrinter
basePath={newPath.join(".")}
depth={depth + 1}
fields={value}
/>
) : (
<PISTransformer depth={depth + 1} root={value as I_PIS} />
<PISTransformer
depth={depth + 1}
path={newPath}
root={value as I_PIS}
/>
)}
</div>
);
Expand Down
58 changes: 29 additions & 29 deletions packages/client/src/hooks/favouriteLookupTable.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
import { useMemo } from "react";

import I_PIS from "@/objects/PIS/PIS.interface";
import I_PIS, { I_PISField } from "@/objects/PIS/PIS.interface";

export const useFavouriteLookupTable = (
dataArray: I_PIS[],
): Record<string, () => string | number | undefined> => {
return useMemo(() => {
const table: Record<string, () => string | number | undefined> = {};

for (const data of dataArray) {
if (!data) continue;

const flatten = (obj: I_PIS, prefix = "") => {
for (const key in obj) {
const value = obj[key];
const path = prefix ? `${prefix}.${key}` : key;
const extractFields = (node: unknown, path: string[] = []) => {
if (!node || typeof node !== "object") return;

if (
value !== null &&
typeof value === "object" &&
!Array.isArray(value)
) {
flatten(value, path);
} else {
table[path] = () => {
if (Array.isArray(value)) return undefined;
if (typeof value === "boolean") return value ? "T" : "F";
if (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "undefined"
)
return value;
return undefined;
};
}
// If node is an array of I_PISField
if (
Array.isArray(node) &&
node.length &&
typeof node[0] === "object" &&
"name" in node[0] &&
"data" in node[0]
) {
for (const field of node as I_PISField[]) {
if (!field?.name) continue;
const fullPath = [...path, field.name].join(".");
table[fullPath] = () => {
const value = field.data?.[0]?.value;
if (typeof value === "boolean") return value ? "T" : "F";
return value;
};
}
};
return;
}

flatten(data);
// Traverse nested properties
for (const key of Object.keys(node)) {
extractFields((node as Record<string, unknown>)[key], [...path, key]);
}
};

for (const data of dataArray) {
extractFields(data);
}

return table;
Expand Down
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7734,6 +7734,14 @@ __metadata:
languageName: node
linkType: hard

"@next/swc-darwin-arm64@npm:15.3.4":
version: 15.3.4
resolution: "@next/swc-darwin-arm64@npm:15.3.4"
checksum: 10c0/538f192270cf4b7b8a7db387da7c83026c72ae427891efebc9fe7cd6e1d6243f74a2f5524c2b5f5031c4594a71b73e4fbe78d2a3eba3d43bc4bb30895d08d8b3
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard

"@next/swc-darwin-x64@npm:15.1.4":
version: 15.1.4
resolution: "@next/swc-darwin-x64@npm:15.1.4"
Expand Down Expand Up @@ -22360,6 +22368,7 @@ __metadata:
dependencies:
"@mantine/dates": "npm:^8.0.1"
"@mantine/notifications": "npm:^7.17.3"
"@next/swc-darwin-arm64": "npm:15.3.4"
"@types/eslint": "npm:^9.6.0"
"@typescript-eslint/eslint-plugin": "npm:^7.4.0"
"@typescript-eslint/parser": "npm:^7.4.0"
Expand Down