Skip to content
This repository was archived by the owner on Aug 31, 2022. It is now read-only.

Commit ebc237d

Browse files
committed
Update createdAt and updatedAt fields with defaults for Sessions type
Convert session sharing components to use PatternFly React
1 parent 4dd2fe8 commit ebc237d

File tree

22 files changed

+765
-633
lines changed

22 files changed

+765
-633
lines changed

config/router.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ module.exports = [
7575
component: './Search',
7676
},
7777
{
78-
path: '/explore',
79-
name: 'explore',
80-
component: './Explore',
78+
path: '/sessions',
79+
name: 'sessions',
80+
component: './Sessions',
8181
},
8282
{
8383
path: '/private',

mock/api.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,12 @@ export const mockSearch = {
106106
},
107107
};
108108

109-
export const mockSessionUrl = {
109+
export const mockSession = {
110110
data: {
111-
createUrl: {
112-
id: 'test_id',
111+
createSession: {
112+
id: '1',
113+
config: '{}',
114+
description: 'test_description',
113115
},
114116
},
115117
};

prisma/datamodel.prisma

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ type User {
66
password: String!
77
}
88

9-
type Url {
9+
type Session {
1010
id: ID! @id
11-
created: DateTime!
12-
updated: DateTime!
11+
createdAt: DateTime! @createdAt
12+
updatedAt: DateTime! @updatedAt
1313
config: String!
1414
description: String
1515
}

prisma/src/resolvers.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ const resolvers = {
5959
});
6060
return user;
6161
},
62-
createUrl: async (parent, { created, updated, config, description }, ctx) => {
63-
const url = await ctx.prisma.createUrl({
64-
created,
65-
updated,
62+
createSession: async (parent, { createdAt, updatedAt, config, description }, ctx) => {
63+
const session = await ctx.prisma.createSession({
64+
createdAt,
65+
updatedAt,
6666
config,
6767
description,
6868
});
69-
return url;
69+
return session;
7070
},
7171
},
7272
};

prisma/src/typeDefs.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ const typeDefs = gql`
1010
username: String!
1111
}
1212
13-
type Url {
13+
type Session {
1414
id: ID!
15-
created: DateTime!
16-
updated: DateTime!
15+
createdAt: DateTime!
16+
updatedAt: DateTime!
1717
config: String!
1818
description: String
1919
}
@@ -25,7 +25,12 @@ const typeDefs = gql`
2525
type Mutation {
2626
register(firstName: String!, lastName: String!, username: String!, password: String!): User!
2727
login(username: String!, password: String!): LoginResponse!
28-
createUrl(created: DateTime!, updated: DateTime!, config: String!, description: String!): Url!
28+
createSession(
29+
createdAt: DateTime!
30+
updatedAt: DateTime!
31+
config: String!
32+
description: String
33+
): Session!
2934
}
3035
3136
type LoginResponse {

src/common/menu.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { isUrl } from '../utils/utils';
33
const menuData = [
44
{
55
name: 'Dashboard',
6-
icon: 'dashboard',
76
path: '/private',
87
routes: [
98
{
@@ -30,13 +29,11 @@ const menuData = [
3029
},
3130
{
3231
name: 'Search',
33-
icon: 'search',
3432
path: '/search',
3533
},
3634
{
37-
name: 'Explore',
38-
icon: 'global',
39-
path: '/explore',
35+
name: 'Sessions',
36+
path: '/sessions',
4037
},
4138
];
4239

src/components/GlobalHeader/index.js

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@ import {
1313
DropdownToggle,
1414
} from '@patternfly/react-core';
1515
import { SearchIcon } from '@patternfly/react-icons';
16-
import { Alert, Badge } from 'antd';
1716
import { connect } from 'dva';
1817
import pbenchLogo from '../../assets/pbench_logo.svg';
1918
import imgAvatar from '../../assets/avatar.svg';
2019
import SessionModal from '../SessionModal';
2120

22-
@connect(({ store, auth }) => ({
23-
store,
21+
@connect(({ auth }) => ({
2422
auth: auth.auth,
2523
}))
2624
class GlobalHeader extends Component {
@@ -38,22 +36,7 @@ class GlobalHeader extends Component {
3836
});
3937
};
4038

41-
exitUserSession = () => {
42-
const { dispatch } = this.props;
43-
const sessionConfig = window.localStorage.getItem('persist:session');
44-
45-
dispatch({
46-
type: 'global/exitUserSession',
47-
});
48-
dispatch({
49-
type: 'global/rehydrateSession',
50-
payload: JSON.parse(sessionConfig),
51-
});
52-
window.localStorage.removeItem('persist:session');
53-
dispatch(routerRedux.push('/'));
54-
};
55-
56-
logoutSession = () => {
39+
logoutUser = () => {
5740
const { dispatch } = this.props;
5841
dispatch({
5942
type: 'auth/logoutUser',
@@ -72,36 +55,17 @@ class GlobalHeader extends Component {
7255
};
7356

7457
render() {
75-
const {
76-
savingSession,
77-
sessionBannerVisible,
78-
sessionDescription,
79-
sessionId,
80-
dispatch,
81-
store,
82-
auth,
83-
} = this.props;
58+
const { savingSession, dispatch, auth } = this.props;
8459
const { isProfileDropdownOpen } = this.state;
8560

8661
const profileDropdownItems = [
8762
<DropdownItem onClick={() => this.navigateToProfile()}>Profile</DropdownItem>,
88-
<DropdownItem onClick={() => this.logoutSession()}>Logout</DropdownItem>,
63+
<DropdownItem onClick={() => this.logoutUser()}>Logout</DropdownItem>,
8964
];
9065

9166
const PageToolbar = (
9267
<PageHeaderTools>
93-
{sessionBannerVisible && (
94-
<Alert
95-
message={sessionDescription}
96-
type="info"
97-
description={`Session ID: ${sessionId}`}
98-
closeText="Exit Session"
99-
icon={<Badge status="processing" />}
100-
onClose={this.exitUserSession}
101-
banner
102-
/>
103-
)}
104-
<SessionModal savingSession={savingSession} sessionConfig={store} dispatch={dispatch} />
68+
<SessionModal savingSession={savingSession} dispatch={dispatch} />
10569
<PageHeaderToolsGroup>
10670
<PageHeaderToolsItem>
10771
<Button

src/components/SessionModal/index.js

Lines changed: 81 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,148 @@
11
import React, { Component } from 'react';
22
import { CopyToClipboard } from 'react-copy-to-clipboard';
3-
import { Modal, Form, Input, message } from 'antd';
4-
import { ToolbarItem, Button } from '@patternfly/react-core';
3+
import {
4+
Alert,
5+
AlertGroup,
6+
Modal,
7+
ModalVariant,
8+
Form,
9+
FormGroup,
10+
TextArea,
11+
TextInput,
12+
ToolbarItem,
13+
Button,
14+
} from '@patternfly/react-core';
515
import { ShareAltIcon } from '@patternfly/react-icons';
616

7-
const { TextArea } = Input;
8-
917
class SessionModal extends Component {
1018
constructor(props) {
1119
super(props);
1220

1321
this.state = {
1422
description: '',
15-
visible: false,
23+
shareModalVisible: false,
24+
successModalVisible: false,
25+
copyLinkAlertVisible: false,
1626
sessionUrl: '',
1727
};
1828
}
1929

20-
showSuccess = () => {
21-
const { sessionUrl } = this.state;
22-
23-
Modal.success({
24-
title: 'Generated session link',
25-
content: (
26-
<div style={{ display: 'flex', flex: 1, flexDirection: 'row' }}>
27-
<Input value={sessionUrl} />
28-
<CopyToClipboard text={sessionUrl}>
29-
<Button style={{ marginLeft: 8 }} onClick={this.copyLink}>
30-
Copy Link
31-
</Button>
32-
</CopyToClipboard>
33-
</div>
34-
),
35-
});
36-
};
30+
toggleShareModal = () => {
31+
const { shareModalVisible } = this.state;
3732

38-
handleCancel = () => {
3933
this.setState({
40-
visible: false,
34+
shareModalVisible: !shareModalVisible,
4135
});
4236
};
4337

44-
showModal = () => {
38+
toggleSuccessModal = () => {
39+
const { successModalVisible } = this.state;
40+
4541
this.setState({
46-
visible: true,
42+
successModalVisible: !successModalVisible,
4743
});
4844
};
4945

50-
onGenerate = () => {
46+
onGenerateUrl = () => {
5147
const { dispatch } = this.props;
52-
let { sessionConfig } = this.props;
5348
const { description } = this.state;
54-
sessionConfig = JSON.stringify(sessionConfig);
49+
50+
// eslint-disable-next-line no-underscore-dangle
51+
const { routing, global, dashboard, search } = window.g_app._store.getState();
52+
const sessionConfig = JSON.stringify({ routing, global, dashboard, search });
5553

5654
dispatch({
57-
type: 'global/saveUserSession',
55+
type: 'sessions/saveSession',
5856
payload: {
5957
sessionConfig,
6058
description,
6159
},
6260
}).then(result => {
6361
this.setState({
64-
visible: false,
65-
sessionUrl: `${window.location.origin}/#/dashboard/share/${result.data.createUrl.id}`,
62+
shareModalVisible: false,
63+
sessionUrl: `${window.location.origin}/dashboard/share/${result.data.createSession.id}`,
6664
});
67-
this.showSuccess();
65+
this.toggleSuccessModal();
6866
});
6967
};
7068

7169
copyLink = () => {
72-
const { sessionUrl } = this.state;
73-
message.success(`Copied the link: ${sessionUrl}`);
70+
this.setState({ copyLinkAlertVisible: true });
7471
};
7572

76-
changeDescription = e => {
73+
updateDescription = value => {
7774
this.setState({
78-
description: e.target.value,
75+
description: value,
7976
});
8077
};
8178

8279
render() {
83-
const { visible, description } = this.state;
80+
const {
81+
shareModalVisible,
82+
successModalVisible,
83+
copyLinkAlertVisible,
84+
description,
85+
sessionUrl,
86+
} = this.state;
8487
const { savingSession } = this.props;
8588

8689
return (
8790
<span>
8891
<ToolbarItem>
89-
<Button onClick={this.showModal} variant="plain">
92+
<Button onClick={this.toggleShareModal} variant="plain">
9093
<ShareAltIcon />
9194
</Button>
9295
</ToolbarItem>
9396
<Modal
97+
variant={ModalVariant.small}
9498
title="Share Session Link"
95-
visible={visible}
96-
onOk={this.onGenerate}
97-
onCancel={this.handleCancel}
98-
footer={[
99-
<Button key="back" onClick={this.handleCancel}>
100-
Cancel
101-
</Button>,
102-
<Button key="submit" type="primary" onClick={this.onGenerate} loading={savingSession}>
99+
isOpen={shareModalVisible}
100+
onClose={this.toggleShareModal}
101+
actions={[
102+
<Button
103+
key="submit"
104+
type="primary"
105+
onClick={this.onGenerateUrl}
106+
loading={savingSession}
107+
>
103108
Save
104109
</Button>,
110+
<Button key="back" variant="link" onClick={this.toggleShareModal}>
111+
Cancel
112+
</Button>,
105113
]}
106114
>
107-
<Form layout="vertical">
108-
<Form.Item label="Description">
115+
<Form>
116+
<FormGroup label="Description">
109117
<TextArea
110-
rows={2}
111118
id="description"
112-
placeholder={description}
113-
onChange={this.changeDescription}
119+
name="description"
120+
value={description}
121+
onChange={this.updateDescription}
114122
/>
115-
</Form.Item>
123+
</FormGroup>
116124
</Form>
117125
</Modal>
126+
<Modal
127+
variant={ModalVariant.small}
128+
title="Generated session link"
129+
isOpen={successModalVisible}
130+
onClose={this.toggleSuccessModal}
131+
>
132+
{copyLinkAlertVisible && (
133+
<AlertGroup isToast>
134+
<Alert title={`Copied the link: ${sessionUrl}`} />
135+
</AlertGroup>
136+
)}
137+
<div style={{ display: 'flex', flexDirection: 'row' }}>
138+
<TextInput value={sessionUrl} />
139+
<CopyToClipboard text={sessionUrl}>
140+
<Button style={{ marginLeft: 8 }} onClick={this.copyLink}>
141+
Copy Link
142+
</Button>
143+
</CopyToClipboard>
144+
</div>
145+
</Modal>
118146
</span>
119147
);
120148
}

0 commit comments

Comments
 (0)