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.
Files changed (136) hide show
  1. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts +2 -1
  2. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts.map +1 -1
  3. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js.map +1 -1
  4. package/lib/components/scan-admin/scan-card/scan-card-header.js +1 -1
  5. package/lib/components/scan-admin/scan-card/scan-card-header.js.map +1 -1
  6. package/lib/components/scan-admin/scan-card/utils.js +1 -1
  7. package/lib/components/scan-admin/scan-card/utils.js.map +1 -1
  8. package/lib/components/sidepanel/navigation-item.d.ts +0 -1
  9. package/lib/components/sidepanel/navigation-item.d.ts.map +1 -1
  10. package/lib/components/sidepanel/navigation-item.js +22 -8
  11. package/lib/components/sidepanel/navigation-item.js.map +1 -1
  12. package/lib/components/sidepanel/sidebar-context.d.ts +16 -0
  13. package/lib/components/sidepanel/sidebar-context.d.ts.map +1 -0
  14. package/lib/components/sidepanel/sidebar-context.js +15 -0
  15. package/lib/components/sidepanel/sidebar-context.js.map +1 -0
  16. package/lib/components/sidepanel/sidepanel.d.ts +4 -4
  17. package/lib/components/sidepanel/sidepanel.d.ts.map +1 -1
  18. package/lib/components/sidepanel/sidepanel.js +47 -10
  19. package/lib/components/sidepanel/sidepanel.js.map +1 -1
  20. package/lib/default/menu-content.d.ts +1 -1
  21. package/lib/default/menu-content.js +1 -1
  22. package/lib/default/menu-content.js.map +1 -1
  23. package/lib/extension-registry-service.d.ts +6 -0
  24. package/lib/extension-registry-service.d.ts.map +1 -1
  25. package/lib/extension-registry-service.js +17 -0
  26. package/lib/extension-registry-service.js.map +1 -1
  27. package/lib/hooks/use-local-storage.d.ts +23 -0
  28. package/lib/hooks/use-local-storage.d.ts.map +1 -0
  29. package/lib/hooks/use-local-storage.js +62 -0
  30. package/lib/hooks/use-local-storage.js.map +1 -0
  31. package/lib/main.d.ts.map +1 -1
  32. package/lib/main.js +5 -5
  33. package/lib/main.js.map +1 -1
  34. package/lib/other-pages.d.ts.map +1 -1
  35. package/lib/other-pages.js +7 -7
  36. package/lib/other-pages.js.map +1 -1
  37. package/lib/pages/admin-dashboard/{admin-routes.d.ts → admin-dashboard-routes.d.ts} +6 -9
  38. package/lib/pages/admin-dashboard/admin-dashboard-routes.d.ts.map +1 -0
  39. package/lib/pages/admin-dashboard/{admin-routes.js → admin-dashboard-routes.js} +6 -9
  40. package/lib/pages/admin-dashboard/admin-dashboard-routes.js.map +1 -0
  41. package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
  42. package/lib/pages/admin-dashboard/admin-dashboard.js +45 -101
  43. package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
  44. package/lib/pages/admin-dashboard/admin-header.d.ts +19 -0
  45. package/lib/pages/admin-dashboard/admin-header.d.ts.map +1 -0
  46. package/lib/pages/admin-dashboard/admin-header.js +16 -0
  47. package/lib/pages/admin-dashboard/admin-header.js.map +1 -0
  48. package/lib/pages/admin-dashboard/admin-sidepanel.d.ts +19 -0
  49. package/lib/pages/admin-dashboard/admin-sidepanel.d.ts.map +1 -0
  50. package/lib/pages/admin-dashboard/admin-sidepanel.js +17 -0
  51. package/lib/pages/admin-dashboard/admin-sidepanel.js.map +1 -0
  52. package/lib/pages/admin-dashboard/customers/customer-member-list.js +1 -1
  53. package/lib/pages/admin-dashboard/customers/customer-member-list.js.map +1 -1
  54. package/lib/pages/admin-dashboard/customers/customers.js +1 -1
  55. package/lib/pages/admin-dashboard/customers/customers.js.map +1 -1
  56. package/lib/pages/admin-dashboard/namespace-admin.d.ts.map +1 -1
  57. package/lib/pages/admin-dashboard/namespace-admin.js +4 -1
  58. package/lib/pages/admin-dashboard/namespace-admin.js.map +1 -1
  59. package/lib/pages/admin-dashboard/namespace-change-dialog.d.ts.map +1 -1
  60. package/lib/pages/admin-dashboard/namespace-change-dialog.js +6 -1
  61. package/lib/pages/admin-dashboard/namespace-change-dialog.js.map +1 -1
  62. package/lib/pages/admin-dashboard/namespace-delete-dialog.d.ts +23 -0
  63. package/lib/pages/admin-dashboard/namespace-delete-dialog.d.ts.map +1 -0
  64. package/lib/pages/admin-dashboard/namespace-delete-dialog.js +53 -0
  65. package/lib/pages/admin-dashboard/namespace-delete-dialog.js.map +1 -0
  66. package/lib/pages/admin-dashboard/nav-types.d.ts +27 -0
  67. package/lib/pages/admin-dashboard/nav-types.d.ts.map +1 -0
  68. package/lib/pages/admin-dashboard/nav-types.js +14 -0
  69. package/lib/pages/admin-dashboard/nav-types.js.map +1 -0
  70. package/lib/pages/admin-dashboard/publisher-admin.js +1 -1
  71. package/lib/pages/admin-dashboard/publisher-admin.js.map +1 -1
  72. package/lib/pages/admin-dashboard/scan-admin.d.ts.map +1 -1
  73. package/lib/pages/admin-dashboard/scan-admin.js +2 -5
  74. package/lib/pages/admin-dashboard/scan-admin.js.map +1 -1
  75. package/lib/pages/admin-dashboard/usage-stats/usage-stats.js +1 -1
  76. package/lib/pages/admin-dashboard/usage-stats/usage-stats.js.map +1 -1
  77. package/lib/pages/admin-dashboard/welcome.d.ts +5 -1
  78. package/lib/pages/admin-dashboard/welcome.d.ts.map +1 -1
  79. package/lib/pages/admin-dashboard/welcome.js +18 -16
  80. package/lib/pages/admin-dashboard/welcome.js.map +1 -1
  81. package/lib/pages/extension-detail/extension-detail-routes.d.ts +0 -1
  82. package/lib/pages/extension-detail/extension-detail-routes.d.ts.map +1 -1
  83. package/lib/pages/extension-detail/extension-detail-routes.js +2 -3
  84. package/lib/pages/extension-detail/extension-detail-routes.js.map +1 -1
  85. package/lib/pages/extension-detail/extension-detail.d.ts.map +1 -1
  86. package/lib/pages/extension-detail/extension-detail.js +120 -249
  87. package/lib/pages/extension-detail/extension-detail.js.map +1 -1
  88. package/lib/pages/extension-detail/use-extension-details.d.ts +23 -0
  89. package/lib/pages/extension-detail/use-extension-details.d.ts.map +1 -0
  90. package/lib/pages/extension-detail/use-extension-details.js +80 -0
  91. package/lib/pages/extension-detail/use-extension-details.js.map +1 -0
  92. package/lib/pages/user/avatar.js +1 -1
  93. package/lib/pages/user/avatar.js.map +1 -1
  94. package/lib/pages/user/user-setting-tabs.d.ts.map +1 -1
  95. package/lib/pages/user/user-setting-tabs.js +1 -1
  96. package/lib/pages/user/user-setting-tabs.js.map +1 -1
  97. package/lib/pages/user/user-settings-namespace-detail.d.ts +1 -0
  98. package/lib/pages/user/user-settings-namespace-detail.d.ts.map +1 -1
  99. package/lib/pages/user/user-settings-namespace-detail.js +19 -3
  100. package/lib/pages/user/user-settings-namespace-detail.js.map +1 -1
  101. package/lib/pages/user/user-settings-namespaces.js.map +1 -1
  102. package/package.json +3 -1
  103. package/src/components/scan-admin/scan-card/scan-card-expanded-content.tsx +4 -4
  104. package/src/components/scan-admin/scan-card/scan-card-header.tsx +1 -1
  105. package/src/components/scan-admin/scan-card/utils.ts +1 -1
  106. package/src/components/sidepanel/navigation-item.tsx +79 -23
  107. package/src/components/sidepanel/sidebar-context.tsx +17 -0
  108. package/src/components/sidepanel/sidepanel.tsx +57 -29
  109. package/src/default/menu-content.tsx +1 -1
  110. package/src/extension-registry-service.ts +18 -0
  111. package/src/hooks/use-local-storage.ts +67 -0
  112. package/src/main.tsx +11 -6
  113. package/src/other-pages.tsx +20 -16
  114. package/src/pages/admin-dashboard/{admin-routes.ts → admin-dashboard-routes.ts} +5 -8
  115. package/src/pages/admin-dashboard/admin-dashboard.tsx +71 -216
  116. package/src/pages/admin-dashboard/admin-header.tsx +59 -0
  117. package/src/pages/admin-dashboard/admin-sidepanel.tsx +59 -0
  118. package/src/pages/admin-dashboard/customers/customer-member-list.tsx +1 -1
  119. package/src/pages/admin-dashboard/customers/customers.tsx +1 -1
  120. package/src/pages/admin-dashboard/namespace-admin.tsx +5 -0
  121. package/src/pages/admin-dashboard/namespace-change-dialog.tsx +55 -46
  122. package/src/pages/admin-dashboard/namespace-delete-dialog.tsx +89 -0
  123. package/src/pages/admin-dashboard/nav-types.ts +31 -0
  124. package/src/pages/admin-dashboard/publisher-admin.tsx +1 -1
  125. package/src/pages/admin-dashboard/scan-admin.tsx +2 -5
  126. package/src/pages/admin-dashboard/usage-stats/usage-stats.tsx +1 -1
  127. package/src/pages/admin-dashboard/welcome.tsx +80 -48
  128. package/src/pages/extension-detail/extension-detail-routes.ts +2 -3
  129. package/src/pages/extension-detail/extension-detail.tsx +290 -409
  130. package/src/pages/extension-detail/use-extension-details.tsx +101 -0
  131. package/src/pages/user/avatar.tsx +1 -1
  132. package/src/pages/user/user-setting-tabs.tsx +3 -2
  133. package/src/pages/user/user-settings-namespace-detail.tsx +38 -5
  134. package/src/pages/user/user-settings-namespaces.tsx +1 -1
  135. package/lib/pages/admin-dashboard/admin-routes.d.ts.map +0 -1
  136. package/lib/pages/admin-dashboard/admin-routes.js.map +0 -1
