aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/EditableView.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx65
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx82
3 files changed, 120 insertions, 29 deletions
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 373b63282..c3612fee9 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -134,7 +134,7 @@ export class EditableView extends React.Component<EditableProps> {
return (
<div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
style={{ display: this.props.display, height: "auto", maxHeight: `${this.props.height}` }}
- onClick={this.onClick} >
+ onClick={this.onClick}>
<span style={{ fontStyle: this.props.fontStyle, fontSize: this.props.fontSize }}>{this.props.contents}</span>
</div>
);
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index c91f1017b..f1e013edd 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -24,7 +24,7 @@ import { SelectionManager } from "../../util/SelectionManager";
import { library } from '@fortawesome/fontawesome-svg-core';
import { faExpand } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
library.add(faExpand);
@@ -44,6 +44,8 @@ export interface CellProps {
setIsEditing: (isEditing: boolean) => void;
isEditable: boolean;
setPreviewDoc: (doc: Doc) => void;
+ setComputed: (script: string, doc: Doc, field: string, row: number, col: number) => boolean;
+ getField: (row: number, col?: number) => void;
}
@observer
@@ -82,11 +84,18 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
@action
onPointerDown = (e: React.PointerEvent): void => {
this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
+ this.props.setPreviewDoc(this.props.rowProps.original);
+
+ let field = this.props.rowProps.original[this.props.rowProps.column.id!];
+ let doc = FieldValue(Cast(field, Doc));
+ if (typeof field === "object" && doc) this.props.setPreviewDoc(doc);
}
- applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => {
- const res = run({ this: doc });
+ applyToDoc = (doc: Doc, row: number, col: number, run: (args?: { [name: string]: any }) => any) => {
+ const res = run({ this: doc, $r: row, $c: col, $: (r: number = 0, c: number = 0) => this.props.getField(r + row, c + col) });
if (!res.success) return false;
+ // doc[this.props.fieldKey] = res.result;
+ // return true;
doc[this.props.rowProps.column.id as string] = res.result;
return true;
}
@@ -146,10 +155,16 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
addDocTab: this.props.addDocTab,
};
- // let onItemDown = (e: React.PointerEvent) => {
- // SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
- // this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
- // };
+ let field = props.Document[props.fieldKey];
+ let doc = FieldValue(Cast(field, Doc));
+ let fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
+
+ let onItemDown = (e: React.PointerEvent) => {
+ if (fieldIsDoc) {
+ SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
+ this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
+ }
+ };
let onPointerEnter = (e: React.PointerEvent): void => {
if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) {
dragRef!.current!.className = "collectionSchemaView-cellContainer doc-drag-over";
@@ -159,7 +174,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
dragRef!.current!.className = "collectionSchemaView-cellContainer";
};
- let field = props.Document[props.fieldKey];
let contents: any = "incorrect type";
if (type === undefined) contents = <FieldView {...props} />;
if (type === "number") contents = typeof field === "number" ? NumCast(field) : "--" + typeof field + "--";
@@ -175,18 +189,16 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
if (this.props.isFocused && this.props.isEditable) className += " focused";
if (this.props.isFocused && !this.props.isEditable) className += " inactive";
- let doc = FieldValue(Cast(field, Doc));
- if (type === "document") console.log("doc", typeof field);
- let fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
- let docExpander = (
- <div className="collectionSchemaView-cellContents-docExpander" onPointerDown={this.expandDoc} >
- <FontAwesomeIcon icon="expand" size="sm" />
- </div>
- );
+
+ // let docExpander = (
+ // <div className="collectionSchemaView-cellContents-docExpander" onPointerDown={this.expandDoc} >
+ // <FontAwesomeIcon icon="expand" size="sm" />
+ // </div>
+ // );
return (
- <div className="collectionSchemaView-cellContainer" ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
- <div className={className} ref={this._focusRef} tabIndex={-1}>
+ <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }} ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
+ <div className={className} ref={this._focusRef} onPointerDown={onItemDown} tabIndex={-1}>
<div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
<EditableView
editing={this._isEditing}
@@ -203,24 +215,27 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
}
}
SetValue={(value: string) => {
- let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
+ if (value.startsWith(":=")) {
+ return this.props.setComputed(value.substring(2), props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
+ }
+ let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
if (!script.compiled) {
return false;
}
- return this.applyToDoc(props.Document, script.run);
+ return this.applyToDoc(props.Document, this.props.row, this.props.col, script.run);
}}
OnFillDown={async (value: string) => {
- let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } });
+ let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
if (!script.compiled) {
return;
}
const run = script.run;
- //TODO This should be able to be refactored to compile the script once
const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
- val && val.forEach(doc => this.applyToDoc(doc, run));
- }} />
+ val && val.forEach((doc, i) => this.applyToDoc(doc, i, this.props.col, run));
+ }}
+ />
</div >
- {fieldIsDoc ? docExpander : null}
+ {/* {fieldIsDoc ? docExpander : null} */}
</div>
</div>
);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index d504f9799..42843ad30 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -321,13 +321,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
let cols = this.columns.map(col => {
-
let header = <CollectionSchemaHeader
keyValue={col}
possibleKeys={possibleKeys}
existingKeys={this.columns.map(c => c.heading)}
keyType={this.getColumnType(col)}
- typeConst={col.type !== undefined || columnTypes.get(col.heading) !== undefined}
+ typeConst={columnTypes.get(col.heading) !== undefined}
onSelect={this.changeColumns}
setIsEditing={this.setHeaderIsEditing}
deleteColumn={this.deleteColumn}
@@ -360,7 +359,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
moveDocument: this.props.moveDocument,
setIsEditing: this.setCellIsEditing,
isEditable: isEditable,
- setPreviewDoc: this.props.setPreviewDoc
+ setPreviewDoc: this.props.setPreviewDoc,
+ setComputed: this.setComputed,
+ getField: this.getField,
};
let colType = this.getColumnType(col);
@@ -772,6 +773,81 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
}
+ getField = (row: number, col?: number) => {
+ // const docs = DocListCast(this.props.Document[this.props.fieldKey]);
+
+ let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
+ const docs = DocListCast(cdoc[this.props.fieldKey]);
+
+ row = row % docs.length;
+ while (row < 0) row += docs.length;
+ const columns = this.columns;
+ const doc = docs[row];
+ if (col === undefined) {
+ return doc;
+ }
+ if (col >= 0 && col < columns.length) {
+ const column = this.columns[col].heading;
+ return doc[column];
+ }
+ return undefined;
+ }
+
+ createTransformer = (row: number, col: number): Transformer => {
+ const self = this;
+ const captures: { [name: string]: Field } = {};
+
+ const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
+ return root => {
+ function visit(node: ts.Node) {
+ node = ts.visitEachChild(node, visit, context);
+ if (ts.isIdentifier(node)) {
+ const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
+ const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
+ if (isntPropAccess && isntPropAssign) {
+ if (node.text === "$r") {
+ return ts.createNumericLiteral(row.toString());
+ } else if (node.text === "$c") {
+ return ts.createNumericLiteral(col.toString());
+ } else if (node.text === "$") {
+ if (ts.isCallExpression(node.parent)) {
+ // captures.doc = self.props.Document;
+ // captures.key = self.props.fieldKey;
+ }
+ }
+ }
+ }
+
+ return node;
+ }
+ return ts.visitNode(root, visit);
+ };
+ };
+
+ // const getVars = () => {
+ // return { capturedVariables: captures };
+ // };
+
+ return { transformer, /*getVars*/ };
+ }
+
+ setComputed = (script: string, doc: Doc, field: string, row: number, col: number): boolean => {
+ script =
+ `const $ = (row:number, col?:number) => {
+ if(col === undefined) {
+ return (doc as any)[key][row + ${row}];
+ }
+ return (doc as any)[key][row + ${row}][(doc as any).schemaColumns[col + ${col}].heading];
+ }
+ return ${script}`;
+ const compiled = CompileScript(script, { params: { this: Doc.name }, capturedVariables: { doc: this.props.Document, key: this.props.fieldKey }, typecheck: true, transformer: this.createTransformer(row, col) });
+ if (compiled.compiled) {
+ doc[field] = new ComputedField(compiled);
+ return true;
+ }
+ return false;
+ }
+
render() {
// if (SelectionManager.SelectedDocuments().length > 0) console.log(StrCast(SelectionManager.SelectedDocuments()[0].Document.title));
// if (DocumentManager.Instance.getDocumentView(this.props.Document)) console.log(StrCast(this.props.Document.title), SelectionManager.IsSelected(DocumentManager.Instance.getDocumentView(this.props.Document)!))