Skip to content

Commit fac66c5

Browse files
author
David Echelberger
authored
Merge pull request #148 from kaleido-io/subscriptions
2 parents 2d97f86 + 94a0d09 commit fac66c5

File tree

10 files changed

+414
-7
lines changed

10 files changed

+414
-7
lines changed

src/components/Lists/SubList.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { useEffect, useState } from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import { ISubscription } from '../../interfaces';
4+
import { IDataListItem } from '../../interfaces/lists';
5+
import { FFCopyButton } from '../Buttons/CopyButton';
6+
import { FFCircleLoader } from '../Loaders/FFCircleLoader';
7+
import { FFListItem } from './FFListItem';
8+
import { FFListText } from './FFListText';
9+
import { FFListTimestamp } from './FFListTimestamp';
10+
import { FFSkeletonList } from './FFSkeletonList';
11+
12+
interface Props {
13+
sub?: ISubscription;
14+
}
15+
16+
export const SubList: React.FC<Props> = ({ sub }) => {
17+
const { t } = useTranslation();
18+
const [dataList, setDataList] = useState<IDataListItem[]>(FFSkeletonList);
19+
20+
useEffect(() => {
21+
if (sub) {
22+
setDataList([
23+
{
24+
label: t('id'),
25+
value: <FFListText color="primary" text={sub.id} />,
26+
button: <FFCopyButton value={sub.id} />,
27+
},
28+
{
29+
label: t('transport'),
30+
value: <FFListText color="primary" text={sub.transport} />,
31+
},
32+
{
33+
label: t('created'),
34+
value: <FFListTimestamp ts={sub.created} />,
35+
},
36+
]);
37+
}
38+
}, [sub]);
39+
40+
return (
41+
<>
42+
{!sub ? (
43+
<FFCircleLoader color="warning" />
44+
) : (
45+
dataList.map((d, idx) => <FFListItem key={idx} item={d} />)
46+
)}
47+
</>
48+
);
49+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright © 2022 Kaleido, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
import HexagonIcon from '@mui/icons-material/Hexagon';
18+
import React, { useContext } from 'react';
19+
import { useTranslation } from 'react-i18next';
20+
import { useLocation, useNavigate } from 'react-router-dom';
21+
import { ApplicationContext } from '../../contexts/ApplicationContext';
22+
import { FF_NAV_PATHS, INavItem } from '../../interfaces';
23+
import { NavSection } from './NavSection';
24+
25+
export const MyNodeNav = () => {
26+
const { t } = useTranslation();
27+
const navigate = useNavigate();
28+
const { selectedNamespace } = useContext(ApplicationContext);
29+
const { pathname } = useLocation();
30+
31+
const myNodePath = FF_NAV_PATHS.myNodePath(selectedNamespace);
32+
const myNodeSubscriptionsPath =
33+
FF_NAV_PATHS.myNodeSubscriptionsPath(selectedNamespace);
34+
35+
const navItems: INavItem[] = [
36+
{
37+
name: t('dashboard'),
38+
action: () => navigate(myNodePath),
39+
itemIsActive: pathname === myNodePath,
40+
},
41+
{
42+
name: t('subscriptions'),
43+
action: () => navigate(myNodeSubscriptionsPath),
44+
itemIsActive: pathname === myNodeSubscriptionsPath,
45+
},
46+
];
47+
48+
return (
49+
<NavSection
50+
icon={<HexagonIcon />}
51+
navItems={navItems}
52+
title={t('myNode')}
53+
/>
54+
);
55+
};

src/components/Navigation/Navigation.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { FF_NAV_PATHS } from '../../interfaces';
1717
import { MenuLogo } from '../MenuLogo';
1818
import { ActivityNav } from './ActivityNav';
1919
import { BlockchainNav } from './BlockchainNav';
20+
import { MyNodeNav } from './MyNodeNav';
2021
import { NavItem } from './NavItem';
2122
import { NetworkNav } from './NetworkNav';
2223
import { OffChainNav } from './OffChainNav';
@@ -45,13 +46,7 @@ export const Navigation: React.FC = () => {
4546
<OffChainNav />
4647
<TokensNav />
4748
<NetworkNav />
48-
<NavItem
49-
name={t('myNode')}
50-
icon={<HexagonIcon />}
51-
action={() => navigate(FF_NAV_PATHS.myNodePath(selectedNamespace))}
52-
itemIsActive={pathname === FF_NAV_PATHS.myNodePath(selectedNamespace)}
53-
isRoot
54-
/>
49+
<MyNodeNav />
5550
<NavItem
5651
name={t('docs')}
5752
icon={<MenuBookIcon />}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright © 2022 Kaleido, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
import { Grid } from '@mui/material';
18+
import React from 'react';
19+
import { useTranslation } from 'react-i18next';
20+
import { ISubscription } from '../../interfaces';
21+
import { DEFAULT_PADDING } from '../../theme';
22+
import { JsonViewAccordion } from '../Accordions/JsonViewerAccordion';
23+
import { SubList } from '../Lists/SubList';
24+
import { DisplaySlide } from './DisplaySlide';
25+
import { SlideHeader } from './SlideHeader';
26+
27+
interface Props {
28+
sub: ISubscription;
29+
open: boolean;
30+
onClose: () => void;
31+
}
32+
33+
export const SubscriptionSlide: React.FC<Props> = ({ sub, open, onClose }) => {
34+
const { t } = useTranslation();
35+
36+
return (
37+
<>
38+
<DisplaySlide open={open} onClose={onClose}>
39+
<Grid container direction="column" p={DEFAULT_PADDING}>
40+
{/* Header */}
41+
<SlideHeader subtitle={t('subscription')} title={sub.name} />
42+
{/* Data list */}
43+
<Grid container item pb={DEFAULT_PADDING}>
44+
<SubList sub={sub} />
45+
</Grid>
46+
47+
{sub.filter && (
48+
<Grid container item pb={DEFAULT_PADDING}>
49+
<JsonViewAccordion
50+
isOpen
51+
header={t('filter')}
52+
json={sub.filter}
53+
/>
54+
</Grid>
55+
)}
56+
{sub.options && (
57+
<Grid container item>
58+
<JsonViewAccordion
59+
isOpen
60+
header={t('options')}
61+
json={sub.options}
62+
/>
63+
</Grid>
64+
)}
65+
</Grid>
66+
</DisplaySlide>
67+
</>
68+
);
69+
};

src/interfaces/api.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,13 @@ export interface IPagedOrganizationResponse {
342342
total: number;
343343
}
344344

345+
export interface IPagedSubscriptionsResponse {
346+
pageParam: number;
347+
count: number;
348+
items: ISubscription[];
349+
total: number;
350+
}
351+
345352
export interface IPagedTokenPoolResponse {
346353
pageParam: number;
347354
count: number;
@@ -380,6 +387,17 @@ export interface IStatus {
380387
};
381388
}
382389

390+
export interface ISubscription {
391+
id: string;
392+
namespace: string;
393+
name: string;
394+
transport: string;
395+
filter?: any;
396+
options?: any;
397+
created: string;
398+
updated: string | null;
399+
}
400+
383401
export interface ITokenAccount {
384402
key: string;
385403
}

src/interfaces/filters.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ export const PoolFilters = [
140140
'tx.id',
141141
];
142142

143+
export const SubscriptionFilters = [
144+
'id',
145+
'namespace',
146+
'name',
147+
'transport',
148+
'events',
149+
'filters',
150+
'options',
151+
'created',
152+
];
153+
143154
export const TransactionFilters = ['id', 'type', 'created', 'blockchainids'];
144155

145156
export const TransferFilters = [

src/interfaces/navigation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const OFFCHAIN_PATH = 'offChain';
4242
export const OPERATIONS_PATH = 'operations';
4343
export const ORGANIZATIONS_PATH = 'organizations';
4444
export const POOLS_PATH = 'pools';
45+
export const SUBSCRIPTIONS_PATH = 'subscriptions';
4546
export const TOKENS_PATH = 'tokens';
4647
export const TRANSACTIONS_PATH = 'transactions';
4748
export const TRANSFERS_PATH = 'transfers';
@@ -121,6 +122,8 @@ export const FF_NAV_PATHS = {
121122
`/${NAMESPACES_PATH}/${ns}/${NETWORK_PATH}/${IDENTITIES_PATH}`,
122123
// My Node
123124
myNodePath: (ns: string) => `/${NAMESPACES_PATH}/${ns}/${MY_NODES_PATH}`,
125+
myNodeSubscriptionsPath: (ns: string) =>
126+
`/${NAMESPACES_PATH}/${ns}/${MY_NODES_PATH}/${SUBSCRIPTIONS_PATH}`,
124127
// Docs
125128
docsPath: DOCS_PATH,
126129
};

src/pages/MyNode/Routes.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RouteObject } from 'react-router-dom';
22
import { NAMESPACES_PATH } from '../../interfaces';
33
import { MyNodeDashboard } from './views/Dashboard';
4+
import { MyNodeSubscriptions } from './views/Subscriptions';
45

56
export const MyNodeRoutes: RouteObject = {
67
path: `${NAMESPACES_PATH}/:namespace/myNode`,
@@ -10,5 +11,9 @@ export const MyNodeRoutes: RouteObject = {
1011
index: true,
1112
element: <MyNodeDashboard />,
1213
},
14+
{
15+
path: 'subscriptions',
16+
element: <MyNodeSubscriptions />,
17+
},
1318
],
1419
};

0 commit comments

Comments
 (0)