From 4e1ff9a1613f897f24bc59a981e94d8bf227fd10 Mon Sep 17 00:00:00 2001 From: Janicki Artur Date: Thu, 6 Dec 2018 17:35:48 +0100 Subject: [PATCH] add help dialog, change attrs dialog and store Feature #14500_admin_api_tokens Arvados-DCO-1.1-Signed-off-by: Janicki Artur --- .../api-client-authorizations-actions.ts | 10 +++ .../attributes-dialog.tsx | 23 +++++++ .../help-dialog.tsx | 66 +++++++++++++++++++ .../main-content-bar/main-content-bar.tsx | 3 +- .../api-client-authorization-panel-root.tsx | 27 ++++++-- .../api-client-authorization-panel.tsx | 4 ++ src/views/workbench/workbench.tsx | 2 + 7 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 src/views-components/api-client-authorizations-dialog/help-dialog.tsx diff --git a/src/store/api-client-authorizations/api-client-authorizations-actions.ts b/src/store/api-client-authorizations/api-client-authorizations-actions.ts index 5f52aa2a..8ed8a389 100644 --- a/src/store/api-client-authorizations/api-client-authorizations-actions.ts +++ b/src/store/api-client-authorizations/api-client-authorizations-actions.ts @@ -21,6 +21,7 @@ export type ApiClientAuthorizationsActions = UnionOf async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { @@ -69,4 +70,13 @@ export const removeApiClientAuthorization = (uuid: string) => } catch (e) { return; } + }; + +export const openApiClientAuthorizationsHelpDialog = () => + (dispatch: Dispatch, getState: () => RootState) => { + const apiHost = getState().properties.apiHost; + const user = getState().auth.user; + const email = user ? user.email : ''; + const apiToken = getState().auth.apiToken; + dispatch(dialogActions.OPEN_DIALOG({ id: API_CLIENT_AUTHORIZATION_HELP_DIALOG, data: { apiHost, apiToken, email } })); }; \ No newline at end of file diff --git a/src/views-components/api-client-authorizations-dialog/attributes-dialog.tsx b/src/views-components/api-client-authorizations-dialog/attributes-dialog.tsx index 662c8808..e7defd64 100644 --- a/src/views-components/api-client-authorizations-dialog/attributes-dialog.tsx +++ b/src/views-components/api-client-authorizations-dialog/attributes-dialog.tsx @@ -12,6 +12,7 @@ import { WithDialogProps, withDialog } from "~/store/dialog/with-dialog"; import { API_CLIENT_AUTHORIZATION_ATTRIBUTES_DIALOG } from '~/store/api-client-authorizations/api-client-authorizations-actions'; import { ArvadosTheme } from '~/common/custom-theme'; import { ApiClientAuthorization } from '~/models/api-client-authorization'; +import { formatDate } from '~/common/formatters'; type CssRules = 'root'; @@ -41,6 +42,28 @@ export const AttributesApiClientAuthorizationDialog = compose( {data.apiClientAuthorization.uuid} Owner uuid {data.apiClientAuthorization.ownerUuid} + API Client ID + {data.apiClientAuthorization.apiClientId} + API Token + {data.apiClientAuthorization.apiToken} + Created by IP address + {data.apiClientAuthorization.createdByIpAddress || '(none)'} + Default owner + {data.apiClientAuthorization.defaultOwnerUuid || '(none)'} + Expires at + {formatDate(data.apiClientAuthorization.expiresAt) || '(none)'} + Last used at + {formatDate(data.apiClientAuthorization.lastUsedAt) || '(none)'} + Last used by IP address + {data.apiClientAuthorization.lastUsedByIpAddress || '(none)'} + Scopes + {JSON.stringify(data.apiClientAuthorization.scopes || '(none)')} + User ID + {data.apiClientAuthorization.userId || '(none)'} + Created at + {formatDate(data.apiClientAuthorization.createdAt) || '(none)'} + Updated at + {formatDate(data.apiClientAuthorization.updatedAt) || '(none)'} } diff --git a/src/views-components/api-client-authorizations-dialog/help-dialog.tsx b/src/views-components/api-client-authorizations-dialog/help-dialog.tsx new file mode 100644 index 00000000..d2802fad --- /dev/null +++ b/src/views-components/api-client-authorizations-dialog/help-dialog.tsx @@ -0,0 +1,66 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from "react"; +import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography } from "@material-ui/core"; +import { WithDialogProps } from "~/store/dialog/with-dialog"; +import { withDialog } from '~/store/dialog/with-dialog'; +import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet'; +import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles'; +import { ArvadosTheme } from '~/common/custom-theme'; +import { compose } from "redux"; +import { API_CLIENT_AUTHORIZATION_HELP_DIALOG } from '~/store/api-client-authorizations/api-client-authorizations-actions'; + +type CssRules = 'codeSnippet'; + +const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + codeSnippet: { + borderRadius: theme.spacing.unit * 0.5, + border: `1px solid ${theme.palette.grey["400"]}`, + '& pre': { + fontSize: '0.815rem' + } + } +}); + +interface HelpApiClientAuthorizationDataProps { + apiHost: string; + apiToken: string; + email: string; +} + +export const HelpApiClientAuthorizationDialog = compose( + withDialog(API_CLIENT_AUTHORIZATION_HELP_DIALOG), + withStyles(styles))( + (props: WithDialogProps & WithStyles) => + + HELP: + + + {/* // lines={snippetText2(props.data)} /> */} + + + + + + ); + +const snippetText = (data: HelpApiClientAuthorizationDataProps) => `### Pasting the following lines at a shell prompt will allow Arvados SDKs +### to authenticate to your account, ${data.email} + +read ARVADOS_API_TOKEN < { const pathname = router.location ? router.location.pathname : ''; return !Routes.matchWorkflowRoute(pathname) && !Routes.matchVirtualMachineRoute(pathname) && !Routes.matchRepositoriesRoute(pathname) && !Routes.matchSshKeysRoute(pathname) && - !Routes.matchKeepServicesRoute(pathname) && !Routes.matchComputeNodesRoute(pathname); + !Routes.matchKeepServicesRoute(pathname) && !Routes.matchComputeNodesRoute(pathname) && + !Routes.matchApiClientAuthorizationsRoute(pathname); }; export const MainContentBar = connect((state: RootState) => ({ diff --git a/src/views/api-client-authorization-panel/api-client-authorization-panel-root.tsx b/src/views/api-client-authorization-panel/api-client-authorization-panel-root.tsx index bd50a593..52921b30 100644 --- a/src/views/api-client-authorization-panel/api-client-authorization-panel-root.tsx +++ b/src/views/api-client-authorization-panel/api-client-authorization-panel-root.tsx @@ -8,16 +8,23 @@ import { Table, TableHead, TableRow, TableCell, TableBody, Tooltip, IconButton } from '@material-ui/core'; import { ArvadosTheme } from '~/common/custom-theme'; -import { MoreOptionsIcon } from '~/components/icon/icon'; +import { MoreOptionsIcon, HelpIcon } from '~/components/icon/icon'; import { ApiClientAuthorization } from '~/models/api-client-authorization'; +import { formatDate } from '~/common/formatters'; -type CssRules = 'root' | 'tableRow'; +type CssRules = 'root' | 'tableRow' | 'helpIconGrid' | 'tableGrid'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ root: { width: '100%', overflow: 'auto' }, + helpIconGrid: { + textAlign: 'right' + }, + tableGrid: { + marginTop: theme.spacing.unit + }, tableRow: { '& td, th': { whiteSpace: 'nowrap' @@ -27,6 +34,7 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ export interface ApiClientAuthorizationPanelRootActionProps { openRowOptions: (event: React.MouseEvent, keepService: ApiClientAuthorization) => void; + openHelpDialog: () => void; } export interface ApiClientAuthorizationPanelRootDataProps { @@ -38,10 +46,17 @@ type ApiClientAuthorizationPanelRootProps = ApiClientAuthorizationPanelRootActio & ApiClientAuthorizationPanelRootDataProps & WithStyles; export const ApiClientAuthorizationPanelRoot = withStyles(styles)( - ({ classes, hasApiClientAuthorizations, apiClientAuthorizations, openRowOptions }: ApiClientAuthorizationPanelRootProps) => + ({ classes, hasApiClientAuthorizations, apiClientAuthorizations, openRowOptions, openHelpDialog }: ApiClientAuthorizationPanelRootProps) => - {hasApiClientAuthorizations && + {hasApiClientAuthorizations && + + + + + + + @@ -67,8 +82,8 @@ export const ApiClientAuthorizationPanelRoot = withStyles(styles)( {apiClientAuthorizatio.apiToken} {apiClientAuthorizatio.createdByIpAddress || '(none)'} {apiClientAuthorizatio.defaultOwnerUuid || '(none)'} - {apiClientAuthorizatio.expiresAt || '(none)'} - {apiClientAuthorizatio.lastUsedAt || '(none)'} + {formatDate(apiClientAuthorizatio.expiresAt) || '(none)'} + {formatDate(apiClientAuthorizatio.lastUsedAt) || '(none)'} {apiClientAuthorizatio.lastUsedByIpAddress || '(none)'} {JSON.stringify(apiClientAuthorizatio.scopes)} {apiClientAuthorizatio.userId} diff --git a/src/views/api-client-authorization-panel/api-client-authorization-panel.tsx b/src/views/api-client-authorization-panel/api-client-authorization-panel.tsx index 06d32bfe..75b79abf 100644 --- a/src/views/api-client-authorization-panel/api-client-authorization-panel.tsx +++ b/src/views/api-client-authorization-panel/api-client-authorization-panel.tsx @@ -11,6 +11,7 @@ import { ApiClientAuthorizationPanelRootActionProps } from '~/views/api-client-authorization-panel/api-client-authorization-panel-root'; import { openApiClientAuthorizationContextMenu } from '~/store/context-menu/context-menu-actions'; +import { openApiClientAuthorizationsHelpDialog } from '~/store/api-client-authorizations/api-client-authorizations-actions'; const mapStateToProps = (state: RootState): ApiClientAuthorizationPanelRootDataProps => { return { @@ -22,6 +23,9 @@ const mapStateToProps = (state: RootState): ApiClientAuthorizationPanelRootDataP const mapDispatchToProps = (dispatch: Dispatch): ApiClientAuthorizationPanelRootActionProps => ({ openRowOptions: (event, apiClientAuthorization) => { dispatch(openApiClientAuthorizationContextMenu(event, apiClientAuthorization)); + }, + openHelpDialog: () => { + dispatch(openApiClientAuthorizationsHelpDialog()); } }); diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index 1f2c6020..1f5a5035 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -70,6 +70,7 @@ import { AttributesComputeNodeDialog } from '~/views-components/compute-nodes-di import { AttributesKeepServiceDialog } from '~/views-components/keep-services-dialog/attributes-dialog'; import { AttributesSshKeyDialog } from '~/views-components/ssh-keys-dialog/attributes-dialog'; import { VirtualMachineAttributesDialog } from '~/views-components/virtual-machines-dialog/attributes-dialog'; +import { HelpApiClientAuthorizationDialog } from '~/views-components/api-client-authorizations-dialog/help-dialog'; type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content'; @@ -169,6 +170,7 @@ export const WorkbenchPanel = + -- 2.30.2