bd700bcd4344b0295d35799933afc803b32b5122
[arvados-workbench2.git] / src / views / process-panel / process-log-card.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import {
7     StyleRulesCallback,
8     WithStyles,
9     withStyles,
10     Card,
11     CardHeader,
12     IconButton,
13     CardContent,
14     Tooltip,
15     Grid,
16     Typography,
17 } from '@material-ui/core';
18 import { ArvadosTheme } from 'common/custom-theme';
19 import {
20     CloseIcon,
21     CollectionIcon,
22     LogIcon,
23     MaximizeIcon
24 } from 'components/icon/icon';
25 import { Process } from 'store/processes/process';
26 import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view';
27 import {
28     FilterOption,
29     ProcessLogForm
30 } from 'views/process-panel/process-log-form';
31 import { ProcessLogCodeSnippet } from 'views/process-panel/process-log-code-snippet';
32 import { DefaultView } from 'components/default-view/default-view';
33 import { CodeSnippetDataProps } from 'components/code-snippet/code-snippet';
34
35 type CssRules = 'card' | 'content' | 'title' | 'iconHeader' | 'header' | 'root' | 'logViewer' | 'logViewerContainer';
36
37 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
38     card: {
39         height: '100%'
40     },
41     header: {
42         paddingTop: theme.spacing.unit,
43         paddingBottom: theme.spacing.unit,
44     },
45     content: {
46         padding: theme.spacing.unit * 0,
47         height: '100%',
48     },
49     logViewer: {
50         height: '100%',
51     },
52     logViewerContainer: {
53         height: '100%',
54     },
55     title: {
56         overflow: 'hidden',
57         paddingTop: theme.spacing.unit * 0.5
58     },
59     iconHeader: {
60         fontSize: '1.875rem',
61         color: theme.customs.colors.green700
62     },
63     root: {
64         height: '100%',
65     },
66 });
67
68 export interface ProcessLogsCardDataProps {
69     process: Process;
70     selectedFilter: FilterOption;
71     filters: FilterOption[];
72 }
73
74 export interface ProcessLogsCardActionProps {
75     onLogFilterChange: (filter: FilterOption) => void;
76     navigateToLog: (uuid: string) => void;
77 }
78
79 type ProcessLogsCardProps = ProcessLogsCardDataProps
80     & ProcessLogsCardActionProps
81     & CodeSnippetDataProps
82     & WithStyles<CssRules>
83     & MPVPanelProps;
84
85 export const ProcessLogsCard = withStyles(styles)(
86     ({ classes, process, filters, selectedFilter, lines, onLogFilterChange, navigateToLog,
87         doHidePanel, doMaximizePanel, panelMaximized, panelName }: ProcessLogsCardProps) =>
88         <Grid item className={classes.root} xs={12}>
89             <Card className={classes.card}>
90                 <CardHeader className={classes.header}
91                     avatar={<LogIcon className={classes.iconHeader} />}
92                     action={<Grid container direction='row' alignItems='center'>
93                         <Grid item>
94                             <ProcessLogForm selectedFilter={selectedFilter}
95                                 filters={filters} onChange={onLogFilterChange} />
96                         </Grid>
97                         <Grid item>
98                             <Tooltip title="Go to Log collection" disableFocusListener>
99                                 <IconButton onClick={() => navigateToLog(process.containerRequest.logUuid!)}>
100                                     <CollectionIcon />
101                                 </IconButton>
102                             </Tooltip>
103                         </Grid>
104                         { doMaximizePanel && !panelMaximized &&
105                         <Tooltip title={`Maximize ${panelName || 'panel'}`} disableFocusListener>
106                             <IconButton onClick={doMaximizePanel}><MaximizeIcon /></IconButton>
107                         </Tooltip> }
108                         { doHidePanel && <Grid item>
109                             <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
110                                 <IconButton onClick={doHidePanel}><CloseIcon /></IconButton>
111                             </Tooltip>
112                         </Grid> }
113                     </Grid>}
114                     title={
115                         <Typography noWrap variant='h6' className={classes.title}>
116                             Logs
117                         </Typography>}
118                 />
119                 <CardContent className={classes.content}>
120                     {lines.length > 0
121                         ? < Grid
122                             className={classes.logViewerContainer}
123                             container
124                             spacing={24}
125                             direction='column'>
126                             <Grid className={classes.logViewer} item xs>
127                                 <ProcessLogCodeSnippet lines={lines} />
128                             </Grid>
129                         </Grid>
130                         : <DefaultView
131                             icon={LogIcon}
132                             messages={['No logs yet']} />
133                     }
134                 </CardContent>
135             </Card>
136         </Grid >
137 );
138