diff --git a/ui-ngx/package.json b/ui-ngx/package.json index a438fd1520..c6c905fe5a 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -12,31 +12,34 @@ }, "private": true, "dependencies": { - "@angular/animations": "^18.2.6", - "@angular/cdk": "^18.2.6", - "@angular/common": "^18.2.6", - "@angular/compiler": "^18.2.6", - "@angular/core": "^18.2.6", + "@angular/animations": "18.2.6", + "@angular/cdk": "18.2.6", + "@angular/common": "18.2.6", + "@angular/compiler": "18.2.6", + "@angular/core": "18.2.6", "@angular/flex-layout": "^15.0.0-beta.42", - "@angular/forms": "^18.2.6", - "@angular/material": "^18.2.6", - "@angular/platform-browser": "^18.2.6", - "@angular/platform-browser-dynamic": "^18.2.6", - "@angular/router": "^18.2.6", + "@angular/forms": "18.2.6", + "@angular/material": "18.2.6", + "@angular/platform-browser": "18.2.6", + "@angular/platform-browser-dynamic": "18.2.6", + "@angular/router": "18.2.6", "@auth0/angular-jwt": "^5.2.0", - "@date-io/core": "1.3.7", - "@date-io/date-fns": "1.3.7", + "@emotion/react": "11.13.3", + "@emotion/styled": "11.13.0", "@flowjs/flow.js": "^2.14.1", "@flowjs/ngx-flow": "~0.8.1", "@fortawesome/fontawesome-svg-core": "^6.6.0", "@geoman-io/leaflet-geoman-free": "2.14.2", "@iplab/ngx-color-picker": "^18.0.1", "@mat-datetimepicker/core": "~14.0.0", - "@material-ui/core": "4.12.3", - "@material-ui/icons": "4.11.2", - "@material-ui/pickers": "3.3.10", "@mdi/svg": "^7.4.47", "@messageformat/core": "^3.3.0", + "@mui/icons-material": "6.1.1", + "@mui/lab": "6.0.0-beta.10", + "@mui/material": "6.1.1", + "@mui/styles": "6.1.1", + "@mui/system": "6.1.1", + "@mui/x-date-pickers": "7.18.0", "@ngrx/effects": "^18.0.2", "@ngrx/store": "^18.0.2", "@ngrx/store-devtools": "^18.0.2", @@ -45,14 +48,13 @@ "@svgdotjs/svg.js": "^3.2.4", "@svgdotjs/svg.panzoom.js": "^2.1.2", "@tinymce/tinymce-angular": "^8.0.1", - "ace-builds": "1.4.13", + "ace-builds": "1.36.2", "ace-diff": "^3.0.3", "angular-gridster2": "~18.0.1", "angular2-hotkeys": "^16.0.1", "canvas-gauges": "^2.1.7", "core-js": "^3.38.1", - "date-fns": "2.0.0-alpha.27", - "dayjs": "1.11.4", + "dayjs": "1.11.13", "echarts": "https://github.com/thingsboard/echarts/archive/5.5.0-TB.tar.gz", "flot": "https://github.com/thingsboard/flot.git#0.9-work", "flot.curvedlines": "https://github.com/MichaelZinsmaier/CurvedLines.git#master", @@ -87,11 +89,11 @@ "prop-types": "^15.8.1", "qrcode": "^1.5.4", "raphael": "^2.3.0", - "rc-select": "13.2.1", - "react": "17.0.2", - "react-ace": "9.5.0", - "react-dom": "17.0.2", - "react-dropzone": "^11.4.2", + "rc-select": "14.15.2", + "react": "18.3.1", + "react-ace": "12.0.0", + "react-dom": "18.3.1", + "react-dropzone": "14.2.3", "reactcss": "^1.2.3", "rxjs": "~7.8.1", "schema-inspector": "^2.1.0", @@ -110,18 +112,18 @@ }, "devDependencies": { "@angular-builders/custom-webpack": "~18.0.0", - "@angular-devkit/build-angular": "^18.2.6", - "@angular-devkit/core": "^18.2.6", - "@angular-devkit/schematics": "^18.2.6", + "@angular-devkit/build-angular": "18.2.7", + "@angular-devkit/core": "18.2.7", + "@angular-devkit/schematics": "18.2.7", "@angular-eslint/builder": "18.3.1", "@angular-eslint/eslint-plugin": "18.3.1", "@angular-eslint/eslint-plugin-template": "18.3.1", "@angular-eslint/schematics": "18.3.1", "@angular-eslint/template-parser": "18.3.1", - "@angular/cli": "^18.2.6", - "@angular/compiler-cli": "^18.2.6", - "@angular/language-service": "^18.2.6", - "@ngtools/webpack": "18.2.6", + "@angular/cli": "18.2.7", + "@angular/compiler-cli": "18.2.6", + "@angular/language-service": "18.2.6", + "@ngtools/webpack": "18.2.7", "@types/ace-diff": "^2.1.1", "@types/canvas-gauges": "^2.1.4", "@types/flot": "^0.0.32", @@ -138,8 +140,8 @@ "@types/lodash": "^4.17.9", "@types/node": "~18.15.11", "@types/raphael": "^2.3.2", - "@types/react": "17.0.37", - "@types/react-dom": "17.0.11", + "@types/react": "18.3.10", + "@types/react-dom": "18.3.0", "@types/systemjs": "6.13.1", "@types/tinycolor2": "^1.4.6", "@types/tooltipster": "^0.0.35", @@ -161,10 +163,9 @@ "webpack": "5.95.0" }, "resolutions": { - "@types/react": "17.0.37", - "@date-io/core": "1.3.7", - "rc-virtual-list": "3.4.13", - "ace-builds": "1.4.13", + "@types/react": "18.3.10", + "rc-virtual-list": "3.5.2", + "ace-builds": "1.36.2", "tinymce": "6.8.4" } } diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index bca6a05644..82ac4e299c 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -42,7 +42,6 @@ import { RafService } from '@core/services/raf.service'; import { EntityAliases } from '@shared/models/alias.models'; import { EntityInfo } from '@app/shared/models/entity.models'; import { IDashboardComponent } from '@home/models/dashboard-component.models'; -import moment_ from 'moment'; import { AlarmData, AlarmDataPageLink, diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol.component.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol.component.ts index 755bc99bbc..d72d95f367 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol.component.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/scada-symbol.component.ts @@ -78,7 +78,6 @@ import { SaveWidgetTypeAsDialogResult } from '@home/pages/widget/save-widget-type-as-dialog.component'; import { WidgetService } from '@core/http/widget.service'; -import { de } from 'date-fns/locale'; @Component({ selector: 'tb-scada-symbol', diff --git a/ui-ngx/src/app/shared/components/json-form/json-form.component.ts b/ui-ngx/src/app/shared/components/json-form/json-form.component.ts index 8311616b26..691b1eca1b 100644 --- a/ui-ngx/src/app/shared/components/json-form/json-form.component.ts +++ b/ui-ngx/src/app/shared/components/json-form/json-form.component.ts @@ -18,11 +18,11 @@ import { ChangeDetectorRef, Component, ElementRef, - forwardRef, Injector, + forwardRef, Input, OnChanges, OnDestroy, - OnInit, Renderer2, + Renderer2, SimpleChanges, ViewChild, ViewContainerRef, ViewEncapsulation @@ -32,20 +32,15 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { deepClone, isString } from '@app/core/utils'; -import { TranslateService } from '@ngx-translate/core'; import { JsonFormProps } from './react/json-form.models'; import inspector from 'schema-inspector'; import tinycolor from 'tinycolor2'; import { DialogService } from '@app/core/services/dialog.service'; -// import * as React from 'react'; -// import * as ReactDOM from 'react-dom'; -// import ReactSchemaForm from './react/json-form-react'; import JsonFormUtils from './react/json-form-utils'; import { JsonFormComponentData } from './json-form-component.models'; import { GroupInfo } from '@shared/models/widget.models'; import { Observable } from 'rxjs/internal/Observable'; import { forkJoin, from } from 'rxjs'; -import { MouseEvent } from 'react'; import { TbPopoverService } from '@shared/components/popover.service'; @Component({ @@ -66,7 +61,7 @@ import { TbPopoverService } from '@shared/components/popover.service'; ], encapsulation: ViewEncapsulation.None }) -export class JsonFormComponent implements OnInit, ControlValueAccessor, Validator, OnChanges, OnDestroy { +export class JsonFormComponent implements ControlValueAccessor, Validator, OnChanges, OnDestroy { @ViewChild('reactRoot', {static: true}) reactRootElmRef: ElementRef; @@ -109,13 +104,14 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato isFullscreen = false; fullscreenFinishFn: (el: Element) => void; + private reactRoot: any; + private propagateChange = null; private propagateChangePending = false; private writingValue = false; private updateViewPending = false; constructor(public elementRef: ElementRef, - private translate: TranslateService, private dialogs: DialogService, private popoverService: TbPopoverService, private renderer: Renderer2, @@ -124,9 +120,6 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato private cd: ChangeDetectorRef) { } - ngOnInit(): void { - } - ngOnDestroy(): void { this.destroyReactSchemaForm(); } @@ -269,33 +262,25 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato } // import ReactSchemaForm from './react/json-form-react'; - const reactSchemaFormObservables: Observable[] = []; - reactSchemaFormObservables.push(from(import('react'))); - reactSchemaFormObservables.push(from(import('react-dom'))); - reactSchemaFormObservables.push(from(import('./react/json-form-react'))); + const reactSchemaFormObservables: Observable[] = [ + from(import('react')), + from(import('react-dom')), + from(import('react-dom/client')), + from(import('./react/json-form-react')) + ]; forkJoin(reactSchemaFormObservables).subscribe( (modules) => { - const react = modules[0]; - const reactDom = modules[1]; - const jsonFormReact = modules[2].default; - reactDom.render(react.createElement(jsonFormReact, this.formProps), this.reactRootElmRef.nativeElement); + const react = modules[0]; + const reactDomClient = modules[2]; + const jsonFormReact = modules[3].default; + this.reactRoot = reactDomClient.createRoot(this.reactRootElmRef.nativeElement); + this.reactRoot.render(react.createElement(jsonFormReact, this.formProps)); } ); - /* import('./react/json-form-react').then( - (mod) => { - ReactDOM.render(React.createElement(mod.default, this.formProps), this.reactRootElmRef.nativeElement); - } - );*/ - // ReactDOM.render(React.createElement(ReactSchemaForm, this.formProps), this.reactRootElmRef.nativeElement); } private destroyReactSchemaForm() { - import('react-dom').then( - (reactDom) => { - reactDom.unmountComponentAtNode(this.reactRootElmRef.nativeElement); - } - ); - // ReactDOM.unmountComponentAtNode(this.reactRootElmRef.nativeElement); + this.reactRoot?.unmount(); } private validateModel(): boolean { diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-ace-editor.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-ace-editor.tsx index 8d5a0d1038..07683fad82 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-ace-editor.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-ace-editor.tsx @@ -17,16 +17,16 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import ThingsboardBaseComponent from './json-form-base-component'; import reactCSS from 'reactcss'; -import Button from '@material-ui/core/Button'; +import Button from '@mui/material/Button'; import { JsonFormFieldProps, JsonFormFieldState } from '@shared/components/json-form/react/json-form.models'; import { IEditorProps } from 'react-ace/src/types'; import { mergeMap } from 'rxjs/operators'; import { getAce } from '@shared/models/ace/ace.models'; import { from } from 'rxjs'; import { Observable } from 'rxjs/internal/Observable'; -import { CircularProgress, IconButton } from '@material-ui/core'; +import { CircularProgress, IconButton } from '@mui/material'; import { MouseEvent } from 'react'; -import { Help, HelpOutline } from '@material-ui/icons'; +import { Help, HelpOutline } from '@mui/icons-material'; const ReactAce = React.lazy(() => { return getAce().pipe( diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-array.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-array.tsx index 2cd9f08034..17dca8a909 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-array.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-array.tsx @@ -16,12 +16,12 @@ import * as React from 'react'; import JsonFormUtils from './json-form-utils'; import ThingsboardBaseComponent from './json-form-base-component'; -import Button from '@material-ui/core/Button'; +import Button from '@mui/material/Button'; import _ from 'lodash'; -import IconButton from '@material-ui/core/IconButton'; -import Clear from '@material-ui/icons/Clear'; -import Add from '@material-ui/icons/Add'; -import Tooltip from '@material-ui/core/Tooltip'; +import IconButton from '@mui/material/IconButton'; +import Clear from '@mui/icons-material/Clear'; +import Add from '@mui/icons-material/Add'; +import Tooltip from '@mui/material/Tooltip'; import { JsonFormData, JsonFormFieldProps, diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-base-component.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-base-component.tsx index 1288861217..b65a6799bc 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-base-component.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-base-component.tsx @@ -42,8 +42,10 @@ export default ThingsboardBaseComponent => class

onChangeValidate(e, forceUpdate?: boolean) { let value = null; if (this.props.form.schema.type === 'integer' || this.props.form.schema.type === 'number') { - if (e.target.value === null || e.target.value === '') { + if (!e || e.target?.value === null || e.target?.value === '') { value = undefined; + } else if (typeof e === 'number') { + value = Number(e); } else if (e.target.value.indexOf('.') === -1) { value = parseInt(e.target.value, 10); } else { diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx index a74a7b8f9c..bd592eabd7 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx @@ -15,9 +15,9 @@ */ import * as React from 'react'; import ThingsboardBaseComponent from './json-form-base-component'; -import Checkbox from '@material-ui/core/Checkbox'; +import Checkbox from '@mui/material/Checkbox'; import { JsonFormFieldProps, JsonFormFieldState } from './json-form.models.js'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControlLabel from '@mui/material/FormControlLabel'; class ThingsboardCheckbox extends React.Component { render() { @@ -26,6 +26,7 @@ class ThingsboardCheckbox extends React.Component { + containerRef = React.createRef(); + constructor(props) { super(props); this.onBlur = this.onBlur.bind(this); @@ -55,17 +56,17 @@ class ThingsboardColor extends React.Component { + colContainer.click(() => { if (!this.props.form.readonly) { - this.onSwatchClick(event); + this.onSwatchClick(); } }); } componentWillUnmount() { - const node = ReactDOM.findDOMNode(this); + const node = this.containerRef.current; const colContainer = $(node).children('#color-container'); colContainer.off( 'click' ); } @@ -91,7 +92,7 @@ class ThingsboardColor extends React.Component { this.onValueChanged(color); @@ -99,7 +100,7 @@ class ThingsboardColor extends React.Component +

+
- + sx={this.props.form.style || {width: '100%'}} + />
- +
); } } diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-icon.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-icon.tsx index f898aa8714..da3e19550a 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-icon.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-icon.tsx @@ -17,12 +17,12 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import ThingsboardBaseComponent from './json-form-base-component'; import reactCSS from 'reactcss'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; +import TextField from '@mui/material/TextField'; +import IconButton from '@mui/material/IconButton'; import { JsonFormFieldProps, JsonFormFieldState } from '@shared/components/json-form/react/json-form.models'; -import Clear from '@material-ui/icons/Clear'; -import Icon from '@material-ui/core/Icon'; -import Tooltip from '@material-ui/core/Tooltip'; +import Clear from '@mui/icons-material/Clear'; +import Icon from '@mui/material/Icon'; +import Tooltip from '@mui/material/Tooltip'; interface ThingsboardIconState extends JsonFormFieldState { icon: string | null; diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-image.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-image.tsx index d13d86e451..42eb5a41a9 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-image.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-image.tsx @@ -17,9 +17,9 @@ import React from 'react'; import Dropzone from 'react-dropzone'; import ThingsboardBaseComponent from './json-form-base-component'; import { JsonFormFieldProps, JsonFormFieldState } from '@shared/components/json-form/react/json-form.models'; -import IconButton from '@material-ui/core/IconButton'; -import Clear from '@material-ui/icons/Clear'; -import Tooltip from '@material-ui/core/Tooltip'; +import IconButton from '@mui/material/IconButton'; +import Clear from '@mui/icons-material/Clear'; +import Tooltip from '@mui/material/Tooltip'; interface ThingsboardImageState extends JsonFormFieldState { imageUrl: string; @@ -91,7 +91,7 @@ class ThingsboardImage extends React.Component
+ accept={ {'image/*': []} } multiple={false}> {({getRootProps, getInputProps}) => (
Drop an image or click to select a file to upload.
diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-number.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-number.tsx index e440f4b824..90805374a2 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-number.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-number.tsx @@ -16,7 +16,7 @@ import * as React from 'react'; import ThingsboardBaseComponent from './json-form-base-component'; import { JsonFormFieldProps, JsonFormFieldState } from '@shared/components/json-form/react/json-form.models'; -import { TextField } from '@material-ui/core'; +import { TextField } from '@mui/material'; interface ThingsboardNumberState extends JsonFormFieldState { focused: boolean; @@ -78,6 +78,7 @@ class ThingsboardNumber extends React.Component { diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-rc-select.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-rc-select.tsx index 4af321087d..f130c2695a 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-rc-select.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-rc-select.tsx @@ -134,10 +134,10 @@ class ThingsboardRcSelect extends React.Component 0) { - options = this.state.items.map((item, idx) => ( - + options = this.state.items.map((item) => ( + )); } diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-react.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-react.tsx index 57fb235212..a56054a614 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-react.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-react.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import * as React from 'react'; -import { createTheme, ThemeProvider } from '@material-ui/core/styles'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; import thingsboardTheme from './styles/thingsboardTheme'; import ThingsboardSchemaForm from './json-form-schema-form'; import { JsonFormProps } from './json-form.models'; diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx index 1e641493b0..d7b9ffa9c5 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx @@ -46,7 +46,7 @@ import _ from 'lodash'; import tinycolor from 'tinycolor2'; import { GroupInfo } from '@shared/models/widget.models'; import ThingsboardMarkdown from '@shared/components/json-form/react/json-form-markdown'; -import { MouseEvent } from 'react'; +import { MouseEvent, ReactNode } from 'react'; class ThingsboardSchemaForm extends React.Component { @@ -149,7 +149,7 @@ class ThingsboardSchemaForm extends React.Component { if (this.props.mapper) { mapper = _.merge(this.mapper, this.props.mapper); } - const forms = merged.map(function(form, index) { + const forms: ReactNode[] = merged.map(function(form, index) { return this.builder(form, this.props.model, index, this.onChange, this.onColorClick, this.onIconClick, this.onToggleFullscreen, this.onHelpClick, mapper); }.bind(this)); diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-select.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-select.tsx index ea59b73791..fa296e6ef4 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-select.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-select.tsx @@ -15,11 +15,12 @@ */ import * as React from 'react'; import { JsonFormFieldProps, JsonFormFieldState } from '@shared/components/json-form/react/json-form.models'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import InputLabel from '@material-ui/core/InputLabel'; -import Select from '@material-ui/core/Select'; +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import InputLabel from '@mui/material/InputLabel'; +import Select, { SelectChangeEvent } from '@mui/material/Select'; import ThingsboardBaseComponent from '@shared/components/json-form/react/json-form-base-component'; +import { isObject } from '@core/utils'; interface ThingsboardSelectState extends JsonFormFieldState { currentValue: any; @@ -27,34 +28,39 @@ interface ThingsboardSelectState extends JsonFormFieldState { class ThingsboardSelect extends React.Component { + static getDerivedStateFromProps(props) { + if (props.model && props.form.key) { + return { + currentValue: ThingsboardSelect.getModelKey(props.model, props.form.key) + || (props.form.titleMap != null ? props.form.titleMap[0].value : '') + } + } + } + + static getModelKey(model, key) { + if (Array.isArray(key)) { + const res = key.reduce((cur, nxt) => (cur[nxt] || {}), model); + if (res && isObject(res)) { + return undefined; + } else { + return res; + } + } else { + return model[key]; + } + } + constructor(props) { super(props); this.onSelected = this.onSelected.bind(this); - const possibleValue = this.getModelKey(this.props.model, this.props.form.key); + const possibleValue = ThingsboardSelect.getModelKey(this.props.model, this.props.form.key); this.state = { currentValue: this.props.model !== undefined && possibleValue ? possibleValue : this.props.form.titleMap != null ? this.props.form.titleMap[0].value : '' }; } - componentWillReceiveProps(nextProps) { - if (nextProps.model && nextProps.form.key) { - this.setState({ - currentValue: this.getModelKey(nextProps.model, nextProps.form.key) - || (nextProps.form.titleMap != null ? nextProps.form.titleMap[0].value : '') - }); - } - } - - getModelKey(model, key) { - if (Array.isArray(key)) { - return key.reduce((cur, nxt) => (cur[nxt] || {}), model); - } else { - return model[key]; - } - } - - onSelected(event: React.ChangeEvent<{ name?: string; value: any }>) { + onSelected(event: SelectChangeEvent) { this.setState({ currentValue: event.target.value @@ -72,8 +78,9 @@ class ThingsboardSelect extends React.Component - {this.props.form.title} + {this.props.form.title}