Add new React component 'ThingsboardIcon', a form to select an icon from datakey settings
This commit is contained in:
parent
6091f1a8d8
commit
dd03bf30d8
@ -22,13 +22,17 @@ import ReactSchemaForm from './react/json-form-react.jsx';
|
||||
import jsonFormTemplate from './json-form.tpl.html';
|
||||
import { utils } from 'react-schema-form';
|
||||
|
||||
import MaterialIconsDialogController from './material-icons-dialog.controller';
|
||||
import materialIconsDialogTemplate from './material-icons-dialog.tpl.html';
|
||||
|
||||
export default angular.module('thingsboard.directives.jsonForm', [])
|
||||
.directive('tbJsonForm', JsonForm)
|
||||
.controller('MaterialIconsDialogController', MaterialIconsDialogController)
|
||||
.value('ReactSchemaForm', ReactSchemaForm)
|
||||
.name;
|
||||
|
||||
/*@ngInject*/
|
||||
function JsonForm($compile, $templateCache, $mdColorPicker) {
|
||||
function JsonForm($compile, $templateCache, $mdColorPicker, $mdDialog, $document) {
|
||||
|
||||
var linker = function (scope, element) {
|
||||
|
||||
@ -90,6 +94,9 @@ function JsonForm($compile, $templateCache, $mdColorPicker) {
|
||||
onColorClick: function(event, key, val) {
|
||||
scope.showColorPicker(event, val);
|
||||
},
|
||||
onIconClick: function(event) {
|
||||
scope.openIconDialog(event);
|
||||
},
|
||||
onToggleFullscreen: function() {
|
||||
scope.isFullscreen = !scope.isFullscreen;
|
||||
scope.formProps.isFullscreen = scope.isFullscreen;
|
||||
@ -123,6 +130,23 @@ function JsonForm($compile, $templateCache, $mdColorPicker) {
|
||||
});
|
||||
}
|
||||
|
||||
scope.openIconDialog = function(event) {
|
||||
$mdDialog.show({
|
||||
controller: 'MaterialIconsDialogController',
|
||||
controllerAs: 'vm',
|
||||
templateUrl: materialIconsDialogTemplate,
|
||||
parent: angular.element($document[0].body),
|
||||
locals: {icon: scope.icon},
|
||||
multiple: true,
|
||||
fullscreen: true,
|
||||
targetEvent: event
|
||||
}).then(function (icon) {
|
||||
if (event.data && event.data.onValueChanged) {
|
||||
event.data.onValueChanged(icon);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scope.onFullscreenChanged = function() {}
|
||||
|
||||
scope.validate = function(){
|
||||
|
||||
@ -131,7 +131,7 @@ class ThingsboardArray extends React.Component {
|
||||
}
|
||||
let forms = this.props.form.items.map(function(form, index){
|
||||
var copy = this.copyWithIndex(form, i);
|
||||
return this.props.builder(copy, this.props.model, index, this.props.onChange, this.props.onColorClick, this.props.onToggleFullscreen, this.props.mapper, this.props.builder);
|
||||
return this.props.builder(copy, this.props.model, index, this.props.onChange, this.props.onColorClick, this.props.onIconClick, this.props.onToggleFullscreen, this.props.mapper, this.props.builder);
|
||||
}.bind(this));
|
||||
arrays.push(
|
||||
<li key={keys[i]} className="list-group-item">
|
||||
|
||||
@ -19,7 +19,7 @@ class ThingsboardFieldSet extends React.Component {
|
||||
|
||||
render() {
|
||||
let forms = this.props.form.items.map(function(form, index){
|
||||
return this.props.builder(form, this.props.model, index, this.props.onChange, this.props.onColorClick, this.props.onToggleFullscreen, this.props.mapper, this.props.builder);
|
||||
return this.props.builder(form, this.props.model, index, this.props.onChange, this.props.onColorClick, this.props.onIconClick, this.props.onToggleFullscreen, this.props.mapper, this.props.builder);
|
||||
}.bind(this));
|
||||
|
||||
return (
|
||||
|
||||
134
ui/src/app/components/react/json-form-icon.jsx
Normal file
134
ui/src/app/components/react/json-form-icon.jsx
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright © 2016-2019 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ThingsboardBaseComponent from './json-form-base-component.jsx';
|
||||
import reactCSS from 'reactcss';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import IconButton from 'material-ui/IconButton';
|
||||
|
||||
class ThingsboardIcon extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onValueChanged = this.onValueChanged.bind(this);
|
||||
this.onIconClick = this.onIconClick.bind(this);
|
||||
this.onClear = this.onClear.bind(this);
|
||||
var icon = props.value ? props.value : '';
|
||||
this.state = {
|
||||
icon: icon
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
var node = ReactDOM.findDOMNode(this);
|
||||
var iconContainer = $(node).children('#icon-container');
|
||||
iconContainer.click(this, function(event) {
|
||||
event.data.onIconClick(event);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
var node = ReactDOM.findDOMNode(this);
|
||||
var iconContainer = $(node).children('#icon-container');
|
||||
iconContainer.off( "click" );
|
||||
}
|
||||
|
||||
onValueChanged(value) {
|
||||
var icon = value;
|
||||
|
||||
this.setState({
|
||||
icon: value
|
||||
})
|
||||
this.props.onChange(this.props.form.key, value);
|
||||
}
|
||||
|
||||
onIconClick(event) {
|
||||
this.props.onIconClick(event);
|
||||
}
|
||||
|
||||
onClear(event) {
|
||||
if (event) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
this.onValueChanged('');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const styles = reactCSS({
|
||||
'default': {
|
||||
clear: {
|
||||
marginTop: '15px'
|
||||
},
|
||||
container: {
|
||||
display: 'flex'
|
||||
},
|
||||
icon: {
|
||||
display: 'inline-block',
|
||||
marginRight: '10px',
|
||||
marginTop: '16px',
|
||||
marginBottom: 'auto',
|
||||
cursor: 'pointer',
|
||||
border: 'solid 1px rgba(0, 0, 0, .27)'
|
||||
},
|
||||
iconContainer: {
|
||||
display: 'flex',
|
||||
width: '100%'
|
||||
},
|
||||
iconText: {
|
||||
display: 'inline-block',
|
||||
width: '100%'
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var fieldClass = "tb-field";
|
||||
if (this.props.form.required) {
|
||||
fieldClass += " tb-required";
|
||||
}
|
||||
if (this.state.focused) {
|
||||
fieldClass += " tb-focused";
|
||||
}
|
||||
|
||||
var pickedIcon = 'more_horiz';
|
||||
if (this.state.icon != '') {
|
||||
pickedIcon = this.state.icon;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={ styles.container }>
|
||||
<div id="icon-container" style={ styles.iconContainer }>
|
||||
<IconButton iconClassName="material-icons" style={ styles.icon }>
|
||||
{pickedIcon}
|
||||
</IconButton>
|
||||
<TextField
|
||||
className={fieldClass}
|
||||
floatingLabelText={this.props.form.title}
|
||||
hintText={this.props.form.placeholder}
|
||||
errorText={this.props.error}
|
||||
value={this.state.icon}
|
||||
disabled={this.props.form.readonly}
|
||||
style={ styles.iconText } />
|
||||
</div>
|
||||
<IconButton iconClassName="material-icons" tooltip="Clear" onTouchTap={this.onClear}>clear</IconButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ThingsboardBaseComponent(ThingsboardIcon);
|
||||
@ -52,6 +52,7 @@ ReactSchemaForm.propTypes = {
|
||||
option: React.PropTypes.object,
|
||||
onModelChange: React.PropTypes.func,
|
||||
onColorClick: React.PropTypes.func,
|
||||
onIconClick: React.PropTypes.func,
|
||||
onToggleFullscreen: React.PropTypes.func
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ import ThingsboardImage from './json-form-image.jsx';
|
||||
import ThingsboardCheckbox from './json-form-checkbox.jsx';
|
||||
import Help from 'react-schema-form/lib/Help';
|
||||
import ThingsboardFieldSet from './json-form-fieldset.jsx';
|
||||
import ThingsboardIcon from './json-form-icon.jsx';
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
@ -58,11 +59,13 @@ class ThingsboardSchemaForm extends React.Component {
|
||||
'css': ThingsboardCss,
|
||||
'color': ThingsboardColor,
|
||||
'rc-select': ThingsboardRcSelect,
|
||||
'fieldset': ThingsboardFieldSet
|
||||
'fieldset': ThingsboardFieldSet,
|
||||
'icon': ThingsboardIcon
|
||||
};
|
||||
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onColorClick = this.onColorClick.bind(this);
|
||||
this.onIconClick = this.onIconClick.bind(this);
|
||||
this.onToggleFullscreen = this.onToggleFullscreen.bind(this);
|
||||
this.hasConditions = false;
|
||||
}
|
||||
@ -84,7 +87,7 @@ class ThingsboardSchemaForm extends React.Component {
|
||||
}
|
||||
|
||||
|
||||
builder(form, model, index, onChange, onColorClick, onToggleFullscreen, mapper) {
|
||||
builder(form, model, index, onChange, onColorClick, onIconClick, onToggleFullscreen, mapper) {
|
||||
var type = form.type;
|
||||
let Field = this.mapper[type];
|
||||
if(!Field) {
|
||||
@ -97,7 +100,7 @@ class ThingsboardSchemaForm extends React.Component {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return <Field model={model} form={form} key={index} onChange={onChange} onColorClick={onColorClick} onToggleFullscreen={onToggleFullscreen} mapper={mapper} builder={this.builder}/>
|
||||
return <Field model={model} form={form} key={index} onChange={onChange} onColorClick={onColorClick} onIconClick={onIconClick} onToggleFullscreen={onToggleFullscreen} mapper={mapper} builder={this.builder}/>
|
||||
}
|
||||
|
||||
createSchema(theForm) {
|
||||
@ -107,7 +110,7 @@ class ThingsboardSchemaForm extends React.Component {
|
||||
mapper = _.merge(this.mapper, this.props.mapper);
|
||||
}
|
||||
let forms = merged.map(function(form, index) {
|
||||
return this.builder(form, this.props.model, index, this.onChange, this.onColorClick, this.onToggleFullscreen, mapper);
|
||||
return this.builder(form, this.props.model, index, this.onChange, this.onColorClick, this.onIconClick, this.onToggleFullscreen, mapper);
|
||||
}.bind(this));
|
||||
|
||||
let formClass = 'SchemaForm';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user