4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 import _cloneDeep
from 'lodash/cloneDeep'
22 import _isArray
from 'lodash/isArray'
23 import _isObject
from 'lodash/isObject'
24 import _keys
from 'lodash/keys'
25 import React
from 'react';
26 import PureRenderMixin
from 'react-addons-pure-render-mixin'
27 import messages
from './messages'
28 import serializers
from '../libraries/model/DescriptorModelSerializer'
29 import JSONViewer
from 'widgets/JSONViewer/JSONViewer';
30 import PopupWindow
from './PopupWindow'
31 import DetailsPanelToolbar
from './DetailsPanelToolbar'
32 import NavigateDescriptorModel
from './NavigateDescriptorModel'
33 import NavigateDescriptorErrors
from './NavigateDescriptorErrors'
34 import CatalogItemDetailsEditor
from './CatalogItemDetailsEditor'
35 import SelectionManager
from '../libraries/SelectionManager'
37 import '../styles/DetailsPanel.scss'
39 function checkForErrors(errors
) {
40 return _keys(errors
).reduce((inError
, k
) => {
41 function traverseObject(obj
, key
) {
42 const node
= obj
[key
];
44 return node
.reduce((inError
, v
, i
) => {
46 return _keys(v
).reduce((inError
, k
) => {
47 return inError
|| traverseObject(v
, k
);
52 } else if (_isObject(node
)) {
53 return _keys(node
).reduce((inError
, k
) => {
54 return inError
|| traverseObject(node
, k
);
60 return inError
|| traverseObject(errors
, k
);
64 const DetailsPanel
= React
.createClass({
65 mixins
: [PureRenderMixin
, SelectionManager
.reactPauseResumeMixin
],
75 componentWillMount() {
77 const height
= this.panel
&& this.panel
.offsetHeight
;
78 this.setState({ height
});
83 componentDidUpdate() {
84 SelectionManager
.refreshOutline();
86 componentWillUnmount() {
89 router
: React
.PropTypes
.object
,
90 userProfile
: React
.PropTypes
.object
92 componentWillUpdate(nextProps
) {
93 if ((nextProps
.layout
!= this.props
.layout
)
94 && (nextProps
.layout
.height
!= this.props
.layout
.height
)) {
95 this.componentWillMount();
101 let bodyContent
= this.props
.hasNoCatalogs
? null : messages
.detailsWelcome();
102 const selected
= this.props
.containers
.filter(d
=> SelectionManager
.isSelected(d
));
103 const selectedContainer
= selected
[0];
104 let workingHeight
= this.state
.height
|| 1;
106 function makeId(container
, path
) {
107 let idParts
= [_isArray(path
) ? path
.join(':') : path
];
108 idParts
.push(container
.uid
);
109 while (container
.parent
) {
110 container
= container
.parent
;
111 idParts
.push(container
.uid
);
113 return idParts
.reverse().join(':');
116 if (selectedContainer
) {
121 container
={selectedContainer
}
122 showHelp
={this.props
.showHelp
.forAll
}
123 width
={this.props
.layout
.right
} />
125 workingHeight
-= 32 + 35;
127 <NavigateDescriptorModel key
='navigate' container
={selectedContainer
} idMaker
={makeId
}
128 style
={{ margin
: '8px 8px 15px' }} />
130 workingHeight
-= 8 + 15 + 37;
131 if (checkForErrors(selectedContainer
.uiState
.error
)) {
133 <NavigateDescriptorErrors key
='errors' container
={selectedContainer
} idMaker
={makeId
}
134 style
={{ margin
: '8px 8px 15px' }} />
136 workingHeight
-= 8 + 15 + 37;
139 <div key
='editor' className
="DetailsPanelBody">
140 <CatalogItemDetailsEditor
141 container
={selectedContainer
}
143 showHelp
={this.props
.showHelp
}
144 collapsePanelsByDefault
={this.props
.collapsePanelsByDefault
}
145 openPanelsWithData
={this.props
.openPanelsWithData
}
146 width
={this.props
.layout
.right
}
147 height
={workingHeight
} />
150 const edit
= _cloneDeep(selectedContainer
.model
);
151 json
= serializers
.serialize(edit
) || edit
;
153 const jsonViewerTitle
= selectedContainer
? selectedContainer
.model
.name
: 'nothing selected';
155 <div ref
={el
=> this.panel
= el
} className
="DetailsPanel" data
-resizable
="left" data
-resizable
-handle
-offset
="0 5" style
={{ width
: this.props
.layout
.right
}} onClick
={event
=> event
.preventDefault()}>
157 <PopupWindow show
={this.props
.showJSONViewer
} title
={jsonViewerTitle
}><JSONViewer json
={json
} /></PopupWindow
>
163 export default DetailsPanel
;