EntityDetail.jsx 6.2 KB
Newer Older
Jaden's avatar
Jaden committed
1
// @flow
2
import * as React from 'react';
Jaden's avatar
Jaden committed
3
4
5
6
import {
	Container,
	Row,
	Col,
7
8
9
10
11
	TabContent,
	TabPane,
	Nav,
	NavItem,
	NavLink,
Jaden's avatar
Jaden committed
12
13
} from 'reactstrap';

14
15
16
17
import { connect } from 'react-redux';

import cn from 'classnames';

18
import * as Actions from '@store/actions.js';
19
import * as Selectors from '@store/selectors.js';
Jaden's avatar
Jaden committed
20
21
22
23
24
25

import {
	Route,
	Link
} from 'react-router-dom';

26
import type { BeatObject } from '@helpers/beat';
27
import { getDefaultEntityObject } from '@helpers/beat';
28
import ValidSchemaBadge from './ValidSchemaBadge.jsx';
29

30
31
32
33
34
35
import DataformatEditorContainer from './dataformat';
import AlgorithmEditorContainer from './algorithm';
import LibraryEditorContainer from './library';
import DatabaseEditorContainer from './database';
import ExperimentEditorContainer from './experiment';
import ToolchainEditorContainer from './toolchain';
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
36
import PlotterEditorContainer from './plotter';
37
import PlotterparameterEditorContainer from './plotterparameter';
38

Jaden's avatar
Jaden committed
39
type Props = {
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
40
41
	// the match object from react-router
	// used to find which object to render
42
	match: any,
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
43
44
	// the history object from react-router
	// used to push new history to
45
	history: any,
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
46
	// gets the object based on the current URL
47
	getEntityObject: () => BeatObject,
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
48
	// updates the current object
49
	updateFunc: (BeatObject) => any,
Jaden's avatar
Jaden committed
50
51
};

Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
52
// 3 tabs so far: editor, docs, raw json
53
type Tab = '0' | '1' | '2';
Jaden's avatar
Jaden committed
54

55
type State = {
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
56
	// which tab is active
57
58
	activeTab: Tab,
};
59

Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
60
61
// wrapper for editors
// doesnt really do much now besides the raw json tab
62
export class EntityDetail extends React.Component<Props, State> {
63
64
	constructor(props: Props){
		super(props);
65
66
	}

67
68
69
	state = {
		activeTab: '0',
	}
70

71
72
73
74
75
76
	switchToTab = (tab: Tab) => {
		this.setState({
			activeTab: tab
		});
	}

77
78
79
80
	saveChanges = (newObj: BeatObject) => {
		this.props.updateFunc(newObj);
	}

81
82
	render () {
		return (
83
84
			<Container>
				<Row>
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
85
					{/* title line (name & validation info) */}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
					<Col>
						<h4 style={{'textAlign': 'center'}}>
							<span style={{'textTransform': 'capitalize'}}>
								{ this.props.match.params.entity }
							</span>
							{' '}
							<pre style={{display: 'inline'}}>
								{ this.props.getEntityObject().name }
							</pre>
							<ValidSchemaBadge entity={this.props.match.params.entity} obj={this.props.getEntityObject()} />
						</h4>
					</Col>
				</Row>
				<Row>
					<Col sm='12'>
						<Nav tabs className='nav-fill'>
							<NavItem>
								<NavLink
									className={cn({ active: this.state.activeTab === '0' })}
									onClick={() => this.switchToTab('0')}
								>
									Editor
								</NavLink>
							</NavItem>
							<NavItem>
								<NavLink
									className={cn({ active: this.state.activeTab === '1' })}
									onClick={() => this.switchToTab('1')}
								>
									Documentation
								</NavLink>
							</NavItem>
							<NavItem>
								<NavLink
									className={cn({ active: this.state.activeTab === '2' })}
									onClick={() => this.switchToTab('2')}
								>
									Raw JSON
								</NavLink>
							</NavItem>
						</Nav>
127
						<TabContent activeTab={this.state.activeTab} className='mt-2'>
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
128
							{/* Uses the appropriate editor, could probably be done nicer */}
129
130
131
							<TabPane tabId='0'>
								{
									this.props.match.params.entity === 'algorithm' &&
132
										<AlgorithmEditorContainer
133
134
135
136
137
138
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
								{
									this.props.match.params.entity === 'dataformat' &&
139
										<DataformatEditorContainer
140
141
142
143
144
145
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
								{
									this.props.match.params.entity === 'library' &&
146
										<LibraryEditorContainer
147
148
149
150
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
151
152
								{
									this.props.match.params.entity === 'database' &&
153
										<DatabaseEditorContainer
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
154
155
156
157
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
158
159
160
161
162
163
164
								{
									this.props.match.params.entity === 'experiment' &&
										<ExperimentEditorContainer
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
165
166
167
168
169
170
171
								{
									this.props.match.params.entity === 'toolchain' &&
										<ToolchainEditorContainer
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
172
173
174
175
176
177
178
								{
									this.props.match.params.entity === 'plotter' &&
										<PlotterEditorContainer
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
179
180
181
182
183
184
185
								{
									this.props.match.params.entity === 'plotterparameter' &&
										<PlotterparameterEditorContainer
											data={this.props.getEntityObject()}
											saveFunc={this.saveChanges}
										/>
								}
186
187
							</TabPane>
							<TabPane tabId='1'>
188
189
								<Row>
									<Col>
190
										<h4 style={{textAlign: 'center'}}>Under construction 😄</h4>
191
192
									</Col>
								</Row>
193
194
195
196
197
198
199
200
							</TabPane>
							<TabPane tabId='2'>
								<pre>{ JSON.stringify(this.props.getEntityObject(), null, 4) }</pre>
							</TabPane>
						</TabContent>
					</Col>
				</Row>
			</Container>
201
202
203
204
		);
	}
}

205
const mapStateToProps = (state, ownProps) => {
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
206
	// which beat entity is currently active: 'algorithm', 'plotter', 'database', etc.
207
	const entity = ownProps.match.params.entity;
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
208
	// the name of the object ("atnt/1", "plot/isoroc/1", "user/tc/test/1/exp", etc.)
209
210
	const name = ownProps.match.params.name;
	const obj = {
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
211
212
		// uses a selector based off the entity and finds the obj given the name
		// if the obj doesnt exist (huge edge case) just return a default obj to not break everything
213
		getEntityObject: (): BeatObject => Selectors[`${ entity }Get`](state).find(o => o.name === name) || getDefaultEntityObject(),
214
215
216
217
218
	};

	return obj;
};

219
const mapDispatchToProps = (dispatch, ownProps) => ({
Jaden DIEFENBAUGH's avatar
Jaden DIEFENBAUGH committed
220
	// replace the obj in the Redux store with the new object
221
222
223
224
225
226
	updateFunc: (obj) => {
		dispatch(Actions[`${ ownProps.match.params.entity }Update`](ownProps.match.params.name, obj));
		ownProps.history.push(`/${ ownProps.match.params.entity }/${ obj.name }`);
	},
});

227
export default connect(mapStateToProps, mapDispatchToProps)(EntityDetail);