openvsx-webui-test 0.20.0-dev.5 → 0.20.2-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts +2 -1
- package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-header.js +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-header.js.map +1 -1
- package/lib/components/scan-admin/scan-card/utils.js +1 -1
- package/lib/components/scan-admin/scan-card/utils.js.map +1 -1
- package/lib/components/sidepanel/navigation-item.d.ts +0 -1
- package/lib/components/sidepanel/navigation-item.d.ts.map +1 -1
- package/lib/components/sidepanel/navigation-item.js +22 -8
- package/lib/components/sidepanel/navigation-item.js.map +1 -1
- package/lib/components/sidepanel/sidebar-context.d.ts +16 -0
- package/lib/components/sidepanel/sidebar-context.d.ts.map +1 -0
- package/lib/components/sidepanel/sidebar-context.js +15 -0
- package/lib/components/sidepanel/sidebar-context.js.map +1 -0
- package/lib/components/sidepanel/sidepanel.d.ts +4 -4
- package/lib/components/sidepanel/sidepanel.d.ts.map +1 -1
- package/lib/components/sidepanel/sidepanel.js +47 -10
- package/lib/components/sidepanel/sidepanel.js.map +1 -1
- package/lib/default/menu-content.d.ts +1 -1
- package/lib/default/menu-content.js +1 -1
- package/lib/default/menu-content.js.map +1 -1
- package/lib/extension-registry-service.d.ts +6 -0
- package/lib/extension-registry-service.d.ts.map +1 -1
- package/lib/extension-registry-service.js +17 -0
- package/lib/extension-registry-service.js.map +1 -1
- package/lib/hooks/use-local-storage.d.ts +23 -0
- package/lib/hooks/use-local-storage.d.ts.map +1 -0
- package/lib/hooks/use-local-storage.js +62 -0
- package/lib/hooks/use-local-storage.js.map +1 -0
- package/lib/main.d.ts.map +1 -1
- package/lib/main.js +5 -5
- package/lib/main.js.map +1 -1
- package/lib/other-pages.d.ts.map +1 -1
- package/lib/other-pages.js +7 -7
- package/lib/other-pages.js.map +1 -1
- package/lib/pages/admin-dashboard/{admin-routes.d.ts → admin-dashboard-routes.d.ts} +6 -9
- package/lib/pages/admin-dashboard/admin-dashboard-routes.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/{admin-routes.js → admin-dashboard-routes.js} +6 -9
- package/lib/pages/admin-dashboard/admin-dashboard-routes.js.map +1 -0
- package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/admin-dashboard.js +45 -101
- package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
- package/lib/pages/admin-dashboard/admin-header.d.ts +19 -0
- package/lib/pages/admin-dashboard/admin-header.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/admin-header.js +16 -0
- package/lib/pages/admin-dashboard/admin-header.js.map +1 -0
- package/lib/pages/admin-dashboard/admin-sidepanel.d.ts +19 -0
- package/lib/pages/admin-dashboard/admin-sidepanel.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/admin-sidepanel.js +17 -0
- package/lib/pages/admin-dashboard/admin-sidepanel.js.map +1 -0
- package/lib/pages/admin-dashboard/customers/customer-member-list.js +1 -1
- package/lib/pages/admin-dashboard/customers/customer-member-list.js.map +1 -1
- package/lib/pages/admin-dashboard/customers/customers.js +1 -1
- package/lib/pages/admin-dashboard/customers/customers.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-admin.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/namespace-admin.js +4 -1
- package/lib/pages/admin-dashboard/namespace-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-change-dialog.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/namespace-change-dialog.js +6 -1
- package/lib/pages/admin-dashboard/namespace-change-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-delete-dialog.d.ts +23 -0
- package/lib/pages/admin-dashboard/namespace-delete-dialog.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/namespace-delete-dialog.js +53 -0
- package/lib/pages/admin-dashboard/namespace-delete-dialog.js.map +1 -0
- package/lib/pages/admin-dashboard/nav-types.d.ts +27 -0
- package/lib/pages/admin-dashboard/nav-types.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/nav-types.js +14 -0
- package/lib/pages/admin-dashboard/nav-types.js.map +1 -0
- package/lib/pages/admin-dashboard/publisher-admin.js +1 -1
- package/lib/pages/admin-dashboard/publisher-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/scan-admin.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/scan-admin.js +2 -5
- package/lib/pages/admin-dashboard/scan-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats.js +1 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats.js.map +1 -1
- package/lib/pages/admin-dashboard/welcome.d.ts +5 -1
- package/lib/pages/admin-dashboard/welcome.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/welcome.js +18 -16
- package/lib/pages/admin-dashboard/welcome.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail-routes.d.ts +0 -1
- package/lib/pages/extension-detail/extension-detail-routes.d.ts.map +1 -1
- package/lib/pages/extension-detail/extension-detail-routes.js +2 -3
- package/lib/pages/extension-detail/extension-detail-routes.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail.d.ts.map +1 -1
- package/lib/pages/extension-detail/extension-detail.js +120 -249
- package/lib/pages/extension-detail/extension-detail.js.map +1 -1
- package/lib/pages/extension-detail/use-extension-details.d.ts +23 -0
- package/lib/pages/extension-detail/use-extension-details.d.ts.map +1 -0
- package/lib/pages/extension-detail/use-extension-details.js +80 -0
- package/lib/pages/extension-detail/use-extension-details.js.map +1 -0
- package/lib/pages/user/avatar.js +1 -1
- package/lib/pages/user/avatar.js.map +1 -1
- package/lib/pages/user/user-setting-tabs.d.ts.map +1 -1
- package/lib/pages/user/user-setting-tabs.js +1 -1
- package/lib/pages/user/user-setting-tabs.js.map +1 -1
- package/lib/pages/user/user-settings-namespace-detail.d.ts +1 -0
- package/lib/pages/user/user-settings-namespace-detail.d.ts.map +1 -1
- package/lib/pages/user/user-settings-namespace-detail.js +19 -3
- package/lib/pages/user/user-settings-namespace-detail.js.map +1 -1
- package/lib/pages/user/user-settings-namespaces.js.map +1 -1
- package/package.json +3 -1
- package/src/components/scan-admin/scan-card/scan-card-expanded-content.tsx +4 -4
- package/src/components/scan-admin/scan-card/scan-card-header.tsx +1 -1
- package/src/components/scan-admin/scan-card/utils.ts +1 -1
- package/src/components/sidepanel/navigation-item.tsx +79 -23
- package/src/components/sidepanel/sidebar-context.tsx +17 -0
- package/src/components/sidepanel/sidepanel.tsx +57 -29
- package/src/default/menu-content.tsx +1 -1
- package/src/extension-registry-service.ts +18 -0
- package/src/hooks/use-local-storage.ts +67 -0
- package/src/main.tsx +11 -6
- package/src/other-pages.tsx +20 -16
- package/src/pages/admin-dashboard/{admin-routes.ts → admin-dashboard-routes.ts} +5 -8
- package/src/pages/admin-dashboard/admin-dashboard.tsx +71 -216
- package/src/pages/admin-dashboard/admin-header.tsx +59 -0
- package/src/pages/admin-dashboard/admin-sidepanel.tsx +59 -0
- package/src/pages/admin-dashboard/customers/customer-member-list.tsx +1 -1
- package/src/pages/admin-dashboard/customers/customers.tsx +1 -1
- package/src/pages/admin-dashboard/namespace-admin.tsx +5 -0
- package/src/pages/admin-dashboard/namespace-change-dialog.tsx +55 -46
- package/src/pages/admin-dashboard/namespace-delete-dialog.tsx +89 -0
- package/src/pages/admin-dashboard/nav-types.ts +31 -0
- package/src/pages/admin-dashboard/publisher-admin.tsx +1 -1
- package/src/pages/admin-dashboard/scan-admin.tsx +2 -5
- package/src/pages/admin-dashboard/usage-stats/usage-stats.tsx +1 -1
- package/src/pages/admin-dashboard/welcome.tsx +80 -48
- package/src/pages/extension-detail/extension-detail-routes.ts +2 -3
- package/src/pages/extension-detail/extension-detail.tsx +290 -409
- package/src/pages/extension-detail/use-extension-details.tsx +101 -0
- package/src/pages/user/avatar.tsx +1 -1
- package/src/pages/user/user-setting-tabs.tsx +3 -2
- package/src/pages/user/user-settings-namespace-detail.tsx +38 -5
- package/src/pages/user/user-settings-namespaces.tsx +1 -1
- package/lib/pages/admin-dashboard/admin-routes.d.ts.map +0 -1
- package/lib/pages/admin-dashboard/admin-routes.js.map +0 -1
|
@@ -8,38 +8,38 @@
|
|
|
8
8
|
* SPDX-License-Identifier: EPL-2.0
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
import { ChangeEvent, FunctionComponent, useState, useContext, useEffect, useRef } from 'react';
|
|
12
|
+
import {
|
|
13
|
+
Button, Checkbox, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, FormControlLabel, TextField
|
|
14
|
+
} from '@mui/material';
|
|
15
|
+
import { ButtonWithProgress } from '../../components/button-with-progress';
|
|
16
|
+
import { Namespace, SuccessResult, isError } from '../../extension-registry-types';
|
|
17
|
+
import { MainContext } from '../../context';
|
|
18
|
+
import { InfoDialog } from '../../components/info-dialog';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
export interface NamespaceChangeDialogProps {
|
|
21
|
+
open: boolean;
|
|
22
|
+
onClose: () => void;
|
|
23
|
+
namespace: Namespace;
|
|
24
|
+
setLoadingState: (loading: boolean) => void;
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
export const NamespaceChangeDialog: FunctionComponent<NamespaceChangeDialogProps> = props => {
|
|
28
|
+
const { open } = props;
|
|
29
|
+
const { service, handleError } = useContext(MainContext);
|
|
30
|
+
const [working, setWorking] = useState(false);
|
|
31
|
+
const [newNamespace, setNewNamespace] = useState('');
|
|
32
|
+
const [removeOldNamespace, setRemoveOldNamespace] = useState(false);
|
|
33
|
+
const [mergeIfNewNamespaceAlreadyExists, setMergeIfNewNamespaceAlreadyExists] = useState(false);
|
|
34
|
+
const [infoDialogIsOpen, setInfoDialogIsOpen] = useState(false);
|
|
35
|
+
const [infoDialogMessage, setInfoDialogMessage] = useState('');
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
const abortController = useRef<AbortController>(new AbortController());
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
return () => {
|
|
40
|
+
abortController.current.abort();
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
43
|
|
|
44
44
|
useEffect(() => {
|
|
45
45
|
if (open) {
|
|
@@ -70,7 +70,12 @@
|
|
|
70
70
|
setWorking(true);
|
|
71
71
|
props.setLoadingState(true);
|
|
72
72
|
const oldNamespace = props.namespace.name;
|
|
73
|
-
const result = await service.admin.changeNamespace(abortController.current, {
|
|
73
|
+
const result = await service.admin.changeNamespace(abortController.current, {
|
|
74
|
+
oldNamespace,
|
|
75
|
+
newNamespace,
|
|
76
|
+
removeOldNamespace,
|
|
77
|
+
mergeIfNewNamespaceAlreadyExists
|
|
78
|
+
});
|
|
74
79
|
if (isError(result)) {
|
|
75
80
|
throw result;
|
|
76
81
|
}
|
|
@@ -87,12 +92,12 @@
|
|
|
87
92
|
}
|
|
88
93
|
};
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
return <>
|
|
91
96
|
<Dialog onClose={onClose} open={open} aria-labelledby='form-dialog-title'>
|
|
92
97
|
<DialogTitle id='form-dialog-title'>Change Namespace</DialogTitle>
|
|
93
98
|
<DialogContent>
|
|
94
99
|
<DialogContentText>
|
|
95
|
-
|
|
100
|
+
Enter the new Namespace name.
|
|
96
101
|
</DialogContentText>
|
|
97
102
|
<TextField
|
|
98
103
|
autoFocus
|
|
@@ -106,27 +111,31 @@
|
|
|
106
111
|
}}
|
|
107
112
|
/>
|
|
108
113
|
<FormControlLabel
|
|
109
|
-
control={<Checkbox checked={removeOldNamespace} onChange={onRemoveOldNamespaceChange}
|
|
110
|
-
|
|
114
|
+
control={<Checkbox checked={removeOldNamespace} onChange={onRemoveOldNamespaceChange}
|
|
115
|
+
name='remove-old-namespace'/>}
|
|
116
|
+
label={`Remove '${props.namespace.name}' namespace after namespace change`}/>
|
|
111
117
|
<FormControlLabel
|
|
112
|
-
control={<Checkbox checked={mergeIfNewNamespaceAlreadyExists}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
control={<Checkbox checked={mergeIfNewNamespaceAlreadyExists}
|
|
119
|
+
onChange={onMergeIfNewNamespaceAlreadyExistsChange}
|
|
120
|
+
name='merge-change-namespace'/>}
|
|
121
|
+
label='Merge namespaces if new namespace already exists'/>
|
|
122
|
+
</DialogContent>
|
|
123
|
+
<DialogActions>
|
|
124
|
+
<Button
|
|
117
125
|
variant='contained'
|
|
118
126
|
color='primary'
|
|
119
|
-
onClick={onClose}
|
|
127
|
+
onClick={onClose}>
|
|
120
128
|
Cancel
|
|
121
129
|
</Button>
|
|
122
130
|
<ButtonWithProgress
|
|
123
131
|
sx={{ ml: 1 }}
|
|
124
132
|
working={working}
|
|
125
|
-
onClick={handleChangeNamespace}
|
|
133
|
+
onClick={handleChangeNamespace}>
|
|
126
134
|
Change Namespace
|
|
127
135
|
</ButtonWithProgress>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
</DialogActions>
|
|
137
|
+
</Dialog>
|
|
138
|
+
<InfoDialog infoMessage={infoDialogMessage} isInfoDialogOpen={infoDialogIsOpen}
|
|
139
|
+
handleCloseDialog={onInfoDialogClose}/>
|
|
140
|
+
</>;
|
|
141
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* Copyright (c) 2026 Contributors to the Eclipse Foundation.
|
|
3
|
+
*
|
|
4
|
+
* See the NOTICE file(s) distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
*
|
|
7
|
+
* This program and the accompanying materials are made available under the
|
|
8
|
+
* terms of the Eclipse Public License 2.0 which is available at
|
|
9
|
+
* https://www.eclipse.org/legal/epl-2.0.
|
|
10
|
+
*
|
|
11
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
12
|
+
*****************************************************************************/
|
|
13
|
+
|
|
14
|
+
import { FunctionComponent, useState, useContext, useEffect, useRef } from 'react';
|
|
15
|
+
import {
|
|
16
|
+
Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle
|
|
17
|
+
} from '@mui/material';
|
|
18
|
+
import { ButtonWithProgress } from '../../components/button-with-progress';
|
|
19
|
+
import { Namespace, isError } from '../../extension-registry-types';
|
|
20
|
+
import { MainContext } from '../../context';
|
|
21
|
+
|
|
22
|
+
export interface NamespaceDeleteDialogProps {
|
|
23
|
+
open: boolean;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
onDelete: () => void;
|
|
26
|
+
namespace: Namespace;
|
|
27
|
+
setLoadingState: (loading: boolean) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const NamespaceDeleteDialog: FunctionComponent<NamespaceDeleteDialogProps> = props => {
|
|
31
|
+
const { open, onClose, onDelete, namespace } = props;
|
|
32
|
+
const { service, handleError } = useContext(MainContext);
|
|
33
|
+
const [working, setWorking] = useState(false);
|
|
34
|
+
|
|
35
|
+
const abortController = useRef<AbortController>(new AbortController());
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
return () => {
|
|
38
|
+
abortController.current.abort();
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
const handleDeleteNamespace = async () => {
|
|
43
|
+
try {
|
|
44
|
+
if (!props.namespace) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
setWorking(true);
|
|
48
|
+
props.setLoadingState(true);
|
|
49
|
+
const name = props.namespace.name;
|
|
50
|
+
const result = await service.admin.deleteNamespace(abortController.current, { name });
|
|
51
|
+
if (isError(result)) {
|
|
52
|
+
throw result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
props.setLoadingState(false);
|
|
56
|
+
setWorking(false);
|
|
57
|
+
onDelete();
|
|
58
|
+
} catch (err) {
|
|
59
|
+
props.setLoadingState(false);
|
|
60
|
+
setWorking(false);
|
|
61
|
+
handleError(err);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return <>
|
|
66
|
+
<Dialog onClose={onClose} open={open} aria-labelledby='form-dialog-title'>
|
|
67
|
+
<DialogTitle id='form-dialog-title'>Delete Namespace</DialogTitle>
|
|
68
|
+
<DialogContent>
|
|
69
|
+
<DialogContentText>
|
|
70
|
+
Are you sure you want to delete the namespace <strong>{namespace.name}</strong>?
|
|
71
|
+
</DialogContentText>
|
|
72
|
+
</DialogContent>
|
|
73
|
+
<DialogActions>
|
|
74
|
+
<Button
|
|
75
|
+
variant='contained'
|
|
76
|
+
color='primary'
|
|
77
|
+
onClick={onClose}>
|
|
78
|
+
Cancel
|
|
79
|
+
</Button>
|
|
80
|
+
<ButtonWithProgress
|
|
81
|
+
sx={{ ml: 1 }}
|
|
82
|
+
working={working}
|
|
83
|
+
onClick={handleDeleteNamespace}>
|
|
84
|
+
Delete Namespace
|
|
85
|
+
</ButtonWithProgress>
|
|
86
|
+
</DialogActions>
|
|
87
|
+
</Dialog>
|
|
88
|
+
</>;
|
|
89
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* Copyright (c) 2026 Contributors to the Eclipse Foundation.
|
|
3
|
+
*
|
|
4
|
+
* See the NOTICE file(s) distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
*
|
|
7
|
+
* This program and the accompanying materials are made available under the
|
|
8
|
+
* terms of the Eclipse Public License 2.0 which is available at
|
|
9
|
+
* https://www.eclipse.org/legal/epl-2.0.
|
|
10
|
+
*
|
|
11
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
12
|
+
*****************************************************************************/
|
|
13
|
+
|
|
14
|
+
import { ReactNode } from 'react';
|
|
15
|
+
|
|
16
|
+
export interface RouteEntry {
|
|
17
|
+
path: string;
|
|
18
|
+
name: string;
|
|
19
|
+
icon: ReactNode;
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface NavGroup {
|
|
24
|
+
name: string;
|
|
25
|
+
icon: ReactNode;
|
|
26
|
+
children: RouteEntry[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type NavEntry = RouteEntry | NavGroup;
|
|
30
|
+
|
|
31
|
+
export const isNavGroup = (entry: NavEntry): entry is NavGroup => 'children' in entry;
|
|
@@ -16,7 +16,7 @@ import { MainContext } from '../../context';
|
|
|
16
16
|
import { StyledInput } from './namespace-input';
|
|
17
17
|
import { SearchListContainer } from './search-list-container';
|
|
18
18
|
import { PublisherDetails } from './publisher-details';
|
|
19
|
-
import { AdminDashboardRoutes } from './admin-routes';
|
|
19
|
+
import { AdminDashboardRoutes } from './admin-dashboard-routes';
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
22
22
|
export const UpdateContext = createContext({ handleUpdate: () => { } });
|
|
@@ -45,14 +45,11 @@ const ScanAdminContent: FunctionComponent = () => {
|
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
47
|
<Box sx={{
|
|
48
|
-
width: '
|
|
49
|
-
maxWidth:
|
|
48
|
+
width: '100%',
|
|
49
|
+
maxWidth: 1500,
|
|
50
50
|
mx: 'auto',
|
|
51
51
|
px: 2,
|
|
52
52
|
pb: 3,
|
|
53
|
-
position: 'relative',
|
|
54
|
-
left: '50%',
|
|
55
|
-
transform: 'translateX(-50%)',
|
|
56
53
|
}}>
|
|
57
54
|
<Typography variant='h5' gutterBottom sx={{ mb: 2 }}>
|
|
58
55
|
Extension Scans
|
|
@@ -17,7 +17,7 @@ import { useParams, useNavigate } from "react-router-dom";
|
|
|
17
17
|
import { MainContext } from "../../../context";
|
|
18
18
|
import type { Customer } from "../../../extension-registry-types";
|
|
19
19
|
import { handleError } from "../../../utils";
|
|
20
|
-
import { AdminDashboardRoutes } from "../admin-routes";
|
|
20
|
+
import { AdminDashboardRoutes } from "../admin-dashboard-routes";
|
|
21
21
|
import { SearchListContainer } from "../search-list-container";
|
|
22
22
|
import { CustomerSearch } from "./usage-stats-search";
|
|
23
23
|
import { UsageStatsChart } from "../../../components/rate-limiting/usage-stats/usage-stats-chart";
|
|
@@ -9,54 +9,86 @@
|
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
|
|
11
11
|
import { FunctionComponent } from 'react';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
12
|
+
import { Box, Card, CardActionArea, CardContent, Divider, Grid, Typography } from '@mui/material';
|
|
13
|
+
import { useNavigate } from 'react-router-dom';
|
|
14
|
+
import { isNavGroup, NavEntry, RouteEntry } from './nav-types';
|
|
15
|
+
|
|
16
|
+
interface NavSection {
|
|
17
|
+
groupName?: string;
|
|
18
|
+
entries: RouteEntry[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Preserve the original group structure: ungrouped items come first as a section without a title. */
|
|
22
|
+
function buildSections(items: NavEntry[]): NavSection[] {
|
|
23
|
+
const ungrouped: RouteEntry[] = items.filter((e): e is RouteEntry => !isNavGroup(e));
|
|
24
|
+
const groups: NavSection[] = items
|
|
25
|
+
.filter(isNavGroup)
|
|
26
|
+
.map(group => ({ groupName: group.name, entries: group.children }));
|
|
27
|
+
|
|
28
|
+
return ungrouped.length > 0 ? [{ entries: ungrouped }, ...groups] : groups;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const NavCard: FunctionComponent<{ entry: RouteEntry }> = ({ entry }) => {
|
|
32
|
+
const navigate = useNavigate();
|
|
33
|
+
return (
|
|
34
|
+
<Card variant='outlined' sx={{ height: '100%' }}>
|
|
35
|
+
<CardActionArea
|
|
36
|
+
onClick={() => navigate(entry.path)}
|
|
37
|
+
sx={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', py: 3, px: 2 }}
|
|
38
|
+
>
|
|
39
|
+
<Box sx={{ fontSize: 40, color: 'primary.main', mb: 1, display: 'flex' }}>
|
|
40
|
+
{entry.icon}
|
|
41
|
+
</Box>
|
|
42
|
+
<CardContent sx={{ textAlign: 'center', p: 1 }}>
|
|
43
|
+
<Typography variant='h6' gutterBottom>{entry.name}</Typography>
|
|
44
|
+
{entry.description && (
|
|
45
|
+
<Typography variant='body2' color='text.secondary'>
|
|
46
|
+
{entry.description}
|
|
47
|
+
</Typography>
|
|
48
|
+
)}
|
|
49
|
+
</CardContent>
|
|
50
|
+
</CardActionArea>
|
|
51
|
+
</Card>
|
|
52
|
+
);
|
|
39
53
|
};
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<Typography>
|
|
53
|
-
<StyledLink to={props.route}>
|
|
54
|
-
{props.label}
|
|
55
|
-
</StyledLink>
|
|
55
|
+
export interface WelcomeProps {
|
|
56
|
+
items: NavEntry[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const Welcome: FunctionComponent<WelcomeProps> = ({ items }) => {
|
|
60
|
+
const sections = buildSections(items);
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Box sx={{ py: 4, px: 2 }}>
|
|
64
|
+
<Typography variant='h5' gutterBottom>
|
|
65
|
+
Welcome to the Admin Dashboard
|
|
56
66
|
</Typography>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
67
|
+
<Typography variant='body1' color='text.secondary' sx={{ mb: 4 }}>
|
|
68
|
+
Select a section below to get started
|
|
69
|
+
</Typography>
|
|
70
|
+
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
|
|
71
|
+
{sections.map((section, i) => (
|
|
72
|
+
<Box key={section.groupName ?? '__root__'}>
|
|
73
|
+
{section.groupName && (
|
|
74
|
+
<>
|
|
75
|
+
<Typography variant='overline' color='text.secondary' sx={{ mb: 1, display: 'block' }}>
|
|
76
|
+
{section.groupName}
|
|
77
|
+
</Typography>
|
|
78
|
+
<Divider sx={{ mb: 2 }} />
|
|
79
|
+
</>
|
|
80
|
+
)}
|
|
81
|
+
{!section.groupName && i > 0 && <Divider sx={{ mb: 2 }} />}
|
|
82
|
+
<Grid container spacing={3}>
|
|
83
|
+
{section.entries.map(entry => (
|
|
84
|
+
<Grid item key={entry.path} xs={12} sm={6} md={4} lg={3}>
|
|
85
|
+
<NavCard entry={entry} />
|
|
86
|
+
</Grid>
|
|
87
|
+
))}
|
|
88
|
+
</Grid>
|
|
89
|
+
</Box>
|
|
90
|
+
))}
|
|
91
|
+
</Box>
|
|
92
|
+
</Box>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
@@ -18,12 +18,11 @@ export namespace ExtensionDetailRoutes {
|
|
|
18
18
|
export const NAMESPACE = ':namespace';
|
|
19
19
|
export const NAME = ':name';
|
|
20
20
|
export const TARGET = `:target(${getTargetPlatforms().join('|')})`;
|
|
21
|
-
export const VERSION = ':version?';
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
export const ROOT = 'extension';
|
|
25
|
-
export const MAIN = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME,
|
|
26
|
-
export const MAIN_TARGET = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME, Parameters.TARGET,
|
|
24
|
+
export const MAIN = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME, '*']);
|
|
25
|
+
export const MAIN_TARGET = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME, Parameters.TARGET, '*']);
|
|
27
26
|
export const LATEST = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME]);
|
|
28
27
|
export const LATEST_TARGET = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME, Parameters.TARGET]);
|
|
29
28
|
export const PRE_RELEASE = createRoute([ROOT, Parameters.NAMESPACE, Parameters.NAME, 'pre-release']);
|