From 5ec4eb68855520712ce320d41b71025c17617ddd Mon Sep 17 00:00:00 2001 From: Wojciech Kozyra Date: Tue, 30 Jan 2018 02:02:38 +0100 Subject: [PATCH] detector + results bug fixes --- config/docker.run.sh | 5 +- config/webpack.config.js | 1 + flow/decl/require.js | 1 + package-lock.json | 13 +--- src/api/endpoint.js | 5 +- src/components/Chart/ChartInterface.js | 18 ++--- .../ZoneName.js => EditableName.js} | 8 +- .../Editor/ZoneEditor/ZoneEditor.js | 5 +- src/components/Editor/ZoneEditor/index.js | 1 - src/components/Editor/index.js | 3 + .../Results/components/ResultDetailsLayout.js | 4 +- .../containers/ResultDetailsContainer.js | 4 + src/routes/Results/reducer.js | 9 ++- src/routes/Results/saga.js | 17 ++++- src/routes/Results/selector.js | 10 ++- .../components/DetectorItemLayout.js | 7 ++ .../containers/DetectorItemContainer.js | 9 +++ .../Geometry/components/ZoneItemLayout.js | 6 +- .../CompoundMaterialEditorLayout.js | 1 - src/utils/simulation/detectorInfo.js | 74 +++++++++++++++++-- 20 files changed, 152 insertions(+), 49 deletions(-) rename src/components/Editor/{ZoneEditor/ZoneName.js => EditableName.js} (87%) create mode 100644 src/components/Editor/index.js diff --git a/config/docker.run.sh b/config/docker.run.sh index 654c314b4..c8e3672d2 100644 --- a/config/docker.run.sh +++ b/config/docker.run.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -echo "window.env = {};" > $1/env.js -echo "window.env.BACKEND_PUBLIC_URL = \"$YAPTIDE_BACKEND_PUBLIC_URL\";" >> $1/env.js +echo "window.process = window.process || {};" > $1/env.js +echo "window.process.env = {};" >> $1/env.js +echo "window.process.env.BACKEND_PUBLIC_URL = \"$YAPTIDE_BACKEND_PUBLIC_URL\";" >> $1/env.js nginx -c /etc/nginx/nginx.conf diff --git a/config/webpack.config.js b/config/webpack.config.js index 36056820d..63a3aedfc 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -108,6 +108,7 @@ if (!__TEST__) { plugins.push( new webpack.DefinePlugin({ + 'process.env.BACKEND_PUBLIC_URL': JSON.stringify(BACKEND_PUBLIC_URL), __DEV__, __TEST__, __PROD__, diff --git a/flow/decl/require.js b/flow/decl/require.js index c3d57d566..1c2485156 100644 --- a/flow/decl/require.js +++ b/flow/decl/require.js @@ -5,3 +5,4 @@ declare var require: { ensure(ids: Array, callback?: { (require: typeof require): void }, chunk?: string): void } declare var BACKEND_PUBLIC_URL: string; +declare var process: Object; diff --git a/package-lock.json b/package-lock.json index 9d8a99510..4ad1ab369 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1854,12 +1854,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", "dev": true - }, - "dotenv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-2.0.0.tgz", - "integrity": "sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk=", - "dev": true } } }, @@ -4074,9 +4068,10 @@ } }, "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-2.0.0.tgz", + "integrity": "sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk=", + "dev": true }, "double-bits": { "version": "1.1.1", diff --git a/src/api/endpoint.js b/src/api/endpoint.js index 1d1f63b4c..ddaa41c13 100644 --- a/src/api/endpoint.js +++ b/src/api/endpoint.js @@ -1,6 +1,7 @@ /* @flow */ -window.env = window.env || {}; -export const baseURL = `${window.location.protocol}//${window.env.BACKEND_PUBLIC_URL}`; +window.process = window.process || {}; +window.process.env = window.process.env || {}; +export const baseURL = `${window.location.protocol}//${window.process.env.BACKEND_PUBLIC_URL}`; export type Endpoint = 'LOGIN' | 'REGISTER'; diff --git a/src/components/Chart/ChartInterface.js b/src/components/Chart/ChartInterface.js index e00247831..a8727871a 100644 --- a/src/components/Chart/ChartInterface.js +++ b/src/components/Chart/ChartInterface.js @@ -46,16 +46,16 @@ class ChartInterface extends React.Component { let axis1Label = { label: 'unknown', unit: 'unknown', startValue: 0, endValue: 100 }; let axis2Label = { label: 'unknown', unit: 'unknown', startValue: 0, endValue: 100 }; if (this.props.data.length === 1) { - axis1Label = this.props.labels.dimensions[1]; - axis2Label = this.props.labels.dimensions[2]; - data = _.flatten(this.props.data); - } else if (this.props.data[0].length > 1) { - axis1Label = this.props.labels.dimensions[0]; - axis2Label = this.props.labels.dimensions[2]; - data = _.map(this.props.data, item => _.flatten(item)); - } else if (this.props.data[0][0].length > 1) { - axis1Label = this.props.labels.dimensions[0]; + axis1Label = this.props.labels.dimensions[2]; axis2Label = this.props.labels.dimensions[1]; + data = this.props.data[0]; + } else if (this.props.data[0].length === 1) { + axis1Label = this.props.labels.dimensions[2]; + axis2Label = this.props.labels.dimensions[0]; + data = _.map(this.props.data, item => item[0]); + } else if (this.props.data[0][0].length === 1) { + axis1Label = this.props.labels.dimensions[1]; + axis2Label = this.props.labels.dimensions[0]; data = _.map(this.props.data, array2d => _.map(array2d, array1d => array1d[0])); } return ( diff --git a/src/components/Editor/ZoneEditor/ZoneName.js b/src/components/Editor/EditableName.js similarity index 87% rename from src/components/Editor/ZoneEditor/ZoneName.js rename to src/components/Editor/EditableName.js index 6438f85b1..2e96b8826 100644 --- a/src/components/Editor/ZoneEditor/ZoneName.js +++ b/src/components/Editor/EditableName.js @@ -10,6 +10,7 @@ const UNDEFINED_ZONE = '-------------'; type Props = { name: string, + label: string, updateName: (value: string) => void, classes: Object, }; @@ -19,7 +20,7 @@ type State = { name: string, }; -class ZoneName extends React.Component { +class EditableName extends React.Component { props: Props state: State = { isEditOn: false, @@ -45,7 +46,6 @@ class ZoneName extends React.Component { ? ( { className={classes.label} noWrap > - {`Zone: ${this.props.name}` || UNDEFINED_ZONE} + {`${this.props.label}${this.props.name}` || UNDEFINED_ZONE} ) @@ -74,4 +74,4 @@ const styles = (theme: Object) => ({ }, }); -export default withStyles(styles)(ZoneName); +export default withStyles(styles)(EditableName); diff --git a/src/components/Editor/ZoneEditor/ZoneEditor.js b/src/components/Editor/ZoneEditor/ZoneEditor.js index 682627268..fe96b20e5 100644 --- a/src/components/Editor/ZoneEditor/ZoneEditor.js +++ b/src/components/Editor/ZoneEditor/ZoneEditor.js @@ -5,10 +5,10 @@ import Style from 'styles'; import Typography from 'material-ui/Typography'; import { withStyles } from 'material-ui/styles'; import { - ZoneName, ZoneOperation, MaterialSelector, } from 'components/Editor/ZoneEditor'; +import { EditableName } from 'components/Editor'; import type { OperationType, ConstructionPath, PrintableOperation } from 'model/simulation/zone'; import type { PrintableMaterial } from 'model/simulation/material'; @@ -35,7 +35,8 @@ class ZoneEditor extends React.Component { render() { const { classes } = this.props; const zoneTitle = ( - diff --git a/src/components/Editor/ZoneEditor/index.js b/src/components/Editor/ZoneEditor/index.js index fd35dc85c..df6e28ac6 100644 --- a/src/components/Editor/ZoneEditor/index.js +++ b/src/components/Editor/ZoneEditor/index.js @@ -2,6 +2,5 @@ export { default as ZoneOperation } from './ZoneOperation'; export { default as MaterialSelector } from './MaterialSelector'; -export { default as ZoneName } from './ZoneName'; export { default as OperationSelector } from './OperationSelector.js'; export { default as ZoneEditor } from './ZoneEditor'; diff --git a/src/components/Editor/index.js b/src/components/Editor/index.js new file mode 100644 index 000000000..bd6ce64bd --- /dev/null +++ b/src/components/Editor/index.js @@ -0,0 +1,3 @@ +/* @flow */ + +export { default as EditableName } from './EditableName'; diff --git a/src/routes/Results/components/ResultDetailsLayout.js b/src/routes/Results/components/ResultDetailsLayout.js index a69aa5358..7ac4f9ca3 100644 --- a/src/routes/Results/components/ResultDetailsLayout.js +++ b/src/routes/Results/components/ResultDetailsLayout.js @@ -4,11 +4,13 @@ import React from 'react'; import Paper from 'material-ui/Paper'; import { withStyles } from 'material-ui/styles'; import type { Score, DimensionsInfo } from 'model/result'; +import type { Detector } from 'model/simulation/detector'; import { ChartInterface } from 'components/Chart'; import { generateDetectorChartLabels } from 'utils/simulation/detectorInfo'; import AppLayout from 'pages/AppLayout'; type Props = { + setup: Detector, scored: Score, dimensions: DimensionsInfo, classes: Object, @@ -27,7 +29,7 @@ class ResultDetailsLayout extends React.Component { data={this.props.scored} numberOfDimensions={this.props.dimensions.numberOfDimensions} classes={{ root: classes.chart }} - labels={generateDetectorChartLabels(({ name: 'test', shape: null }: any))} + labels={generateDetectorChartLabels(this.props.setup)} /> { diff --git a/src/routes/Results/containers/ResultDetailsContainer.js b/src/routes/Results/containers/ResultDetailsContainer.js index 43eadd46e..24b8213d1 100644 --- a/src/routes/Results/containers/ResultDetailsContainer.js +++ b/src/routes/Results/containers/ResultDetailsContainer.js @@ -3,6 +3,7 @@ import React from 'react'; import { connect } from 'react-redux'; import type { Score, DetectorResultsInfo } from 'model/result'; +import type { Detector } from 'model/simulation/detector'; import { LoadingCircle } from 'pages/Empty'; import ResultDetailsLayout from '../components/ResultDetailsLayout'; import selector from '../selector'; @@ -11,6 +12,7 @@ import { actionCreator } from '../reducer'; type Props = { scored: Score, metadata: DetectorResultsInfo, + setup: Detector, isFetchPending: bool, fetchResults: () => void, } @@ -30,6 +32,7 @@ class ResultDetailsContainer extends React.Component { } return ( @@ -41,6 +44,7 @@ const mapStateToProps = (state, props) => { return { scored: selector.resultScoreSelector(state, props.params.detectorId), metadata: selector.resultOverviewSelector(state, props.params.detectorId), + setup: selector.resultSetupSelector(state, props.params.detectorId), }; }; diff --git a/src/routes/Results/reducer.js b/src/routes/Results/reducer.js index 17ddfd86c..d1e77d839 100644 --- a/src/routes/Results/reducer.js +++ b/src/routes/Results/reducer.js @@ -21,10 +21,11 @@ const ACTION_HANDLERS = { }) ), [actionType.FETCH_SIMULATION_RESULTS_SUCCESS]: (state, action) => { - const { detectors, results } = action.results; - const detectorIds = _.map(detectors, item => item.metadata.filename); + const { detectors: results } = action.results; + const { detectors: setup } = action.setup; - const detectorsMap = _.keyBy(detectors, item => item.metadata.filename); + const detectorIds = _.map(results, item => item.detectorId); + const detectorsMap = _.keyBy(results, item => item.detectorId); const detectorsProcessed = _.mapValues(detectorsMap, (item) => { const { scored, ...rest } = item; return rest; @@ -32,9 +33,9 @@ const ACTION_HANDLERS = { const detectorsScore = _.mapValues(detectorsMap, item => item.scored); return state.merge({ - ...results, detectorIds, detectors: detectorsProcessed, + detectorsSetup: setup, detectorsScore, dataStatus: 'success', }); diff --git a/src/routes/Results/saga.js b/src/routes/Results/saga.js index b96c42fb6..a9c07202b 100644 --- a/src/routes/Results/saga.js +++ b/src/routes/Results/saga.js @@ -14,7 +14,10 @@ export function* fetchSimulationResults( versionId: state.results.get('versionId'), dataStatus: state.results.get('dataStatus'), })); - if (dataStatus !== 'none' && projectId === action.projectId && versionId === action.versionId) { + if (dataStatus !== 'none' + && projectId === action.projectId + && versionId === action.versionId + ) { return; } yield put({ @@ -22,11 +25,19 @@ export function* fetchSimulationResults( projectId: action.projectId, versionId: action.versionId, }); - const response = yield call( + const results = yield call( api.get, endpoint.simulationResults(action.projectId, action.versionId), ); - yield put({ type: actionType.FETCH_SIMULATION_RESULTS_SUCCESS, results: response.data }); + const setup = yield call( + api.get, + endpoint.simulationSetup(action.projectId, action.versionId), + ); + yield put({ + type: actionType.FETCH_SIMULATION_RESULTS_SUCCESS, + setup: setup.data, + results: results.data, + }); } catch (error) { yield put({ type: actionType.FETCH_SIMULATION_RESULTS_ERROR, error: error.response.data }); } diff --git a/src/routes/Results/selector.js b/src/routes/Results/selector.js index 60b13b751..6c1cce9fe 100644 --- a/src/routes/Results/selector.js +++ b/src/routes/Results/selector.js @@ -11,12 +11,17 @@ function resultsListSelector( } function resultOverviewSelector(state: Store, detectorId: DetectorResultId): ?DetectorResultsInfo { - const overview = state.results.getIn(['detectors', detectorId]); + const overview = state.results.getIn(['detectors', String(detectorId)]); return overview ? overview.toJS() : undefined; } function resultScoreSelector(state: Store, detectorId: DetectorResultId): ?Score { - const score = state.results.getIn(['detectorsScore', detectorId]); + const score = state.results.getIn(['detectorsScore', String(detectorId)]); + return score ? score.toJS() : undefined; +} + +function resultSetupSelector(state: Store, detectorId: DetectorResultId): ?Score { + const score = state.results.getIn(['detectorsSetup', String(detectorId)]); return score ? score.toJS() : undefined; } @@ -24,4 +29,5 @@ export default { resultsListSelector, resultOverviewSelector, resultScoreSelector, + resultSetupSelector, }; diff --git a/src/routes/Workspace/Detectors/components/DetectorItemLayout.js b/src/routes/Workspace/Detectors/components/DetectorItemLayout.js index 2d2281540..0e2843729 100644 --- a/src/routes/Workspace/Detectors/components/DetectorItemLayout.js +++ b/src/routes/Workspace/Detectors/components/DetectorItemLayout.js @@ -8,6 +8,7 @@ import Button from 'material-ui/Button'; import DeleteIcon from 'material-ui-icons/Delete'; import type { Detector } from 'model/simulation/detector'; import { t } from 'i18n'; +import { EditableName } from 'components/Editor'; import ParticleEditor from 'components/Editor/ParticleEditor'; import DetectorGeometryItemLayout from './DetectorGeometryItemLayout'; import DetectorScoringItemLayout from './DetectorScoringItemLayout'; @@ -15,6 +16,7 @@ import DetectorScoringItemLayout from './DetectorScoringItemLayout'; type Props = { detector: Detector, updateType: (type: string) => void, + detectorNameUpdate: (value: string) => void, geometryUpdate: (value: Object, type: string) => void, particleUpdate: (value: Object) => void, scoringUpdate: (value: Object) => void, @@ -44,6 +46,11 @@ class DetectorItemLayout extends React.Component { className={classes.root} elevation={4} > + { detectorGeometry: defaultDetectorGeometryForType(type), }); } + + detectorNameUpdate = (name: string) => { + this.props.updateDetector({ + ...this.props.detector, + name, + }); + } + geometryUpdate = (type: string, value: any) => { this.props.updateDetector({ ...this.props.detector, @@ -61,6 +69,7 @@ class DetectorItemContainer extends React.Component { classes={this.props.classes} detector={this.props.detector || EMPTY} updateType={this.updateType} + detectorNameUpdate={this.detectorNameUpdate} geometryUpdate={this.geometryUpdate} particleUpdate={this.particleUpdate} scoringUpdate={this.scoringUpdate} diff --git a/src/routes/Workspace/Geometry/components/ZoneItemLayout.js b/src/routes/Workspace/Geometry/components/ZoneItemLayout.js index a4329f620..9d361383c 100644 --- a/src/routes/Workspace/Geometry/components/ZoneItemLayout.js +++ b/src/routes/Workspace/Geometry/components/ZoneItemLayout.js @@ -5,7 +5,8 @@ import Paper from 'material-ui/Paper'; import Button from 'material-ui/Button'; import RightArrowIcon from 'material-ui-icons/KeyboardArrowRight'; import { withStyles } from 'material-ui/styles'; -import { ZoneName, ZoneEditor } from 'components/Editor/ZoneEditor'; +import { ZoneEditor } from 'components/Editor/ZoneEditor'; +import { EditableName } from 'components/Editor'; import type { OperationType, ConstructionPath, PrintableOperation } from 'model/simulation/zone'; import type { PrintableMaterial } from 'model/simulation/material'; @@ -43,7 +44,8 @@ class ZoneItemLayout extends React.Component { render() { const { classes, zoneName, base, construction, materialId, materials } = this.props; const zoneTitle = ( - { props: Props updateColor = (color: Color) => { - console.log(color); this.props.updateField(color, 'color'); } diff --git a/src/utils/simulation/detectorInfo.js b/src/utils/simulation/detectorInfo.js index c9cb749b3..2f9ea7812 100644 --- a/src/utils/simulation/detectorInfo.js +++ b/src/utils/simulation/detectorInfo.js @@ -1,19 +1,79 @@ /* @flow */ import type { ChartLabels } from 'model/result/chart'; -import type { Detector } from 'model/simulation/detector'; +import type { + Detector, + Cylinder, + Mesh, + Geomap, +} from 'model/simulation/detector'; + +const dimensionsGenerators = { + geomap: (geometry: Geomap) => ([ + { + label: 'z', + unit: 'cm', + startValue: geometry.center.z - (geometry.size.z / 2), + endValue: geometry.center.z + (geometry.size.z / 2), + }, { + label: 'y', + unit: 'cm', + startValue: geometry.center.y - (geometry.size.y / 2), + endValue: geometry.center.y + (geometry.size.y / 2), + }, { + label: 'x', + unit: 'cm', + startValue: geometry.center.x - (geometry.size.x / 2), + endValue: geometry.center.x + (geometry.size.x / 2), + }, + ]), + mesh: (geometry: Mesh) => ([ + { + label: 'z', + unit: 'cm', + startValue: geometry.center.z - (geometry.size.z / 2), + endValue: geometry.center.z + (geometry.size.z / 2), + }, { + label: 'y', + unit: 'cm', + startValue: geometry.center.y - (geometry.size.y / 2), + endValue: geometry.center.y + (geometry.size.y / 2), + }, { + label: 'x', + unit: 'cm', + startValue: geometry.center.x - (geometry.size.x / 2), + endValue: geometry.center.x + (geometry.size.x / 2), + }, + ]), + cylinder: (geometry: Cylinder) => ([ + { + label: 'z', + unit: 'cm', + startValue: geometry.zValue.min, + endValue: geometry.zValue.max, + }, { + label: 'θ', + unit: 'rad', + startValue: geometry.angle.min, + endValue: geometry.angle.max, + }, { + label: 'R', + unit: 'cm', + startValue: geometry.radius.min, + endValue: geometry.radius.max, + }, + ]), + plane: (() => []: any), + zone: (() => []: any), +}; export function generateDetectorChartLabels(detector: Detector): ChartLabels { - const _ = detector; // eslint-disable-line + const type = detector.detectorGeometry.type; // TODO: replace mock after detector model is implemented. return { valueLabel: 'Energy', valueUnit: 'eV', - dimensions: [ - { label: 'x', unit: 'mm', startValue: -20.050, endValue: -20.005 }, - { label: 'y', unit: 'mm', startValue: -20, endValue: 110 }, - { label: 'z', unit: 'mm', startValue: -20, endValue: 110 }, - ], + dimensions: dimensionsGenerators[type]((detector.detectorGeometry: any)), }; }