Commit 4dde2eec1a1c53b9291bd832a48b04c40d5c117f

Authored by HollyFang
1 parent ab494596

add SceemaGroup so that it can display better when there are many configuration item

@@ -145,11 +145,13 @@ function JsonForm($compile, $templateCache, $mdColorPicker) { @@ -145,11 +145,13 @@ function JsonForm($compile, $templateCache, $mdColorPicker) {
145 }; 145 };
146 schema.strict = true; 146 schema.strict = true;
147 var form = scope.form ? angular.copy(scope.form) : [ "*" ]; 147 var form = scope.form ? angular.copy(scope.form) : [ "*" ];
  148 + var groupInfoes = scope.groupInfoes ? angular.copy(scope.groupInfoes) : [];
148 var model = scope.model || {}; 149 var model = scope.model || {};
149 scope.model = inspector.sanitize(schema, model).data; 150 scope.model = inspector.sanitize(schema, model).data;
150 scope.formProps.option.formDefaults.readonly = readonly; 151 scope.formProps.option.formDefaults.readonly = readonly;
151 scope.formProps.schema = schema; 152 scope.formProps.schema = schema;
152 scope.formProps.form = form; 153 scope.formProps.form = form;
  154 + scope.formProps.groupInfoes = groupInfoes;
153 scope.formProps.model = angular.copy(scope.model); 155 scope.formProps.model = angular.copy(scope.model);
154 if (!skipRerender) { 156 if (!skipRerender) {
155 recompile(); 157 recompile();
@@ -176,6 +178,12 @@ function JsonForm($compile, $templateCache, $mdColorPicker) { @@ -176,6 +178,12 @@ function JsonForm($compile, $templateCache, $mdColorPicker) {
176 } 178 }
177 }); 179 });
178 180
  181 + scope.$watch('groupInfoes',function(newValue, prevValue) {
  182 + if (newValue && newValue != prevValue) {
  183 + scope.updateValues();
  184 + }
  185 + });
  186 +
