Connect process log view to store
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Mon, 3 Sep 2018 09:47:36 +0000 (11:47 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Mon, 3 Sep 2018 09:47:36 +0000 (11:47 +0200)
Feature #14100

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/components/code-snippet/code-snippet.tsx
src/store/process-logs-panel/process-logs-panel-actions.ts
src/store/workbench/workbench-actions.ts
src/views/process-log-panel/process-log-code-snippet.tsx
src/views/process-log-panel/process-log-form.tsx
src/views/process-log-panel/process-log-main-card.tsx
src/views/process-log-panel/process-log-panel.tsx

index dda607cd898a54b5e7386de529b09a227545236c..b622210f008eb1c95c43897c6f94e99560fa5cc2 100644 (file)
@@ -30,7 +30,7 @@ export const CodeSnippet = withStyles(styles)(
         <Typography component="div" className={classes.root}>
             {
                 lines.map((line: string, index: number) => {
-                    return <Typography key={index} component="div">{line}</Typography>;
+                    return <Typography key={index} component="pre">{line}</Typography>;
                 })
             }
         </Typography>
index 532ae113feec80d2461c0f64adf7ef4de0d055af..395d26fe5fb71d5120c6c3a7c07fc50da75043e4 100644 (file)
@@ -24,7 +24,7 @@ export const processLogsPanelActions = unionize({
 export type ProcessLogsPanelAction = UnionOf<typeof processLogsPanelActions>;
 
 export const setProcessLogsPanelFilter = (filter: string) =>
-     processLogsPanelActions.SET_PROCESS_LOGS_PANEL_FILTER(filter);
+    processLogsPanelActions.SET_PROCESS_LOGS_PANEL_FILTER(filter);
 
 export const initProcessLogsPanel = (processUuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
@@ -54,19 +54,22 @@ const loadContainerLogs = async (containerUuid: string, logService: LogService)
 };
 
 const createInitialLogPanelState = (logResources: LogResource[]) => {
-    const allLogs = logResources.map(({ properties }) => properties.text);
+    const allLogs = logsToLines(logResources);
     const groupedLogResources = groupBy(logResources, log => log.eventType);
     const groupedLogs = Object
         .keys(groupedLogResources)
         .reduce((grouped, key) => ({
             ...grouped,
-            [key]: groupedLogResources[key].map(({ properties }) => properties.text)
+            [key]: logsToLines(groupedLogResources[key])
         }), {});
     const filters = [SUMMARIZED_FILTER_TYPE, ...Object.keys(groupedLogs)];
     const logs = { [SUMMARIZED_FILTER_TYPE]: allLogs, ...groupedLogs };
     return { filters, logs };
 };
 
+const logsToLines = (logs: LogResource[]) => 
+    logs.map(({properties}) => properties.text);
+
 const MAX_AMOUNT_OF_LOGS = 10000;
 
 const SUMMARIZED_FILTER_TYPE = 'Summarized';
index 97fe549a639b23e23ffbcad389869d8e4a75bfcf..cbe91c3bd375413d7e016bb5171f3bc12eb7b7d9 100644 (file)
@@ -30,6 +30,7 @@ import * as collectionUpdateActions from '~/store/collections/collection-update-
 import * as collectionMoveActions from '~/store/collections/collection-move-actions';
 import * as processesActions from '../processes/processes-actions';
 import { getProcess } from '../processes/process';
+import { initProcessLogsPanel } from '../process-logs-panel/process-logs-panel-actions';
 
 
 export const loadWorkbench = () =>
@@ -187,8 +188,7 @@ export const loadProcess = (uuid: string) =>
 
 export const loadProcessLog = (uuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState) => {
-        dispatch<any>(loadProcess(uuid));
-        // ToDo: loadLog();
+        dispatch<any>(initProcessLogsPanel(uuid));
     };
 
 export const resourceIsNotLoaded = (uuid: string) =>
index 99388d66a21568ad35c9b461d65dbe13256d0142..ff6320eeaf03f76c711044b3bfc819a0c5c6e837 100644 (file)
@@ -19,7 +19,7 @@ const theme = createMuiTheme({
         }
     },
     typography: {
-        fontFamily: 'VT323'
+        fontFamily: 'monospace'
     }
 });
 
index dfac832f80e99e99cb1ded6cc6044f1bc7da15b2..698dcb446e74ba064d5d78fe26d43427a24d7b2a 100644 (file)
@@ -35,7 +35,7 @@ export const ProcessLogForm = withStyles(styles)(
                 </InputLabel>
                 <Select
                     value={selectedFilter.value}
-                    onChange={event => onChange}
+                    onChange={({ target }) => onChange({ label: target.innerText, value: target.value })}
                     input={<Input name="eventType" id="log-label-placeholder" />}
                     name="eventType">
                     {
index 09aaf08aca59fb11136805e4ea4ebc59b98ce18b..3158a375c151d34705484a617e04ed1b5da296dc 100644 (file)
@@ -15,6 +15,7 @@ import { MoreOptionsIcon, ProcessIcon } from '~/components/icon/icon';
 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';
 
 type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link';
 
@@ -55,10 +56,10 @@ interface ProcessLogMainCardDataProps {
 export type ProcessLogMainCardProps = ProcessLogMainCardDataProps & CodeSnippetDataProps & ProcessLogFormDataProps & ProcessLogFormActionProps;
 
 export const ProcessLogMainCard = withStyles(styles)(
-    ({ classes, process, selectedFilter, filters, onChange, lines }: ProcessLogMainCardProps & WithStyles<CssRules>) => 
+    ({ classes, process, selectedFilter, filters, onChange, lines }: ProcessLogMainCardProps & WithStyles<CssRules>) =>
         <Grid item xs={12}>
             <Link to={`/processes/${process.containerRequest.uuid}`} className={classes.backLink}>
-                <BackIcon className={classes.backIcon}/> Back
+                <BackIcon className={classes.backIcon} /> Back
             </Link>
             <Card className={classes.card}>
                 <CardHeader
@@ -79,20 +80,25 @@ export const ProcessLogMainCard = withStyles(styles)(
                     }
                     subheader={process.containerRequest.description} />
                 <CardContent>
-                    <Grid container spacing={24} alignItems='center'>
-                        <Grid item xs={6}>
-                            <ProcessLogForm selectedFilter={selectedFilter} filters={filters} onChange={onChange} />
+                    {lines.length > 0
+                        ? < Grid container spacing={24} alignItems='center'>
+                            <Grid item xs={6}>
+                                <ProcessLogForm selectedFilter={selectedFilter} filters={filters} onChange={onChange} />
+                            </Grid>
+                            <Grid item xs={6} className={classes.link}>
+                                <Typography component='div'>
+                                    Container log for request {process.containerRequest.uuid}
+                                </Typography>
+                            </Grid>
+                            <Grid item xs={12}>
+                                <ProcessLogCodeSnippet lines={lines} />
+                            </Grid>
                         </Grid>
-                        <Grid item xs={6} className={classes.link}>
-                            <Typography component='div'>
-                                Container log for request {process.containerRequest.uuid}
-                            </Typography>
-                        </Grid>
-                        <Grid item xs={12}>
-                            <ProcessLogCodeSnippet lines={lines}/>
-                        </Grid>
-                    </Grid>
+                        : <DefaultView
+                            icon={ProcessIcon}
+                            messages={['No logs yet']} />
+                    }
                 </CardContent>
             </Card>
-        </Grid>
+        </Grid >
 );
\ No newline at end of file
index 0936d3bded186b6ad61002db346c5329731aed65..e4ceae39886c2b832bf5ab3fddb2b25b478c8f8b 100644 (file)
@@ -10,19 +10,8 @@ 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';
-
-const SELECT_OPTIONS = [
-    { label: 'Dispatch', value: 'dispatch' },
-    { label: 'Crunch-run', value: 'crunch-run' },
-    { label: 'Crunchstat', value: 'crunchstat' },
-    { label: 'Hoststat', value: 'hoststat' },
-    { label: 'Node-info', value: 'node-info' },
-    { label: 'Arv-mount', value: 'arv-mount' },
-    { label: 'Stdout', value: 'stdout' },
-    { label: 'Stderr', value: 'stderr' }
-];
-
-const lines = ['Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum', 'Lorem Ipsum'];
+import { getProcessPanelLogs } from '~/store/process-logs-panel/process-logs-panel';
+import { setProcessLogsPanelFilter } from '~/store/process-logs-panel/process-logs-panel-actions';
 
 export interface Log {
     object_uuid: string;
@@ -37,15 +26,15 @@ export interface FilterOption {
     value: string;
 }
 
-const mapStateToProps = ({ router, resources }: RootState): ProcessLogPanelRootDataProps => {
+const mapStateToProps = ({ router, resources, processLogsPanel }: RootState): ProcessLogPanelRootDataProps => {
     const pathname = router.location ? router.location.pathname : '';
     const match = matchProcessLogRoute(pathname);
     const uuid = match ? match.params.id : '';
     return {
         process: getProcess(uuid)(resources),
-        selectedFilter: SELECT_OPTIONS[0],
-        filters: SELECT_OPTIONS,
-        lines
+        selectedFilter: { label: processLogsPanel.selectedFilter, value: processLogsPanel.selectedFilter },
+        filters: processLogsPanel.filters.map(filter => ({ label: filter, value: filter })),
+        lines: getProcessPanelLogs(processLogsPanel)
     };
 };
 
@@ -53,7 +42,9 @@ const mapDispatchToProps = (dispatch: Dispatch): ProcessLogPanelRootActionProps
     onContextMenu: (event: React.MouseEvent<HTMLElement>) => {
         dispatch<any>(openProcessContextMenu(event));
     },
-    onChange: (filter: FilterOption) => { return; }
+    onChange: (filter: FilterOption) => {
+        dispatch(setProcessLogsPanelFilter(filter.value));
+    }
 });
 
 export const ProcessLogPanel = connect(mapStateToProps, mapDispatchToProps)(ProcessLogPanelRoot);