optimizations

This commit is contained in:
proddy
2025-10-31 18:38:38 +01:00
parent ca1506de8b
commit 6b7534b7fb
19 changed files with 967 additions and 624 deletions

View File

@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useBlocker } from 'react-router';
import { toast } from 'react-toastify';
@@ -35,6 +35,10 @@ import { DeviceValueTypeNames, DeviceValueUOM_s } from './types';
import type { Entities, EntityItem } from './types';
import { entityItemValidation } from './validators';
const MIN_ID = -100;
const MAX_ID = 100;
const ICON_SIZE = 12;
const CustomEntities = () => {
const { LL } = useI18nContext();
const [numChanges, setNumChanges] = useState<number>(0);
@@ -53,18 +57,20 @@ const CustomEntities = () => {
initialData: []
});
useInterval(() => {
const intervalCallback = useCallback(() => {
if (!dialogOpen && !numChanges) {
void fetchEntities();
}
});
}, [dialogOpen, numChanges, fetchEntities]);
useInterval(intervalCallback);
const { send: writeEntities } = useRequest(
(data: Entities) => writeCustomEntities(data),
{ immediate: false }
);
function hasEntityChanged(ei: EntityItem) {
const hasEntityChanged = useCallback((ei: EntityItem) => {
return (
ei.id !== ei.o_id ||
ei.ram !== ei.o_ram ||
@@ -80,19 +86,21 @@ const CustomEntities = () => {
ei.deleted !== ei.o_deleted ||
(ei.value || '') !== (ei.o_value || '')
);
}
}, []);
const entity_theme = useTheme({
Table: `
const entity_theme = useMemo(
() =>
useTheme({
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(60px, 1fr)) minmax(80px, auto) 80px 80px 80px 120px;
`,
BaseRow: `
BaseRow: `
font-size: 14px;
.td {
height: 32px;
}
`,
BaseCell: `
BaseCell: `
&:nth-of-type(1) {
padding: 8px;
}
@@ -112,7 +120,7 @@ const CustomEntities = () => {
text-align: center;
}
`,
HeaderRow: `
HeaderRow: `
text-transform: uppercase;
background-color: black;
color: #90CAF9;
@@ -121,7 +129,7 @@ const CustomEntities = () => {
height: 36px;
}
`,
Row: `
Row: `
background-color: #1e1e1e;
position: relative;
cursor: pointer;
@@ -132,9 +140,11 @@ const CustomEntities = () => {
background-color: #177ac9;
}
`
});
}),
[]
);
const saveEntities = async () => {
const saveEntities = useCallback(async () => {
await writeEntities({
entities: entities
.filter((ei: EntityItem) => !ei.deleted)
@@ -163,7 +173,7 @@ const CustomEntities = () => {
await fetchEntities();
setNumChanges(0);
});
};
}, [entities, writeEntities, LL, fetchEntities]);
const editEntityItem = useCallback((ei: EntityItem) => {
setCreating(false);
@@ -171,36 +181,39 @@ const CustomEntities = () => {
setDialogOpen(true);
}, []);
const onDialogClose = () => {
const onDialogClose = useCallback(() => {
setDialogOpen(false);
};
}, []);
const onDialogCancel = async () => {
const onDialogCancel = useCallback(async () => {
await fetchEntities().then(() => {
setNumChanges(0);
});
};
}, [fetchEntities]);
const onDialogSave = (updatedItem: EntityItem) => {
setDialogOpen(false);
void updateState(readCustomEntities(), (data: EntityItem[]) => {
const new_data = creating
? [
...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id),
updatedItem
]
: data.map((ei) =>
ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei
);
setNumChanges(new_data.filter((ei) => hasEntityChanged(ei)).length);
return new_data;
});
};
const onDialogSave = useCallback(
(updatedItem: EntityItem) => {
setDialogOpen(false);
void updateState(readCustomEntities(), (data: EntityItem[]) => {
const new_data = creating
? [
...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id),
updatedItem
]
: data.map((ei) =>
ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei
);
setNumChanges(new_data.filter((ei) => hasEntityChanged(ei)).length);
return new_data;
});
},
[creating, hasEntityChanged]
);
const onDialogDup = (item: EntityItem) => {
const onDialogDup = useCallback((item: EntityItem) => {
setCreating(true);
setSelectedEntityItem({
id: Math.floor(Math.random() * (Math.floor(200) - 100) + 100),
id: Math.floor(Math.random() * (MAX_ID - MIN_ID) + MIN_ID),
name: item.name + '_',
ram: item.ram,
device_id: item.device_id,
@@ -215,12 +228,12 @@ const CustomEntities = () => {
value: item.value
});
setDialogOpen(true);
};
}, []);
const addEntityItem = () => {
const addEntityItem = useCallback(() => {
setCreating(true);
setSelectedEntityItem({
id: Math.floor(Math.random() * (Math.floor(200) - 100) + 100),
id: Math.floor(Math.random() * (MAX_ID - MIN_ID) + MIN_ID),
name: '',
ram: 0,
device_id: '0',
@@ -235,22 +248,30 @@ const CustomEntities = () => {
value: ''
});
setDialogOpen(true);
};
}, []);
function formatValue(value: unknown, uom: number) {
const formatValue = useCallback((value: unknown, uom: number) => {
return value === undefined
? ''
: typeof value === 'number'
? new Intl.NumberFormat().format(value) +
(uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: (value as string) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
}
(uom === 0 ? '' : ` ${DeviceValueUOM_s[uom]}`)
: `${value as string}${uom === 0 ? '' : ` ${DeviceValueUOM_s[uom]}`}`;
}, []);
function showHex(value: number, digit: number) {
return '0x' + value.toString(16).toUpperCase().padStart(digit, '0');
}
const showHex = useCallback((value: number, digit: number) => {
return `0x${value.toString(16).toUpperCase().padStart(digit, '0')}`;
}, []);
const renderEntity = () => {
const filteredAndSortedEntities = useMemo(
() =>
entities
?.filter((ei: EntityItem) => !ei.deleted)
.sort((a: EntityItem, b: EntityItem) => a.name.localeCompare(b.name)) ?? [],
[entities]
);
const renderEntity = useCallback(() => {
if (!entities) {
return (
<FormLoader onRetry={fetchEntities} errorMessage={error?.message || ''} />
@@ -260,9 +281,7 @@ const CustomEntities = () => {
return (
<Table
data={{
nodes: entities
.filter((ei: EntityItem) => !ei.deleted)
.sort((a: EntityItem, b: EntityItem) => a.name.localeCompare(b.name))
nodes: filteredAndSortedEntities
}}
theme={entity_theme}
layout={{ custom: true }}
@@ -285,7 +304,10 @@ const CustomEntities = () => {
<Cell>
{ei.name}&nbsp;
{ei.writeable && (
<EditOutlinedIcon color="primary" sx={{ fontSize: 12 }} />
<EditOutlinedIcon
color="primary"
sx={{ fontSize: ICON_SIZE }}
/>
)}
</Cell>
<Cell>
@@ -304,7 +326,17 @@ const CustomEntities = () => {
)}
</Table>
);
};
}, [
entities,
error,
fetchEntities,
entity_theme,
editEntityItem,
LL,
filteredAndSortedEntities,
showHex,
formatValue
]);
return (
<SectionContent>