From 1534032e710b57106297576edb28e84b652a76f0 Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Tue, 11 Sep 2018 11:10:45 +0200 Subject: [PATCH] Implement command dialog, update code snippet styles Feature #14130 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- src/components/code-snippet/code-snippet.tsx | 11 ++-- .../default-code-snippet.tsx | 6 +-- .../context-menu/context-menu-actions.ts | 9 ++-- .../processes/process-command-actions.ts | 27 ++++++++++ .../action-sets/process-action-set.ts | 3 +- .../process-command-dialog.tsx | 46 +++++++++++++++++ .../process-log-main-card.tsx | 50 +++++++++++-------- .../process-log-panel-root.tsx | 5 +- .../process-log-panel/process-log-panel.tsx | 8 ++- .../process-panel/process-panel-root.tsx | 10 ++-- src/views/process-panel/process-panel.tsx | 4 +- .../process-panel/process-subprocesses.tsx | 6 ++- src/views/workbench/workbench.tsx | 26 +++++----- 13 files changed, 146 insertions(+), 65 deletions(-) create mode 100644 src/store/processes/process-command-actions.ts create mode 100644 src/views-components/process-command-dialog/process-command-dialog.tsx diff --git a/src/components/code-snippet/code-snippet.tsx b/src/components/code-snippet/code-snippet.tsx index eb0e709a9b..6cba299f15 100644 --- a/src/components/code-snippet/code-snippet.tsx +++ b/src/components/code-snippet/code-snippet.tsx @@ -5,15 +5,13 @@ import * as React from 'react'; import { StyleRulesCallback, WithStyles, Typography, withStyles, Theme } from '@material-ui/core'; import { ArvadosTheme } from '~/common/custom-theme'; +import * as classNames from 'classnames'; type CssRules = 'root'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ root: { boxSizing: 'border-box', - width: '100%', - height: 'auto', - maxHeight: '550px', overflow: 'auto', padding: theme.spacing.unit } @@ -21,13 +19,16 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ export interface CodeSnippetDataProps { lines: string[]; + className?: string; } type CodeSnippetProps = CodeSnippetDataProps & WithStyles; export const CodeSnippet = withStyles(styles)( - ({ classes, lines }: CodeSnippetProps) => - + ({ classes, lines, className }: CodeSnippetProps) => + { lines.map((line: string, index: number) => { return {line}; diff --git a/src/components/default-code-snippet/default-code-snippet.tsx b/src/components/default-code-snippet/default-code-snippet.tsx index b8c0a7be93..e8b89f321c 100644 --- a/src/components/default-code-snippet/default-code-snippet.tsx +++ b/src/components/default-code-snippet/default-code-snippet.tsx @@ -23,9 +23,7 @@ const theme = createMuiTheme({ } }); -type DefaultCodeSnippet = CodeSnippetDataProps; - -export const DefaultCodeSnippet = (props: DefaultCodeSnippet) => +export const DefaultCodeSnippet = (props: CodeSnippetDataProps) => - + ; \ No newline at end of file diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts index eabf41ae71..d85059d6e1 100644 --- a/src/store/context-menu/context-menu-actions.ts +++ b/src/store/context-menu/context-menu-actions.ts @@ -13,6 +13,7 @@ import { UserResource } from '~/models/user'; import { isSidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions'; import { extractUuidKind, ResourceKind } from '~/models/resource'; import { matchProcessRoute } from '~/routes/routes'; +import { Process } from '~/store/processes/process'; export const contextMenuActions = unionize({ OPEN_CONTEXT_MENU: ofType<{ position: ContextMenuPosition, resource: ContextMenuResource }>(), @@ -84,14 +85,10 @@ export const openSidePanelContextMenu = (event: React.MouseEvent, i } }; -export const openProcessContextMenu = (event: React.MouseEvent) => +export const openProcessContextMenu = (event: React.MouseEvent, process: Process) => (dispatch: Dispatch, getState: () => RootState) => { - const { location } = getState().router; - const pathname = location ? location.pathname : ''; - const match = matchProcessRoute(pathname); - const uuid = match ? match.params.id : ''; const resource = { - uuid, + uuid: process.containerRequest.uuid, ownerUuid: '', kind: ResourceKind.PROCESS, name: '', diff --git a/src/store/processes/process-command-actions.ts b/src/store/processes/process-command-actions.ts new file mode 100644 index 0000000000..de55a2cb50 --- /dev/null +++ b/src/store/processes/process-command-actions.ts @@ -0,0 +1,27 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { dialogActions } from '~/store/dialog/dialog-actions'; +import { RootState } from '../store'; +import { Dispatch } from 'redux'; +import { getProcess } from '~/store/processes/process'; + +export const PROCESS_COMMAND_DIALOG_NAME = 'processCommandDialog'; + +export interface ProcessCommandDialogData { + command: string; + processName: string; +} + +export const openProcessCommandDialog = (processUuid: string) => + (dispatch: Dispatch, getState: () => RootState) => { + const process = getProcess(processUuid)(getState().resources); + if (process) { + const data: ProcessCommandDialogData = { + command: process.containerRequest.command.join(' '), + processName: process.containerRequest.name, + }; + dispatch(dialogActions.OPEN_DIALOG({ id: PROCESS_COMMAND_DIALOG_NAME, data })); + } + }; diff --git a/src/views-components/context-menu/action-sets/process-action-set.ts b/src/views-components/context-menu/action-sets/process-action-set.ts index 1a291dfd50..107f1828c6 100644 --- a/src/views-components/context-menu/action-sets/process-action-set.ts +++ b/src/views-components/context-menu/action-sets/process-action-set.ts @@ -14,6 +14,7 @@ import { navigateToProcessLogs } from '~/store/navigation/navigation-action'; import { openMoveProcessDialog } from '~/store/processes/process-move-actions'; import { openProcessUpdateDialog } from "~/store/processes/process-update-actions"; import { openCopyProcessDialog } from '~/store/processes/process-copy-actions'; +import { openProcessCommandDialog } from '../../../store/processes/process-command-actions'; export const processActionSet: ContextMenuActionSet = [[ { @@ -71,7 +72,7 @@ export const processActionSet: ContextMenuActionSet = [[ icon: CommandIcon, name: "Command", execute: (dispatch, resource) => { - // add code + dispatch(openProcessCommandDialog(resource.uuid)); } }, { diff --git a/src/views-components/process-command-dialog/process-command-dialog.tsx b/src/views-components/process-command-dialog/process-command-dialog.tsx new file mode 100644 index 0000000000..4bde68d8be --- /dev/null +++ b/src/views-components/process-command-dialog/process-command-dialog.tsx @@ -0,0 +1,46 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from "react"; +import { Dialog, DialogTitle, DialogActions, Button, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core'; +import { withDialog } from "~/store/dialog/with-dialog"; +import { PROCESS_COMMAND_DIALOG_NAME } from '~/store/processes/process-command-actions'; +import { WithDialogProps } from '~/store/dialog/with-dialog'; +import { ProcessCommandDialogData } from '~/store/processes/process-command-actions'; +import { DefaultCodeSnippet } from "~/components/default-code-snippet/default-code-snippet"; +import { compose } from 'redux'; + +type CssRules = 'codeSnippet'; + +const styles: StyleRulesCallback = theme => ({ + codeSnippet: { + marginLeft: theme.spacing.unit * 3, + marginRight: theme.spacing.unit * 3, + } +}); + +export const ProcessCommandDialog = compose( + withDialog(PROCESS_COMMAND_DIALOG_NAME), + withStyles(styles), +)( + (props: WithDialogProps & WithStyles) => + + {`Command - ${props.data.processName}`} + + + + + +); \ No newline at end of file diff --git a/src/views/process-log-panel/process-log-main-card.tsx b/src/views/process-log-panel/process-log-main-card.tsx index 66811f47b8..7ac40c0cc6 100644 --- a/src/views/process-log-panel/process-log-main-card.tsx +++ b/src/views/process-log-panel/process-log-main-card.tsx @@ -16,6 +16,7 @@ import { ArvadosTheme } from '~/common/custom-theme'; import { CodeSnippetDataProps } from '~/components/code-snippet/code-snippet'; import { BackIcon } from '~/components/icon/icon'; import { DefaultView } from '~/components/default-view/default-view'; +import { openContextMenu } from '../../store/context-menu/context-menu-actions'; type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link'; @@ -53,10 +54,18 @@ interface ProcessLogMainCardDataProps { process: Process; } -export type ProcessLogMainCardProps = ProcessLogMainCardDataProps & CodeSnippetDataProps & ProcessLogFormDataProps & ProcessLogFormActionProps; +export interface ProcessLogMainCardActionProps { + onContextMenu: (event: React.MouseEvent, process: Process) => void; +} + +export type ProcessLogMainCardProps = ProcessLogMainCardDataProps + & ProcessLogMainCardActionProps + & CodeSnippetDataProps + & ProcessLogFormDataProps + & ProcessLogFormActionProps; export const ProcessLogMainCard = withStyles(styles)( - ({ classes, process, selectedFilter, filters, onChange, lines }: ProcessLogMainCardProps & WithStyles) => + ({ classes, process, selectedFilter, filters, onChange, lines, onContextMenu }: ProcessLogMainCardProps & WithStyles) => Back @@ -65,34 +74,35 @@ export const ProcessLogMainCard = withStyles(styles)( } action={ -
- - - - - -
- } + onContextMenu(event, process)} aria-label="More options"> + + + + } title={ {process.containerRequest.name} - - } + } subheader={process.containerRequest.description} /> {lines.length > 0 - ? < Grid container spacing={24} alignItems='center'> - - - - - - Go to Log collection + ? < Grid + container + spacing={24} + direction='column'> + + + + + + + Go to Log collection + - + diff --git a/src/views/process-log-panel/process-log-panel-root.tsx b/src/views/process-log-panel/process-log-panel-root.tsx index 0845a41097..38870c4027 100644 --- a/src/views/process-log-panel/process-log-panel-root.tsx +++ b/src/views/process-log-panel/process-log-panel-root.tsx @@ -10,14 +10,13 @@ import { ProcessLogFormDataProps, ProcessLogFormActionProps } from '~/views/proc import { DefaultView } from '~/components/default-view/default-view'; import { ProcessIcon } from '~/components/icon/icon'; import { CodeSnippetDataProps } from '~/components/code-snippet/code-snippet'; +import { ProcessLogMainCardActionProps } from './process-log-main-card'; export type ProcessLogPanelRootDataProps = { process?: Process; } & ProcessLogFormDataProps & CodeSnippetDataProps; -export type ProcessLogPanelRootActionProps = { - onContextMenu: (event: React.MouseEvent) => void; -} & ProcessLogFormActionProps; +export type ProcessLogPanelRootActionProps = ProcessLogMainCardActionProps & ProcessLogFormActionProps; export type ProcessLogPanelRootProps = ProcessLogPanelRootDataProps & ProcessLogPanelRootActionProps; diff --git a/src/views/process-log-panel/process-log-panel.tsx b/src/views/process-log-panel/process-log-panel.tsx index 2b2d684277..d578e78456 100644 --- a/src/views/process-log-panel/process-log-panel.tsx +++ b/src/views/process-log-panel/process-log-panel.tsx @@ -2,13 +2,11 @@ // // SPDX-License-Identifier: AGPL-3.0 -import * as React from 'react'; import { RootState } from '~/store/store'; import { connect } from 'react-redux'; import { getProcess } from '~/store/processes/process'; import { Dispatch } from 'redux'; import { openProcessContextMenu } from '~/store/context-menu/context-menu-actions'; -import { matchProcessLogRoute } from '~/routes/routes'; import { ProcessLogPanelRootDataProps, ProcessLogPanelRootActionProps, ProcessLogPanelRoot } from './process-log-panel-root'; import { getProcessPanelLogs } from '~/store/process-logs-panel/process-logs-panel'; import { setProcessLogsPanelFilter } from '~/store/process-logs-panel/process-logs-panel-actions'; @@ -39,10 +37,10 @@ const mapStateToProps = (state: RootState): ProcessLogPanelRootDataProps => { }; const mapDispatchToProps = (dispatch: Dispatch): ProcessLogPanelRootActionProps => ({ - onContextMenu: (event: React.MouseEvent) => { - dispatch(openProcessContextMenu(event)); + onContextMenu: (event, process) => { + dispatch(openProcessContextMenu(event, process)); }, - onChange: (filter: FilterOption) => { + onChange: filter => { dispatch(setProcessLogsPanelFilter(filter.value)); } }); diff --git a/src/views/process-panel/process-panel-root.tsx b/src/views/process-panel/process-panel-root.tsx index d12704bcf4..ab8af36ffb 100644 --- a/src/views/process-panel/process-panel-root.tsx +++ b/src/views/process-panel/process-panel-root.tsx @@ -20,19 +20,19 @@ export interface ProcessPanelRootDataProps { } export interface ProcessPanelRootActionProps { - onContextMenu: (event: React.MouseEvent) => void; + onContextMenu: (event: React.MouseEvent, process: Process) => void; onToggle: (status: string) => void; } export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRootActionProps; -export const ProcessPanelRoot = (props: ProcessPanelRootProps) => - props.process +export const ProcessPanelRoot = ({process, ...props}: ProcessPanelRootProps) => + process ? + process={process} + onContextMenu={event => props.onContextMenu(event, process)} /> ({ - onContextMenu: event => { - dispatch(openProcessContextMenu(event)); + onContextMenu: (event, process) => { + dispatch(openProcessContextMenu(event, process)); }, onToggle: status => { dispatch(toggleProcessPanelFilter(status)); diff --git a/src/views/process-panel/process-subprocesses.tsx b/src/views/process-panel/process-subprocesses.tsx index 6e00deb0f1..d3f87701fc 100644 --- a/src/views/process-panel/process-subprocesses.tsx +++ b/src/views/process-panel/process-subprocesses.tsx @@ -9,14 +9,16 @@ import { Process } from '~/store/processes/process'; export interface ProcessSubprocessesDataProps { subprocesses: Array; - onContextMenu: (event: React.MouseEvent) => void; + onContextMenu: (event: React.MouseEvent, process: Process) => void; } export const ProcessSubprocesses = ({ onContextMenu, subprocesses }: ProcessSubprocessesDataProps) => { return {subprocesses.map(subprocess => - + onContextMenu(event, subprocess)} + subprocess={subprocess} /> )} ; diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index 56fabeba0c..5c4648b6d3 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -40,8 +40,9 @@ import { MoveCollectionDialog } from '~/views-components/dialog-forms/move-colle import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/files-upload-collection-dialog'; import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog'; import { TrashPanel } from "~/views/trash-panel/trash-panel"; -import { MainContentBar } from '../../views-components/main-content-bar/main-content-bar'; +import { MainContentBar } from '~/views-components/main-content-bar/main-content-bar'; import { Grid } from '@material-ui/core'; +import { ProcessCommandDialog } from '~/views-components/process-command-dialog/process-command-dialog'; type CssRules = 'root' | 'contentWrapper' | 'content' | 'appBar'; @@ -144,24 +145,25 @@ export const Workbench = withStyles(styles)( } - - - - - - + + + + - - - - - + + + + + + + + ; } -- 2.30.2