@@ -0,0 +1,101 @@
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 { useContext, useState, useEffect, useCallback, useRef } from 'react';
15
+ import { MainContext } from '../../context';
16
+ import { Extension, isError } from '../../extension-registry-types';
17
+ import { ErrorResponse } from '../../server-request';
18
+
19
+ interface UseExtensionDetailResult {
20
+ loading: boolean;
21
+ extension: Extension | undefined;
22
+ error: Error | undefined;
23
+ icon: string | undefined;
24
+ reload: () => void;
25
+ }
26
+
27
+ export const useExtensionDetail = (
28
+ namespace: string,
29
+ name: string,
30
+ target: string,
31
+ version: string
32
+ ): UseExtensionDetailResult => {
33
+ const abortController = useRef<AbortController>(new AbortController());
34
+
35
+ const { handleError, service } = useContext(MainContext);
36
+ const [loading, setLoading] = useState(true);
37
+ const [error, setError] = useState<Error>();
38
+ const [extension, setExtension] = useState<Extension>();
39
+ const [icon, setIcon] = useState<string>();
40
+ const [reloadKey, setReloadKey] = useState(0);
41
+
42
+ useEffect(() => {
43
+ return () => {
44
+ abortController.current.abort();
45
+ if (icon) {
46
+ URL.revokeObjectURL(icon);
47
+ }
48
+ };
49
+ }, []);
50
+
51
+ useEffect(() => {
52
+ if (!namespace || !name) return;
53
+
54
+ const fetchExtension = async () => {
55
+ setExtension(undefined);
56
+ setError(undefined);
57
+ setIcon(undefined);
58
+
59
+ const extensionUrl = service.getExtensionApiUrl({ namespace, name, target, version });
60
+ const response = await service.getExtensionDetail(abortController.current, extensionUrl);
61
+ if (isError(response)) throw response;
62
+
63
+ const ext = response as Extension;
64
+ const iconUrl = await service.getExtensionIcon(abortController.current, ext);
65
+ if (abortController.current.signal.aborted) {
66
+ if (iconUrl) {
67
+ URL.revokeObjectURL(iconUrl);
68
+ }
69
+ } else {
70
+ setExtension(ext);
71
+ setIcon(iconUrl);
72
+ }
73
+ };
74
+
75
+ setLoading(true);
76
+ fetchExtension()
77
+ .then(() => {
78
+ setLoading(false);
79
+ })
80
+ .catch(err => {
81
+ if (abortController.current.signal.aborted) {
82
+ setLoading(false);
83
+ return;
84
+ }
85
+
86
+ const errorResponse = err as Partial<ErrorResponse>;
87
+ if (errorResponse?.status === 404) {
88
+ setError(new Error(`Extension Not Found: ${namespace}.${name}`));
89
+ } else {
90
+ setError(err instanceof Error ? err : new Error('Failed to load extension details'));
91
+ handleError(err as Error | Partial<ErrorResponse>);
92
+ }
93
+ setLoading(false);
94
+ });
95
+ }, [namespace, name, target, version, reloadKey]);
96
+
97
+ // This function updates the reloadKey state to trigger a refetch of the extension details.
98
+ const reload = useCallback(() => setReloadKey(k => k + 1), []);
99
+
100
+ return { loading, extension, error, icon, reload };
101
+ };
@@ -12,7 +12,7 @@ import { FunctionComponent, useContext, useRef, useState } from 'react';
12
12
  import { Avatar, Menu, Typography, MenuItem, Link, Divider, IconButton } from '@mui/material';
