Skip to content

Commit

Permalink
Merge pull request #217 from ral-facilities/DESGOG-239-select-btn-in-…
Browse files Browse the repository at this point in the history
…channel-meta-panel

Add a button in channel metadata panel to add/remove the displayed channel
  • Loading branch information
kennethnym authored Mar 23, 2023
2 parents 2538e26 + ee5a532 commit 431af1e
Show file tree
Hide file tree
Showing 8 changed files with 907 additions and 440 deletions.
31 changes: 31 additions & 0 deletions cypress/integration/table/channels.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,35 @@ describe('Data Channels Component', () => {

cy.findByRole('checkbox', { name: 'Shot Number' }).should('exist');
});

it('displays a button in channel metadata panel that adds or removes the displayed channel', () => {
cy.contains('Data Channels').click();
cy.contains('system').click();
cy.findByRole('button', { name: 'Shot Number' }).click();

cy.findByRole('button', { name: 'Add this channel' }).click();

cy.findByRole('checkbox', { name: 'Shot Number' }).should('be.checked');
cy.findByRole('button', { name: 'Add this channel' }).should('not.exist');
cy.findByRole('button', { name: 'Remove this channel' }).should('exist');

cy.findByRole('button', { name: 'Add Channels' }).click();
cy.findByRole('columnheader', { name: 'Shot Number' }).should('be.visible');

// reopen data channel dialog
cy.contains('Data Channels').click();
cy.contains('system').click();
cy.findByRole('button', { name: 'Shot Number' }).click();

cy.findByRole('button', { name: 'Remove this channel' }).click();

cy.findByRole('checkbox', { name: 'Shot Number' }).should('not.be.checked');
cy.findByRole('button', { name: 'Remove this channel' }).should(
'not.exist'
);
cy.findByRole('button', { name: 'Add this channel' }).should('exist');

cy.findByRole('button', { name: 'Add Channels' }).click();
cy.findByRole('columnheader', { name: 'Shot Number' }).should('not.exist');
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"@testing-library/dom": "9.0.0",
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.2",
"@testing-library/user-event": "^14.4.3",
"@types/react-router-dom": "5.3.3",
"@types/testing-library__jest-dom": "5.14.3",
"@typescript-eslint/eslint-plugin": "5.52.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,40 @@ exports[`Channel Metadata Panel should render correctly for no channel selected

exports[`Channel Metadata Panel should render correctly for scalar channel with units selected 1`] = `
<DocumentFragment>
<h3
class="MuiTypography-root MuiTypography-body1 MuiTypography-gutterBottom css-um3j9i-MuiTypography-root"
<div
class="css-3y1137-MuiStack-root"
>
Channel_ABCDE
</h3>
<h3
class="MuiTypography-root MuiTypography-body1 css-ndaqpv-MuiTypography-root"
>
Channel_ABCDE
</h3>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall css-11qr2p8-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="MuiButton-startIcon MuiButton-iconSizeSmall css-y6rp3m-MuiButton-startIcon"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
data-testid="AddIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
/>
</svg>
</span>
Add this channel
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
<p
class="MuiTypography-root MuiTypography-body2 MuiTypography-gutterBottom css-ejgmvm-MuiTypography-root"
>
Expand Down Expand Up @@ -153,11 +182,40 @@ exports[`Channel Metadata Panel should render correctly for scalar channel with

exports[`Channel Metadata Panel should render correctly for system channel 1`] = `
<DocumentFragment>
<h3
class="MuiTypography-root MuiTypography-body1 MuiTypography-gutterBottom css-um3j9i-MuiTypography-root"
<div
class="css-3y1137-MuiStack-root"
>
Shot Number
</h3>
<h3
class="MuiTypography-root MuiTypography-body1 css-ndaqpv-MuiTypography-root"
>
Shot Number
</h3>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall css-11qr2p8-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="MuiButton-startIcon MuiButton-iconSizeSmall css-y6rp3m-MuiButton-startIcon"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
data-testid="AddIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
/>
</svg>
</span>
Add this channel
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
<p
class="MuiTypography-root MuiTypography-body2 MuiTypography-gutterBottom css-ejgmvm-MuiTypography-root"
>
Expand All @@ -173,11 +231,40 @@ exports[`Channel Metadata Panel should render correctly for system channel 1`] =

exports[`Channel Metadata Panel should render correctly for waveform channel with units selected 1`] = `
<DocumentFragment>
<h3
class="MuiTypography-root MuiTypography-body1 MuiTypography-gutterBottom css-um3j9i-MuiTypography-root"
<div
class="css-3y1137-MuiStack-root"
>
CHANNEL_CDEFG
</h3>
<h3
class="MuiTypography-root MuiTypography-body1 css-ndaqpv-MuiTypography-root"
>
CHANNEL_CDEFG
</h3>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall css-11qr2p8-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="MuiButton-startIcon MuiButton-iconSizeSmall css-y6rp3m-MuiButton-startIcon"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
data-testid="AddIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
/>
</svg>
</span>
Add this channel
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
<p
class="MuiTypography-root MuiTypography-body2 MuiTypography-gutterBottom css-ejgmvm-MuiTypography-root"
>
Expand Down
48 changes: 47 additions & 1 deletion src/channels/channelMetadataPanel.component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { QueryClient } from '@tanstack/react-query';
import { renderComponentWithProviders } from '../setupTests';
import { RootState } from '../state/store';
import { staticChannels } from '../api/channels';
import userEvent from '@testing-library/user-event';

describe('Channel Metadata Panel', () => {
let displayedChannel: FullChannelMetadata | undefined;
Expand All @@ -16,7 +17,12 @@ describe('Channel Metadata Panel', () => {
queryClient?: QueryClient
) => {
return renderComponentWithProviders(
<ChannelMetadataPanel displayedChannel={displayedChannel} />,
<ChannelMetadataPanel
isChannelSelected={false}
onSelectChannel={jest.fn()}
onDeselectChannel={jest.fn()}
displayedChannel={displayedChannel}
/>,
{
preloadedState: initialState,
queryClient,
Expand Down Expand Up @@ -67,4 +73,44 @@ describe('Channel Metadata Panel', () => {

expect(view.asFragment()).toMatchSnapshot();
});

it('should add displayed channel when add channel button is clicked', async () => {
const user = userEvent.setup();
const onSelectChannel = jest.fn();

renderComponentWithProviders(
<ChannelMetadataPanel
isChannelSelected={false}
onSelectChannel={onSelectChannel}
onDeselectChannel={jest.fn()}
displayedChannel={displayedChannel}
/>
);

await user.click(screen.getByRole('button', { name: 'Add this channel' }));

expect(onSelectChannel).toHaveBeenCalledWith(displayedChannel?.systemName);
});

it('should remove displayed channel when it is selected and when remove channel button is clicked', async () => {
const user = userEvent.setup();
const onDeselectChannel = jest.fn();

renderComponentWithProviders(
<ChannelMetadataPanel
isChannelSelected
onSelectChannel={jest.fn()}
onDeselectChannel={onDeselectChannel}
displayedChannel={displayedChannel}
/>
);

await user.click(
screen.getByRole('button', { name: 'Remove this channel' })
);

expect(onDeselectChannel).toHaveBeenCalledWith(
displayedChannel?.systemName
);
});
});
57 changes: 53 additions & 4 deletions src/channels/channelMetadataPanel.component.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
Button,
Divider,
Stack,
Table,
TableBody,
TableCell,
Expand All @@ -8,6 +10,8 @@ import {
TableRow,
Typography,
} from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import RemoveIcon from '@mui/icons-material/Remove';
import React from 'react';
import { useChannelSummary } from '../api/channels';
import {
Expand All @@ -22,6 +26,9 @@ import {

type ChannelMetadataPanelProps = {
displayedChannel: FullChannelMetadata | undefined;
isChannelSelected: boolean;
onSelectChannel: (channel: string) => void;
onDeselectChannel: (channel: string) => void;
};

const Heading = (props: React.ComponentProps<typeof Typography>) => {
Expand All @@ -48,18 +55,60 @@ const Body = (props: React.ComponentProps<typeof Typography>) => {
};

const ChannelMetadataPanel = (props: ChannelMetadataPanelProps) => {
const { displayedChannel } = props;
const {
displayedChannel,
isChannelSelected,
onSelectChannel,
onDeselectChannel,
} = props;

const { data: channelSummary } = useChannelSummary(
displayedChannel?.systemName
);

function addCurrentChannel() {
if (displayedChannel?.systemName) {
onSelectChannel(displayedChannel.systemName);
}
}

function removeCurrentChannel() {
if (displayedChannel?.systemName) {
onDeselectChannel(displayedChannel.systemName);
}
}

if (displayedChannel) {
return (
<>
<Heading>
{displayedChannel?.name ?? displayedChannel.systemName}
</Heading>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Heading gutterBottom={false}>
{displayedChannel?.name ?? displayedChannel.systemName}
</Heading>
{isChannelSelected ? (
<Button
variant="outlined"
startIcon={<RemoveIcon />}
size="small"
onClick={removeCurrentChannel}
>
Remove this channel
</Button>
) : (
<Button
variant="contained"
startIcon={<AddIcon />}
size="small"
onClick={addCurrentChannel}
>
Add this channel
</Button>
)}
</Stack>
{displayedChannel?.name && (
<Body>System name: {displayedChannel.systemName}</Body>
)}
Expand Down
3 changes: 3 additions & 0 deletions src/channels/channelTree.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type ChannelTreeProps = {
setCurrNode: (newNode: string) => void;
handleChannelChecked: (channel: string, checked: boolean) => void;
handleChannelSelected: (channel: FullChannelMetadata) => void;
displayedChannel?: FullChannelMetadata;
};

const ChannelTree = (props: ChannelTreeProps) => {
Expand All @@ -25,6 +26,7 @@ const ChannelTree = (props: ChannelTreeProps) => {
setCurrNode,
handleChannelChecked,
handleChannelSelected,
displayedChannel,
} = props;

const nodes = currNode
Expand All @@ -48,6 +50,7 @@ const ChannelTree = (props: ChannelTreeProps) => {
return (
<ListItem key={key} disablePadding disableGutters>
<ListItemButton
selected={displayedChannel?.systemName === key}
onClick={() => {
if (!leaf) {
setCurrNode(`${currNode !== '/' ? currNode : ''}/${key}`);
Expand Down
12 changes: 11 additions & 1 deletion src/channels/channelsDialogue.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ const ChannelsDialogue = (props: ChannelsDialogueProps) => {
<ChannelTree
currNode={currNode}
tree={channelTree ?? { name: '/', children: {} }}
displayedChannel={displayedChannel}
setCurrNode={onChangeNode}
handleChannelChecked={handleChannelChecked}
handleChannelSelected={setDisplayedChannel}
Expand All @@ -197,7 +198,16 @@ const ChannelsDialogue = (props: ChannelsDialogueProps) => {
'calc(100vh - (2 * 32px + 72px + 42px + 2 * 20px + 53px))',
}}
>
<ChannelMetadataPanel displayedChannel={displayedChannel} />
<ChannelMetadataPanel
displayedChannel={displayedChannel}
isChannelSelected={
displayedChannel?.systemName
? selectedIds.includes(displayedChannel.systemName)
: false
}
onSelectChannel={onChannelSelect}
onDeselectChannel={onChannelDeselect}
/>
</Grid>
</Grid>
</DialogContent>
Expand Down
Loading

0 comments on commit 431af1e

Please sign in to comment.