diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 5bde062..92484b3 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -186,17 +186,6 @@ class Dashboard extends Component { }); - /*let widgets = []; - widgets = this.state.dashboard.get('widgets'); - - const widgetKey = Dashboard.getNewWidgetKey(); - widgets[widgetKey] = widget; - - const dashboard = this.state.dashboard.set('widgets',widgets); - - // this.increaseHeightWithWidget(widget); - - this.setState({ dashboard });*/ }; @@ -206,11 +195,9 @@ class Dashboard extends Component { } widgetChange(widget, index, callback = null){ - - let tempChanges = this.state.widgetChangeData; - tempChanges.push(widget); - - this.setState({ widgetChangeData: tempChanges}) + let temp = this.state.widgetChangeData; + temp.push(widget); + this.setState({widgetChangeData: temp}); } @@ -294,7 +281,7 @@ class Dashboard extends Component { data: widget }); }); - this.setState({ editing: false }); + this.setState({ editing: false, widgetChangeData: [], widgetAddData: [] }); }; saveChanges() { @@ -312,21 +299,28 @@ class Dashboard extends Component { cancelEditing() { //raw widget has no id -> cannot be deleted in its original form - /* - this.state.widgetAddData.forEach( widget => { + let temp = []; + this.state.widgetAddData.forEach(rawWidget => { + this.state.widgets.forEach(widget => { + if(widget.y === rawWidget.y && widget.x === rawWidget.x && widget.type === rawWidget.type){ + temp.push(widget); + } + }) + }) + + temp.forEach( widget => { AppDispatcher.dispatch({ type: 'widgets/start-remove', data: widget, token: this.state.sessionToken }); - }); */ - + }); AppDispatcher.dispatch({ type: 'widgets/start-load', token: this.state.sessionToken, param: '?dashboardID=1' }); - this.setState({ editing: false, widgetChangeData: [], widgetAddData: [] }); + this.setState({ editing: false, widgetChangeData: [], widgetAddData: []}); }; diff --git a/src/styles/widgets.css b/src/styles/widgets.css index c5f775e..33e03f0 100644 --- a/src/styles/widgets.css +++ b/src/styles/widgets.css @@ -249,6 +249,7 @@ span.signal-unit::after { width: 100%; height: 100%; display: flex; + flex: none; word-wrap: break-word; } diff --git a/src/widget/dropzone.js b/src/widget/dropzone.js index f962719..530ec1e 100644 --- a/src/widget/dropzone.js +++ b/src/widget/dropzone.js @@ -28,20 +28,20 @@ const dropzoneTarget = { position.y -= dropzoneRect.top; // Z-Index is one more the top most children - let foundZ = props.children.reduce( (maxZ, currentChildren) => { - if (currentChildren.props != null) { + let foundZ = props.widgets.reduce( (maxZ, currentWidget) => { + if (currentWidget != null) { // Is there a simpler way? Is not easy to expose a getter in a Container.create(Component) - let widget = currentChildren.props.data; - if (widget && widget.z) { - if (widget.z > maxZ) { - return widget.z; + if (currentWidget.z > maxZ) { + return currentWidget.z; } - } } - + return maxZ; - }, 0); - position.z = foundZ >= 100? foundZ : ++foundZ; + }, 0) + position.z = foundZ >= 100? foundZ : foundZ += 10; + if(monitor.getItem().name === "Box"){ + position.z = 0; + } props.onDrop(monitor.getItem(), position); } diff --git a/src/widget/edit-widget/edit-widget-control-creator.js b/src/widget/edit-widget/edit-widget-control-creator.js index 2cd37a4..ae457b7 100644 --- a/src/widget/edit-widget/edit-widget-control-creator.js +++ b/src/widget/edit-widget/edit-widget-control-creator.js @@ -129,7 +129,8 @@ export default function CreateControls(widgetType = null, widget = null, session case 'Box': DialogControls.push( handleChange(e)} />, - handleChange(e)} /> + handleChange(e)} />, + handleChange(e)} /> ); break; case 'Label': @@ -155,7 +156,8 @@ export default function CreateControls(widgetType = null, widget = null, session case 'NumberInput': DialogControls.push( handleChange(e)} />, - handleChange(e)} /> + handleChange(e)} />, + handleChange(e)} /> ); break; diff --git a/src/widget/edit-widget/edit-widget-number-control.js b/src/widget/edit-widget/edit-widget-number-control.js index 7b4ffa5..5354863 100644 --- a/src/widget/edit-widget/edit-widget-number-control.js +++ b/src/widget/edit-widget/edit-widget-number-control.js @@ -25,21 +25,25 @@ class EditWidgetNumberControl extends Component { this.state = { widget: { customProperties:{} - } - }; + } + }; } - + static getDerivedStateFromProps(props, state){ return{ - widget: props.widget - }; - } + widget: props.widget + }; + } - render() { + render() { + let step = 1; + if(this.props.controlId ==='customProperties.background_color_opacity'){ + step = 0.1; + } return ( {this.props.label} - this.props.handleChange(e)} /> + this.props.handleChange(e)} /> ); } diff --git a/src/widget/edit-widget/edit-widget.js b/src/widget/edit-widget/edit-widget.js index 46b92a1..c8517bd 100644 --- a/src/widget/edit-widget/edit-widget.js +++ b/src/widget/edit-widget/edit-widget.js @@ -57,12 +57,36 @@ class EditWidgetDialog extends React.Component { const file = this.props.files.find(element => element.id === fileId); // scale width to match aspect + if(file.dimensions){ const aspectRatio = file.dimensions.width / file.dimensions.height; changeObject.width = this.state.temporal.height * aspectRatio; + } return changeObject; } + setMaxWidth(changeObject){ + if(changeObject.type === 'Label'){ + changeObject.customProperties.maxWidth = (changeObject.customProperties.textSize* 0.34) * changeObject.name.length; + } + else if (changeObject.type === 'Value'){ + // changeObject.customProperties.maxWidth = (changeObject.customProperties.textSize* 0.5) * (changeObject.name.length+13); + } + return changeObject; + } + + setNewLockRestrictions(changeObject){ + if(changeObject.customProperties.orientation === 0){ + changeObject.customProperties.resizeTopBottomLock = true; + changeObject.customProperties.resizeRightLeftLock = false; + } + else if(changeObject.customProperties.orientation === 1){ + changeObject.customProperties.resizeTopBottomLock = false; + changeObject.customProperties.resizeRightLeftLock = true; + } + return changeObject; + } + handleChange(e) { // TODO: check what we really need in this function. Can we reduce its complexity? @@ -73,13 +97,13 @@ class EditWidgetDialog extends React.Component { // not a customProperty customProperty = false; } - - if (e.target.id === 'lockAspect') { + + if (parts[1] === 'lockAspect') { //not a customProperty customProperty ? changeObject[parts[0]][parts[1]] = e.target.checked : changeObject[e.target.id] = e.target.checked; // correct image aspect if turned on - if (e.target.checked) { + if (e.target.checked && this.state.temporal.customProperties.file) { changeObject = this.assignAspectRatio(changeObject, this.state.temporal.customProperties.file); } } else if (e.target.id.includes('file')) { @@ -91,7 +115,15 @@ class EditWidgetDialog extends React.Component { // TODO this if condition requires changes to work!!! changeObject = this.assignAspectRatio(changeObject, e.target.value); } - } else if (e.target.type === 'number') { + }else if (parts[1] === 'textSize'){ + changeObject[parts[0]][parts[1]] = Number(e.target.value); + changeObject = this.setMaxWidth(changeObject); + + }else if(parts[1] === 'orientation'){ + customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value ; + changeObject = this.setNewLockRestrictions(changeObject); + } + else if (e.target.type === 'number') { customProperty ? changeObject[parts[0]][parts[1]] = Number(e.target.value) : changeObject[e.target.id] = Number(e.target.value); } else if(e.target.id === 'name'){ if(customProperty ? (changeObject[parts[0]][parts[1]] != null) : (changeObject[e.target.id] != null)){ @@ -99,6 +131,7 @@ class EditWidgetDialog extends React.Component { } else{ customProperty ? changeObject[parts[0]][parts[1]]= 'default' : changeObject[e.target.id] = 'default'; } + changeObject = this.setMaxWidth(changeObject); } else { customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value ; } diff --git a/src/widget/editable-widget-container.js b/src/widget/editable-widget-container.js index f49312e..f96e02c 100644 --- a/src/widget/editable-widget-container.js +++ b/src/widget/editable-widget-container.js @@ -84,16 +84,21 @@ class EditableWidgetContainer extends React.Component { render() { const widget = this.props.widget; + let resizingRestricted = false; + if(widget.customProperties.resizeRightLeftLock || widget.customProperties.resizeTopBottomLock){ + resizingRestricted = true; + } + const resizing = { - bottom: !widget.isLocked, - bottomLeft: !widget.isLocked, - bottomRight: !widget.isLocked, - left: !widget.isLocked, - right: !widget.idLocked, - top: !widget.isLocked, - topLeft: !widget.isLocked, - topRight: !widget.isLocked + bottom: !(widget.customProperties.resizeTopBottomLock || widget.isLocked), + bottomLeft: !(resizingRestricted|| widget.isLocked), + bottomRight: !(resizingRestricted || widget.isLocked), + left: !(widget.customProperties.resizeRightLeftLock || widget.isLocked), + right: !(widget.customProperties.resizeRightLeftLock || widget.isLocked), + top: !(widget.customProperties.resizeTopBottomLock || widget.isLocked), + topLeft: !(resizingRestricted || widget.isLocked), + topRight: !(resizingRestricted || widget.isLocked) }; const gridArray = [ this.props.grid, this.props.grid ]; @@ -108,6 +113,7 @@ class EditableWidgetContainer extends React.Component { default={{ x: Number(widget.x), y: Number(widget.y), width: widget.width, height: widget.height }} minWidth={widget.minWidth} minHeight={widget.minHeight} + maxWidth ={widget.customProperties.maxWidth || '100%' } lockAspectRatio={Boolean(widget.isLocked)} bounds={'parent'} className={widgetClasses} diff --git a/src/widget/widget-area.js b/src/widget/widget-area.js index b4d31f0..0686066 100644 --- a/src/widget/widget-area.js +++ b/src/widget/widget-area.js @@ -50,7 +50,7 @@ class WidgetArea extends React.Component { return absolutHeight > currentHeight ? absolutHeight : currentHeight; }, 0); - return + return {this.props.children} diff --git a/src/widget/widget-container.js b/src/widget/widget-container.js index 31360e2..5b2e064 100644 --- a/src/widget/widget-container.js +++ b/src/widget/widget-container.js @@ -26,7 +26,7 @@ class WidgetContainer extends React.Component { height: Number(this.props.widget.height), left: Number(this.props.widget.x), top: Number(this.props.widget.y), - zindex: Number(this.props.widget.z), + zIndex: Number(this.props.widget.z), position: 'absolute' }; diff --git a/src/widget/widget-context-menu.js b/src/widget/widget-context-menu.js index bf83fc8..0ce2604 100644 --- a/src/widget/widget-context-menu.js +++ b/src/widget/widget-context-menu.js @@ -34,7 +34,7 @@ class WidgetContextMenu extends React.Component { }; moveAbove = event => { - this.props.widget.z++; + this.props.widget.z += 10; if (this.props.widget.z > 100) { this.props.widget.z = 100; } @@ -53,7 +53,7 @@ class WidgetContextMenu extends React.Component { }; moveUnderneath = event => { - this.props.widget.z--; + this.props.widget.z -= 10; if (this.props.widget.z < 0) { this.props.widget.z = 0; } @@ -90,7 +90,7 @@ class WidgetContextMenu extends React.Component { render() { const isLocked = this.props.widget.locked; const ContextMenu = () => ( - + Edit Delete diff --git a/src/widget/widget-factory.js b/src/widget/widget-factory.js index b32200d..3673a63 100644 --- a/src/widget/widget-factory.js +++ b/src/widget/widget-factory.js @@ -70,11 +70,12 @@ class WidgetFactory { case 'Value': widget.minWidth = 70; widget.minHeight = 20; - widget.width = 120; + widget.width = 150; widget.height = 30; widget.customProperties.textSize = 16; widget.name = 'Value'; widget.customProperties.showUnit = false; + widget.customProperties.resizeTopBottomLock = true; break; case 'Plot': widget.customProperties.ylabel = ''; @@ -96,11 +97,13 @@ class WidgetFactory { case 'Label': widget.minWidth = 20; widget.minHeight = 20; + widget.customProperties.maxWidth = 100; widget.width = 100; widget.height = 35; widget.name = 'Label'; widget.customProperties.textSize = 32; widget.customProperties.fontColor = 0; + widget.customProperties.resizeTopBottomLock = true; break; case 'PlotTable': widget.customProperties.ylabel = ''; @@ -137,6 +140,8 @@ class WidgetFactory { widget.minHeight = 50; widget.width = 200; widget.height = 50; + widget.customProperties.showUnit = false; + widget.customProperties.resizeTopBottomLock = true; break; case 'Slider': widget.minWidth = 380; @@ -150,6 +155,8 @@ class WidgetFactory { widget.customProperties.showUnit = true; widget.customProperties.continous_update = false; widget.customProperties.default_value = 0; + widget.customProperties.resizeLeftRightLock = false; + widget.customProperties.resizeTopBottomLock = true; break; case 'Gauge': @@ -169,6 +176,7 @@ class WidgetFactory { widget.width = 100; widget.height = 100; widget.customProperties.border_color = 0; + widget.customProperties.background_color_opacity = 0.5; widget.z = 0; break; case 'HTML': diff --git a/src/widget/widgets/box.js b/src/widget/widgets/box.js index 758dec3..ff470f3 100644 --- a/src/widget/widgets/box.js +++ b/src/widget/widgets/box.js @@ -27,7 +27,7 @@ class WidgetBox extends Component { let colorStyle = { borderColor: colors[this.props.widget.customProperties.border_color], backgroundColor: colors[this.props.widget.customProperties.background_color], - opacity: this.props.widget.customProperties.background_color_opacity + opacity: this.props.widget.customProperties.background_color_opacity, } return ( diff --git a/src/widget/widgets/gauge.js b/src/widget/widgets/gauge.js index 4079c2d..cd778ad 100644 --- a/src/widget/widgets/gauge.js +++ b/src/widget/widgets/gauge.js @@ -31,17 +31,20 @@ class WidgetGauge extends Component { unit: '', minValue: null, maxValue: null, + useColorZones: false, + useMinMax: false, + useMinMaxChange: false, }; } componentDidMount() { this.gauge = new Gauge(this.gaugeCanvas).setOptions(this.computeGaugeOptions(this.props.widget)); - //this.gauge.maxValue = this.state.maxValue; - //this.gauge.setMinValue(this.state.minValue); + this.gauge.maxValue = this.state.maxValue; + this.gauge.setMinValue(this.state.minValue); this.gauge.animationSpeed = 30; - //this.gauge.set(this.state.value); + this.gauge.set(this.state.value); - //this.updateLabels(this.state.minValue, this.state.maxValue); + this.updateLabels(this.state.minValue, this.state.maxValue); } componentDidUpdate(prevProps: Readonly

, prevState: Readonly, snapshot: SS): void { @@ -57,9 +60,19 @@ class WidgetGauge extends Component { this.gauge.set(this.state.value) } + if(prevState.useMinMax === true && this.state.useMinMax === false){ + this.setState({useMinMaxChange: true}); + } + // update labels - if(prevState.minValue !== this.state.minValue || prevState.maxValue !== this.state.maxValue){ - this.updateLabels(this.state.minValue, this.state.maxValue) + if(prevState.minValue !== this.state.minValue || prevState.maxValue !== this.state.maxValue || prevState.useColorZones !== this.state.useColorZones + || prevState.useMinMax !== this.state.useMinMax){ + this.gauge = new Gauge(this.gaugeCanvas).setOptions(this.computeGaugeOptions(this.props.widget)); + this.gauge.maxValue = this.state.maxValue; + this.gauge.setMinValue(this.state.minValue); + this.gauge.animationSpeed = 30; + this.gauge.set(this.state.value); + this.updateLabels(this.state.minValue, this.state.maxValue) } } @@ -69,9 +82,10 @@ class WidgetGauge extends Component { if(props.widget.signalIDs.length === 0){ return null; } - let returnState = {} + returnState["useColorZones"] = props.widget.customProperties.colorZones; + // Update unit (assuming there is exactly one signal for this widget) let signalID = props.widget.signalIDs[0]; let widgetSignal = props.signals.find(sig => sig.id === signalID); @@ -105,7 +119,8 @@ class WidgetGauge extends Component { const value = Math.round(signalData[signalData.length - 1].y * 1e3) / 1e3; let minValue = null; let maxValue = null; - if (state.value !== value && value != null) { + + if ((state.value !== value && value != null) || props.widget.customProperties.valueUseMinMax || state.useMinMaxChange) { //value has changed updateValue = true; @@ -114,17 +129,18 @@ class WidgetGauge extends Component { minValue = state.minValue; maxValue = state.maxValue; - - if (minValue == null) { + + if (minValue == null || state.useMinMaxChange) { minValue = value - 0.5; updateLabels = true; updateMinValue = true; } - if (maxValue == null) { + if (maxValue == null || state.useMinMaxChange) { maxValue = value + 0.5; updateLabels = true; updateMaxValue = true; + returnState["useMinMaxChange"] = false; } if (props.widget.customProperties.valueUseMinMax) { @@ -141,7 +157,7 @@ class WidgetGauge extends Component { } } - if (updateLabels === false) { + if (updateLabels === false && state.gauge) { // check if min/max changed if (minValue > state.gauge.minValue) { minValue = state.gauge.minValue; @@ -155,6 +171,13 @@ class WidgetGauge extends Component { } } + if(props.widget.customProperties.valueUseMinMax !== state.useMinMax){ + returnState["useMinMax"] = props.widget.customProperties.valueUseMinMax; + } + if(props.widget.customProperties.colorZones !== state.useColorZones){ + returnState["useColorZones"] = props.widget.customProperties.colorZones; + } + // prepare returned state if(updateValue === true){ returnState["value"] = value; diff --git a/src/widget/widgets/input.js b/src/widget/widgets/input.js index 2ad1fea..59e2290 100644 --- a/src/widget/widgets/input.js +++ b/src/widget/widgets/input.js @@ -84,9 +84,13 @@ class WidgetInput extends Component { this.handleKeyPress(e) } onBlur={ (e) => this.valueChanged(this.state.value) } onChange={ (e) => this.valueIsChanging(e.target.value) } placeholder="Enter value" value={ this.state.value } /> + {this.props.widget.customProperties.showUnit? ( {this.state.unit} + ):( +

+ )} diff --git a/src/widget/widgets/table.js b/src/widget/widgets/table.js index 54426bd..a7ef37b 100644 --- a/src/widget/widgets/table.js +++ b/src/widget/widgets/table.js @@ -92,6 +92,14 @@ class WidgetTable extends Component { } render() { + + let rows = this.state.rows; + if(rows.length === 0){ + rows.push({ + name: "no entries" + }) + } + var columns = [ , @@ -102,7 +110,7 @@ class WidgetTable extends Component { return (
- +
{ columns }
diff --git a/src/widget/widgets/value.js b/src/widget/widgets/value.js index 5f826d8..8951d80 100644 --- a/src/widget/widgets/value.js +++ b/src/widget/widgets/value.js @@ -68,14 +68,16 @@ class WidgetValue extends Component { } render() { - var value_to_render = Number(this.state.value); + let value_to_render = Number(this.state.value); + let value_width = this.props.widget.customProperties.textSize*0.55* (this.state.value.length +2); + let unit_width = this.props.widget.customProperties.textSize*2; return (
- {this.props.widget.name} - {Number.isNaN(value_to_render) ? NaN : format('.3s')(value_to_render)} + {this.props.widget.name} + {Number.isNaN(value_to_render) ? NaN : format('.3s')(value_to_render)} {this.props.widget.customProperties.showUnit && - [{this.state.unit}] - } + [{this.state.unit}] + }
); }