13
13
  import { Link as RouteLink } from 'react-router-dom';
14
14
  import { UserSettingsRoutes } from './user-settings-routes';
15
- import { AdminDashboardRoutes } from '../admin-dashboard/admin-routes';
15
+ import { AdminDashboardRoutes } from '../admin-dashboard/admin-dashboard-routes';
16
16
  import { MainContext } from '../../context';
17
17
  import { LogoutForm } from './logout';
18
18
 
@@ -20,6 +20,7 @@ export const UserSettingTabs = (): ReactElement => {
20
20
  const isATablet = useMediaQuery(theme.breakpoints.down('md'));
21
21
  const isAMobile = useMediaQuery(theme.breakpoints.down('sm'));
22
22
  const { tab } = useParams();
23
+
23
24
  const navigate = useNavigate();
24
25
 
25
26
  const handleChange = (event: ChangeEvent, newTab: string) => {
@@ -32,10 +33,10 @@ export const UserSettingTabs = (): ReactElement => {
32
33
 
33
34
  return (
34
35
  <Tabs
35
- value={tab}
36
+ value={tab ?? 'extensions'}
36
37
  onChange={handleChange}
37
38
  orientation={isATablet ? 'horizontal' : 'vertical'}
38
- centered={isAMobile ? true : false}
39
+ centered={isAMobile}
39
40
  indicatorColor='secondary'
40
41
  >
41
42
  <Tab value='profile' label='Profile' />
@@ -14,9 +14,10 @@ import { Box, Button, Link, Paper, Grid, Typography } from '@mui/material';
14
14
  import { styled, Theme } from '@mui/material/styles';
15
15
  import WarningIcon from '@mui/icons-material/Warning';
16
16
  import { UserNamespaceExtensionListContainer } from './user-namespace-extension-list';
17
- import { AdminDashboardRoutes } from '../admin-dashboard/admin-routes';
17
+ import { AdminDashboardRoutes } from '../admin-dashboard/admin-dashboard-routes';
18
18
  import { Namespace, UserData } from '../../extension-registry-types';
19
19
  import { NamespaceChangeDialog } from '../admin-dashboard/namespace-change-dialog';
20
+ import { NamespaceDeleteDialog } from '../admin-dashboard/namespace-delete-dialog';
20
21
  import { UserNamespaceMemberList } from './user-namespace-member-list';
21
22
  import { UserNamespaceDetails } from './user-namespace-details';
22
23
 
@@ -61,6 +62,7 @@ const NamespaceHeader = styled(Box)(({ theme }: { theme: Theme }) => ({
61
62
 
62
63
  export const NamespaceDetail: FunctionComponent<NamespaceDetailProps> = props => {
63
64
  const [changeDialogIsOpen, setChangeDialogIsOpen] = useState(false);
65
+ const [deleteDialogIsOpen, setDeleteDialogIsOpen] = useState(false);
64
66
  const { pathname } = useLocation();
65
67
 
66
68
  const handleCloseChangeDialog = async () => {
@@ -70,6 +72,19 @@ export const NamespaceDetail: FunctionComponent<NamespaceDetailProps> = props =>
70
72
  setChangeDialogIsOpen(true);
71
73
  };
72
74
 
75
+ const handleCloseDeleteDialog = async () => {
76
+ setDeleteDialogIsOpen(false);
77
+ };
78
+ const handleDeletedNamespace = async () => {
79
+ setDeleteDialogIsOpen(false);
80
+ if (props.onDelete !== undefined) {
81
+ props.onDelete();
82
+ }
83
+ };
84
+
85
+ const handleOpenDeleteDialog = () => {
86
+ setDeleteDialogIsOpen(true);
87
+ };
73
88
  const warningColor = props.theme === 'dark' ? '#fff' : '#151515';
74
89
  return <>
75
90
  <NamespaceDetailContainer container direction='column' spacing={4}>
@@ -101,9 +116,20 @@ export const NamespaceDetail: FunctionComponent<NamespaceDetailProps> = props =>
101
116
  <NamespaceHeader>
102
117
  <Typography variant='h4'>{props.namespace.name}</Typography>
103
118
  { pathname.startsWith(AdminDashboardRoutes.NAMESPACE_ADMIN)
104
- ? <Button sx={{ ml: { xs: 2, sm: 2, md: 2, lg: 0, xl: 0 } }} variant='outlined' onClick={handleOpenChangeDialog}>
105
- Change Namespace
106
- </Button>
119
+ ?
120
+ <Box>
121
+ <Button sx={{ ml: { xs: 2, sm: 2, md: 2, lg: 0, xl: 0 } }} variant='outlined' onClick={handleOpenChangeDialog}>
122
+ Change Namespace
123
+ </Button>
124
+ { Object.keys(props.namespace.extensions).length === 0 &&
125
+ <Button
126
+ variant='outlined'
127
+ sx={{ color: 'error.main', height: 36, ml: { xs: 2 } }}
128
+ onClick={handleOpenDeleteDialog}>
129
+ Delete
130
+ </Button>
131
+ }
132
+ </Box>
107
133
  : null
108
134
  }
109
135
  </NamespaceHeader>
@@ -137,6 +163,12 @@ export const NamespaceDetail: FunctionComponent<NamespaceDetailProps> = props =>
137
163
  onClose={handleCloseChangeDialog}
138
164
  namespace={props.namespace}
139
165
  setLoadingState={props.setLoadingState} />
166
+ <NamespaceDeleteDialog
167
+ open={deleteDialogIsOpen}
168
+ onClose={handleCloseDeleteDialog}
169
+ onDelete={handleDeletedNamespace}
170
+ namespace={props.namespace}
171
+ setLoadingState={props.setLoadingState} />
140
172
  </>;
141
173
  };
142
174
 
@@ -147,4 +179,5 @@ export interface NamespaceDetailProps {
147
179
  setLoadingState: (loading: boolean) => void;
148
180
  namespaceAccessUrl?: string;
149
181
  theme?: string;
150
- }
182
+ onDelete?: () => void;
183
+ }
@@ -117,7 +117,7 @@ export const UserSettingsNamespaces: FunctionComponent = () => {
117
117
  filterUsers={(foundUser: UserData) => foundUser.provider !== user?.provider || foundUser.loginName !== user?.loginName}
118
118
  fixSelf={true}
119
119
  namespaceAccessUrl={namespaceAccessUrl}
120
- theme={pageSettings.themeType}/>
120
+ theme={pageSettings.themeType} />
121
121
  </Box>;
122
122
  } else if (!loading) {
123
123
  namespaceContainer = <Typography variant='body1'>No namespaces available. Read <Link color='secondary' href={namespaceAccessUrl} target='_blank'>here</Link> about claiming namespaces.</Typography>;
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-routes.d.ts","sourceRoot":"","sources":["../../../src/pages/admin-dashboard/admin-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAI/E,yBAAiB,oBAAoB,CAAC;IAC3B,MAAM,IAAI,oBAAoB,CAAC;IAC/B,MAAM,IAAI,QAAsB,CAAC;IACjC,MAAM,eAAe,QAAoC,CAAC;IAC1D,MAAM,eAAe,QAAoC,CAAC;IAC1D,MAAM,eAAe,QAAmC,CAAC;IACzD,MAAM,WAAW,QAA+B,CAAC;IACjD,MAAM,KAAK,QAA+B,CAAC;IAC3C,MAAM,SAAS,QAAmC,CAAC;IACnD,MAAM,WAAW,QAA+B,CAAC;IACjD,MAAM,IAAI,QAA8B,CAAC;CACnD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-routes.js","sourceRoot":"","sources":["../../../src/pages/admin-dashboard/admin-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,KAAW,oBAAoB,CAWpC;AAXD,WAAiB,oBAAoB;IACpB,yBAAI,GAAG,iBAAiB,CAAC;IACzB,yBAAI,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,CAAC,CAAC,CAAC;IAC3B,oCAAe,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,oCAAe,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,oCAAe,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IACnD,gCAAW,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,0BAAK,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACrC,8BAAS,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAC7C,gCAAW,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,yBAAI,GAAG,WAAW,CAAC,CAAC,qBAAA,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC,EAXgB,oBAAoB,KAApB,oBAAoB,QAWpC"}