Skip to content

Commit 99606f7

Browse files
committed
Show current Snap ID
1 parent 42f522a commit 99606f7

File tree

4 files changed

+168
-38
lines changed

4 files changed

+168
-38
lines changed

packages/snaps-sandbox/src/App.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Flex, HStack } from '@chakra-ui/react';
1+
import { HStack } from '@chakra-ui/react';
22
import type { FunctionComponent } from 'react';
33

44
import { Sandbox } from './components';
@@ -7,14 +7,6 @@ import { Sidebar } from './features/sidebar';
77
export const App: FunctionComponent = () => (
88
<HStack gap="0">
99
<Sidebar />
10-
<Flex
11-
justify="center"
12-
flexGrow="1"
13-
maxWidth="100%"
14-
minHeight="100vh"
15-
paddingY="24"
16-
>
17-
<Sandbox />
18-
</Flex>
10+
<Sandbox />
1911
</HStack>
2012
);
Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { Box, Container, Grid, Heading, HStack } from '@chakra-ui/react';
1+
import { Box, Container, Grid, Heading, HStack, Stack } from '@chakra-ui/react';
22
import type { FunctionComponent } from 'react';
33

44
import { Request } from './Request';
55
import { RequestButton } from './RequestButton';
66
import { Response } from './Response';
7+
import { Status } from './Status.js';
78

