Skip to content

Commit 6d0656e

Browse files
authored
Merge pull request #49 from oslabs-beta/alex/workspace-fix
Alex/workspace fix
2 parents 54641d9 + 0a3019a commit 6d0656e

File tree

11 files changed

+261
-48
lines changed

11 files changed

+261
-48
lines changed

src/client/components-v2/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ const App = () => {
3939
<Box sx={{ height: '100%', display: 'flex' }}>
4040
{/* New MUI workspace. */}
4141
{/* <WorkspaceContainer currentWorkspaceId={currentWorkspaceId} setWorkspace={setWorkspace} /> */}
42-
{/* <HistoryOrWorkspaceContainer currentWorkspaceId={currentWorkspaceId} setWorkspace={setWorkspace} /> */}
42+
<HistoryOrWorkspaceContainer currentWorkspaceId={currentWorkspaceId} setWorkspace={setWorkspace} />
4343
{/* Legacy workspace. */}
44-
<ContentsContainer />
44+
{/* <ContentsContainer /> */}
4545
<Divider orientation="vertical"/>
4646
{/* New MUI main container. */}
4747
<MainContainer currentWorkspaceId={currentWorkspaceId} />

src/client/components-v2/history-workspace-display/HistoryOrWorkspaceContainer.tsx

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import * as React from 'react';
2+
import { useSelector, useDispatch } from 'react-redux';
23
import Tabs from '@mui/material/Tabs';
34
import Tab from '@mui/material/Tab';
45
import Typography from '@mui/material/Typography';
6+
import Button from '@mui/material/Button';
57
import Box from '@mui/material/Box';
8+
import BarGraph from '../../components/display/BarGraph';
9+
import ScheduleContainer from '../../components/containers/ScheduleContainer';
610
import WorkspaceContainer from "../workspace/WorkspaceContainer";
711
import HistoryContainer from '../../components/containers/HistoryContainer';
812
import AccessTimeIcon from '@mui/icons-material/AccessTime';
913
import WorkIcon from '@mui/icons-material/Work';
14+
import ScheduleSendRoundedIcon from '@mui/icons-material/ScheduleSendRounded';
1015

1116
interface TabPanelProps {
1217
children?: React.ReactNode;
@@ -42,24 +47,55 @@ function a11yProps(index: number) {
4247
}
4348

4449
export default function HistoryOrWorkspaceContainer(props) {
50+
const [showGraph, setShowGraph] = React.useState(false);
4551
const [value, setValue] = React.useState(0);
4652

53+
const currentResponse = useSelector((store: any) => store.business.currentResponse);
54+
4755
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
4856
setValue(newValue);
4957
};
5058

5159
return (
52-
<Box sx={{ minWidth: '25%', overflow: 'auto', maxHeight: '100%', overflowX: 'auto' }}>
53-
<Box sx={{ borderBottom: 1, borderColor: 'divider', }}>
60+
<Box sx={{ minWidth: '25%', overflow: 'auto', maxHeight: '100%', overflowX: 'auto', overflowY: 'scroll' }}>
61+
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
5462
<Tabs value={value} onChange={handleChange} aria-label="basic tabs example">
5563
<Tab icon={<WorkIcon fontSize='small'/>} {...a11yProps(0)} sx={{fontSize:'10px', overflowWrap: "break-word", maxWidth: '50%'}}/>
56-
<Tab icon={<AccessTimeIcon fontSize='small'/>} {...a11yProps(1)} sx={{fontSize:'10px', overflowWrap: "break-word", maxWidth: '50%'}}/>
64+
<Tab icon={<ScheduleSendRoundedIcon fontSize='small'/>} {...a11yProps(1)} sx={{fontSize:'10px', overflowWrap: "break-word", maxWidth: '50%'}}/>
65+
<Tab icon={<AccessTimeIcon fontSize='small'/>} {...a11yProps(2)} sx={{fontSize:'10px', overflowWrap: "break-word", maxWidth: '50%'}}/>
5766
</Tabs>
5867
</Box>
68+
{value === 1 && (<Box
69+
sx={{
70+
display: 'flex',
71+
flexDirection: 'column',
72+
px: 1,
73+
py: 1
74+
}}
75+
>
76+
<Button
77+
className={`is-flex is-align-items-center is-justify-content-center is-graph-footer is-clickable`}
78+
variant='outlined'
79+
onClick={() => setShowGraph(showGraph === false)}
80+
>
81+
{showGraph && 'Hide Response Metrics'}
82+
{!showGraph && 'View Response Metrics'}
83+
</Button>
84+
{( showGraph && <Box sx={{
85+
py: 1
86+
}}>
87+
<BarGraph />
88+
</Box>
89+
)}
90+
</Box>
91+
)}
5992
<TabPanel value={value} index={0}>
6093
<WorkspaceContainer {...props} />
6194
</TabPanel>
6295
<TabPanel value={value} index={1}>
96+
<ScheduleContainer />
97+
</TabPanel>
98+
<TabPanel value={value} index={2}>
6399
<HistoryContainer />
64100
</TabPanel>
65101
</Box>
Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,64 @@
11
import React from "react";
2+
import { connect, useSelector, useDispatch } from 'react-redux';
3+
import * as actions from '../../features/business/businessSlice';
4+
5+
// import RequestCard from "./RequestCard";
6+
import SingleReqResContainer from "../../components/containers/SingleReqResContainer";
7+
import ReqResContainer from "../../components/containers/ReqResContainer";
28

3-
import RequestCard from "./RequestCard";
49

510
import TreeView from '@mui/lab/TreeView';
611
import TreeItem from '@mui/lab/TreeItem';
712
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
813
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
914
import { Box, Typography } from '@mui/material';
1015

11-
export default function CollectionTree({ currentWorkspace }) {
16+
const mapStateToProps = (store) => ({
17+
reqResArray: store.business.reqResArray,
18+
currentTab: store.business.currentTab,
19+
});
20+
21+
const mapDispatchToProps = (dispatch) => ({
22+
reqResDelete: (reqRes) => {
23+
dispatch(actions.reqResDelete(reqRes));
24+
},
25+
reqResUpdate: (reqRes) => {
26+
dispatch(actions.reqResUpdate(reqRes));
27+
},
28+
});
29+
30+
function CollectionTree({ currentWorkspace, reqResDelete, reqResUpdate }) {
1231

1332
const { reqResArray } = currentWorkspace;
1433
const requestTreeItems = []
15-
for (let content of reqResArray) {
34+
for (let i = 0; i < reqResArray.length; i+=1) {
1635
requestTreeItems.push(
17-
<RequestCard
18-
key={content.id}
19-
content={content}
20-
/>
36+
<TreeItem
37+
key={reqResArray[i].id}
38+
nodeId={reqResArray[i].id}
39+
label={
40+
<SingleReqResContainer
41+
className="reqResChild"
42+
content={reqResArray[i]}
43+
key={reqResArray[i].id}
44+
index={i}
45+
reqResDelete={reqResDelete}
46+
reqResUpdate={reqResUpdate}
47+
/>
48+
}
49+
/>
2150
)
2251
}
2352
// key={request.id} request={request}
2453

54+
// <RequestCard
55+
// key={reqResArray[i].id}
56+
// content={reqResArray[i]}
57+
// index={i}
58+
// reqResDelete={reqResDelete}
59+
// reqResUpdate={reqResUpdate}
60+
// />
61+
2562
return (
2663
<Box
2764
className="collection-tree"
@@ -37,17 +74,21 @@ export default function CollectionTree({ currentWorkspace }) {
3774
Start this Workspace by adding a request from the composer.
3875
</Typography>
3976
// If there are requests in the current workspace, render the collection tree.
40-
: <TreeView
41-
aria-label="collection navigator"
42-
defaultCollapseIcon={<ExpandMoreIcon />}
43-
defaultExpandIcon={<ChevronRightIcon />}
44-
sx={{ flexGrow: 1, overflowY: 'auto' }}
45-
>
46-
<TreeItem nodeId={currentWorkspace.id} label={currentWorkspace.name}>
47-
{requestTreeItems}
48-
</TreeItem>
49-
</TreeView>
77+
: <ReqResContainer displaySchedule />
78+
// : <TreeView
79+
// aria-label="collection navigator"
80+
// defaultCollapseIcon={<ExpandMoreIcon />}
81+
// defaultExpandIcon={<ChevronRightIcon />}
82+
// sx={{ flexGrow: 1, overflowY: 'auto' }}
83+
// >
84+
// <TreeItem nodeId={currentWorkspace.id} label={currentWorkspace.name}>
85+
// {requestTreeItems}
86+
// </TreeItem>
87+
// </TreeView>
5088
}
5189
</Box>
5290
);
5391
}
92+
93+
94+
export default connect(mapStateToProps, mapDispatchToProps)(CollectionTree);
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
import React from "react";
2+
import { connect } from "react-redux";
23
import { Box } from '@mui/material';
34
import WorkspaceSelect from './WorkspaceSelect';
4-
import SaveWorkspaceButton from "./buttons/SaveWorkspaceButton";
5+
import DeleteWorkspaceButton from "./buttons/DeleteWorkspaceButton"
56
import ExportWorkspaceButton from "./buttons/ExportWorkspaceButton";
67
import InviteToWorkspaceButton from "./buttons/InviteToWorkspaceButton";
78

8-
export default function CurrentWorkspaceDisplay(props) {
9+
const mapStateToProps = (store) => {
10+
return {
11+
workspaces: store.business.collections,
12+
};
13+
};
14+
15+
function CurrentWorkspaceDisplay(props) {
916
return (
1017
<Box sx={{ display: 'flex', flexGrow: 1, alignItems: 'center', pb: 1 }}>
1118
{/* The below select menu should contain all saved workspaces in the Swell app. */}
1219
<WorkspaceSelect {...props} />
13-
<SaveWorkspaceButton />
20+
{/* <SaveWorkspaceButton /> */}
21+
<DeleteWorkspaceButton id={props.currentWorkspaceId} currentWorkspace={props.currentWorkspace} />
1422
<ExportWorkspaceButton />
1523
<InviteToWorkspaceButton />
1624
</Box>
1725
)
1826
}
27+
28+
export default connect(mapStateToProps)(CurrentWorkspaceDisplay);

src/client/components-v2/workspace/WorkspaceContainer.tsx

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22
import { useSelector } from 'react-redux';
33

44
// Local components
55
import CurrentWorskpaceDisplay from "./CurrentWorkspaceDisplay";
6+
import LegacyWorkspace from "../../components/containers/WorkspaceContainer";
7+
import BarGraph from "../../components/display/BarGraph";
8+
// import CollectionsContainer from "../../components/containers/CollectionsContainer";
69
import CollectionTree from './CollectionTree';
710

811
// MUI components and SVG icons
912
import { Box, Button, Typography, SelectChangeEvent, Divider } from '@mui/material';
1013
import { AddRounded } from '@mui/icons-material';
1114

1215
export default function WorkspaceContainer({ currentWorkspaceId, setWorkspace }) {
16+
1317
/**
1418
* TODO: change the workspace container to have adjustable width sizing via user dragging
1519
* TODO: reimplement the "Schedule" functionality somehow
1620
* TODO: refactor store to remove explicit any
1721
*/
1822

19-
// // currentWorkspace is the current Workspace's UUID. It is only altered in WorkspaceSelect.tsx, which is rendered by CurrentWorskpaceDisplay.tsx
20-
// const [currentWorkspaceId, setWorkspace] = React.useState('');
21-
2223
const handleWorkspaceChange = (event: SelectChangeEvent) => {
2324
setWorkspace(event.target.value as string);
2425
}
@@ -34,22 +35,32 @@ export default function WorkspaceContainer({ currentWorkspaceId, setWorkspace })
3435
return (
3536
<Box className="workspace-container" sx={{ minWidth: '20%', align: 'center', p: 1.5 }}>
3637
{/* The display for your current workspace. Contains functionality for saving, importing, exporting, and adding other GitHub users to your workspace. */}
37-
<CurrentWorskpaceDisplay currentWorkspaceId={currentWorkspaceId} handleWorkspaceChange={handleWorkspaceChange}/>
38+
<CurrentWorskpaceDisplay currentWorkspaceId={currentWorkspaceId} currentWorkspace={currentWorkspace} handleWorkspaceChange={handleWorkspaceChange}/>
39+
<Box className="collections-container">
40+
<Typography>Requests</Typography>
41+
<Divider orientation="horizontal" />
42+
<LegacyWorkspace />
43+
</Box>
44+
3845
{/* Conditionally render either a message or collection tree depending on if a workspace is selected */}
39-
{currentWorkspace === undefined
40-
? <Typography variant="caption">Get started by selecting, importing, or creating a new workspace.</Typography>
41-
: <Box className="collections-container">
42-
<Typography>Collections</Typography>
43-
<Divider orientation="horizontal" />
44-
<CollectionTree currentWorkspace={currentWorkspace}/>
45-
</Box>
46+
{
47+
// currentWorkspace === undefined
48+
// ? <Typography variant="caption">Get started by selecting, importing, or creating a new workspace.</Typography>
49+
// : <Box className="collections-container">
50+
// <Typography>Requests</Typography>
51+
// <Divider orientation="horizontal" />
52+
// <LegacyWorkspace />
53+
// {/* <CollectionTree currentWorkspace={currentWorkspace}/> */}
54+
// </Box>
4655
}
56+
4757
{/**
4858
* TODO:
4959
* Below button is not ready to be added. Would eventually be used to add another collection to a workspace.
5060
* However, workspaces are currently only built to handle 1 collection max.
5161
* Need to refactor Redux store to get this button to work.
5262
*/}
63+
5364
{/* <Button variant="text" sx={{ width: 1, maxHeight: '24px', minHeight: '24px' }}>
5465
<AddRounded fontSize="small"/>
5566
</Button> */}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react';
2+
import { useDispatch } from 'react-redux';
3+
import Menu from '@mui/material/Menu';
4+
import MenuItem from '@mui/material/MenuItem';
5+
import Typography from '@mui/material/Typography';
6+
import * as actions from '../../features/business/businessSlice';
7+
8+
export default function WorkspaceContextMenu({ id, name, reqResArray }) {
9+
const [contextMenu, setContextMenu] = React.useState<{
10+
mouseX: number;
11+
mouseY: number;
12+
} | null>(null);
13+
14+
const handleContextMenu = (event: React.MouseEvent) => {
15+
event.preventDefault();
16+
setContextMenu(
17+
contextMenu === null
18+
? {
19+
mouseX: event.clientX + 2,
20+
mouseY: event.clientY - 6,
21+
}
22+
: // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
23+
// Other native context menus might behave different.
24+
// With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
25+
null,
26+
);
27+
};
28+
29+
const handleClose = () => {
30+
setContextMenu(null);
31+
};
32+
33+
const dispatch = useDispatch();
34+
const collectionToReqRes = (reqResArray) => {
35+
dispatch(actions.collectionToReqRes(reqResArray));
36+
}
37+
38+
// <MenuItem
39+
// key={workspace.id}
40+
// value={workspace.id}
41+
// onClick={() => collectionToReqRes(workspace.reqResArray)}
42+
// >
43+
// {workspace.name}
44+
// </MenuItem>
45+
46+
return(
47+
<MenuItem
48+
key={id}
49+
value={id}
50+
onClick={() => collectionToReqRes(reqResArray)}
51+
>
52+
<div onContextMenu={handleContextMenu} style={{ cursor: 'context-menu', width: '100%' }}>
53+
<Typography>{name}</Typography>
54+
<Menu
55+
open={contextMenu !== null}
56+
onClose={handleClose}
57+
anchorReference="anchorPosition"
58+
anchorPosition={
59+
contextMenu !== null
60+
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
61+
: undefined
62+
}
63+
>
64+
<MenuItem onClick={handleClose}>Delete</MenuItem>
65+
</Menu>
66+
</div>
67+
</MenuItem>
68+
)
69+
}

0 commit comments

Comments
 (0)