Commit 4dde2eec1a1c53b9291bd832a48b04c40d5c117f
1 parent
ab494596
add SceemaGroup so that it can display better when there are many configuration item
Showing
7 changed files
with
113 additions
and
21 deletions
@@ -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 |