diff --git a/actions/generals.js b/actions/generals.js index 2623b1c57..2ebb32525 100644 --- a/actions/generals.js +++ b/actions/generals.js @@ -2,6 +2,7 @@ export const VFB_ERROR = 'VFB_ERROR'; export const VFB_LOAD_ID = 'VFB_LOAD_ID'; export const VFB_ID_LOADED = 'VFB_ID_LOADED'; export const VFB_UI_UPDATED = 'VFB_UI_UPDATED'; +export const INSTANCE_ADDED = 'INSTANCE_ADDED' export const vfbError = errorMessage => ({ type: VFB_ERROR, @@ -26,3 +27,8 @@ export const vfbUIUpdated = layout => ({ type: VFB_UI_UPDATED, data: layout }); + +export const instanceAdded = instance => ({ + type: INSTANCE_ADDED, + data: instance +}); diff --git a/components/VFBMain.js b/components/VFBMain.js index 14ba73e1d..c3be3d8ea 100644 --- a/components/VFBMain.js +++ b/components/VFBMain.js @@ -44,7 +44,6 @@ export default class VFBMain extends React.Component { quickHelpVisible: undefined, UIUpdated: false, htmlFromToolbar: undefined, - idOnFocus: undefined, instanceOnFocus: undefined, idSelected: undefined, }; @@ -76,10 +75,10 @@ export default class VFBMain extends React.Component { this.idOnFocus = undefined; this.instanceOnFocus = undefined; this.idFromURL = undefined; - this.firstLoad = true; this.idsFromURL = []; this.urlQueryLoader = undefined; this.quickHelpRender = undefined; + this.firstLoad = true; this.UIElementsVisibility = {}; @@ -229,13 +228,9 @@ export default class VFBMain extends React.Component { continue; } if (this.hasVisualType(variableIds[singleId])) { - this.handlerInstanceUpdate(Instances[variableIds[singleId]]); - /* - * FIXME: the handlerInstanceUpdate above has been placed there to provide the meta data earlier - * and avoid to wait for the 3d viewer and slice to be loaded before to display the data - * we need to edit the callback passed to resolve3d here below to avoid the double switching - * with the metadata. - */ + if (!this.firstLoad) { + this.handlerInstanceUpdate(meta); + } this.resolve3D(variableIds[singleId], function (id) { var instance = Instances.getInstance(id); GEPPETTO.SceneController.deselectAll(); @@ -751,6 +746,7 @@ export default class VFBMain extends React.Component { name={"Canvas"} baseZoom="1.2" wireframeEnabled={true} + minimiseAnimation={false} onLoad={this.ThreeDViewerIdLoaded} ref={ref => this.canvasReference = ref} />) } else if (component === "termInfo") { @@ -1030,6 +1026,11 @@ export default class VFBMain extends React.Component { } var that = this; + + GEPPETTO.on(GEPPETTO.Events.Instance_added, function (instance) { + that.props.instanceAdded(instance); + }); + GEPPETTO.on(GEPPETTO.Events.Model_loaded, function () { that.addVfbId(that.idsFinalList); @@ -1178,11 +1179,13 @@ export default class VFBMain extends React.Component { */ for (var counter = 0; counter < this.idsFromURL.length; counter++) { if (this.idsFromURL[counter] === this.idOnFocus && this.idFromURL !== this.idOnFocus) { + this.TermInfoIdLoaded(this.idOnFocus); this.idsFromURL.splice(counter, 1); return; } if (this.idsFromURL[counter] === this.idOnFocus && this.idFromURL === this.idOnFocus) { this.idsFromURL.splice(counter, 1); + this.firstLoad = false; break; } } @@ -1190,6 +1193,8 @@ export default class VFBMain extends React.Component { // Update the term info component if (this.termInfoReference !== undefined && this.termInfoReference !== null) { this.termInfoReference.setTermInfo(this.instanceOnFocus, this.idOnFocus); + } else { + this.TermInfoIdLoaded(this.idOnFocus); } // Update the tree browser diff --git a/components/interface/VFBLoader/VFBLoader.js b/components/interface/VFBLoader/VFBLoader.js index 8f649b15e..4c9d6f529 100644 --- a/components/interface/VFBLoader/VFBLoader.js +++ b/components/interface/VFBLoader/VFBLoader.js @@ -4,330 +4,45 @@ require('./VFBLoader.less'); export default class VFBLoader extends Component { constructor (props) { super(props) - - this.state = { - loading: false, - percentage: 0, - loadedCounter: 0, - idsLoaded: [], - queuedItems: [], - idsMap: {}, - layout: undefined, - stepstoLoad: 0, - stepsLoaded: 0, - instancesToLoad: 0, - instancesLoaded: 0 - }; - - this.nextStep = this.nextStep.bind(this); - - this.componentsMap = props.componentsMap; - } - - static getDerivedStateFromProps (nextProps, prevState) { - // Variables from props and state - var idsMap = prevState.idsMap; - var queuedItems = prevState.queuedItems; - var idsLoaded = prevState.idsLoaded; - var stepstoLoad = 0; - var stepsLoaded = 0; - var instancesToLoad = 0; - var instancesLoaded = 0; - var layout = nextProps.generals.layout; - - // function to add new instances to the map that keep tracks of each component loaded - var addIdToMap = function (singleId) { - stepstoLoad = 0; - stepsLoaded = 0; - instancesToLoad = 0; - instancesLoaded = 0; - // If this id is not listed in idsMap the we add it - if (idsMap.singleId === undefined) { - idsMap[singleId] = { - loaded: false, - components: {} - }; - checkSuffixChildren(singleId); - return true; - } - return false; - }; - - // function to update the instances map - var updateIdsMap = function () { - stepstoLoad = 0; - stepsLoaded = 0; - instancesToLoad = 0; - instancesLoaded = 0; - for (let singleId in idsMap) { - checkSuffixChildren(singleId); - } - }; - - // function that create the inner map per instance to track each component - var checkSuffixChildren = function (id) { - if (Instances[id] !== undefined && Instances[id].children.length > 0) { - var loaded = true; - Instances[id].children.map(child => { - var childId = child.getId(); - for (let key in nextProps.componentsMap) { - if (typeof nextProps.componentsMap[key].geppettoSuffix === "string") { - if (childId.includes(nextProps.componentsMap[key].geppettoSuffix)) { - if (idsMap[id].components[nextProps.componentsMap[key].matchingString] !== undefined) { - if (layout[nextProps.componentsMap[key].matchingString] == false - && idsMap[id].components[nextProps.componentsMap[key].matchingString].available) { - idsMap[id].components[nextProps.componentsMap[key].matchingString].available = false; - } - if (idsMap[id].components[nextProps.componentsMap[key].matchingString].loaded - && idsMap[id].components[nextProps.componentsMap[key].matchingString].available) { - stepstoLoad++; - stepsLoaded++; - } - if (idsMap[id].components[nextProps.componentsMap[key].matchingString].available - && idsMap[id].components[nextProps.componentsMap[key].matchingString].loaded == false) { - stepstoLoad++; - loaded = false; - } - } else { - if (layout[nextProps.componentsMap[key].matchingString]) { - idsMap[id].components[nextProps.componentsMap[key].matchingString] = { - loaded: false, - available: true, - }; - stepstoLoad++; - loaded = false; - } else { - idsMap[id].components[nextProps.componentsMap[key].matchingString] = { - loaded: false, - available: false, - }; - } - } - } - } else if (nextProps.componentsMap[key].geppettoSuffix.length > 1) { - nextProps.componentsMap[key].geppettoSuffix.map(suffix => { - if (childId.includes(suffix)) { - if (idsMap[id].components[nextProps.componentsMap[key].matchingString] !== undefined) { - if (layout[nextProps.componentsMap[key].matchingString] == false - && idsMap[id].components[nextProps.componentsMap[key].matchingString].available) { - idsMap[id].components[nextProps.componentsMap[key].matchingString].available = false; - } - if (layout[nextProps.componentsMap[key].matchingString] - && idsMap[id].components[nextProps.componentsMap[key].matchingString].loaded) { - stepstoLoad++; - stepsLoaded++; - } - if (layout[nextProps.componentsMap[key].matchingString] - && idsMap[id].components[nextProps.componentsMap[key].matchingString].loaded == false) { - stepstoLoad++; - loaded = false; - } - } else { - if (layout[nextProps.componentsMap[key].matchingString]) { - idsMap[id].components[nextProps.componentsMap[key].matchingString] = { - loaded: false, - available: true, - }; - loaded = false; - stepstoLoad++; - } else { - idsMap[id].components[nextProps.componentsMap[key].matchingString] = { - loaded: false, - available: false, - }; - } - } - } - }); - } - } - }); - if (loaded) { - delete idsMap[id]; - } - } else { - stepstoLoad++; - } - }; - - // If there are new instances to load add them to the map and to the queueItems array - if (nextProps.generals.idsToLoad !== undefined && nextProps.generals.idsToLoad.length > 0) { - var idsToLoad = nextProps.generals.idsToLoad; - var updated = false; - idsToLoad.map(singleId => { - if (!idsLoaded.includes(singleId) && addIdToMap(singleId)) { - updated = true; - idsLoaded.push(singleId); - queuedItems.push(singleId); - } - }); - - var instancesToLoad = queuedItems.length; - var instancesLoaded = instancesToLoad - Object.keys(idsMap).length; - - if (updated) { - return { - ...prevState, - loading: true, - idsMap: idsMap, - queuedItems: queuedItems, - stepstoLoad: stepstoLoad, - stepsLoaded: stepsLoaded, - instancesToLoad: instancesToLoad, - instancesLoaded: instancesLoaded, - }; - } else { - return null; - } - } - - // If an instances has been partially or totally loaded update the map - if (nextProps.generals.idLoaded !== undefined) { - if (idsMap[nextProps.generals.idLoaded.id] === undefined) { - return null; - } - checkSuffixChildren(nextProps.generals.idLoaded.id); - if (idsMap[nextProps.generals.idLoaded.id].components[nextProps.generals.idLoaded.component] !== undefined) { - idsMap[nextProps.generals.idLoaded.id].components[nextProps.generals.idLoaded.component].loaded = true; - } - updateIdsMap(); - - var instancesToLoad = queuedItems.length; - var instancesLoaded = instancesToLoad - Object.keys(idsMap).length; - - return { - ...prevState, - loading: true, - idsMap: idsMap, - queuedItems: queuedItems, - stepstoLoad: stepstoLoad, - stepsLoaded: stepsLoaded, - instancesToLoad: instancesToLoad, - instancesLoaded: instancesLoaded, - }; - } - - return null; - } - - - nextStep () { - if (this.state.percentage <= this.state.totalUIItems) { - this.setState(prevState => ({ percentage: prevState.percentage + 1 })) - } } componentDidUpdate (prevProps, prevState) { - if ((Object.keys(this.state.idsMap).length === 0 && this.state.loading === true)) { - this.setState({ - loading: false, - percentage: 0, - loadedCounter: 0, - queuedItems: [], - idsMap: {}, - layout: undefined, - stepstoLoad: 0, - stepsLoaded: 0, - instancesToLoad: 0, - instancesLoaded: 0 - }, () => { - GEPPETTO.trigger('stop_spin_logo'); - }); + if (!this.props.generals.loading) { + GEPPETTO.trigger('stop_spin_logo'); } } componentDidMount () { var that = this; GEPPETTO.on('stop_spin_logo', function () { - if (that.state.loading) { + if (that.props.generals.loading) { GEPPETTO.trigger('spin_logo'); } }); - - GEPPETTO.on(GEPPETTO.Events.Instances_added, function (instances) { - var idsMap = JSON.parse(JSON.stringify(that.state.idsMap)); - var requireUpdate = false; - - for (let id in idsMap) { - if (Instances[id] !== undefined && Instances[id].children.length > 0) { - var loaded = true; - Instances[id].children.map(child => { - var childId = child.getId(); - for (let key in that.componentsMap) { - if (typeof that.componentsMap[key].geppettoSuffix === "string") { - if (childId.includes(that.componentsMap[key].geppettoSuffix)) { - if (idsMap[id].components[that.componentsMap[key].matchingString] !== undefined) { - if (that.props.generals.layout[that.componentsMap[key].matchingString] - && idsMap[id].components[that.componentsMap[key].matchingString].loaded == false) { - loaded = false; - } - } else { - if (that.props.generals.layout[that.componentsMap[key].matchingString]) { - idsMap[id].components[that.componentsMap[key].matchingString] = { - loaded: false, - available: true, - }; - loaded = false; - } - } - } - } else if (that.componentsMap[key].geppettoSuffix.length > 1) { - that.componentsMap[key].geppettoSuffix.map(suffix => { - if (childId.includes(suffix)) { - if (idsMap[id].components[that.componentsMap[key].matchingString] !== undefined) { - if (that.props.generals.layout[that.componentsMap[key].matchingString] - && idsMap[id].components[that.componentsMap[key].matchingString].loaded == false) { - loaded = false; - } - } else { - if (that.props.generals.layout[that.componentsMap[key].matchingString]) { - idsMap[id].components[that.componentsMap[key].matchingString] = { - loaded: false, - available: true, - }; - loaded = false; - } - } - } - }); - } - } - }); - if (loaded) { - delete idsMap[id]; - requireUpdate = true; - } - } - } - - if (requireUpdate) { - that.setState({ idsMap: idsMap }); - } - }); } render () { - if (!this.state.loading) { + if (!this.props.generals.loading) { return null; } return (
- +
) } } const ProgressBar = props => { - let instancesToLoad = props.params.instancesToLoad; - let instancesLoaded = props.params.instancesLoaded + 1; + let instancesToLoad = props.params.idsToLoad; + let instancesLoaded = props.params.idsLoaded + 1; return (
- +
) }; const Filler = props => ( -
+
); diff --git a/components/interface/VFBLoader/VFBLoaderContainer.js b/components/interface/VFBLoader/VFBLoaderContainer.js index 263386042..b8fe9d847 100644 --- a/components/interface/VFBLoader/VFBLoaderContainer.js +++ b/components/interface/VFBLoader/VFBLoaderContainer.js @@ -1,11 +1,6 @@ import { connect } from "react-redux"; import VFBLoader from "./VFBLoader"; -const componentsMap = require('../../configuration/VFBLoader/VFBLoaderConfiguration').componentsMap; - -const mapStateToProps = state => ({ - componentsMap: componentsMap, - ...state, -}); +const mapStateToProps = state => ({ ...state }); export default connect(mapStateToProps)(VFBLoader); diff --git a/components/interface/VFBTermInfo/VFBTermInfo.js b/components/interface/VFBTermInfo/VFBTermInfo.js index dedacb6c2..9a160d109 100644 --- a/components/interface/VFBTermInfo/VFBTermInfo.js +++ b/components/interface/VFBTermInfo/VFBTermInfo.js @@ -619,7 +619,7 @@ export default class VFBTermInfoWidget extends React.Component { Model.getDatasources()[0].fetchVariable(path, function () { var m = Instances.getInstance(meta); this.setTermInfo(m, m.name); - window.resolve3D(path); + window.addVfbId(path); }.bind(this)); } } diff --git a/containers/VFBMainContainer.js b/containers/VFBMainContainer.js index 9d004ca05..aa00367b4 100644 --- a/containers/VFBMainContainer.js +++ b/containers/VFBMainContainer.js @@ -1,5 +1,5 @@ import VFBMain from '../components/VFBMain'; -import { vfbLoadId, vfbIdLoaded, vfbUIUpdated } from '../actions/generals'; +import { vfbLoadId, vfbIdLoaded, vfbUIUpdated, instanceAdded } from '../actions/generals'; import { connect } from "react-redux"; const mapStateToProps = state => ({ ...state }); @@ -7,7 +7,8 @@ const mapStateToProps = state => ({ ...state }); const mapDispatchToProps = dispatch => ({ vfbLoadId: id => dispatch(vfbLoadId(id)), vfbIdLoaded: (id, component) => dispatch(vfbIdLoaded(id, component)), - vfbUIUpdated: layout => dispatch(vfbUIUpdated(layout)) + vfbUIUpdated: layout => dispatch(vfbUIUpdated(layout)), + instanceAdded: instance => dispatch(instanceAdded(instance)), }); export default connect(mapStateToProps, mapDispatchToProps)(VFBMain); diff --git a/reducers/generals.js b/reducers/generals.js index e340dc3aa..4cc64279a 100644 --- a/reducers/generals.js +++ b/reducers/generals.js @@ -2,14 +2,21 @@ import { VFB_ERROR, VFB_ID_LOADED, VFB_LOAD_ID, - VFB_UI_UPDATED + VFB_UI_UPDATED, + INSTANCE_ADDED } from '../actions/generals'; +const componentsMap = require('../components/configuration/VFBLoader/VFBLoaderConfiguration').componentsMap; + export const GENERAL_DEFAULT_STATE = { error: undefined, + idsMap: {}, idsList: [], - idsToLoad: undefined, - idLoaded: undefined, + idsLoaded: 0, + idsToLoad: 0, + stepsToLoad: 1, + stepsLoaded: 0, + loading: false, layout: { "ThreeDViewer": true, "StackViewer": true, @@ -22,6 +29,38 @@ export default ( state = {}, action ) => ({ ...generalReducer(state, action) }); +function checkLayoutState (layout) { + var stateValue = false; + Object.keys(layout).map(key => { + if (layout[key]) { + stateValue = true; + } + }); + return stateValue; +} + +function returnComponent (instance_type) { + var matchString = null; + for (let key in componentsMap) { + if (typeof componentsMap[key].geppettoSuffix === "string") { + if (instance_type.includes(componentsMap[key].geppettoSuffix)) { + matchString = componentsMap[key].matchingString; + break; + } + } else if (componentsMap[key].geppettoSuffix.length > 1) { + componentsMap[key].geppettoSuffix.map(suffix => { + if (instance_type.includes(suffix)) { + matchString = componentsMap[key].matchingString; + } + }); + if (matchString !== null) { + break; + } + } + } + return matchString; +} + function generalReducer (state, action) { switch (action.type) { case VFB_ERROR: @@ -30,49 +69,144 @@ function generalReducer (state, action) { error: action.data } case VFB_LOAD_ID: - // action.data is a string or an array? let's check it - if (action.data.length === undefined) { - if (!state.idsList.includes(action.data)) { + // check if data are provided as string or array of strings + if (typeof action.data === "string") { + if (!state.idsList.includes(action.data) && checkLayoutState(state.layout)) { + var idsToLoad = state.idsToLoad + 1; + var newMap = { ...state.idsMap }; + newMap[action.data] = { + loaded: !checkLayoutState(state.layout), + components: {} + }; return { ...state, - idsList: [...state.idsToLoad, action.data], - idsToLoad: [action.data], - idLoaded: undefined + loading: true, + idsMap: newMap, + idsList: [...state.idsList, action.data], + idsToLoad: idsToLoad, }; } } else { var newIds = []; + var idsToLoad = state.idsToLoad; + var newMap = { ...state.idsMap }; action.data.map(item => { - if (!state.idsList.includes(item)) { + if (!state.idsList.includes(item) && checkLayoutState(state.layout)) { + idsToLoad++; newIds.push(item); + newMap[item] = { + loaded: !checkLayoutState(state.layout), + components: {} + }; } }); if (newIds.length > 0) { return { ...state, + loading: true, + idsMap: newMap, idsList: [...state.idsList, ...newIds], - idsToLoad: newIds, - idLoaded: undefined + idsToLoad: idsToLoad, }; } } - return { - ...state, - idsToLoad: undefined, - idLoaded: undefined - }; + return { ...state }; case VFB_ID_LOADED: - return { - ...state, - idsToLoad: undefined, - idLoaded: action.data - }; + var loading = false; + var stepsToLoad = 0; + var stepsLoaded = 0; + var idsLoaded = state.idsLoaded; + var newMap = { ...state.idsMap }; + + if (newMap[action.data.id] === undefined ) { + return { + ...state, + error: "instance " + action.data.id + "is not present anymore in the map" + }; + } + + if (newMap[action.data.id] !== undefined && newMap[action.data.id].components[action.data.component]) { + var newComponents = { ...newMap[action.data.id].components }; + newMap[action.data.id].components = newComponents; + newMap[action.data.id].components[action.data.component].loaded = true; + } + + for (let singleId in newMap) { + var instanceLoaded = true; + if (Object.keys(newMap[singleId].components).length === 0) { + stepsToLoad++; + loading = true; + instanceLoaded = false; + } + + for (let singleComponent in newMap[singleId].components) { + if (newMap[singleId].components[singleComponent].loaded) { + stepsToLoad++; + stepsLoaded++; + } else { + stepsToLoad++; + loading = true; + instanceLoaded = false; + } + } + + if (instanceLoaded) { + idsLoaded++; + delete newMap[action.data.id]; + } + } + + if (loading) { + return { + ...state, + idsMap: newMap, + loading: loading, + idsLoaded: idsLoaded, + stepsToLoad: stepsToLoad, + stepsLoaded: stepsLoaded, + }; + } else { + return { + ...state, + idsToLoad: 0, + idsLoaded: 0, + idsList: [], + stepsToLoad: 0, + stepsLoaded: 0, + idsMap: newMap, + loading: loading, + }; + } case VFB_UI_UPDATED: return { ...state, - idsToLoad: undefined, - idLoaded: undefined, layout: action.data + }; + case INSTANCE_ADDED: + var newMap = { ...state.idsMap }; + var newInstance = action.data.split("."); + var component = returnComponent(newInstance[1]); + if (newMap[newInstance[0]] !== undefined + && component !== null + && newMap[newInstance[0]].components[component] === undefined + && Instances[newInstance[0]][newInstance[1]] !== undefined) { + var newComponents = { ...newMap[newInstance[0]].components }; + newMap[newInstance[0]].components = newComponents; + if (state.layout[component]) { + newMap[newInstance[0]].components[component] = { + loaded: false, + loadable: true + } + } else { + newMap[newInstance[0]].components[component] = { + loaded: true, + loadable: false + } + } } + return { + ...state, + idsMap: newMap, + }; } }