Merge branch '13857-workflow-view'
[arvados-workbench2.git] / src / views-components / data-explorer / renderers.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { Grid, Typography, withStyles, Tooltip, IconButton } from '@material-ui/core';
7 import { FavoriteStar } from '../favorite-star/favorite-star';
8 import { ResourceKind, TrashableResource } from '~/models/resource';
9 import { ProjectIcon, CollectionIcon, ProcessIcon, DefaultIcon, WorkflowIcon, ShareIcon } from '~/components/icon/icon';
10 import { formatDate, formatFileSize } from '~/common/formatters';
11 import { resourceLabel } from '~/common/labels';
12 import { connect } from 'react-redux';
13 import { RootState } from '~/store/store';
14 import { getResource } from '~/store/resources/resources';
15 import { GroupContentsResource } from '~/services/groups-service/groups-service';
16 import { getProcess, Process, getProcessStatus, getProcessStatusColor } from '~/store/processes/process';
17 import { ArvadosTheme } from '~/common/custom-theme';
18 import { compose } from 'redux';
19 import { WorkflowResource } from '~/models/workflow';
20 import { ResourceStatus } from '~/views/workflow-panel/workflow-panel-view';
21 import { getUuidPrefix } from '~/store/workflow-panel/workflow-panel-actions';
22
23 export const renderName = (item: { name: string; uuid: string, kind: string }) =>
24     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
25         <Grid item>
26             {renderIcon(item)}
27         </Grid>
28         <Grid item>
29             <Typography color="primary" style={{ width: '450px' }}>
30                 {item.name}
31             </Typography>
32         </Grid>
33         <Grid item>
34             <Typography variant="caption">
35                 <FavoriteStar resourceUuid={item.uuid} />
36             </Typography>
37         </Grid>
38     </Grid>;
39
40 export const ResourceName = connect(
41     (state: RootState, props: { uuid: string }) => {
42         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
43         return resource || { name: '', uuid: '', kind: '' };
44     })(renderName);
45
46 export const renderIcon = (item: { kind: string }) => {
47     switch (item.kind) {
48         case ResourceKind.PROJECT:
49             return <ProjectIcon />;
50         case ResourceKind.COLLECTION:
51             return <CollectionIcon />;
52         case ResourceKind.PROCESS:
53             return <ProcessIcon />;
54         case ResourceKind.WORKFLOW:
55             return <WorkflowIcon />;
56         default:
57             return <DefaultIcon />;
58     }
59 };
60
61 export const renderDate = (date?: string) => {
62     return <Typography noWrap style={{ minWidth: '100px' }}>{formatDate(date)}</Typography>;
63 };
64
65 export const renderWorkflowName = (item: { name: string; uuid: string, kind: string, ownerUuid: string }) =>
66     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
67         <Grid item>
68             {renderIcon(item)}
69         </Grid>
70         <Grid item>
71             <Typography color="primary" style={{ width: '100px' }}>
72                 {item.name}
73             </Typography>
74         </Grid>
75     </Grid>;
76
77 export const RosurceWorkflowName = connect(
78     (state: RootState, props: { uuid: string }) => {
79         const resource = getResource<WorkflowResource>(props.uuid)(state.resources);
80         return resource || { name: '', uuid: '', kind: '', ownerUuid: '' };
81     })(renderWorkflowName);
82
83 const getPublicUuid = (uuidPrefix: string) => {
84     return `${uuidPrefix}-tpzed-anonymouspublic`;
85 };
86
87 // do share onClick
88 export const resourceShare = (uuidPrefix: string, ownerUuid?: string) => {
89     return <Tooltip title="Share">
90         <IconButton onClick={() => undefined}>
91             {ownerUuid === getPublicUuid(uuidPrefix) ? <ShareIcon /> : null}
92         </IconButton>
93     </Tooltip>;
94 };
95
96 export const ResourceShare = connect(
97     (state: RootState, props: { uuid: string }) => {
98         const resource = getResource<WorkflowResource>(props.uuid)(state.resources);
99         const uuidPrefix = getUuidPrefix(state);
100         return {
101             ownerUuid: resource ? resource.ownerUuid : '',
102             uuidPrefix
103         };
104     })((props: { ownerUuid?: string, uuidPrefix: string }) => resourceShare(props.uuidPrefix, props.ownerUuid));
105
106 export const renderWorkflowStatus = (uuidPrefix: string, ownerUuid?: string) => {
107     if (ownerUuid === getPublicUuid(uuidPrefix)) {
108         return renderStatus(ResourceStatus.PUBLIC);
109     } else {
110         return renderStatus(ResourceStatus.PRIVATE);
111     }
112 };
113
114 const renderStatus = (status: string) =>
115     <Typography noWrap style={{ width: '60px' }}>{status}</Typography>;
116
117 export const ResourceWorkflowStatus = connect(
118     (state: RootState, props: { uuid: string }) => {
119         const resource = getResource<WorkflowResource>(props.uuid)(state.resources);
120         const uuidPrefix = getUuidPrefix(state);
121         return {
122             ownerUuid: resource ? resource.ownerUuid : '',
123             uuidPrefix
124         };
125     })((props: { ownerUuid?: string, uuidPrefix: string }) => renderWorkflowStatus(props.uuidPrefix, props.ownerUuid));
126
127 export const ResourceLastModifiedDate = connect(
128     (state: RootState, props: { uuid: string }) => {
129         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
130         return { date: resource ? resource.modifiedAt : '' };
131     })((props: { date: string }) => renderDate(props.date));
132
133 export const ResourceTrashDate = connect(
134     (state: RootState, props: { uuid: string }) => {
135         const resource = getResource<TrashableResource>(props.uuid)(state.resources);
136         return { date: resource ? resource.trashAt : '' };
137     })((props: { date: string }) => renderDate(props.date));
138
139 export const ResourceDeleteDate = connect(
140     (state: RootState, props: { uuid: string }) => {
141         const resource = getResource<TrashableResource>(props.uuid)(state.resources);
142         return { date: resource ? resource.deleteAt : '' };
143     })((props: { date: string }) => renderDate(props.date));
144
145 export const renderFileSize = (fileSize?: number) =>
146     <Typography noWrap style={{ minWidth: '45px' }}>
147         {formatFileSize(fileSize)}
148     </Typography>;
149
150 export const ResourceFileSize = connect(
151     (state: RootState, props: { uuid: string }) => {
152         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
153         return {};
154     })((props: { fileSize?: number }) => renderFileSize(props.fileSize));
155
156 export const renderOwner = (owner: string) =>
157     <Typography noWrap color="primary" >
158         {owner}
159     </Typography>;
160
161 export const ResourceOwner = connect(
162     (state: RootState, props: { uuid: string }) => {
163         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
164         return { owner: resource ? resource.ownerUuid : '' };
165     })((props: { owner: string }) => renderOwner(props.owner));
166
167 export const renderType = (type: string) =>
168     <Typography noWrap>
169         {resourceLabel(type)}
170     </Typography>;
171
172 export const ResourceType = connect(
173     (state: RootState, props: { uuid: string }) => {
174         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
175         return { type: resource ? resource.kind : '' };
176     })((props: { type: string }) => renderType(props.type));
177
178 export const ProcessStatus = compose(
179     connect((state: RootState, props: { uuid: string }) => {
180         return { process: getProcess(props.uuid)(state.resources) };
181     }),
182     withStyles({}, { withTheme: true }))
183     ((props: { process?: Process, theme: ArvadosTheme }) => {
184         const status = props.process ? getProcessStatus(props.process) : "-";
185         return <Typography
186             noWrap
187             align="center"
188             style={{ color: getProcessStatusColor(status, props.theme) }} >
189             {status}
190         </Typography>;
191     });