Skip to content

Commit 39e5b0c

Browse files
authored
Merge pull request #156 from ISISComputingGroup/batched
Batched
2 parents 4e2dd2d + 5feeb44 commit 39e5b0c

19 files changed

+468
-597
lines changed

app/components/Block.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,16 @@ export default function Block({
2424
string | number | undefined
2525
>();
2626
const [showAdvanced, setShowAdvanced] = useState(false);
27+
const [justChanged, setJustChanged] = useState(false);
2728
if (!pv.visible && !showHiddenBlocks) {
2829
return null;
2930
}
3031
if (pv.value != currentValue) {
3132
setCurrentValue(pv.value);
32-
// Let the user know a change has occurred by lighting up the green dot next to the value
33-
const pvChangedIndicator = document.getElementById(
34-
pv.human_readable_name + "_CIRCLE",
35-
);
36-
if (!pvChangedIndicator) return;
37-
if (pvChangedIndicator.classList.contains("text-green-500")) return;
38-
pvChangedIndicator.classList.remove("text-transparent");
39-
pvChangedIndicator.classList.add("text-green-500");
33+
setJustChanged(true);
4034
setTimeout(() => {
41-
pvChangedIndicator.classList.remove("text-green-500");
42-
pvChangedIndicator.classList.add("text-transparent");
43-
}, 2000);
35+
setJustChanged(false);
36+
}, 1000);
4437
}
4538

