Merge branch '21128-toolbar-context-menu'
[arvados-workbench2.git] / src / views-components / advanced-tab-dialog / advanced-tab-dialog.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 { Dialog, DialogActions, Button, StyleRulesCallback, WithStyles, withStyles, DialogTitle, DialogContent, Tabs, Tab, DialogContentText } from '@material-ui/core';
7 import { WithDialogProps } from 'store/dialog/with-dialog';
8 import { withDialog } from "store/dialog/with-dialog";
9 import { compose } from 'redux';
10 import { AdvancedTabDialogData, ADVANCED_TAB_DIALOG } from "store/advanced-tab/advanced-tab";
11 import { DefaultCodeSnippet } from "components/default-code-snippet/default-code-snippet";
12 import { MetadataTab } from 'views-components/advanced-tab-dialog/metadataTab';
13 import { LinkResource } from "models/link";
14 import { ListResults } from "services/common-service/common-service";
15
16 type CssRules = 'content' | 'codeSnippet' | 'spacing';
17
18 const styles: StyleRulesCallback<CssRules> = theme => ({
19     content: {
20         paddingTop: theme.spacing.unit * 3,
21         minHeight: '400px',
22         minWidth: '1232px'
23     },
24     codeSnippet: {
25         borderRadius: theme.spacing.unit * 0.5,
26         border: '1px solid',
27         borderColor: theme.palette.grey["400"],
28         maxHeight: '400px'
29     },
30     spacing: {
31         paddingBottom: theme.spacing.unit * 2
32     },
33 });
34
35 export const AdvancedTabDialog = compose(
36     withDialog(ADVANCED_TAB_DIALOG),
37     withStyles(styles),
38 )(
39     class extends React.Component<WithDialogProps<AdvancedTabDialogData> & WithStyles<CssRules>>{
40         state = {
41             value: 0,
42         };
43
44         componentDidMount() {
45             this.setState({ value: 0 });
46         }
47
48         handleChange = (event: React.MouseEvent<HTMLElement>, value: number) => {
49             this.setState({ value });
50         }
51         render() {
52             const { classes, open, closeDialog } = this.props;
53             const { value } = this.state;
54             const {
55                 apiResponse,
56                 metadata,
57                 pythonHeader,
58                 pythonExample,
59                 cliGetHeader,
60                 cliGetExample,
61                 cliUpdateHeader,
62                 cliUpdateExample,
63                 curlHeader,
64                 curlExample,
65                 uuid,
66             } = this.props.data;
67             return <Dialog
68                 open={open}
69                 maxWidth="lg"
70                 onClose={closeDialog}
71                 onExit={() => this.setState({ value: 0 })} >
72                 <DialogTitle>API Details</DialogTitle>
73                 <Tabs value={value} onChange={this.handleChange} fullWidth>
74                     <Tab label="API RESPONSE" />
75                     <Tab label="METADATA" />
76                     <Tab label="PYTHON EXAMPLE" />
77                     <Tab label="CLI EXAMPLE" />
78                     <Tab label="CURL EXAMPLE" />
79                 </Tabs>
80                 <DialogContent className={classes.content}>
81                     {value === 0 && <div>{dialogContentExample(apiResponse, classes)}</div>}
82                     {value === 1 && <div>
83                         {metadata !== '' && (metadata as ListResults<LinkResource>).items.length > 0 ?
84                             <MetadataTab items={(metadata as ListResults<LinkResource>).items} uuid={uuid} />
85                             : dialogContentHeader('(No metadata links found)')}
86                     </div>}
87                     {value === 2 && dialogContent(pythonHeader, pythonExample, classes)}
88                     {value === 3 && <div>
89                         {dialogContent(cliGetHeader, cliGetExample, classes)}
90                         {dialogContent(cliUpdateHeader, cliUpdateExample, classes)}
91                     </div>}
92                     {value === 4 && dialogContent(curlHeader, curlExample, classes)}
93                 </DialogContent>
94                 <DialogActions>
95                     <Button data-cy="close-advanced-dialog" variant='text' color='primary' onClick={closeDialog}>
96                         Close
97                     </Button>
98                 </DialogActions>
99             </Dialog>;
100         }
101     }
102 );
103
104 const dialogContent = (header: string, example: string, classes: any) =>
105     <div className={classes.spacing}>
106         {dialogContentHeader(header)}
107         {dialogContentExample(example, classes)}
108     </div>;
109
110 const dialogContentHeader = (header: string) =>
111     <DialogContentText>
112         {header}
113     </DialogContentText>;
114
115 const dialogContentExample = (example: JSX.Element | string, classes: any) => {
116     // Pass string to lines param or JSX to child props
117     const stringData = example && (example as string).length ? (example as string) : undefined;
118     return <DefaultCodeSnippet
119         apiResponse
120         className={classes.codeSnippet}
121         lines={stringData ? [stringData] : []}
122     >
123         {React.isValidElement(example) ? (example as JSX.Element) : undefined}
124     </DefaultCodeSnippet>;
125 }