<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>
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) => {
};
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';
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 = () =>
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) =>
}
},
typography: {
- fontFamily: 'VT323'
+ fontFamily: 'monospace'
}
});
</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">
{
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';
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
}
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
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;
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)
};
};
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);