Skip to content

Commit f04bdc4

Browse files
committed
add toggle for showing SP, fix layout, use SP:RBV, refactor toggle and add tests
1 parent 103cccf commit f04bdc4

File tree

10 files changed

+159
-68
lines changed

10 files changed

+159
-68
lines changed

app/components/Block.test.tsx

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ it("renders topbar unchanged", () => {
2020
};
2121
const instName = "Instrument";
2222
const { container } = render(
23-
<Block pv={aBlock} instName={instName} showHiddenBlocks={false} />,
23+
<Block
24+
pv={aBlock}
25+
instName={instName}
26+
showHiddenBlocks={false}
27+
showSetpoints={false}
28+
/>,
2429
{
2530
container: tableBody,
2631
},
@@ -31,7 +36,12 @@ it("renders topbar unchanged", () => {
3136
it("renders nothing if pv is hidden", () => {
3237
const aBlock: IfcBlock = { pvaddress: "SOME:PV", visible: false };
3338
const { container } = render(
34-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
39+
<Block
40+
pv={aBlock}
41+
instName={""}
42+
showHiddenBlocks={false}
43+
showSetpoints={false}
44+
/>,
3545
{
3646
container: tableBody,
3747
},
@@ -46,7 +56,12 @@ it("renders block with correct name", () => {
4656
human_readable_name: "MyBlock",
4757
};
4858
const { container } = render(
49-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
59+
<Block
60+
pv={aBlock}
61+
instName={""}
62+
showHiddenBlocks={false}
63+
showSetpoints={false}
64+
/>,
5065
{
5166
container: tableBody,
5267
},
@@ -65,7 +80,12 @@ it("renders block with run control that is in range as a tick", () => {
6580
runcontrol_enabled: true,
6681
};
6782
const { container } = render(
68-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
83+
<Block
84+
pv={aBlock}
85+
instName={""}
86+
showHiddenBlocks={false}
87+
showSetpoints={false}
88+
/>,
6989
{
7090
container: tableBody,
7191
},
@@ -85,7 +105,12 @@ it("renders block with run control that is not in range as a cross", () => {
85105
runcontrol_enabled: true,
86106
};
87107
const { container } = render(
88-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
108+
<Block
109+
pv={aBlock}
110+
instName={""}
111+
showHiddenBlocks={false}
112+
showSetpoints={false}
113+
/>,
89114
{
90115
container: tableBody,
91116
},
@@ -105,7 +130,12 @@ it("renders block without run control without tick or cross", () => {
105130
runcontrol_enabled: false,
106131
};
107132
const { container } = render(
108-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
133+
<Block
134+
pv={aBlock}
135+
instName={""}
136+
showHiddenBlocks={false}
137+
showSetpoints={false}
138+
/>,
109139
{
110140
container: tableBody,
111141
},
@@ -129,14 +159,19 @@ it("renders block with SP and shows SP value", () => {
129159
value: expectedValue,
130160
};
131161
const { container } = render(
132-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
162+
<Block
163+
pv={aBlock}
164+
instName={""}
165+
showHiddenBlocks={false}
166+
showSetpoints={true}
167+
/>,
133168
{
134169
container: tableBody,
135170
},
136171
);
137172
expect(
138173
container.querySelector(`#${aBlock.human_readable_name}_VALUE`)!.innerHTML,
139-
).toContain(`${expectedValue} (SP: ${expectedSpValue})`);
174+
).toContain(`${expectedValue} <br>(SP: ${expectedSpValue})`);
140175
});
141176

142177
it("renders block without SP and hides SP value", () => {
@@ -149,14 +184,23 @@ it("renders block without SP and hides SP value", () => {
149184
runcontrol_inrange: false,
150185
runcontrol_enabled: false,
151186
value: expectedValue,
187+
sp_value: expectedSpValue,
152188
};
153189
const { container } = render(
154-
<Block pv={aBlock} instName={""} showHiddenBlocks={false} />,
190+
<Block
191+
pv={aBlock}
192+
instName={""}
193+
showHiddenBlocks={false}
194+
showSetpoints={false}
195+
/>,
155196
{
156197
container: tableBody,
157198
},
158199
);
159-
expect(
160-
container.querySelector(`#${aBlock.human_readable_name}_VALUE`)!.innerHTML,
161-
).toContain(`${expectedValue} `);
200+
201+
const valueLabel = container.querySelector(
202+
`#${aBlock.human_readable_name}_VALUE`,
203+
)!.innerHTML;
204+
expect(valueLabel).toContain(`${expectedValue} `);
205+
expect(valueLabel).not.toContain(`${expectedSpValue}`);
162206
});

app/components/Block.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ export default function Block({
99
pv,
1010
instName,
1111
showHiddenBlocks,
12+
showSetpoints,
1213
}: {
1314
pv: IfcBlock;
1415
instName: string;
1516
showHiddenBlocks: boolean;
17+
showSetpoints: boolean;
1618
}) {
1719
const [currentValue, setCurrentValue] = useState<
1820
string | number | undefined
@@ -59,13 +61,21 @@ export default function Block({
5961
<td className="py-1 px-4 ">
6062
<span id={pv.human_readable_name + "_VALUE"}>
6163
{pv.value} {pv.units != null && pv.units}
62-
{pv.sp_value != null && `(SP: ${pv.sp_value})`}{" "}
63-
<a
64-
href="https://github.com/ISISComputingGroup/ibex_user_manual/wiki/Blocks#alarms"
65-
className="text-red-600"
66-
>
67-
{pv.severity != "NONE" && pv.severity}
68-
</a>{" "}
64+
{showSetpoints && pv.sp_value != null ? (
65+
<>
66+
<br />
67+
{`(SP: ${pv.sp_value})`}
68+
</>
69+
) : null}
70+
{pv.severity != "NONE" ? (
71+
<a
72+
href="https://github.com/ISISComputingGroup/ibex_user_manual/wiki/Blocks#alarms"
73+
className="text-red-600"
74+
>
75+
<br />
76+
{pv.severity}
77+
</a>
78+
) : null}
6979
</span>
7080
</td>
7181
<td className="py-1 px-4 flex justify-between items-center">
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import CheckToggle from "@/app/components/CheckToggle";
2+
import { fireEvent, render } from "@testing-library/react";
3+
4+
it.each([true, false])(
5+
"CheckToggle acts on checked variable on a toggle when the initial state is %s",
6+
(initialChecked) => {
7+
const onChange = jest.fn();
8+
const expectedText = "Click me to break the internet";
9+
const { container } = render(
10+
<CheckToggle
11+
checked={initialChecked}
12+
setChecked={onChange}
13+
text={expectedText}
14+
/>,
15+
);
16+
const input = container.getElementsByTagName("input")[0];
17+
expect(input.checked).toBe(initialChecked);
18+
fireEvent.click(input);
19+
expect(onChange).toHaveBeenCalledWith(!initialChecked);
20+
},
21+
);

app/components/CheckToggle.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { Dispatch, SetStateAction } from "react";
2+
3+
export default function CheckToggle({
4+
checked,
5+
setChecked,
6+
text,
7+
}: {
8+
checked: boolean;
9+
setChecked: Dispatch<SetStateAction<boolean>>;
10+
text: string;
11+
}) {
12+
return (
13+
<div className="pt-4">
14+
<label className="inline-flex items-center cursor-pointer">
15+
<input
16+
type="checkbox"
17+
checked={checked}
18+
onChange={() => {
19+
setChecked(!checked);
20+
}}
21+
className="sr-only peer"
22+
/>
23+
<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>
24+
<span className="ms-3 text-sm font-medium text-gray-900">{text}</span>
25+
</label>
26+
</div>
27+
);
28+
}

app/components/Group.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ export default function Group({
88
group,
99
instName,
1010
showHiddenBlocks,
11+
showSetpoints,
1112
}: {
1213
group: IfcGroup;
1314
instName: string;
1415
showHiddenBlocks: boolean;
16+
showSetpoints: boolean;
1517
}) {
1618
if (!group) {
1719
return <h1>Loading...</h1>;
@@ -30,7 +32,7 @@ export default function Group({
3032
<table className="text-sm table-fixed">
3133
<thead>
3234
<tr className="bg-blue-gray-100 text-gray-100">
33-
<th className="py-3 px-4 text-left">Block Name</th>
35+
<th className="py-3 px-4 text-left">Block</th>
3436
<th className="py-3 px-4 text-left">Value</th>
3537
<th className="py-3 px-4 text-left">In-Range</th>
3638
</tr>
@@ -43,6 +45,7 @@ export default function Group({
4345
pv={pv}
4446
instName={instName}
4547
showHiddenBlocks={showHiddenBlocks}
48+
showSetpoints={showSetpoints}
4649
/>
4750
);
4851
})}

app/components/Groups.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,27 @@ export default function Groups({
77
groupsMap,
88
instName,
99
showHiddenBlocks,
10+
showSetpoints,
1011
}: {
1112
groupsMap: Array<IfcGroup>;
1213
instName: string;
1314
showHiddenBlocks: boolean;
15+
showSetpoints: boolean;
1416
}) {
1517
if (!groupsMap) {
1618
return <h1>Loading...</h1>;
1719
}
1820

1921
return (
20-
<div className="rounded-xl grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-8">
22+
<div className="rounded-xl grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-2">
2123
{groupsMap.map((group) => {
2224
return (
2325
<Group
2426
key={group.name}
2527
group={group}
2628
instName={instName}
2729
showHiddenBlocks={showHiddenBlocks}
30+
showSetpoints={showSetpoints}
2831
/>
2932
);
3033
})}

app/components/InstrumentPage.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
getGroupsWithBlocksFromConfigOutput,
44
RC_ENABLE,
55
RC_INRANGE,
6-
SP,
6+
SP_RBV,
77
subscribeToBlockPVs,
88
toPrecision,
99
} from "@/app/components/InstrumentPage";
@@ -15,7 +15,7 @@ test("subscribeToBlockPVs subscribes to all run control PVs", () => {
1515
expect(mockSendJsonMessage.mock.calls.length).toBe(1);
1616
const expectedCall: IfcPVWSRequest = {
1717
type: "subscribe",
18-
pvs: [aBlock, aBlock + RC_ENABLE, aBlock + RC_INRANGE, aBlock + SP],
18+
pvs: [aBlock, aBlock + RC_ENABLE, aBlock + RC_INRANGE, aBlock + SP_RBV],
1919
};
2020
expect(JSON.stringify(mockSendJsonMessage.mock.calls[0][0])).toBe(
2121
JSON.stringify(expectedCall),

0 commit comments

Comments
 (0)