[ARVADOS-WORKBENCH2] created: 1.2.0-219-g8dc7e5f
Git user
git at public.curoverse.com
Fri Aug 31 04:38:00 EDT 2018
at 8dc7e5fc6f2d2a7ce853f935a0a84dacb8c0585f (commit)
commit 8dc7e5fc6f2d2a7ce853f935a0a84dacb8c0585f
Author: Janicki Artur <artur.janicki at contractors.roche.com>
Date: Fri Aug 31 10:37:45 2018 +0200
init view log with props
Feature #14098
Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki at contractors.roche.com>
diff --git a/src/routes/routes.ts b/src/routes/routes.ts
index 20dd135..6901d87 100644
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@ -8,7 +8,7 @@ import { matchPath } from 'react-router';
import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind } from '~/models/resource';
import { getProjectUrl } from '../models/project';
import { getCollectionUrl } from '~/models/collection';
-import { loadProject, loadFavorites, loadCollection } from '~/store/workbench/workbench-actions';
+import { loadProject, loadFavorites, loadCollection, loadProcessLog } from '~/store/workbench/workbench-actions';
import { loadProcess } from '~/store/processes/processes-actions';
export const Routes = {
@@ -18,6 +18,7 @@ export const Routes = {
COLLECTIONS: `/collections/:id(${RESOURCE_UUID_PATTERN})`,
PROCESSES: `/processes/:id(${RESOURCE_UUID_PATTERN})`,
FAVORITES: '/favorites',
+ PROCESS_LOGS: `/process-logs/:id(${RESOURCE_UUID_PATTERN})`
};
export const getResourceUrl = (uuid: string) => {
@@ -34,6 +35,8 @@ export const getResourceUrl = (uuid: string) => {
export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
+export const getProcessLogUrl = (uuid: string) => `/process-logs/${uuid}`;
+
export const addRouteChangeHandlers = (history: History, store: RootStore) => {
const handler = handleLocationChange(store);
handler(history.location);
@@ -59,12 +62,16 @@ export const matchCollectionRoute = (route: string) =>
export const matchProcessRoute = (route: string) =>
matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
+export const matchProcessLogRoute = (route: string) =>
+ matchPath<ResourceRouteParams>(route, { path: Routes.PROCESS_LOGS });
const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
const projectMatch = matchProjectRoute(pathname);
const collectionMatch = matchCollectionRoute(pathname);
const favoriteMatch = matchFavoritesRoute(pathname);
const processMatch = matchProcessRoute(pathname);
+ const processLogMatch = matchProcessLogRoute(pathname);
+
if (projectMatch) {
store.dispatch(loadProject(projectMatch.params.id));
} else if (collectionMatch) {
@@ -73,5 +80,7 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
store.dispatch(loadFavorites());
} else if (processMatch) {
store.dispatch(loadProcess(processMatch.params.id));
+ } else if (processLogMatch) {
+ store.dispatch(loadProcessLog(processLogMatch.params.id));
}
};
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index cf66a53..3440a30 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -12,6 +12,7 @@ import { ProjectResource } from '~/models/project';
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';
export const contextMenuActions = unionize({
OPEN_CONTEXT_MENU: ofType<{ position: ContextMenuPosition, resource: ContextMenuResource }>(),
@@ -69,8 +70,15 @@ export const openSidePanelContextMenu = (event: React.MouseEvent<HTMLElement>, i
export const openProcessContextMenu = (event: React.MouseEvent<HTMLElement>) =>
(dispatch: Dispatch, getState: () => RootState) => {
+ const { location } = getState().router;
+ const pathname = location ? location.pathname : '';
+ // ToDo: We get error from matchProcessRoute
+ // const match = matchProcessRoute(pathname);
+ // console.log('match: ', match);
+ // const uuid = match ? match.params.id : '';
+ const uuid = pathname.split('/').slice(-1)[0];
const resource = {
- uuid: '',
+ uuid,
name: '',
description: '',
kind: ContextMenuKind.PROCESS
diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index 188acf1..6298e25 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -9,7 +9,7 @@ import { getCollectionUrl } from "~/models/collection";
import { getProjectUrl } from "~/models/project";
import { SidePanelTreeCategory } from '../side-panel-tree/side-panel-tree-actions';
-import { Routes, getProcessUrl } from '~/routes/routes';
+import { Routes, getProcessUrl, getProcessLogUrl } from '~/routes/routes';
export const navigateTo = (uuid: string) =>
async (dispatch: Dispatch) => {
@@ -20,7 +20,7 @@ export const navigateTo = (uuid: string) =>
dispatch<any>(navigateToCollection(uuid));
} else if (kind === ResourceKind.CONTAINER_REQUEST) {
dispatch<any>(navigateToProcess(uuid));
- }
+ }
if (uuid === SidePanelTreeCategory.FAVORITES) {
dispatch<any>(navigateToFavorites);
}
@@ -33,3 +33,5 @@ export const navigateToProject = compose(push, getProjectUrl);
export const navigateToCollection = compose(push, getCollectionUrl);
export const navigateToProcess = compose(push, getProcessUrl);
+
+export const navigateToProcessLogs = compose(push, getProcessLogUrl);
\ No newline at end of file
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 3c68c00..97fe549 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -185,6 +185,12 @@ export const loadProcess = (uuid: string) =>
}
};
+export const loadProcessLog = (uuid: string) =>
+ async (dispatch: Dispatch, getState: () => RootState) => {
+ dispatch<any>(loadProcess(uuid));
+ // ToDo: loadLog();
+ };
+
export const resourceIsNotLoaded = (uuid: string) =>
snackbarActions.OPEN_SNACKBAR({
message: `Resource identified by ${uuid} is not loaded.`
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 5d679f5..cc4f8e8 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
@@ -10,6 +10,7 @@ import {
AdvancedIcon, RemoveIcon, ReRunProcessIcon, LogIcon
} from "~/components/icon/icon";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
+import { navigateToProcessLogs } from '~/store/navigation/navigation-action';
export const processActionSet: ContextMenuActionSet = [[
{
@@ -84,7 +85,7 @@ export const processActionSet: ContextMenuActionSet = [[
icon: LogIcon,
name: "Log",
execute: (dispatch, resource) => {
- // add code
+ dispatch<any>(navigateToProcessLogs(resource.uuid));
}
},
{
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index 5d94766..d92948c 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -64,5 +64,6 @@ export enum ContextMenuKind {
COLLECTION_FILES_ITEM = "CollectionFilesItem",
COLLECTION = 'Collection',
COLLECTION_RESOURCE = 'CollectionResource',
- PROCESS = "Process"
+ PROCESS = "Process",
+ PROCESS_LOGS = "ProcessLogs"
}
diff --git a/src/views/process-log-panel/process-log-form.tsx b/src/views/process-log-panel/process-log-form.tsx
new file mode 100644
index 0000000..dfac832
--- /dev/null
+++ b/src/views/process-log-panel/process-log-form.tsx
@@ -0,0 +1,49 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { withStyles, WithStyles, StyleRulesCallback, FormControl, InputLabel, Select, MenuItem, Input } from '@material-ui/core';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { FilterOption } from './process-log-panel';
+
+type CssRules = 'formControl';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ formControl: {
+ minWidth: 200
+ }
+});
+
+export interface ProcessLogFormDataProps {
+ selectedFilter: FilterOption;
+ filters: FilterOption[];
+}
+
+export interface ProcessLogFormActionProps {
+ onChange: (filter: FilterOption) => void;
+}
+
+type ProcessLogFormProps = ProcessLogFormDataProps & ProcessLogFormActionProps & WithStyles<CssRules>;
+
+export const ProcessLogForm = withStyles(styles)(
+ ({ classes, selectedFilter, onChange, filters }: ProcessLogFormProps) =>
+ <form autoComplete="off">
+ <FormControl className={classes.formControl}>
+ <InputLabel shrink htmlFor="log-label-placeholder">
+ Log
+ </InputLabel>
+ <Select
+ value={selectedFilter.value}
+ onChange={event => onChange}
+ input={<Input name="eventType" id="log-label-placeholder" />}
+ name="eventType">
+ {
+ filters.map(option =>
+ <MenuItem key={option.value} value={option.value}>{option.label}</MenuItem>
+ )
+ }
+ </Select>
+ </FormControl>
+ </form>
+);
\ 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
new file mode 100644
index 0000000..db451ab
--- /dev/null
+++ b/src/views/process-log-panel/process-log-main-card.tsx
@@ -0,0 +1,71 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import {
+ StyleRulesCallback, WithStyles, withStyles, Card,
+ CardHeader, IconButton, CardContent, Grid, Typography, Tooltip
+} from '@material-ui/core';
+import { Process } from '~/store/processes/process';
+import { ProcessLogForm, ProcessLogFormDataProps, ProcessLogFormActionProps } from '~/views/process-log-panel/process-log-form';
+import { MoreOptionsIcon, ProcessIcon } from '~/components/icon/icon';
+import { ArvadosTheme } from '~/common/custom-theme';
+
+type CssRules = 'root' | 'card' | 'iconHeader';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ root: {
+
+ },
+ card: {
+ width: '100%'
+ },
+ iconHeader: {
+ fontSize: '1.875rem',
+ color: theme.customs.colors.green700
+ }
+});
+
+
+interface ProcessLogMainCardDataProps {
+ process: Process;
+}
+
+export type ProcessLogMainCardProps = ProcessLogMainCardDataProps & ProcessLogFormDataProps & ProcessLogFormActionProps;
+
+export const ProcessLogMainCard = withStyles(styles)(
+ ({ classes, process, selectedFilter, filters, onChange }: ProcessLogMainCardProps & WithStyles<CssRules>) =>
+ <Card className={classes.card}>
+ <CardHeader
+ avatar={<ProcessIcon className={classes.iconHeader} />}
+ action={
+ <div>
+ <IconButton aria-label="More options">
+ <MoreOptionsIcon />
+ </IconButton>
+ </div>
+ }
+ title={
+ <Tooltip title={process.containerRequest.name}>
+ <Typography noWrap variant="title">
+ {process.containerRequest.name}
+ </Typography>
+ </Tooltip>
+ }
+ subheader={process.containerRequest.description} />
+ <CardContent>
+ <Grid container spacing={24} alignItems='center'>
+ <Grid item xs={6}>
+ <ProcessLogForm selectedFilter={selectedFilter} filters={filters} onChange={onChange} />
+ </Grid>
+ <Grid item xs={6}>
+ Container log for request ardev-xvhdp-q3uqbfxeb6w64pm
+ </Grid>
+ <Grid item xs={12}>
+ {/* add snippet */}
+ </Grid>
+ </Grid>
+ </CardContent>
+ </Card>
+);
\ No newline at end of file
diff --git a/src/views/process-log-panel/process-log-panel-root.tsx b/src/views/process-log-panel/process-log-panel-root.tsx
new file mode 100644
index 0000000..fe8a5b1
--- /dev/null
+++ b/src/views/process-log-panel/process-log-panel-root.tsx
@@ -0,0 +1,36 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { Grid } from '@material-ui/core';
+import { Process } from '~/store/processes/process';
+import { ProcessLogMainCard } from '~/views/process-log-panel/process-log-main-card';
+import { ProcessLogFormDataProps, ProcessLogFormActionProps } from '~/views/process-log-panel/process-log-form';
+import { DefaultView } from '~/components/default-view/default-view';
+import { ProcessIcon } from '~/components/icon/icon';
+
+export type ProcessLogPanelRootDataProps = {
+ process?: Process;
+} & ProcessLogFormDataProps;
+
+export type ProcessLogPanelRootActionProps = {
+ onContextMenu: (event: React.MouseEvent<HTMLElement>) => void;
+} & ProcessLogFormActionProps;
+
+export type ProcessLogPanelRootProps = ProcessLogPanelRootDataProps & ProcessLogPanelRootActionProps;
+
+export const ProcessLogPanelRoot = (props: ProcessLogPanelRootProps) =>
+ props.process
+ ? <Grid container spacing={16}>
+ <ProcessLogMainCard
+ process={props.process}
+ {...props} />
+ </Grid>
+ : <Grid container
+ alignItems='center'
+ justify='center'>
+ <DefaultView
+ icon={ProcessIcon}
+ messages={['Process Log not found']} />
+ </Grid>;
diff --git a/src/views/process-log-panel/process-log-panel.tsx b/src/views/process-log-panel/process-log-panel.tsx
new file mode 100644
index 0000000..1ce06af
--- /dev/null
+++ b/src/views/process-log-panel/process-log-panel.tsx
@@ -0,0 +1,57 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// 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';
+
+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' }
+];
+
+export interface Log {
+ object_uuid: string;
+ event_at: string;
+ event_type: string;
+ summary: string;
+ properties: any;
+}
+
+export interface FilterOption {
+ label: string;
+ value: string;
+}
+
+const mapStateToProps = ({ router, resources }: 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: string[]
+ };
+};
+
+const mapDispatchToProps = (dispatch: Dispatch): ProcessLogPanelRootActionProps => ({
+ onContextMenu: (event: React.MouseEvent<HTMLElement>) => {
+ dispatch<any>(openProcessContextMenu(event));
+ },
+ onChange: (filter: FilterOption) => { return; }
+});
+
+export const ProcessLogPanel = connect(mapStateToProps, mapDispatchToProps)(ProcessLogPanelRoot);
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index ef5fe21..21396d1 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -27,6 +27,7 @@ import { MultipleFilesRemoveDialog } from '~/views-components/file-remove-dialog
import { Routes } from '~/routes/routes';
import { SidePanel } from '~/views-components/side-panel/side-panel';
import { ProcessPanel } from '~/views/process-panel/process-panel';
+import { ProcessLogPanel } from '~/views/process-log-panel/process-log-panel';
import { Breadcrumbs } from '~/views-components/breadcrumbs/breadcrumbs';
import { CreateProjectDialog } from '~/views-components/dialog-forms/create-project-dialog';
import { CreateCollectionDialog } from '~/views-components/dialog-forms/create-collection-dialog';
@@ -35,7 +36,6 @@ import { UpdateCollectionDialog } from '~/views-components/dialog-forms/update-c
import { UpdateProjectDialog } from '~/views-components/dialog-forms/update-project-dialog';
import { MoveProjectDialog } from '~/views-components/dialog-forms/move-project-dialog';
import { MoveCollectionDialog } from '~/views-components/dialog-forms/move-collection-dialog';
-
import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/files-upload-collection-dialog';
import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
@@ -167,6 +167,7 @@ export const Workbench = withStyles(styles)(
<Route path={Routes.COLLECTIONS} component={CollectionPanel} />
<Route path={Routes.FAVORITES} component={FavoritePanel} />
<Route path={Routes.PROCESSES} component={ProcessPanel} />
+ <Route path={Routes.PROCESS_LOGS} component={ProcessLogPanel} />
</Switch>
</div>
{user && <DetailsPanel />}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list