openvsx-webui-test 0.20.0-dev.0 → 0.20.0-dev.1
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/error-dialog.d.ts.map +1 -1
- package/lib/components/error-dialog.js +3 -5
- package/lib/components/error-dialog.js.map +1 -1
- package/lib/components/generate-token-dialog.d.ts +22 -0
- package/lib/components/generate-token-dialog.d.ts.map +1 -0
- package/lib/components/generate-token-dialog.js +91 -0
- package/lib/components/generate-token-dialog.js.map +1 -0
- package/lib/components/rate-limiting/usage-stats/usage-stats-chart.d.ts.map +1 -1
- package/lib/components/rate-limiting/usage-stats/usage-stats-chart.js +14 -11
- package/lib/components/rate-limiting/usage-stats/usage-stats-chart.js.map +1 -1
- package/lib/components/timestamp.d.ts +1 -0
- package/lib/components/timestamp.d.ts.map +1 -1
- package/lib/components/timestamp.js +2 -1
- package/lib/components/timestamp.js.map +1 -1
- package/lib/default/menu-content.d.ts +1 -1
- package/lib/extension-registry-service.d.ts +7 -1
- package/lib/extension-registry-service.d.ts.map +1 -1
- package/lib/extension-registry-service.js +41 -0
- package/lib/extension-registry-service.js.map +1 -1
- package/lib/extension-registry-types.d.ts +6 -0
- package/lib/extension-registry-types.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/admin-dashboard.js +17 -27
- package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
- package/lib/pages/admin-dashboard/customers/customer-details.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/customers/customer-details.js +2 -1
- package/lib/pages/admin-dashboard/customers/customer-details.js.map +1 -1
- package/lib/pages/admin-dashboard/customers/customer-token-list.d.ts +19 -0
- package/lib/pages/admin-dashboard/customers/customer-token-list.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/customers/customer-token-list.js +70 -0
- package/lib/pages/admin-dashboard/customers/customer-token-list.js.map +1 -0
- package/lib/pages/user/{generate-token-dialog.d.ts → generate-access-token-dialog.d.ts} +2 -2
- package/lib/pages/user/generate-access-token-dialog.d.ts.map +1 -0
- package/lib/pages/user/generate-access-token-dialog.js +33 -0
- package/lib/pages/user/generate-access-token-dialog.js.map +1 -0
- package/lib/pages/user/user-settings-tokens.js +3 -3
- package/lib/pages/user/user-settings-tokens.js.map +1 -1
- package/lib/utils.d.ts +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +10 -5
- package/lib/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/components/error-dialog.tsx +3 -5
- package/src/components/generate-token-dialog.tsx +167 -0
- package/src/components/rate-limiting/usage-stats/usage-stats-chart.tsx +18 -12
- package/src/components/timestamp.tsx +3 -1
- package/src/extension-registry-service.ts +49 -1
- package/src/extension-registry-types.ts +7 -0
- package/src/pages/admin-dashboard/admin-dashboard.tsx +17 -27
- package/src/pages/admin-dashboard/customers/customer-details.tsx +4 -0
- package/src/pages/admin-dashboard/customers/customer-token-list.tsx +135 -0
- package/src/pages/user/generate-access-token-dialog.tsx +49 -0
- package/src/pages/user/user-settings-tokens.tsx +3 -3
- package/src/utils.ts +9 -5
- package/lib/components/copy-to-clipboard.d.ts +0 -21
- package/lib/components/copy-to-clipboard.d.ts.map +0 -1
- package/lib/components/copy-to-clipboard.js +0 -25
- package/lib/components/copy-to-clipboard.js.map +0 -1
- package/lib/pages/user/generate-token-dialog.d.ts.map +0 -1
- package/lib/pages/user/generate-token-dialog.js +0 -79
- package/lib/pages/user/generate-token-dialog.js.map +0 -1
- package/src/components/copy-to-clipboard.tsx +0 -50
- package/src/pages/user/generate-token-dialog.tsx +0 -157
|
@@ -0,0 +1,135 @@
|
|
|
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, useEffect, useState, useContext, useRef } from 'react';
|
|
15
|
+
import {
|
|
16
|
+
Box,
|
|
17
|
+
Typography,
|
|
18
|
+
Divider,
|
|
19
|
+
List,
|
|
20
|
+
ListItem,
|
|
21
|
+
ListItemText,
|
|
22
|
+
IconButton,
|
|
23
|
+
Paper,
|
|
24
|
+
Button,
|
|
25
|
+
type PaperProps
|
|
26
|
+
} from '@mui/material';
|
|
27
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
28
|
+
import AddIcon from '@mui/icons-material/Add';
|
|
29
|
+
import { MainContext } from '../../../context';
|
|
30
|
+
import { Customer, isError, RateLimitToken } from '../../../extension-registry-types';
|
|
31
|
+
import { GenerateTokenDialog } from '../../../components/generate-token-dialog';
|
|
32
|
+
import { Timestamp } from "../../../components/timestamp";
|
|
33
|
+
|
|
34
|
+
const sectionPaperProps: PaperProps = { elevation: 1, sx: { p: 3, mb: 3 } };
|
|
35
|
+
|
|
36
|
+
export const CustomerTokenList: FunctionComponent<CustomerTokenListProps> = props => {
|
|
37
|
+
const { service, handleError } = useContext(MainContext);
|
|
38
|
+
const [tokens, setTokens] = useState<RateLimitToken[]>([]);
|
|
39
|
+
const [dialogOpen, setDialogOpen] = useState(false);
|
|
40
|
+
const abortController = useRef<AbortController>(new AbortController());
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
fetchTokens();
|
|
44
|
+
}, [props.customer]);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
return () => {
|
|
48
|
+
abortController.current.abort();
|
|
49
|
+
};
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const fetchTokens = async () => {
|
|
53
|
+
try {
|
|
54
|
+
const result = await service.admin.getCustomerRateLimitTokens(abortController.current, props.customer.name);
|
|
55
|
+
setTokens([...result]);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
handleError(err);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleGenerate = async (description: string): Promise<string> => {
|
|
62
|
+
const token = await service.admin.createCustomerRateLimitToken(abortController.current, props.customer.name, description);
|
|
63
|
+
await fetchTokens();
|
|
64
|
+
return token.value ?? '';
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleDelete = async (tokenId: number) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = await service.admin.deleteCustomerRateLimitToken(abortController.current, props.customer.name, tokenId);
|
|
70
|
+
if (isError(result)) {
|
|
71
|
+
throw result;
|
|
72
|
+
}
|
|
73
|
+
await fetchTokens();
|
|
74
|
+
} catch (err) {
|
|
75
|
+
handleError(err);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return <Paper {...sectionPaperProps}>
|
|
80
|
+
<Box
|
|
81
|
+
sx={{
|
|
82
|
+
display: 'flex',
|
|
83
|
+
justifyContent: 'space-between',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
mb: 1,
|
|
86
|
+
flexDirection: { xs: 'column', sm: 'column', md: 'row', lg: 'row', xl: 'row' }
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<Typography variant='h6'>Tokens</Typography>
|
|
90
|
+
<Button size='small' startIcon={<AddIcon />} onClick={() => setDialogOpen(true)}>
|
|
91
|
+
Generate Token
|
|
92
|
+
</Button>
|
|
93
|
+
</Box>
|
|
94
|
+
<Divider sx={{ mb: 1 }} />
|
|
95
|
+
{tokens.length === 0 ? (
|
|
96
|
+
<Typography variant='body2' color='text.secondary' sx={{ py: 1 }}>
|
|
97
|
+
No rate limiting tokens for this customer.
|
|
98
|
+
</Typography>
|
|
99
|
+
) : (
|
|
100
|
+
<List dense disablePadding>
|
|
101
|
+
{tokens.map(token => (
|
|
102
|
+
<ListItem
|
|
103
|
+
key={token.id}
|
|
104
|
+
secondaryAction={
|
|
105
|
+
<IconButton edge='end' size='small' color='error' onClick={() => handleDelete(token.id)} title='Delete token'>
|
|
106
|
+
<DeleteIcon fontSize='small' />
|
|
107
|
+
</IconButton>
|
|
108
|
+
}
|
|
109
|
+
>
|
|
110
|
+
<ListItemText
|
|
111
|
+
primary={
|
|
112
|
+
<Typography sx={{ fontWeight: 'bold', overflow: 'hidden', textOverflow: 'ellipsis' }}>{token.description || 'N/A'}</Typography>
|
|
113
|
+
}
|
|
114
|
+
secondary={
|
|
115
|
+
<Typography variant='body2'>Created: <Timestamp value={token.createdTimestamp}/></Typography>
|
|
116
|
+
}
|
|
117
|
+
/>
|
|
118
|
+
</ListItem>
|
|
119
|
+
))}
|
|
120
|
+
</List>
|
|
121
|
+
)}
|
|
122
|
+
|
|
123
|
+
<GenerateTokenDialog
|
|
124
|
+
open={dialogOpen}
|
|
125
|
+
onClose={() => setDialogOpen(false)}
|
|
126
|
+
onGenerate={handleGenerate}
|
|
127
|
+
onError={handleError}
|
|
128
|
+
title='Generate token'
|
|
129
|
+
/>
|
|
130
|
+
</Paper>;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export interface CustomerTokenListProps {
|
|
134
|
+
customer: Customer;
|
|
135
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2019 TypeFox and others
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
+
********************************************************************************/
|
|
10
|
+
|
|
11
|
+
import { FunctionComponent, useContext, useRef, useState } from 'react';
|
|
12
|
+
import { Button } from '@mui/material';
|
|
13
|
+
import { GenerateTokenDialog } from '../../components/generate-token-dialog';
|
|
14
|
+
import { isError } from '../../extension-registry-types';
|
|
15
|
+
import { MainContext } from '../../context';
|
|
16
|
+
|
|
17
|
+
export const GenerateAccessTokenDialog: FunctionComponent<GenerateTokenDialogProps> = props => {
|
|
18
|
+
const context = useContext(MainContext);
|
|
19
|
+
const abortController = useRef<AbortController>(new AbortController());
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
|
|
22
|
+
const handleGenerate = async (description: string): Promise<string> => {
|
|
23
|
+
if (!context.user) {
|
|
24
|
+
throw new Error('Not logged in');
|
|
25
|
+
}
|
|
26
|
+
const token = await context.service.createAccessToken(abortController.current, context.user, description);
|
|
27
|
+
if (isError(token)) {
|
|
28
|
+
throw token;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
props.handleTokenGenerated();
|
|
32
|
+
|
|
33
|
+
return token.value!;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return <>
|
|
37
|
+
<Button variant='outlined' onClick={() => setOpen(true)}>Generate new token</Button>
|
|
38
|
+
<GenerateTokenDialog
|
|
39
|
+
open={open}
|
|
40
|
+
onClose={() => setOpen(false)}
|
|
41
|
+
onGenerate={handleGenerate}
|
|
42
|
+
onError={context.handleError}
|
|
43
|
+
/>
|
|
44
|
+
</>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export interface GenerateTokenDialogProps {
|
|
48
|
+
handleTokenGenerated: () => void;
|
|
49
|
+
}
|
|
@@ -15,7 +15,7 @@ import { DelayedLoadIndicator } from '../../components/delayed-load-indicator';
|
|
|
15
15
|
import { Timestamp } from '../../components/timestamp';
|
|
16
16
|
import { PersonalAccessToken } from '../../extension-registry-types';
|
|
17
17
|
import { MainContext } from '../../context';
|
|
18
|
-
import {
|
|
18
|
+
import { GenerateAccessTokenDialog } from './generate-access-token-dialog';
|
|
19
19
|
import { UserSettingsRoutes } from './user-settings-routes';
|
|
20
20
|
import styled from '@mui/material/styles/styled';
|
|
21
21
|
|
|
@@ -105,7 +105,7 @@ export const UserSettingsTokens: FunctionComponent = () => {
|
|
|
105
105
|
<Box alignItems='center' overflow='auto'>
|
|
106
106
|
<Typography sx={{ fontWeight: 'bold', overflow: 'hidden', textOverflow: 'ellipsis' }}>{token.description}</Typography>
|
|
107
107
|
<Typography variant='body2'>Created: <Timestamp value={token.createdTimestamp}/></Typography>
|
|
108
|
-
<Typography variant='body2'>Expires: {token.expiresTimestamp ? <Timestamp value={token.expiresTimestamp}/> : 'never'}</Typography>
|
|
108
|
+
<Typography variant='body2'>Expires: {token.expiresTimestamp ? <Timestamp value={token.expiresTimestamp} isFutureTime={true} /> : 'never'}</Typography>
|
|
109
109
|
<Typography variant='body2'>Accessed: {token.accessedTimestamp ? <Timestamp value={token.accessedTimestamp}/> : 'never'}</Typography>
|
|
110
110
|
</Box>
|
|
111
111
|
<Box display='flex' alignItems='center'>
|
|
@@ -159,7 +159,7 @@ export const UserSettingsTokens: FunctionComponent = () => {
|
|
|
159
159
|
}}
|
|
160
160
|
>
|
|
161
161
|
<Box mr={1} mb={1}>
|
|
162
|
-
<
|
|
162
|
+
<GenerateAccessTokenDialog
|
|
163
163
|
handleTokenGenerated={handleTokenGenerated}
|
|
164
164
|
/>
|
|
165
165
|
</Box>
|
package/src/utils.ts
CHANGED
|
@@ -52,22 +52,26 @@ export function toLocalTime(timestamp?: string): string | undefined {
|
|
|
52
52
|
return new Intl.DateTimeFormat(undefined, options).format(date);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const
|
|
55
|
+
const msPerSecond = 1000;
|
|
56
|
+
const msPerMinute = msPerSecond * 60;
|
|
56
57
|
const msPerHour = msPerMinute * 60;
|
|
57
58
|
const msPerDay = msPerHour * 24;
|
|
58
59
|
const msPerMonth = msPerDay * 30.4;
|
|
59
60
|
const msPerYear = msPerDay * 365;
|
|
60
|
-
export function toRelativeTime(timestamp?: string): string | undefined {
|
|
61
|
+
export function toRelativeTime(timestamp?: string, isFutureTime: boolean = false): string | undefined {
|
|
61
62
|
if (!timestamp) {
|
|
62
63
|
return undefined;
|
|
63
64
|
}
|
|
64
65
|
const date = new Date(timestamp);
|
|
65
66
|
const elapsed = Date.now() - date.getTime();
|
|
66
67
|
|
|
67
|
-
if (
|
|
68
|
+
if (isFutureTime) {
|
|
68
69
|
const remaining = -elapsed;
|
|
69
|
-
if (remaining <
|
|
70
|
-
return
|
|
70
|
+
if (remaining < 0) {
|
|
71
|
+
return "now";
|
|
72
|
+
} else if (remaining < msPerMinute) {
|
|
73
|
+
const value = Math.round(remaining / msPerSecond);
|
|
74
|
+
return `in ${value} second${value !== 1 ? 's' : ''}`;
|
|
71
75
|
} else if (remaining < msPerHour) {
|
|
72
76
|
const value = Math.round(remaining / msPerMinute);
|
|
73
77
|
return `in ${value} minute${value !== 1 ? 's' : ''}`;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2020 TypeFox and others
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made available under the
|
|
5
|
-
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
-
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
********************************************************************************/
|
|
10
|
-
import { FunctionComponent, ReactElement } from 'react';
|
|
11
|
-
import { TooltipProps } from '@mui/material';
|
|
12
|
-
export declare const CopyToClipboard: FunctionComponent<CopyToClipboardProps>;
|
|
13
|
-
interface ChildProps {
|
|
14
|
-
copy: (content: any) => void;
|
|
15
|
-
}
|
|
16
|
-
export interface CopyToClipboardProps {
|
|
17
|
-
tooltipProps?: Partial<TooltipProps>;
|
|
18
|
-
children: (props: ChildProps) => ReactElement<any>;
|
|
19
|
-
}
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=copy-to-clipboard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copy-to-clipboard.d.ts","sourceRoot":"","sources":["../../src/components/copy-to-clipboard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;kFAQkF;AAElF,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAElE,OAAO,EAAW,YAAY,EAAE,MAAM,eAAe,CAAC;AAEtD,eAAO,MAAM,eAAe,EAAE,iBAAiB,CAAC,oBAAoB,CA0BnE,CAAC;AAEF,UAAU,UAAU;IAChB,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,YAAY,CAAC,GAAG,CAAC,CAAC;CACtD"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/********************************************************************************
|
|
3
|
-
* Copyright (c) 2020 TypeFox and others
|
|
4
|
-
*
|
|
5
|
-
* This program and the accompanying materials are made available under the
|
|
6
|
-
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
-
* http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
-
*
|
|
9
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
10
|
-
********************************************************************************/
|
|
11
|
-
import { useState } from 'react';
|
|
12
|
-
import copy from 'clipboard-copy';
|
|
13
|
-
import { Tooltip } from '@mui/material';
|
|
14
|
-
export const CopyToClipboard = props => {
|
|
15
|
-
const [showTooltip, setTooltip] = useState(false);
|
|
16
|
-
const handleOnTooltipClose = () => {
|
|
17
|
-
setTooltip(false);
|
|
18
|
-
};
|
|
19
|
-
const onCopy = (content) => {
|
|
20
|
-
copy(content);
|
|
21
|
-
setTooltip(true);
|
|
22
|
-
};
|
|
23
|
-
return (_jsx(Tooltip, { open: showTooltip, title: 'Copied to clipboard!', leaveDelay: 1500, onClose: handleOnTooltipClose, disableHoverListener: true, ...props.tooltipProps ?? {}, children: props.children({ copy: onCopy }) }));
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=copy-to-clipboard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copy-to-clipboard.js","sourceRoot":"","sources":["../../src/components/copy-to-clipboard.tsx"],"names":[],"mappings":";AAAA;;;;;;;;kFAQkF;AAElF,OAAO,EAAmC,QAAQ,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,IAAI,MAAM,gBAAgB,CAAC;AAClC,OAAO,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAC;AAEtD,MAAM,CAAC,MAAM,eAAe,GAA4C,KAAK,CAAC,EAAE;IAC5E,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAE3D,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAC9B,UAAU,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,OAAa,EAAE,EAAE;QAC7B,IAAI,CAAC,OAAO,CAAC,CAAC;QACd,UAAU,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,OAAO,CACH,KAAC,OAAO,IACJ,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,oBAAoB,EAC7B,oBAAoB,WAChB,KAAK,CAAC,YAAY,IAAI,EAAE,YAGxB,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAsB,GAEnD,CACb,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-token-dialog.d.ts","sourceRoot":"","sources":["../../../src/pages/user/generate-token-dialog.tsx"],"names":[],"mappings":"AAAA;;;;;;;;kFAQkF;AAElF,OAAO,EAAe,iBAAiB,EAA2C,MAAM,OAAO,CAAC;AAShG,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,CAAC,wBAAwB,CAqI3E,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACrC,oBAAoB,EAAE,MAAM,IAAI,CAAC;CACpC"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
/********************************************************************************
|
|
3
|
-
* Copyright (c) 2019 TypeFox and others
|
|
4
|
-
*
|
|
5
|
-
* This program and the accompanying materials are made available under the
|
|
6
|
-
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
-
* http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
-
*
|
|
9
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
10
|
-
********************************************************************************/
|
|
11
|
-
import { useContext, useEffect, useState, useRef } from 'react';
|
|
12
|
-
import { Button, Dialog, DialogTitle, DialogContent, DialogContentText, Box, TextField, DialogActions, Typography } from '@mui/material';
|
|
13
|
-
import { ButtonWithProgress } from '../../components/button-with-progress';
|
|
14
|
-
import { CopyToClipboard } from '../../components/copy-to-clipboard';
|
|
15
|
-
import { isError } from '../../extension-registry-types';
|
|
16
|
-
import { MainContext } from '../../context';
|
|
17
|
-
const TOKEN_DESCRIPTION_SIZE = 255;
|
|
18
|
-
export const GenerateTokenDialog = props => {
|
|
19
|
-
const [open, setOpen] = useState(false);
|
|
20
|
-
const [posted, setPosted] = useState(false);
|
|
21
|
-
const [description, setDescription] = useState('');
|
|
22
|
-
const [descriptionError, setDescriptionError] = useState();
|
|
23
|
-
const [token, setToken] = useState();
|
|
24
|
-
const context = useContext(MainContext);
|
|
25
|
-
const abortController = useRef(new AbortController());
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
document.addEventListener('keydown', handleEnter);
|
|
28
|
-
return () => {
|
|
29
|
-
abortController.current.abort();
|
|
30
|
-
document.removeEventListener('keydown', handleEnter);
|
|
31
|
-
};
|
|
32
|
-
}, []);
|
|
33
|
-
const handleOpenDialog = () => {
|
|
34
|
-
setOpen(true);
|
|
35
|
-
setPosted(false);
|
|
36
|
-
setDescription('');
|
|
37
|
-
setToken(undefined);
|
|
38
|
-
};
|
|
39
|
-
const handleClose = () => setOpen(false);
|
|
40
|
-
const handleDescriptionChange = (event) => {
|
|
41
|
-
const description = event.target.value;
|
|
42
|
-
let descriptionError;
|
|
43
|
-
if (description.length > TOKEN_DESCRIPTION_SIZE) {
|
|
44
|
-
descriptionError = `The description must not be longer than ${TOKEN_DESCRIPTION_SIZE} characters.`;
|
|
45
|
-
}
|
|
46
|
-
setDescription(description);
|
|
47
|
-
setDescriptionError(descriptionError);
|
|
48
|
-
};
|
|
49
|
-
const handleGenerate = async () => {
|
|
50
|
-
if (!context.user) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
setPosted(true);
|
|
54
|
-
try {
|
|
55
|
-
const token = await context.service.createAccessToken(abortController.current, context.user, description);
|
|
56
|
-
if (isError(token)) {
|
|
57
|
-
throw token;
|
|
58
|
-
}
|
|
59
|
-
setToken(token);
|
|
60
|
-
props.handleTokenGenerated();
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
context.handleError(err);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
const handleEnter = (e) => {
|
|
67
|
-
if (e.code === 'Enter' && open && !token) {
|
|
68
|
-
handleGenerate();
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
return _jsxs(_Fragment, { children: [_jsx(Button, { variant: 'outlined', onClick: handleOpenDialog, children: "Generate new token" }), _jsxs(Dialog, { open: open, onClose: handleClose, children: [_jsx(DialogTitle, { children: "Generate new token" }), _jsxs(DialogContent, { children: [_jsx(DialogContentText, { children: "Describe where you will use this token." }), _jsx(Box, { my: 2, children: _jsx(TextField, { disabled: Boolean(token), fullWidth: true, label: 'Token Description', error: Boolean(descriptionError), helperText: descriptionError, onChange: handleDescriptionChange }) }), _jsx(TextField, { disabled: !token, margin: 'dense', label: 'Generated Token...', fullWidth: true, multiline: true, variant: 'outlined', rows: 4, value: token ? token.value : '' }), token ?
|
|
72
|
-
_jsx(Box, { children: _jsx(Typography, { sx: { color: 'red', fontWeight: 'bold' }, children: "Copy and paste this token to a safe place. It will not be displayed again." }) }) : null] }), _jsxs(DialogActions, { children: [token ?
|
|
73
|
-
_jsx(CopyToClipboard, { tooltipProps: { placement: 'left' }, children: ({ copy }) => (_jsx(Button, { autoFocus: true, variant: 'contained', color: 'secondary', onClick: () => {
|
|
74
|
-
copy(token.value);
|
|
75
|
-
setTimeout(handleClose, 700);
|
|
76
|
-
}, children: "Copy" })) }) : null, _jsx(Button, { onClick: handleClose, color: 'secondary', children: token ? 'Close' : 'Cancel' }), !token ?
|
|
77
|
-
_jsx(ButtonWithProgress, { autoFocus: true, sx: { ml: 1 }, error: Boolean(descriptionError), working: posted, onClick: handleGenerate, children: "Generate Token" }) : null] })] })] });
|
|
78
|
-
};
|
|
79
|
-
//# sourceMappingURL=generate-token-dialog.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-token-dialog.js","sourceRoot":"","sources":["../../../src/pages/user/generate-token-dialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2020 TypeFox and others
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made available under the
|
|
5
|
-
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
-
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
********************************************************************************/
|
|
10
|
-
|
|
11
|
-
import { FunctionComponent, ReactElement, useState } from 'react';
|
|
12
|
-
import copy from 'clipboard-copy';
|
|
13
|
-
import { Tooltip, TooltipProps } from '@mui/material';
|
|
14
|
-
|
|
15
|
-
export const CopyToClipboard: FunctionComponent<CopyToClipboardProps> = props => {
|
|
16
|
-
const [showTooltip, setTooltip] = useState<boolean>(false);
|
|
17
|
-
|
|
18
|
-
const handleOnTooltipClose = () => {
|
|
19
|
-
setTooltip(false);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const onCopy = (content: any) => {
|
|
23
|
-
copy(content);
|
|
24
|
-
setTooltip(true);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<Tooltip
|
|
29
|
-
open={showTooltip}
|
|
30
|
-
title={'Copied to clipboard!'}
|
|
31
|
-
leaveDelay={1500}
|
|
32
|
-
onClose={handleOnTooltipClose}
|
|
33
|
-
disableHoverListener
|
|
34
|
-
{...props.tooltipProps ?? {}}
|
|
35
|
-
>
|
|
36
|
-
{
|
|
37
|
-
props.children({ copy: onCopy }) as ReactElement<any>
|
|
38
|
-
}
|
|
39
|
-
</Tooltip>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
interface ChildProps {
|
|
44
|
-
copy: (content: any) => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface CopyToClipboardProps {
|
|
48
|
-
tooltipProps?: Partial<TooltipProps>;
|
|
49
|
-
children: (props: ChildProps) => ReactElement<any>;
|
|
50
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2019 TypeFox and others
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made available under the
|
|
5
|
-
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
-
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
********************************************************************************/
|
|
10
|
-
|
|
11
|
-
import { ChangeEvent, FunctionComponent, useContext, useEffect, useState, useRef } from 'react';
|
|
12
|
-
import { Button, Dialog, DialogTitle, DialogContent, DialogContentText, Box, TextField, DialogActions, Typography } from '@mui/material';
|
|
13
|
-
import { ButtonWithProgress } from '../../components/button-with-progress';
|
|
14
|
-
import { CopyToClipboard } from '../../components/copy-to-clipboard';
|
|
15
|
-
import { PersonalAccessToken, isError } from '../../extension-registry-types';
|
|
16
|
-
import { MainContext } from '../../context';
|
|
17
|
-
|
|
18
|
-
const TOKEN_DESCRIPTION_SIZE = 255;
|
|
19
|
-
|
|
20
|
-
export const GenerateTokenDialog: FunctionComponent<GenerateTokenDialogProps> = props => {
|
|
21
|
-
const [open, setOpen] = useState<boolean>(false);
|
|
22
|
-
const [posted, setPosted] = useState<boolean>(false);
|
|
23
|
-
const [description, setDescription] = useState<string>('');
|
|
24
|
-
const [descriptionError, setDescriptionError] = useState<string>();
|
|
25
|
-
const [token, setToken] = useState<PersonalAccessToken>();
|
|
26
|
-
|
|
27
|
-
const context = useContext(MainContext);
|
|
28
|
-
const abortController = useRef<AbortController>(new AbortController());
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
document.addEventListener('keydown', handleEnter);
|
|
32
|
-
return () => {
|
|
33
|
-
abortController.current.abort();
|
|
34
|
-
document.removeEventListener('keydown', handleEnter);
|
|
35
|
-
};
|
|
36
|
-
}, []);
|
|
37
|
-
|
|
38
|
-
const handleOpenDialog = () => {
|
|
39
|
-
setOpen(true);
|
|
40
|
-
setPosted(false);
|
|
41
|
-
setDescription('');
|
|
42
|
-
setToken(undefined);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const handleClose = () => setOpen(false);
|
|
46
|
-
|
|
47
|
-
const handleDescriptionChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
48
|
-
const description = event.target.value;
|
|
49
|
-
let descriptionError: string | undefined;
|
|
50
|
-
if (description.length > TOKEN_DESCRIPTION_SIZE) {
|
|
51
|
-
descriptionError = `The description must not be longer than ${TOKEN_DESCRIPTION_SIZE} characters.`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
setDescription(description);
|
|
55
|
-
setDescriptionError(descriptionError);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const handleGenerate = async () => {
|
|
59
|
-
if (!context.user) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
setPosted(true);
|
|
63
|
-
try {
|
|
64
|
-
const token = await context.service.createAccessToken(abortController.current, context.user, description);
|
|
65
|
-
if (isError(token)) {
|
|
66
|
-
throw token;
|
|
67
|
-
}
|
|
68
|
-
setToken(token);
|
|
69
|
-
props.handleTokenGenerated();
|
|
70
|
-
} catch (err) {
|
|
71
|
-
context.handleError(err);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const handleEnter = (e: KeyboardEvent) => {
|
|
76
|
-
if (e.code === 'Enter' && open && !token) {
|
|
77
|
-
handleGenerate();
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return <>
|
|
82
|
-
<Button variant='outlined' onClick={handleOpenDialog}>Generate new token</Button>
|
|
83
|
-
<Dialog open={open} onClose={handleClose}>
|
|
84
|
-
<DialogTitle>Generate new token</DialogTitle>
|
|
85
|
-
<DialogContent>
|
|
86
|
-
<DialogContentText>
|
|
87
|
-
Describe where you will use this token.
|
|
88
|
-
</DialogContentText>
|
|
89
|
-
<Box my={2}>
|
|
90
|
-
<TextField
|
|
91
|
-
disabled={Boolean(token)}
|
|
92
|
-
fullWidth
|
|
93
|
-
label='Token Description'
|
|
94
|
-
error={Boolean(descriptionError)}
|
|
95
|
-
helperText={descriptionError}
|
|
96
|
-
onChange={handleDescriptionChange} />
|
|
97
|
-
</Box>
|
|
98
|
-
<TextField
|
|
99
|
-
disabled={!token}
|
|
100
|
-
margin='dense'
|
|
101
|
-
label='Generated Token...'
|
|
102
|
-
fullWidth
|
|
103
|
-
multiline
|
|
104
|
-
variant='outlined'
|
|
105
|
-
rows={4}
|
|
106
|
-
value={token ? token.value : ''}
|
|
107
|
-
/>
|
|
108
|
-
{
|
|
109
|
-
token ?
|
|
110
|
-
<Box>
|
|
111
|
-
<Typography sx={{ color: 'red', fontWeight: 'bold' }}>
|
|
112
|
-
Copy and paste this token to a safe place. It will not be displayed again.
|
|
113
|
-
</Typography>
|
|
114
|
-
</Box> : null
|
|
115
|
-
}
|
|
116
|
-
</DialogContent>
|
|
117
|
-
<DialogActions>
|
|
118
|
-
{
|
|
119
|
-
token ?
|
|
120
|
-
<CopyToClipboard tooltipProps={{ placement: 'left' }}>
|
|
121
|
-
{({ copy }) => (
|
|
122
|
-
<Button
|
|
123
|
-
autoFocus
|
|
124
|
-
variant='contained'
|
|
125
|
-
color='secondary'
|
|
126
|
-
onClick={() => {
|
|
127
|
-
copy(token!.value);
|
|
128
|
-
setTimeout(handleClose, 700);
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
Copy
|
|
132
|
-
</Button>
|
|
133
|
-
)}
|
|
134
|
-
</CopyToClipboard> : null
|
|
135
|
-
}
|
|
136
|
-
<Button onClick={handleClose} color='secondary'>
|
|
137
|
-
{token ? 'Close' : 'Cancel'}
|
|
138
|
-
</Button>
|
|
139
|
-
{
|
|
140
|
-
!token ?
|
|
141
|
-
<ButtonWithProgress
|
|
142
|
-
autoFocus
|
|
143
|
-
sx={{ ml: 1 }}
|
|
144
|
-
error={Boolean(descriptionError)}
|
|
145
|
-
working={posted}
|
|
146
|
-
onClick={handleGenerate} >
|
|
147
|
-
Generate Token
|
|
148
|
-
</ButtonWithProgress> : null
|
|
149
|
-
}
|
|
150
|
-
</DialogActions>
|
|
151
|
-
</Dialog>
|
|
152
|
-
</>;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export interface GenerateTokenDialogProps {
|
|
156
|
-
handleTokenGenerated: () => void;
|
|
157
|
-
}
|