89
/**
910
* The main component of the Snaps Sandbox.
@@ -12,35 +13,42 @@ import { Response } from './Response';
1213
*/
1314
export const Sandbox: FunctionComponent = () => {
1415
return (
15-
<Container width={['100%', null, null, '10/12']}>
16-
<Grid
17-
templateColumns="1fr 1fr"
18-
templateRows="auto 1fr"
19-
gap="4"
20-
height="100%"
21-
>
22-
<HStack gap="3">
23-
<Heading as="h3" size="lg">
24-
Request
25-
</Heading>
26-
<RequestButton />
27-
</HStack>
16+
<Box width="100%" height="100vh" paddingY="6">
17+
<Stack height="100%">
18+
<Box marginX="6" alignSelf="flex-end">
19+
<Status />
20+
</Box>
21+
<Container width={['100%', null, null, '10/12']} flexGrow="1">
22+
<Grid
23+
templateColumns="1fr 1fr"
24+
templateRows="auto 1fr"
25+
gap="4"
26+
height="100%"
27+
>
28+
<HStack gap="3">
29+
<Heading as="h3" size="lg">
30+
Request
31+
</Heading>
32+
<RequestButton />
33+
</HStack>
2834

29-
<Heading as="h3" size="lg">
30-
Response
31-
</Heading>
35+
<Heading as="h3" size="lg">
36+
Response
37+
</Heading>
3238

33-
<Box
34-
height="100%"
35-
borderRightWidth="1px"
36-
borderRightStyle="solid"
37-
borderColor="gray.200"
38-
>
39-
<Request />
40-
</Box>
39+
<Box
40+
height="100%"
41+
borderRightWidth="1px"
42+
borderRightStyle="solid"
43+
borderColor="gray.200"
44+
>
45+
<Request />
46+
</Box>
4147

42-
<Response />
43-
</Grid>
44-
</Container>
48+
<Response />
49+
</Grid>
50+
</Container>
51+
</Stack>
52+
</Box>
4553
);
4654
};
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { act } from '@testing-library/react';
2+
import { createStore } from 'jotai';
3+
import { describe, it, expect, vi, beforeEach } from 'vitest';
4+
5+
import { Status } from './Status.js';
6+
import { LOCAL_SNAP_ID } from '../constants';
7+
import { useSnaps } from '../hooks';
8+
import { settingsAtom } from '../state';
9+
import { render } from '../test-utils';
10+
11+
vi.mock('../hooks');
12+
13+
describe('Status', () => {
14+
beforeEach(() => {
15+
vi.mocked(useSnaps).mockReturnValue({
16+
loading: false,
17+
snaps: [],
18+
});
19+
});
20+
21+
it('renders the status component', async () => {
22+
const { getByText } = await act(() => render(<Status />));
23+
24+
expect(getByText('local:http...lhost:3000')).toBeInTheDocument();
25+
});
26+
27+
it('renders "No" if the Snap is not connected', async () => {
28+
const { getByText } = await act(() => render(<Status />));
29+
30+
expect(getByText('No')).toBeInTheDocument();
31+
});
32+
33+
it('renders "Yes" if the Snap is connected', async () => {
34+
vi.mocked(useSnaps).mockReturnValue({
35+
loading: false,
36+
snaps: [LOCAL_SNAP_ID],
37+
});
38+
39+
const { getByText } = await act(() => render(<Status />));
40+
41+
expect(getByText('Yes')).toBeInTheDocument();
42+
});
43+
44+
it(`renders the full snap ID if it's less than 20 characters`, async () => {
45+
const store = createStore();
46+
store.set(settingsAtom, {
47+
snapId: 'npm:short-id',
48+
useCurrentSnapId: false,
49+
});
50+
51+
vi.mocked(useSnaps).mockReturnValue({
52+
loading: false,
53+
snaps: ['local:http://localhost:3000'],
54+
});
55+
56+
const { getAllByText } = await act(() => render(<Status />));
57+
58+
expect(getAllByText('npm:short-id')).toHaveLength(2);
59+
});
60+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
Badge,
3+
DataList,
4+
HoverCard,
5+
HStack,
6+
Portal,
7+
Stack,
8+
Text,
9+
} from '@chakra-ui/react';
10+
import type { FunctionComponent } from 'react';
11+
import { FiAlertCircle, FiCheckCircle, FiXCircle } from 'react-icons/fi';
12+
13+
import { useSnaps } from '../hooks';
14+
import { useSnapId } from '../hooks/useSnapId';
15+
16+
export const Status: FunctionComponent = () => {
17+
const snapId = useSnapId();
18+
const { loading, snaps } = useSnaps();
19+
20+
const isConnected = !loading && snaps.includes(snapId);
21+
22+
const isTruncated = snapId.length > 20;
23+
const truncated = isTruncated
24+
? `${snapId.slice(0, 10)}...${snapId.slice(-10)}`
25+
: snapId;
26+
27+
return (
28+
<HoverCard.Root size="sm">
29+
<HoverCard.Trigger asChild>
30+
<Badge size="lg">
31+
{isConnected ? <FiCheckCircle /> : <FiAlertCircle />}
32+
{truncated}
33+
</Badge>
34+
</HoverCard.Trigger>
35+
<Portal>
36+
<HoverCard.Positioner>
37+
<HoverCard.Content>
38+
<HoverCard.Arrow />
39+
<Stack>
40+
<DataList.Root>
41+
<DataList.Item>
42+
<DataList.ItemLabel>Snap ID</DataList.ItemLabel>
43+
<DataList.ItemValue>{snapId}</DataList.ItemValue>
44+
</DataList.Item>
45+
<DataList.Item>
46+
<DataList.ItemLabel>Connected</DataList.ItemLabel>
47+
<DataList.ItemValue>
48+
<HStack gap="1">
49+
{isConnected ? (
50+
<>
51+
<FiCheckCircle aria-label="Connected" />{' '}
52+
<Text aria-hidden="true">Yes</Text>
53+
</>
54+
) : (
55+
<>
56+
<FiXCircle aria-label="Disconnected" />{' '}
57+
<Text aria-hidden="true">No</Text>
58+
</>
59+
)}
60+
</HStack>
61+
</DataList.ItemValue>
62+
</DataList.Item>
63+
</DataList.Root>
64+
</Stack>
65+
</HoverCard.Content>
66+
</HoverCard.Positioner>
67+
</Portal>
68+
</HoverCard.Root>
69+
);
70+
};

0 commit comments

Comments
 (0)