179 scope.validate(); 187 scope.validate();
180 188
181 recompile(); 189 recompile();
@@ -189,6 +197,7 @@ function JsonForm($compile, $templateCache, $mdColorPicker) { @@ -189,6 +197,7 @@ function JsonForm($compile, $templateCache, $mdColorPicker) {
189 form: '=', 197 form: '=',
190 model: '=', 198 model: '=',
191 formControl: '=', 199 formControl: '=',
  200 + groupInfoes: '=',
192 readonly: '=' 201 readonly: '='
193 }, 202 },
194 link: linker 203 link: linker
@@ -47,6 +47,7 @@ class ReactSchemaForm extends React.Component { @@ -47,6 +47,7 @@ class ReactSchemaForm extends React.Component {
47 ReactSchemaForm.propTypes = { 47 ReactSchemaForm.propTypes = {
48 schema: React.PropTypes.object, 48 schema: React.PropTypes.object,
49 form: React.PropTypes.array, 49 form: React.PropTypes.array,
  50 + groupInfoes: React.PropTypes.array,
50 model: React.PropTypes.object, 51 model: React.PropTypes.object,
51 option: React.PropTypes.object, 52 option: React.PropTypes.object,
52 onModelChange: React.PropTypes.func, 53 onModelChange: React.PropTypes.func,
@@ -56,7 +57,8 @@ ReactSchemaForm.propTypes = { @@ -56,7 +57,8 @@ ReactSchemaForm.propTypes = {
56 57
57 ReactSchemaForm.defaultProps = { 58 ReactSchemaForm.defaultProps = {
58 schema: {}, 59 schema: {},
59 - form: [ "*" ] 60 + form: [ "*" ],
  61 + groupInfoes:[]
60 } 62 }
61 63
62 ReactSchemaForm.childContextTypes = { 64 ReactSchemaForm.childContextTypes = {
@@ -83,6 +83,7 @@ class ThingsboardSchemaForm extends React.Component { @@ -83,6 +83,7 @@ class ThingsboardSchemaForm extends React.Component {
83 this.props.onToggleFullscreen(); 83 this.props.onToggleFullscreen();
84 } 84 }
85 85
  86 +
86 builder(form, model, index, onChange, onColorClick, onToggleFullscreen, mapper) { 87 builder(form, model, index, onChange, onColorClick, onToggleFullscreen, mapper) {
87 var type = form.type; 88 var type = form.type;
88 let Field = this.mapper[type]; 89 let Field = this.mapper[type];
@@ -99,8 +100,8 @@ class ThingsboardSchemaForm extends React.Component { @@ -99,8 +100,8 @@ class ThingsboardSchemaForm extends React.Component {
99 return <Field model={model} form={form} key={index} onChange={onChange} onColorClick={onColorClick} onToggleFullscreen={onToggleFullscreen} mapper={mapper} builder={this.builder}/> 100 return <Field model={model} form={form} key={index} onChange={onChange} onColorClick={onColorClick} onToggleFullscreen={onToggleFullscreen} mapper={mapper} builder={this.builder}/>
100 } 101 }
101 102
102 - render() {  
103 - let merged = utils.merge(this.props.schema, this.props.form, this.props.ignore, this.props.option); 103 + createSchema(theForm) {
  104 + let merged = utils.merge(this.props.schema, theForm, this.props.ignore, this.props.option);
104 let mapper = this.mapper; 105 let mapper = this.mapper;
105 if(this.props.mapper) { 106 if(this.props.mapper) {
106 mapper = _.merge(this.mapper, this.props.mapper); 107 mapper = _.merge(this.mapper, this.props.mapper);
@@ -118,5 +119,43 @@ class ThingsboardSchemaForm extends React.Component { @@ -118,5 +119,43 @@ class ThingsboardSchemaForm extends React.Component {
118 <div style={{width: '100%'}} className={formClass}>{forms}</div> 119 <div style={{width: '100%'}} className={formClass}>{forms}</div>
119 ); 120 );
120 } 121 }
  122 +
  123 + render() {
  124 + if(this.props.groupInfoes&&this.props.groupInfoes.length>0){
  125 + let content=[];
  126 + for(let info of this.props.groupInfoes){
  127 + let forms = this.createSchema(this.props.form[info.formIndex]);
  128 + let item = <ThingsboardSchemaGroup key={content.length} forms={forms} info={info}></ThingsboardSchemaGroup>;
  129 + content.push(item);
  130 + }
  131 + return (<div>{content}</div>);
  132 + }
  133 + else
  134 + return this.createSchema(this.props.form);
  135 + }
121 } 136 }
122 export default ThingsboardSchemaForm; 137 export default ThingsboardSchemaForm;
  138 +
  139 +
  140 +class ThingsboardSchemaGroup extends React.Component{
  141 + constructor(props) {
  142 + super(props);
  143 + this.state={
  144 + showGroup:true
  145 + }
  146 + }
  147 +
  148 + toogleGroup(index) {
  149 + this.setState({
  150 + showGroup:!this.state.showGroup
  151 + });
  152 + }
  153 +
  154 + render() {
  155 + let theCla = "pull-right fa fa-chevron-down md-toggle-icon"+(this.state.showGroup?"":" tb-toggled")
  156 + return (<section className="md-whiteframe-z1" style={{marginTop: '10px'}}>
  157 + <div className='SchemaGroupname md-button-toggle' onClick={this.toogleGroup.bind(this)}>{this.props.info.GroupTitle}<span className={theCla}></span></div>
  158 + <div style={{padding: '20px'}} className={this.state.showGroup?"":"invisible"}>{this.props.forms}</div>
  159 + </section>);
  160 + }
  161 +}
@@ -121,3 +121,12 @@ label.tb-label { @@ -121,3 +121,12 @@ label.tb-label {
121 .tb-head-label { 121 .tb-head-label {
122 color: rgba(0, 0, 0, .54); 122 color: rgba(0, 0, 0, .54);
123 } 123 }
  124 +
  125 +.SchemaGroupname{
  126 + padding: 10px 20px;
  127 + background-color: #f1f1f1;
  128 +}
  129 +
  130 +.invisible{
  131 + display: none;
  132 +}
@@ -63,6 +63,8 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout @@ -63,6 +63,8 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
63 type: "object", 63 type: "object",
64 properties: {} 64 properties: {}
65 }; 65 };
  66 +
  67 + scope.emptySettingsGroupInfoes=[];
66 scope.defaultSettingsForm = [ 68 scope.defaultSettingsForm = [
67 '*' 69 '*'
68 ]; 70 ];
@@ -90,6 +92,7 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout @@ -90,6 +92,7 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
90 92
91 scope.currentSettingsSchema = {}; 93 scope.currentSettingsSchema = {};
92 scope.currentSettings = angular.copy(scope.emptySettingsSchema); 94 scope.currentSettings = angular.copy(scope.emptySettingsSchema);
  95 + scope.currentSettingsGroupInfoes = angular.copy(scope.emptySettingsGroupInfoes);
93 96
94 scope.targetDeviceAlias = { 97 scope.targetDeviceAlias = {
95 value: null 98 value: null
@@ -189,10 +192,12 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout @@ -189,10 +192,12 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
189 if (scope.widgetSettingsSchema && scope.widgetSettingsSchema.schema) { 192 if (scope.widgetSettingsSchema && scope.widgetSettingsSchema.schema) {
190 scope.currentSettingsSchema = scope.widgetSettingsSchema.schema; 193 scope.currentSettingsSchema = scope.widgetSettingsSchema.schema;
191 scope.currentSettingsForm = scope.widgetSettingsSchema.form || angular.copy(scope.defaultSettingsForm); 194 scope.currentSettingsForm = scope.widgetSettingsSchema.form || angular.copy(scope.defaultSettingsForm);
  195 + scope.currentSettingsGroupInfoes = scope.widgetSettingsSchema.groupInfoes;
192 scope.currentSettings = scope.settings; 196 scope.currentSettings = scope.settings;
193 } else { 197 } else {
194 scope.currentSettingsForm = angular.copy(scope.defaultSettingsForm); 198 scope.currentSettingsForm = angular.copy(scope.defaultSettingsForm);
195 scope.currentSettingsSchema = angular.copy(scope.emptySettingsSchema); 199 scope.currentSettingsSchema = angular.copy(scope.emptySettingsSchema);
  200 + scope.currentSettingsGroupInfoes = angular.copy(scope.emptySettingsGroupInfoes);
196 scope.currentSettings = {}; 201 scope.currentSettings = {};
197 } 202 }
198 } 203 }
@@ -281,6 +281,7 @@ @@ -281,6 +281,7 @@
281 <tb-json-form flex schema="currentSettingsSchema" 281 <tb-json-form flex schema="currentSettingsSchema"
282 form="currentSettingsForm" 282 form="currentSettingsForm"
283 model="currentSettings" 283 model="currentSettings"
  284 + group-infoes="currentSettingsGroupInfoes"
284 form-control="ngform"> 285 form-control="ngform">
285 </tb-json-form> 286 </tb-json-form>
286 </ng-form> 287 </ng-form>
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 * 7 *
8 - * http://www.apache.org/licenses/LICENSE-2.0 8 + * http://www.apache.org/licenses/LICENSE-2.0
9 * 9 *
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, 11 * distributed under the License is distributed on an "AS IS" BASIS,
@@ -83,10 +83,10 @@ export default class TbMapWidgetV2 { @@ -83,10 +83,10 @@ export default class TbMapWidgetV2 {
83 this.map = new TbGoogleMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, settings.disableScrollZooming, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType); 83 this.map = new TbGoogleMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, settings.disableScrollZooming, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType);
84 } else if (mapProvider === 'openstreet-map') { 84 } else if (mapProvider === 'openstreet-map') {
85 if (settings.useCustomProvider && settings.customProviderTileUrl) { 85 if (settings.useCustomProvider && settings.customProviderTileUrl) {
86 - openStreetMapProvider.name = settings.customProviderTileUrl;  
87 - openStreetMapProvider.isCustom = true; 86 + openStreetMapProvider.name = settings.customProviderTileUrl;
  87 + openStreetMapProvider.isCustom = true;
88 } else { 88 } else {
89 - openStreetMapProvider.name = settings.mapProvider; 89 + openStreetMapProvider.name = settings.mapProvider;
90 } 90 }
91 this.map = new TbOpenStreetMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, settings.disableScrollZooming, minZoomLevel, openStreetMapProvider); 91 this.map = new TbOpenStreetMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, settings.disableScrollZooming, minZoomLevel, openStreetMapProvider);
92 } else if (mapProvider === 'here') { 92 } else if (mapProvider === 'here') {
@@ -669,22 +669,49 @@ export default class TbMapWidgetV2 { @@ -669,22 +669,49 @@ export default class TbMapWidgetV2 {
669 var schema; 669 var schema;
670 if (mapProvider === 'google-map') { 670 if (mapProvider === 'google-map') {
671 schema = angular.copy(googleMapSettingsSchema); 671 schema = angular.copy(googleMapSettingsSchema);
  672 + schema.groupInfoes=[{
  673 + "formIndex":0,
  674 + "GroupTitle":"Google Map Settings"
  675 + }];
672 } else if (mapProvider === 'openstreet-map') { 676 } else if (mapProvider === 'openstreet-map') {
673 schema = angular.copy(openstreetMapSettingsSchema); 677 schema = angular.copy(openstreetMapSettingsSchema);
  678 + schema.groupInfoes=[{
  679 + "formIndex":0,
  680 + "GroupTitle":"Openstreet Map Settings"
  681 + }];
674 } else if (mapProvider === 'image-map') { 682 } else if (mapProvider === 'image-map') {
675 return imageMapSettingsSchema; 683 return imageMapSettingsSchema;
676 } else if (mapProvider === 'tencent-map') { 684 } else if (mapProvider === 'tencent-map') {
677 schema = angular.copy(tencentMapSettingsSchema); 685 schema = angular.copy(tencentMapSettingsSchema);
  686 + schema.groupInfoes=[{
  687 + "formIndex":0,
  688 + "GroupTitle":"Tencent Map Settings"
  689 + }];
678 } else if (mapProvider === 'here') { 690 } else if (mapProvider === 'here') {
679 schema = angular.copy(hereMapSettingsSchema); 691 schema = angular.copy(hereMapSettingsSchema);
  692 + schema.groupInfoes=[{
  693 + "formIndex":0,
  694 + "GroupTitle":"Here Map Settings"
  695 + }];
680 } 696 }
  697 + if(!schema.groupInfoes)schema.groupInfoes=[];
  698 + schema.form = [schema.form];
  699 +
681 angular.merge(schema.schema.properties, commonMapSettingsSchema.schema.properties); 700 angular.merge(schema.schema.properties, commonMapSettingsSchema.schema.properties);
682 schema.schema.required = schema.schema.required.concat(commonMapSettingsSchema.schema.required); 701 schema.schema.required = schema.schema.required.concat(commonMapSettingsSchema.schema.required);
683 - schema.form = schema.form.concat(commonMapSettingsSchema.form); 702 + schema.form.push(commonMapSettingsSchema.form);//schema.form.concat(commonMapSettingsSchema.form);
  703 + schema.groupInfoes.push({
  704 + "formIndex":schema.groupInfoes.length,
  705 + "GroupTitle":"Common Map Settings"
  706 + });
684 if (drawRoutes) { 707 if (drawRoutes) {
685 angular.merge(schema.schema.properties, routeMapSettingsSchema.schema.properties); 708 angular.merge(schema.schema.properties, routeMapSettingsSchema.schema.properties);
686 schema.schema.required = schema.schema.required.concat(routeMapSettingsSchema.schema.required); 709 schema.schema.required = schema.schema.required.concat(routeMapSettingsSchema.schema.required);
687 - schema.form = schema.form.concat(routeMapSettingsSchema.form); 710 + schema.form.push(routeMapSettingsSchema.form);//schema.form = schema.form.concat(routeMapSettingsSchema.form);
  711 + schema.groupInfoes.push({
  712 + "formIndex":schema.groupInfoes.length,
  713 + "GroupTitle":"Route Map Settings"
  714 + });
688 } 715 }
689 return schema; 716 return schema;
690 } 717 }
@@ -871,16 +898,16 @@ const openstreetMapSettingsSchema = @@ -871,16 +898,16 @@ const openstreetMapSettingsSchema =
871 "type": "string", 898 "type": "string",
872 "default": "OpenStreetMap.Mapnik" 899 "default": "OpenStreetMap.Mapnik"
873 }, 900 },
874 - "useCustomProvider": {  
875 - "title": "Use custom provider",  
876 - "type": "boolean",  
877 - "default": false  
878 - },  
879 - "customProviderTileUrl": {  
880 - "title": "Custom provider tile URL",  
881 - "type": "string",  
882 - "default": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"  
883 - } 901 + "useCustomProvider": {
  902 + "title": "Use custom provider",
  903 + "type": "boolean",
  904 + "default": false
  905 + },
  906 + "customProviderTileUrl": {
  907 + "title": "Custom provider tile URL",
  908 + "type": "string",
  909 + "default": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
  910 + }
884 }, 911 },
885 "required": [] 912 "required": []
886 }, 913 },
@@ -920,8 +947,8 @@ const openstreetMapSettingsSchema = @@ -920,8 +947,8 @@ const openstreetMapSettingsSchema =
920 } 947 }
921 ] 948 ]
922 }, 949 },
923 - "useCustomProvider",  
924 - "customProviderTileUrl" 950 + "useCustomProvider",
  951 + "customProviderTileUrl"
925 ] 952 ]
926 }; 953 };
927 954