import { action, observable, computed, _allowStateChangesInsideComputed } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import { documentSchema } from "../../../fields/documentSchemas"; import { createSchema, makeInterface, listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { StrCast, ScriptCast, Cast } from "../../../fields/Types"; import { InteractionUtils } from "../../util/InteractionUtils"; import { CompileScript, isCompileError, ScriptParam } from "../../util/Scripting"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { EditableView } from "../EditableView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./ScriptingBox.scss"; import { OverlayView } from "../OverlayView"; import { DocumentIconContainer, DocumentIcon } from "./DocumentIcon"; import { List } from "../../../fields/List"; import { DragManager } from "../../util/DragManager"; import { Doc } from "../../../fields/Doc"; const ScriptingSchema = createSchema({}); type ScriptingDocument = makeInterface<[typeof ScriptingSchema, typeof documentSchema]>; const ScriptingDocument = makeInterface(ScriptingSchema, documentSchema); @observer export class ScriptingBox extends ViewBoxAnnotatableComponent(ScriptingDocument) { protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer | undefined; rowProps: any; _paramNum: number = 0; public static LayoutString(fieldStr: string) { return FieldView.LayoutString(ScriptingBox, fieldStr); } _overlayDisposer?: () => void; @observable private _errorMessage: string = ""; @observable private _applied: boolean = false; @observable private _paramsNames: any; @observable private _paramsTypes: any; @observable private _paramsValues: any; @computed get rawScript() { return StrCast(this.dataDoc[this.props.fieldKey + "-rawScript"], StrCast(this.layoutDoc[this.props.fieldKey + "-rawScript"])); } @computed get compileParams() { return Cast(this.dataDoc[this.props.fieldKey + "-params"], listSpec("string"), Cast(this.layoutDoc[this.props.fieldKey + "-params"], listSpec("string"), [])); } set rawScript(value) { this.dataDoc[this.props.fieldKey + "-rawScript"] = value; } set compileParams(value) { this.dataDoc[this.props.fieldKey + "-params"] = value; } @action componentDidMount() { this.rawScript = ScriptCast(this.dataDoc[this.props.fieldKey])?.script?.originalScript || this.rawScript; } componentWillUnmount() { this._overlayDisposer?.(); } @action onFinish = () => { const result = CompileScript(this.rawScript, {}); this.rootDoc.layoutKey = "layout"; this.rootDoc.height = 50; this.rootDoc.width = 100; this.props.Document.documentText = this.rawScript; } @action onError = (error: any) => { for (const entry of error) { this._errorMessage = this._errorMessage + " " + entry.messageText; } } @action onCompile = () => { // const params = this.compileParams.reduce((o: ScriptParam, p: string) => { o[p] = "any"; return o; }, {} as ScriptParam); // const result = CompileScript(this.rawScript, { // editable: true // transformer: DocumentIconContainer.getTransformer(), // params, // typecheck: false // }); // this._errorMessage = isCompileError(result) ? result.errors.map(e => e.messageText).join("\n") : ""; // return this.dataDoc[this.props.fieldKey] = result.compiled ? new ScriptField(result) : undefined; const params = this.compileParams.reduce((o: ScriptParam, p: string) => { const param = p.split(":"); o[param[0].trim()] = param[1].trim(); return o; }, {} as ScriptParam); console.log(this.compileParams); const result = CompileScript(this.rawScript, { editable: true, transformer: DocumentIconContainer.getTransformer(), params, typecheck: true }); this._errorMessage = ""; if (result.compiled) { this._errorMessage = ""; this.props.Document.data = new ScriptField(result); } else { this.onError(result.errors); } this.props.Document.documentText = this.rawScript; } @action onRun = () => { const params = this.compileParams.reduce((o: ScriptParam, p: string) => { const param = p.split(":"); o[param[0].trim()] = param[1].trim(); return o; }, {} as ScriptParam); const result = CompileScript(this.rawScript, { editable: true, transformer: DocumentIconContainer.getTransformer(), params, typecheck: true }); this._errorMessage = ""; if (result.compiled) { // this automatically saves result.run({ self: this.rootDoc, this: this.layoutDoc }, (err: any) => { this._errorMessage = ""; this.onError(err); }); this.props.Document.data = new ScriptField(result); } else { this.onError(result.errors); } this.props.Document.documentText = this.rawScript; //this.onCompile()?.script.run({}, err => this._errorMessage = err.map((e: any) => e.messageText).join("\n")); } @action onApply = () => { const params = this.compileParams.reduce((o: ScriptParam, p: string) => { const param = p.split(":"); o[param[0].trim()] = param[1].trim(); return o; }, {} as ScriptParam); console.log(this.compileParams); const result = CompileScript(this.rawScript, { editable: true, transformer: DocumentIconContainer.getTransformer(), params, typecheck: true }); this._errorMessage = ""; if (result.compiled) { this._errorMessage = ""; this.props.Document.data = new ScriptField(result); this._applied = true; } else { this.onError(result.errors); } this.props.Document.documentText = this.rawScript; this._paramsNames = []; this._paramsTypes = []; this.compileParams.forEach(element => { const param = element.split(":"); this._paramsNames.push(param[0].trim()); this._paramsTypes.push(param[1].trim()); } ); } @action onEdit = () => { this._applied = false; } onFocus = () => { this._overlayDisposer?.(); this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); } @action onDrop = (e: Event, de: DragManager.DropEvent, index: any) => { console.log("drop"); const firstParam = this.compileParams[index].split(":"); const droppedDocs = de.complete.docDragData?.droppedDocuments; if (droppedDocs?.length) { const dropped = droppedDocs[0]; this._paramsValues[index] = dropped; // you can't just bind a variable to a specific Doc. The Doc would have to be added to 'capturedVariables' field of the compile options, but I think it makes more sense to just be declaring this variable to be a Doc } } @action onDelete = (num: number) => { this.compileParams.splice(num, 1); } render() { const params = ""} SetValue={value => { if (value !== "" && value !== " ") { const parameter = value.split(":"); if (parameter[1] !== undefined) { if (parameter[1].trim() === "Doc" || parameter[1].trim() === "string") { //if (!!!this._paramsNames.includes(parameter[0].trim())) { this._errorMessage = ""; this._paramNum++; const par = this.compileParams; this.compileParams = new List(value.split(";").filter(s => s !== " ")); this.compileParams.push.apply(this.compileParams, par); return true; // } else { // this._errorMessage = "this name has already been used"; // return false; // } } else { this._errorMessage = "this type is not supported"; return false; } } else { this._errorMessage = "must set type of parameter"; return false; } } return false; }} />; const listParams = this.compileParams.map((parameter, i) =>
{ if (e.key === "Enter") { this._overlayDisposer?.(); } } } > parameter} onDrop={(e: Event, de: DragManager.DropEvent) => this.onDrop(e, de, i)} SetValue={value => { if (value !== "" && value !== " ") { this.compileParams[i] = value; parameter = value; return true; } else { this.onDelete(i); return true; } }} />
); // const settingParams = this._paramsNames.map((parameter: string, i: number) => //
{ // if (e.key === "Enter") { // this._overlayDisposer?.(); // } // } // } // > // {this._paramsTypes[i] === "Doc" ?
//
//
// {parameter + ":" + this._paramsValues[i] + " = "} //
//
// this._paramsValues[i]} // onDrop={(e: Event, de: DragManager.DropEvent) => this.onDrop(e, de, i)} // SetValue={value => { // this._paramsValues[i] = value; // return true; // }} // /> //
//
//
: null} // {this._paramsTypes[i] === "string" ?
//
//
// {parameter + ":" + this._paramsValues[i] + " = "} //
//
// this._paramsValues[i]} // SetValue={value => { // this._paramsValues[i] = value; // return true; // }} // /> //
//
//
: null} //
// ); const scriptingInputs =
this.props.isSelected(true) && e.stopPropagation()} >