diff options
Diffstat (limited to 'src/client/views/nodes/ScriptingBox.tsx')
-rw-r--r-- | src/client/views/nodes/ScriptingBox.tsx | 171 |
1 files changed, 97 insertions, 74 deletions
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 8c65fd34e..bc19d7ad1 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -1,8 +1,9 @@ -let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default; +/* eslint-disable react/button-has-type */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnAlways, returnEmptyString } from '../../../Utils'; +import { returnAlways, returnEmptyString } from '../../../ClientUtils'; import { Doc } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; @@ -17,10 +18,14 @@ import { ContextMenu } from '../ContextMenu'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; import { OverlayView } from '../OverlayView'; -import { FieldView, FieldViewProps } from '../nodes/FieldView'; +import { FieldView, FieldViewProps } from './FieldView'; import { DocumentIconContainer } from './DocumentIcon'; import './ScriptingBox.scss'; +import { Docs } from '../../documents/Documents'; +import { DocumentType } from '../../documents/DocumentTypes'; + const _global = (window /* browser */ || global) /* node */ as any; +const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default; @observer export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @@ -79,26 +84,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @computed({ keepAlive: true }) get rawScript() { return ScriptCast(this.dataDoc[this.fieldKey])?.script.originalScript ?? ''; } - @computed({ keepAlive: true }) get functionName() { - return StrCast(this.dataDoc[this.fieldKey + '-functionName'], ''); - } - @computed({ keepAlive: true }) get functionDescription() { - return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], ''); - } - @computed({ keepAlive: true }) get compileParams() { - return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []); - } - set rawScript(value) { this.dataDoc[this.fieldKey] = new ScriptField(undefined, undefined, value); } + @computed({ keepAlive: true }) get functionName() { + return StrCast(this.dataDoc[this.fieldKey + '-functionName'], ''); + } set functionName(value) { this.dataDoc[this.fieldKey + '-functionName'] = value; } + @computed({ keepAlive: true }) get functionDescription() { + return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], ''); + } set functionDescription(value) { this.dataDoc[this.fieldKey + '-functionDescription'] = value; } - + @computed({ keepAlive: true }) get compileParams() { + return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []); + } set compileParams(value) { this.dataDoc[this.fieldKey + '-params'] = new List<string>(value); } @@ -107,9 +110,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() if (typeof result === 'object') { const text = descrip ? result[1] : result[2]; return text !== undefined ? text : ''; - } else { - return ''; } + return ''; } onClickScriptDisable = returnAlways; @@ -118,19 +120,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() componentDidMount() { this._props.setContentViewBox?.(this); this.rawText = this.rawScript; - const observer = new _global.ResizeObserver( - action((entries: any) => { + const resizeObserver = new _global.ResizeObserver( + action(() => { const area = document.querySelector('textarea'); if (area) { - for (const {} of entries) { - const getCaretCoordinates = require('textarea-caret'); - const caret = getCaretCoordinates(area, this._selection); - this.resetSuggestionPos(caret); - } + // eslint-disable-next-line global-require + const getCaretCoordinates = require('textarea-caret'); + const caret = getCaretCoordinates(area, this._selection); + this.resetSuggestionPos(caret); } }) ); - observer.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]); + resizeObserver.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]); } @action @@ -138,12 +139,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() if (!this._suggestionRef.current || !this._scriptTextRef.current) return; const suggestionWidth = this._suggestionRef.current.offsetWidth; const scriptWidth = this._scriptTextRef.current.offsetWidth; - const top = caret.top; - const x = this.dataDoc.x; - let left = caret.left; + const { top } = caret; + const { x } = this.dataDoc; + let { left } = caret; if (left + suggestionWidth > x + scriptWidth) { const diff = left + suggestionWidth - (x + scriptWidth); - left = left - diff; + left -= diff; } this._suggestionBoxX = left; @@ -155,7 +156,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } protected createDashEventsTarget = (ele: HTMLDivElement, dropFunc: (e: Event, de: DragManager.DropEvent) => void) => { - //used for stacking and masonry view + // used for stacking and masonry view if (ele) { this.dropDisposer?.(); this.dropDisposer = DragManager.MakeDropTarget(ele, dropFunc, this.layoutDoc); @@ -164,7 +165,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() // only included in buttons, transforms scripting UI to a button @action - onFinish = () => (this.layoutDoc.layout_fieldKey = 'layout'); + onFinish = () => { + this.layoutDoc.layout_fieldKey = 'layout'; + }; // displays error message @action @@ -176,7 +179,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @action onCompile = () => { const params: ScriptParam = {}; - this.compileParams.forEach(p => (params[p.split(':')[0].trim()] = p.split(':')[1].trim())); + this.compileParams.forEach(p => { + params[p.split(':')[0].trim()] = p.split(':')[1].trim(); + }); const result = !this.rawText.trim() ? ({ compiled: false, errors: undefined } as any) @@ -196,7 +201,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() onRun = () => { if (this.onCompile()) { const bindings: { [name: string]: any } = {}; - this.paramsNames.forEach(key => (bindings[key] = this.dataDoc[key])); + this.paramsNames.forEach(key => { + bindings[key] = this.dataDoc[key]; + }); // binds vars so user doesnt have to refer to everything as this.<var> ScriptCast(this.dataDoc[this.fieldKey], null)?.script.run({ ...bindings, this: this.Document }, this.onError); } @@ -247,7 +254,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() this.dataDoc.name = this.functionName; this.dataDoc.description = this.functionDescription; - //this.dataDoc.parameters = this.compileParams; + // this.dataDoc.parameters = this.compileParams; this.dataDoc.script = this.rawScript; ScriptManager.Instance.addScript(this.dataDoc); @@ -255,6 +262,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() this._scriptKeys = ScriptingGlobals.getGlobals(); this._scriptingDescriptions = ScriptingGlobals.getDescriptions(); this._scriptingParams = ScriptingGlobals.getParameters(); + return undefined; }; // overlays document numbers (ex. d32) over all documents when clicked on @@ -267,7 +275,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @action onDrop = (e: Event, de: DragManager.DropEvent, fieldKey: string) => { if (de.complete.docDragData) { - de.complete.docDragData.droppedDocuments.forEach(doc => (this.dataDoc[fieldKey] = doc)); + de.complete.docDragData.droppedDocuments.forEach(doc => { + this.dataDoc[fieldKey] = doc; + }); e.stopPropagation(); return true; } @@ -285,8 +295,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() // sets field of the param name to the selected value in drop down box @action viewChanged = (e: React.ChangeEvent, name: string) => { - //@ts-ignore - const val = e.target.selectedOptions[0].value; + const val = (e.target as any).selectedOptions[0].value; this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true'; }; @@ -306,8 +315,26 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }; renderFunctionInputs() { - const descriptionInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionDescription = e.target.value)} placeholder="enter description here" value={this.functionDescription} />; - const nameInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionName = e.target.value)} placeholder="enter name here" value={this.functionName} />; + const descriptionInput = ( + <textarea + className="scriptingBox-textarea-inputs" + onChange={e => { + this.functionDescription = e.target.value; + }} + placeholder="enter description here" + value={this.functionDescription} + /> + ); + const nameInput = ( + <textarea + className="scriptingBox-textarea-inputs" + onChange={e => { + this.functionName = e.target.value; + }} + placeholder="enter name here" + value={this.functionName} + /> + ); return ( <div className="scriptingBox-inputDiv" onPointerDown={e => this._props.isSelected() && e.stopPropagation()}> @@ -339,7 +366,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() return ( <div className="scriptingBox-paramInputs" onFocus={this.onFocus} onBlur={() => this._overlayDisposer?.()} ref={ele => ele && this.createDashEventsTarget(ele, (e, de) => this.onDrop(e, de, parameter))}> <EditableView - display={'block'} + display="block" maxHeight={72} height={35} fontSize={14} @@ -371,7 +398,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() return ( <div className="scriptingBox-paramInputs" style={{ overflowY: 'hidden' }}> <EditableView - display={'block'} + display="block" maxHeight={72} height={35} fontSize={14} @@ -404,6 +431,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() onChange={e => this.viewChanged(e, parameter)} value={typeof this.dataDoc[parameter] === 'string' ? 'S' + StrCast(this.dataDoc[parameter]) : typeof this.dataDoc[parameter] === 'number' ? 'N' + NumCast(this.dataDoc[parameter]) : 'B' + BoolCast(this.dataDoc[parameter])}> {types.map((type, i) => ( + // eslint-disable-next-line react/no-array-index-key <option key={i} className="scriptingBox-viewOption" value={(typeof type === 'string' ? 'S' : typeof type === 'number' ? 'N' : 'B') + type}> {' '} {type.toString()}{' '} @@ -496,6 +524,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @action suggestionPos = () => { + // eslint-disable-next-line global-require const getCaretCoordinates = require('textarea-caret'); const This = this; document.querySelector('textarea')?.addEventListener('input', function () { @@ -509,7 +538,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() keyHandler(e: any, pos: number) { e.stopPropagation(); if (this._lastChar === 'Enter') { - this.rawText = this.rawText + ' '; + this.rawText += ' '; } if (e.key === '(') { this.suggestionPos(); @@ -524,20 +553,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } } else if (e.key === ')') { this._paramSuggestion = false; - } else { - if (e.key === 'Backspace') { - if (this._lastChar === '(') { - this._paramSuggestion = false; - } else if (this._lastChar === ')') { - if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) { - if (this._scriptParamsText.length > 0) { - this._paramSuggestion = true; - } + } else if (e.key === 'Backspace') { + if (this._lastChar === '(') { + this._paramSuggestion = false; + } else if (this._lastChar === ')') { + if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) { + if (this._scriptParamsText.length > 0) { + this._paramSuggestion = true; } } - } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) { - this._paramSuggestion = false; } + } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) { + this._paramSuggestion = false; } this._lastChar = e.key === 'Backspace' ? this.rawText[this.rawText.length - 2] : e.key; @@ -559,9 +586,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() parameters.forEach((element: string, i: number) => { if (i < numEntered - 1) { - first = first + element; + first += element; } else if (i > numEntered - 1) { - last = last + element; + last += element; } }); @@ -598,16 +625,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() placeholder="write your script here" onFocus={this.onFocus} onBlur={() => this._overlayDisposer?.()} - onChange={action((e: any) => (this.rawText = e.target.value))} + onChange={action((e: any) => { + this.rawText = e.target.value; + })} value={this.rawText} - movePopupAsYouType={true} + movePopupAsYouType loadingComponent={() => <span>Loading</span>} trigger={{ ' ': { dataProvider: (token: any) => this.handleToken(token), - component: (blob: any) => { - return this.renderFuncListElement(blob.entity); - }, + component: (blob: any) => this.renderFuncListElement(blob.entity), output: (item: any, trigger: any) => { this._spaced = true; return trigger + item.trim(); @@ -615,9 +642,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }, '.': { dataProvider: (token: any) => this.handleToken(token), - component: (blob: any) => { - return this.renderFuncListElement(blob.entity); - }, + component: (blob: any) => this.renderFuncListElement(blob.entity), output: (item: any, trigger: any) => { this._spaced = true; return trigger + item.trim(); @@ -653,16 +678,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() // params box on bottom const parameterInput = ( <div className="scriptingBox-params"> - <EditableView - display={'block'} - maxHeight={72} - height={35} - fontSize={22} - contents={''} - GetValue={returnEmptyString} - SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)} - placeholder={'enter parameters here'} - /> + <EditableView display="block" maxHeight={72} height={35} fontSize={22} contents="" GetValue={returnEmptyString} SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)} placeholder="enter parameters here" /> </div> ); @@ -670,13 +686,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() const definedParameters = !this.compileParams.length ? null : ( <div className="scriptingBox-plist" style={{ width: '30%' }}> {this.compileParams.map((parameter, i) => ( + // eslint-disable-next-line react/no-array-index-key <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}> <EditableView - display={'block'} + display="block" maxHeight={72} height={35} fontSize={12} - background-color={'beige'} + background-color="beige" contents={parameter} GetValue={() => parameter} SetValue={value => (value && value !== ' ' ? this.compileParam(value, i) : this.onDelete(i))} @@ -749,6 +766,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {!this.compileParams.length || !this.paramsNames ? null : ( <div className="scriptingBox-plist"> {this.paramsNames.map((parameter: string, i: number) => ( + // eslint-disable-next-line react/no-array-index-key <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}> <div className="scriptingBox-wrapper" style={{ maxHeight: '40px' }}> <div className="scriptingBox-paramNames"> {`${parameter}:${this.paramsTypes[i]} = `} </div> @@ -829,3 +847,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() ); } } + +Docs.Prototypes.TemplateMap.set(DocumentType.SCRIPTING, { + layout: { view: ScriptingBox, dataField: 'data' }, + options: { acl: '', systemIcon: 'BsFileEarmarkCodeFill' }, +}); |