diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 6 | ||||
-rw-r--r-- | src/client/util/Scripting.ts | 1 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/ScriptBox.scss | 8 | ||||
-rw-r--r-- | src/client/views/ScriptBox.tsx | 80 | ||||
-rw-r--r-- | src/server/authentication/models/current_user_utils.ts | 1 |
6 files changed, 87 insertions, 16 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 5eca71ca9..08aa31db2 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -547,6 +547,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.RTF), text, options, undefined, "text"); } + export function ScriptDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.SCRIPT), undefined, options); + } + export function LinkDocument(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, options: DocumentOptions = {}, id?: string) { const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { isLinkButton: true, treeViewHideTitle: true, treeViewOpen: false, removeDropProperties: new List(["isBackground", "isLinkButton"]), ...options }); const linkDocProto = Doc.GetProto(doc); @@ -931,7 +935,7 @@ export namespace DocUtils { }); ContextMenu.Instance.addItem({ description: "Add Template Doc ...", - subitems: DocListCast(Cast(Doc.UserDoc().expandingButtons, Doc, null)?.data).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc).map((dragDoc, i) => ({ + subitems: DocListCast(Cast(Doc.UserDoc().expandingButtons, Doc, null) ?.data).map(btnDoc => Cast(btnDoc ?.dragFactory, Doc, null)).filter(doc => doc).map((dragDoc, i) => ({ description: ":" + StrCast(dragDoc.title), event: (args: { x: number, y: number }) => { const newDoc = Doc.ApplyTemplate(dragDoc); diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index f97d91d10..8207b940d 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -275,6 +275,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp const result = Run(outputText, paramNames, diagnostics, script, options); + if (options.globals) { Scripting.resetScriptingGlobals(); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 1edfc871f..d7c769ddd 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -55,7 +55,7 @@ export class MainView extends React.Component { @observable private _panelHeight: number = 0; @observable private _flyoutTranslate: boolean = true; @observable public flyoutWidth: number = 250; - private get darkScheme() { return BoolCast(Cast(this.userDoc.activeWorkspace, Doc, null)?.darkScheme); } + private get darkScheme() { return BoolCast(Cast(this.userDoc.activeWorkspace, Doc, null) ?.darkScheme); } @computed private get userDoc() { return Doc.UserDoc(); } @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; } @@ -147,6 +147,7 @@ export class MainView extends React.Component { library.add(faPhone); library.add(faClipboard); library.add(faStamp); + library.add(faTerminal); this.initEventListeners(); this.initAuthenticationRouters(); } @@ -389,7 +390,7 @@ export class MainView extends React.Component { mainContainerXf = () => new Transform(0, -this._buttonBarHeight, 1); @computed get flyout() { - const sidebarContent = this.userDoc?.sidebarContainer; + const sidebarContent = this.userDoc ?.sidebarContainer; if (!(sidebarContent instanceof Doc)) { return (null); } @@ -505,7 +506,7 @@ export class MainView extends React.Component { return new Transform(-translateX, -translateY, 1 / scale); } @computed get docButtons() { - const expandingBtns = Doc.UserDoc()?.expandingButtons; + const expandingBtns = Doc.UserDoc() ?.expandingButtons; if (expandingBtns instanceof Doc) { return <div className="mainView-docButtons" ref={this._docBtnRef} style={{ height: !expandingBtns.linearViewIsExpanded ? "42px" : undefined }} > diff --git a/src/client/views/ScriptBox.scss b/src/client/views/ScriptBox.scss index 28326624a..b91a36c1f 100644 --- a/src/client/views/ScriptBox.scss +++ b/src/client/views/ScriptBox.scss @@ -3,6 +3,9 @@ height: 100%; display: flex; flex-direction: column; + pointer-events: all; + background-color: rgb(241, 239, 235); + padding: 10px; } .scriptBox-toolbar { @@ -14,4 +17,9 @@ height: 100%; box-sizing: border-box; resize: none; + padding: 7px; +} + +.scriptBox-button { + width: 50% }
\ No newline at end of file diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 0352ddaca..f094feb0b 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -7,28 +7,50 @@ import { OverlayView } from "./OverlayView"; import { DocumentIconContainer } from "./nodes/DocumentIcon"; import { Opt, Doc } from "../../new_fields/Doc"; import { emptyFunction } from "../../Utils"; -import { ScriptCast } from "../../new_fields/Types"; +import { ScriptCast, StrCast } from "../../new_fields/Types"; import { CompileScript } from "../util/Scripting"; import { ScriptField } from "../../new_fields/ScriptField"; import { DragManager } from "../util/DragManager"; import { EditableView } from "./EditableView"; +import { FieldView, FieldViewProps } from "./nodes/FieldView"; +import { DocAnnotatableComponent } from "./DocComponent"; +import { makeInterface } from "../../new_fields/Schema"; +import { documentSchema } from "../../new_fields/documentSchemas"; +import { CompileResult } from "../northstar/model/idea/idea"; +import { red } from "colors"; +import { forEach } from "typescript-collections/dist/lib/arrays"; export interface ScriptBoxProps { - onSave: (text: string, onError: (error: string) => void) => void; + onSave?: (text: string, onError: (error: string) => void) => void; onCancel?: () => void; initialText?: string; showDocumentIcons?: boolean; setParams?: (p: string[]) => void; } +type ScriptDocument = makeInterface<[typeof documentSchema]>; +const ScriptDocument = makeInterface(documentSchema); + @observer -export class ScriptBox extends React.Component<ScriptBoxProps> { +export class ScriptBox extends DocAnnotatableComponent<FieldViewProps & ScriptBoxProps, ScriptDocument>(ScriptDocument) { + protected multiTouchDisposer?: import("../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; + public static LayoutString(fieldStr: string) { return FieldView.LayoutString(ScriptBox, fieldStr); } + @observable private _scriptText: string; + @observable + private _errorMessage: string; + constructor(props: ScriptBoxProps) { super(props); this._scriptText = props.initialText || ""; + this._errorMessage = ""; + } + + @action + componentDidMount() { + this._scriptText = StrCast(this.props.Document.documentText) || this.props.initialText || ""; } @action @@ -37,8 +59,10 @@ export class ScriptBox extends React.Component<ScriptBoxProps> { } @action - onError = (error: string) => { - console.log(error); + onError = (error: any) => { + for (const entry of error) { + this._errorMessage = this._errorMessage + " " + entry.messageText; + } } overlayDisposer?: () => void; @@ -53,12 +77,43 @@ export class ScriptBox extends React.Component<ScriptBoxProps> { this.overlayDisposer?.(); } + @action + onCompile = () => { + const result = CompileScript(this._scriptText, {}); + this._errorMessage = ""; + if (result.compiled) { + this._errorMessage = ""; + this.props.Document.data = new ScriptField(result); + } + else { + this.onError(result.errors); + } + this.props.Document.documentText = this._scriptText; + } + + @action + onRun = () => { + const result = CompileScript(this._scriptText, {}); + this._errorMessage = ""; + if (result.compiled) { + result.run({}, (err: any) => { + this._errorMessage = ""; + this.onError(err); + }); + this.props.Document.data = new ScriptField(result); + } + else { + this.onError(result.errors); + } + this.props.Document.documentText = this._scriptText; + } + render() { let onFocus: Opt<() => void> = undefined, onBlur: Opt<() => void> = undefined; - if (this.props.showDocumentIcons) { - onFocus = this.onFocus; - onBlur = this.onBlur; - } + //if (this.props.showDocumentIcons) { + onFocus = this.onFocus; + onBlur = this.onBlur; + // } const params = <EditableView contents={""} display={"block"} @@ -71,12 +126,13 @@ export class ScriptBox extends React.Component<ScriptBoxProps> { return ( <div className="scriptBox-outerDiv"> <div style={{ display: "flex", flexDirection: "column", height: "100%" }}> - <textarea className="scriptBox-textarea" onChange={this.onChange} value={this._scriptText} onFocus={onFocus} onBlur={onBlur}></textarea> + <textarea className="scriptBox-textarea" placeholder="write your script here" onChange={this.onChange} value={this._scriptText} onFocus={onFocus} onBlur={onBlur}></textarea> + <div className="errorMessage">{this._errorMessage}</div> <div style={{ background: "beige" }} >{params}</div> </div> <div className="scriptBox-toolbar"> - <button onClick={e => { this.props.onSave(this._scriptText, this.onError); e.stopPropagation(); }}>Save</button> - <button onClick={e => { this.props.onCancel && this.props.onCancel(); e.stopPropagation(); }}>Cancel</button> + <button className="scriptBox-button" onPointerDown={e => { this.onCompile(); e.stopPropagation(); }}>Compile</button> + <button className="scriptBox-button" onPointerDown={e => { this.onRun(); e.stopPropagation(); }}>Run</button> </div> </div> ); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 37b680765..6e900210c 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -74,6 +74,7 @@ export class CurrentUserUtils { { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' }, { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", {_width: 300, _height: 300, title: "New Webpage" })' }, { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' }, + { title: "script", icon: "terminal", ignoreClick: true, drag: 'Docs.Create.ScriptDocument({ _width: 200, _height: 250 title: "untitled script" })' }, { title: "buxton", icon: "cloud-upload-alt", ignoreClick: true, drag: "Docs.Create.Buxton()" }, { title: "screenshot", icon: "photo-video", ignoreClick: true, drag: 'Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" })' }, { title: "webcam", icon: "video", ignoreClick: true, drag: 'Docs.Create.WebCamDocument("", { _width: 400, _height: 400, title: "a test cam" })' }, |