4639
const minimum_date_to_be_shown = 631152000; // This is what PVWS thinks epoch time is for some reason. don't bother showing it as the instrument wasn't running EPICS on 01/01/1990
@@ -79,7 +72,10 @@ export default function Block({
7972
</span>
8073
<svg
8174
id={pv.human_readable_name + "_CIRCLE"}
82-
className="min-w-2 min-h-2 max-w-2 max-h-2 transition-all text-transparent"
75+
className={
76+
"min-w-2 min-h-2 max-w-2 max-h-2 transition-opacity text-green-500 " +
77+
(justChanged ? "opacity-100" : "opacity-0")
78+
}
8379
xmlns="http://www.w3.org/2000/svg"
8480
fill="currentColor"
8581
viewBox="0 0 24 24"

app/components/CheckToggle.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Dispatch, SetStateAction } from "react";
1+
import { Dispatch, SetStateAction, useCallback } from "react";
2+
import { memo } from "react";
23

3-
export default function CheckToggle({
4+
const CheckToggle = memo(function CheckToggle({
45
checked,
56
setChecked,
67
text,
@@ -11,20 +12,24 @@ export default function CheckToggle({
1112
text: string;
1213
textColour?: string;
1314
}) {
15+
const callback = useCallback(() => {
16+
setChecked(!checked);
17+
}, [checked, setChecked]);
18+
1419
return (
1520
<div className="pt-4">
1621
<label className="inline-flex items-center cursor-pointer">
1722
<input
1823
type="checkbox"
1924
checked={checked}
20-
onChange={() => {
21-
setChecked(!checked);
22-
}}
25+
onChange={callback}
2326
className="sr-only peer"
2427
/>
2528
<div className="relative w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
2629
<span className={"ms-3 text-sm font-medium " + textColour}>{text}</span>
2730
</label>
2831
</div>
2932
);
30-
}
33+
});
34+
35+
export default CheckToggle;

app/components/Group.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import Block from "./Block";
22
import { checkIfAllBlocksInGroupAreHidden } from "./GroupUtils";
33

4-
import { IfcGroup } from "@/app/types";
4+
import { tBlockMapping } from "@/app/types";
5+
import { memo } from "react";
56

6-
export default function Group({
7+
const Group = memo(function Group({
78
group,
9+
blocks,
810
instName,
911
showHiddenBlocks,
1012
}: {
11-
group: IfcGroup;
13+
group: string;
14+
blocks: tBlockMapping;
1215
instName: string;
1316
showHiddenBlocks: boolean;
1417
}) {
@@ -17,14 +20,14 @@ export default function Group({
1720
}
1821

1922
// Check if all the blocks in this group are hidden. If so, hide the group.
20-
if (checkIfAllBlocksInGroupAreHidden(group) && !showHiddenBlocks) {
23+
if (checkIfAllBlocksInGroupAreHidden(blocks) && !showHiddenBlocks) {
2124
return null;
2225
}
2326

2427
return (
2528
<div className="w-full bg-gray-700 shadow-md rounded-xl flex flex-col overflow-x-auto">
2629
<h1 className="p-4 bg-gray-600 rounded-t-lg min-w-full text-white">
27-
{group.name}
30+
{group}
2831
</h1>
2932
<table className="text-sm table-fixed">
3033
<thead className="sticky">
@@ -35,7 +38,7 @@ export default function Group({
3538
</tr>
3639
</thead>
3740
<tbody className="text-gray-200 sticky">
38-
{group.blocks.map((pv) => {
41+
{Array.from(blocks.values()).map((pv) => {
3942
return (
4043
<Block
4144
key={pv.human_readable_name}
@@ -49,4 +52,6 @@ export default function Group({
4952
</table>
5053
</div>
5154
);
52-
}
55+
});
56+
57+
export default Group;

app/components/GroupUtils.test.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
import { checkIfAllBlocksInGroupAreHidden } from "./GroupUtils";
22

3-
import { IfcBlock, IfcGroup } from "@/app/types";
3+
import { tBlockMapping } from "@/app/types";
44

55
test("group with all hidden blocks returns true", () => {
6-
const aHiddenBlock: IfcBlock = { pvaddress: "", visible: false };
7-
let group: IfcGroup = { name: "testing", blocks: [aHiddenBlock] };
8-
const result = checkIfAllBlocksInGroupAreHidden(group);
6+
let blocks: tBlockMapping = new Map();
7+
blocks.set("testing", { pvaddress: "", visible: false });
8+
const result = checkIfAllBlocksInGroupAreHidden(blocks);
99
expect(result).toBe(true);
1010
});
1111

12-
test("group with all visible blocks returns true", () => {
13-
let group: IfcGroup = {
14-
name: "testing",
15-
blocks: [{ pvaddress: "", visible: true }],
16-
};
17-
const result = checkIfAllBlocksInGroupAreHidden(group);
12+
test("group with all visible blocks returns false", () => {
13+
let blocks: tBlockMapping = new Map();
14+
blocks.set("testing", { pvaddress: "testing", visible: true });
15+
const result = checkIfAllBlocksInGroupAreHidden(blocks);
1816
expect(result).toBe(false);
1917
});
2018

21-
test("group with mixed visible blocks returns true", () => {
22-
let group: IfcGroup = {
23-
name: "testing",
24-
blocks: [
25-
{ pvaddress: "", visible: false },
26-
{ pvaddress: "", visible: true },
27-
],
28-
};
29-
const result = checkIfAllBlocksInGroupAreHidden(group);
19+
test("group with mixed visible blocks returns false", () => {
20+
let blocks: tBlockMapping = new Map();
21+
blocks.set("block1", { pvaddress: "block1", visible: false });
22+
blocks.set("block2", { pvaddress: "block2", visible: true });
23+
const result = checkIfAllBlocksInGroupAreHidden(blocks);
3024
expect(result).toBe(false);
3125
});

app/components/GroupUtils.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { IfcGroup } from "@/app/types";
1+
import { tBlockMapping } from "@/app/types";
22

3-
export function checkIfAllBlocksInGroupAreHidden(group: IfcGroup): boolean {
4-
return group.blocks.map((block) => block.visible).every((v) => v === false);
3+
export function checkIfAllBlocksInGroupAreHidden(
4+
blocks: tBlockMapping,
5+
): boolean {
6+
return Array.from(blocks.values()).every((block) => block.visible === false);
57
}

app/components/Groups.test.tsx

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
11
import { render } from "@testing-library/react";
22
import Groups from "@/app/components/Groups";
3-
import { IfcGroup } from "@/app/types";
3+
import { tBlockMapping, tGroups } from "@/app/types";
44

55
it("renders groups correctly with hidden and non hidden groups", () => {
6-
const shownGroupWithTwoBlocks: IfcGroup = {
7-
name: "group1",
8-
blocks: [
9-
{
10-
pvaddress: "A:SHOWN:BLOCK",
11-
human_readable_name: "aShownBlock",
12-
value: 2.344,
13-
visible: true,
14-
},
15-
{
16-
pvaddress: "ADIFF:SHOWN:BLOCK",
17-
human_readable_name: "aDifferentShownBlock",
18-
value: 3.14,
19-
visible: true,
20-
},
21-
],
22-
};
23-
const hiddenGroupWithOneBlock: IfcGroup = {
24-
name: "group2",
25-
blocks: [
26-
{
27-
pvaddress: "A:HIDDEN:BLOCK",
28-
human_readable_name: "aHiddenBlock",
29-
visible: false,
30-
},
31-
],
32-
};
6+
let groups: tGroups = new Map();
7+
let blocksForGroup1: tBlockMapping = new Map();
8+
blocksForGroup1.set("A:SHOWN:BLOCK", {
9+
pvaddress: "A:SHOWN:BLOCK",
10+
human_readable_name: "aShownBlock",
11+
value: 2.344,
12+
visible: true,
13+
});
14+
blocksForGroup1.set("ADIFF:SHOWN:BLOCK", {
15+
pvaddress: "ADIFF:SHOWN:BLOCK",
16+
human_readable_name: "aDifferentShownBlock",
17+
value: 3.14,
18+
visible: true,
19+
});
20+
groups.set("group1", blocksForGroup1);
21+
22+
let blocksForGroup2: tBlockMapping = new Map();
23+
blocksForGroup2.set("A:HIDDEN:BLOCK", {
24+
pvaddress: "A:HIDDEN:BLOCK",
25+
human_readable_name: "aHiddenBlock",
26+
visible: false,
27+
});
28+
groups.set("group2", blocksForGroup2);
29+
3330
const { container } = render(
34-
<Groups
35-
instName={"TESTING"}
36-
showHiddenBlocks={false}
37-
groupsMap={[shownGroupWithTwoBlocks, hiddenGroupWithOneBlock]}
38-
/>,
31+
<Groups instName={"TESTING"} showHiddenBlocks={false} groupsMap={groups} />,
3932
);
4033
expect(container).toMatchSnapshot();
4134
});

app/components/Groups.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import Group from "./Group";
2-
3-
import { IfcGroup } from "@/app/types";
2+
import { tGroups } from "@/app/types";
43

54
export default function Groups({
65
groupsMap,
76
instName,
87
showHiddenBlocks,
98
}: {
10-
groupsMap: Array<IfcGroup>;
9+
groupsMap: tGroups;
1110
instName: string;
1211
showHiddenBlocks: boolean;
1312
}) {
1413
return (
1514
<div className="rounded-xl grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 mt-2">
16-
{groupsMap.map((group) => {
15+
{Array.from(groupsMap.entries()).map(([group, blocks]) => {
1716
return (
1817
<Group
19-
key={group.name}
18+
key={group}
2019
group={group}
20+
blocks={blocks}
2121
instName={instName}
2222
showHiddenBlocks={showHiddenBlocks}
2323
/>

0 commit comments

Comments
 (0)