Merge pull request #5733 from vvlladd28/bugs/json-form/full-screen
[3.3.3] UI: Fixed incorrect work buttons in fullscreen mode at json-form
This commit is contained in:
commit
2caa534802
@ -15,8 +15,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div class="tb-json-form" style="background: #fff;" tb-fullscreen [fullscreenElement]="targetFullscreenElement"
|
<div class="tb-json-form" style="background: #fff;" tb-fullscreen [fullscreenElement]="reactFullscreen"
|
||||||
[fullscreen]="isFullscreen"
|
[fullscreen]="isFullscreen"
|
||||||
(fullscreenChanged)="onFullscreenChanged($event)">
|
(fullscreenChanged)="onFullscreenChanged($event)">
|
||||||
<div #reactRoot></div>
|
<div #reactRoot></div>
|
||||||
|
<div class="tb-json-form" #reactFullscreen></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -73,6 +73,9 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato
|
|||||||
@ViewChild('reactRoot', {static: true})
|
@ViewChild('reactRoot', {static: true})
|
||||||
reactRootElmRef: ElementRef<HTMLElement>;
|
reactRootElmRef: ElementRef<HTMLElement>;
|
||||||
|
|
||||||
|
@ViewChild('reactFullscreen', {static: true})
|
||||||
|
reactFullscreenElmRef: ElementRef<HTMLElement>;
|
||||||
|
|
||||||
private readonlyValue: boolean;
|
private readonlyValue: boolean;
|
||||||
get readonly(): boolean {
|
get readonly(): boolean {
|
||||||
return this.readonlyValue;
|
return this.readonlyValue;
|
||||||
@ -106,8 +109,7 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato
|
|||||||
isModelValid = true;
|
isModelValid = true;
|
||||||
|
|
||||||
isFullscreen = false;
|
isFullscreen = false;
|
||||||
targetFullscreenElement: HTMLElement;
|
fullscreenFinishFn: (el: Element) => void;
|
||||||
fullscreenFinishFn: () => void;
|
|
||||||
|
|
||||||
private propagateChange = null;
|
private propagateChange = null;
|
||||||
private propagateChangePending = false;
|
private propagateChangePending = false;
|
||||||
@ -233,8 +235,7 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onToggleFullscreen(element: HTMLElement, fullscreenFinishFn?: () => void) {
|
private onToggleFullscreen(fullscreenFinishFn?: (el: Element) => void) {
|
||||||
this.targetFullscreenElement = element;
|
|
||||||
this.isFullscreen = !this.isFullscreen;
|
this.isFullscreen = !this.isFullscreen;
|
||||||
this.fullscreenFinishFn = fullscreenFinishFn;
|
this.fullscreenFinishFn = fullscreenFinishFn;
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
@ -244,7 +245,7 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato
|
|||||||
this.formProps.isFullscreen = fullscreen;
|
this.formProps.isFullscreen = fullscreen;
|
||||||
this.renderReactSchemaForm(false);
|
this.renderReactSchemaForm(false);
|
||||||
if (this.fullscreenFinishFn) {
|
if (this.fullscreenFinishFn) {
|
||||||
this.fullscreenFinishFn();
|
this.fullscreenFinishFn(this.reactFullscreenElmRef.nativeElement);
|
||||||
this.fullscreenFinishFn = null;
|
this.fullscreenFinishFn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
import ThingsboardBaseComponent from './json-form-base-component';
|
import ThingsboardBaseComponent from './json-form-base-component';
|
||||||
import reactCSS from 'reactcss';
|
import reactCSS from 'reactcss';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
@ -42,6 +43,7 @@ interface ThingsboardAceEditorProps extends JsonFormFieldProps {
|
|||||||
|
|
||||||
interface ThingsboardAceEditorState extends JsonFormFieldState {
|
interface ThingsboardAceEditorState extends JsonFormFieldState {
|
||||||
isFull: boolean;
|
isFull: boolean;
|
||||||
|
fullscreenContainerElement: Element;
|
||||||
helpVisible: boolean;
|
helpVisible: boolean;
|
||||||
helpReady: boolean;
|
helpReady: boolean;
|
||||||
focused: boolean;
|
focused: boolean;
|
||||||
@ -49,7 +51,6 @@ interface ThingsboardAceEditorState extends JsonFormFieldState {
|
|||||||
|
|
||||||
class ThingsboardAceEditor extends React.Component<ThingsboardAceEditorProps, ThingsboardAceEditorState> {
|
class ThingsboardAceEditor extends React.Component<ThingsboardAceEditorProps, ThingsboardAceEditorState> {
|
||||||
|
|
||||||
hostElement: HTMLElement;
|
|
||||||
private aceEditor: IEditorProps;
|
private aceEditor: IEditorProps;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -64,6 +65,7 @@ class ThingsboardAceEditor extends React.Component<ThingsboardAceEditorProps, Th
|
|||||||
const value = props.value ? props.value + '' : '';
|
const value = props.value ? props.value + '' : '';
|
||||||
this.state = {
|
this.state = {
|
||||||
isFull: false,
|
isFull: false,
|
||||||
|
fullscreenContainerElement: null,
|
||||||
helpVisible: false,
|
helpVisible: false,
|
||||||
helpReady: true,
|
helpReady: true,
|
||||||
value,
|
value,
|
||||||
@ -131,12 +133,8 @@ class ThingsboardAceEditor extends React.Component<ThingsboardAceEditorProps, Th
|
|||||||
}
|
}
|
||||||
|
|
||||||
onToggleFull() {
|
onToggleFull() {
|
||||||
this.setState({ isFull: !this.state.isFull });
|
this.props.onToggleFullscreen((el) => {
|
||||||
this.props.onToggleFullscreen(this.hostElement, () => {
|
this.setState({ isFull: !this.state.isFull, fullscreenContainerElement: el });
|
||||||
if (this.aceEditor) {
|
|
||||||
this.aceEditor.resize();
|
|
||||||
this.aceEditor.renderer.updateFull();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,56 +175,61 @@ class ThingsboardAceEditor extends React.Component<ThingsboardAceEditorProps, Th
|
|||||||
if (this.state.isFull) {
|
if (this.state.isFull) {
|
||||||
containerClass += ' fullscreen-form-field';
|
containerClass += ' fullscreen-form-field';
|
||||||
}
|
}
|
||||||
return (
|
const formDom = (
|
||||||
<div>
|
<div className={containerClass}>
|
||||||
<div className='tb-json-form' ref={c => (this.hostElement = c)}>
|
<label className={labelClass}>{this.props.form.title}</label>
|
||||||
<div className={containerClass}>
|
<div className='json-form-ace-editor'>
|
||||||
<label className={labelClass}>{this.props.form.title}</label>
|
<div className='title-panel'>
|
||||||
<div className='json-form-ace-editor'>
|
<label>{this.props.mode}</label>
|
||||||
<div className='title-panel'>
|
{ this.props.onTidy ? <Button style={ styles.tidyButtonStyle }
|
||||||
<label>{this.props.mode}</label>
|
className='tidy-button' onClick={this.onTidy}>Tidy</Button> : null }
|
||||||
{ this.props.onTidy ? <Button style={ styles.tidyButtonStyle }
|
{ this.props.form.helpId ? <div style={ {position: 'relative', display: 'inline-block', marginLeft: '5px'} }>
|
||||||
className='tidy-button' onClick={this.onTidy}>Tidy</Button> : null }
|
<IconButton color='primary'
|
||||||
{ this.props.form.helpId ? <div style={ {position: 'relative', display: 'inline-block', marginLeft: '5px'} }>
|
className='help-button' onClick={this.onHelp}>
|
||||||
<IconButton color='primary'
|
{this.state.helpVisible ? <Help /> : <HelpOutline /> }
|
||||||
className='help-button' onClick={this.onHelp}>
|
</IconButton>
|
||||||
{this.state.helpVisible ? <Help /> : <HelpOutline /> }
|
{ this.state.helpVisible && !this.state.helpReady ?
|
||||||
</IconButton>
|
<div className='tb-absolute-fill help-button-loading'>
|
||||||
{ this.state.helpVisible && !this.state.helpReady ?
|
<CircularProgress size={18} thickness={4}/>
|
||||||
<div className='tb-absolute-fill help-button-loading'>
|
</div> : null }</div> : null }
|
||||||
<CircularProgress size={18} thickness={4}/>
|
<Button style={ styles.tidyButtonStyle }
|
||||||
</div> : null }</div> : null }
|
className='tidy-button' onClick={this.onToggleFull}>
|
||||||
<Button style={ styles.tidyButtonStyle }
|
{this.state.isFull ?
|
||||||
className='tidy-button' onClick={this.onToggleFull}>
|
'Exit fullscreen' : 'Fullscreen'}
|
||||||
{this.state.isFull ?
|
</Button>
|
||||||
'Exit fullscreen' : 'Fullscreen'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<React.Suspense fallback={<div>Loading...</div>}>
|
|
||||||
<ReactAce mode={this.props.mode}
|
|
||||||
theme={'textmate'}
|
|
||||||
height={this.state.isFull ? '100%' : '150px'}
|
|
||||||
width={this.state.isFull ? '100%' : '300px'}
|
|
||||||
onChange={this.onValueChanged}
|
|
||||||
onFocus={this.onFocus}
|
|
||||||
onBlur={this.onBlur}
|
|
||||||
onLoad={this.onLoad}
|
|
||||||
name={this.props.form.title}
|
|
||||||
value={this.state.value}
|
|
||||||
readOnly={this.props.form.readonly}
|
|
||||||
editorProps={{$blockScrolling: Infinity}}
|
|
||||||
enableBasicAutocompletion={true}
|
|
||||||
enableSnippets={true}
|
|
||||||
enableLiveAutocompletion={true}
|
|
||||||
style={style}/>
|
|
||||||
</React.Suspense>
|
|
||||||
</div>
|
|
||||||
<div className='json-form-error'
|
|
||||||
style={{opacity: this.props.valid ? '0' : '1'}}>{this.props.error}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<React.Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<ReactAce mode={this.props.mode}
|
||||||
|
theme={'textmate'}
|
||||||
|
height={this.state.isFull ? '100%' : '150px'}
|
||||||
|
width={this.state.isFull ? '100%' : '300px'}
|
||||||
|
onChange={this.onValueChanged}
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
onBlur={this.onBlur}
|
||||||
|
onLoad={this.onLoad}
|
||||||
|
name={this.props.form.title}
|
||||||
|
value={this.state.value}
|
||||||
|
readOnly={this.props.form.readonly}
|
||||||
|
editorProps={{$blockScrolling: Infinity}}
|
||||||
|
enableBasicAutocompletion={true}
|
||||||
|
enableSnippets={true}
|
||||||
|
enableLiveAutocompletion={true}
|
||||||
|
style={style}/>
|
||||||
|
</React.Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='json-form-error'
|
||||||
|
style={{opacity: this.props.valid ? '0' : '1'}}>{this.props.error}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
if (this.state.isFull) {
|
||||||
|
return ReactDOM.createPortal(formDom, this.state.fullscreenContainerElement);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{formDom}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -106,8 +106,8 @@ class ThingsboardSchemaForm extends React.Component<JsonFormProps, any> {
|
|||||||
this.props.onIconClick(key, val, iconSelectedFn);
|
this.props.onIconClick(key, val, iconSelectedFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
onToggleFullscreen(element: HTMLElement, fullscreenFinishFn?: () => void) {
|
onToggleFullscreen(fullscreenFinishFn?: (el: Element) => void) {
|
||||||
this.props.onToggleFullscreen(element, fullscreenFinishFn);
|
this.props.onToggleFullscreen(fullscreenFinishFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
onHelpClick(event: MouseEvent, helpId: string, helpVisibleFn: (visible: boolean) => void, helpReadyFn: (ready: boolean) => void) {
|
onHelpClick(event: MouseEvent, helpId: string, helpVisibleFn: (visible: boolean) => void, helpReadyFn: (ready: boolean) => void) {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export type OnColorClickFn = (key: (string | number)[], val: tinycolor.ColorForm
|
|||||||
colorSelectedFn: (color: tinycolor.ColorFormats.RGBA) => void) => void;
|
colorSelectedFn: (color: tinycolor.ColorFormats.RGBA) => void) => void;
|
||||||
export type OnIconClickFn = (key: (string | number)[], val: string,
|
export type OnIconClickFn = (key: (string | number)[], val: string,
|
||||||
iconSelectedFn: (icon: string) => void) => void;
|
iconSelectedFn: (icon: string) => void) => void;
|
||||||
export type onToggleFullscreenFn = (element: HTMLElement, fullscreenFinishFn?: () => void) => void;
|
export type onToggleFullscreenFn = (fullscreenFinishFn?: (el: Element) => void) => void;
|
||||||
export type onHelpClickFn = (event: MouseEvent, helpId: string, helpVisibleFn: (visible: boolean) => void,
|
export type onHelpClickFn = (event: MouseEvent, helpId: string, helpVisibleFn: (visible: boolean) => void,
|
||||||
helpReadyFn: (ready: boolean) => void) => void;
|
helpReadyFn: (ready: boolean) => void) => void;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user