}
}
--
cgit v1.2.3-70-g09d2
From 02c5628bdaf43100a6e40baab781342bc27df464 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 21 Jul 2021 12:46:13 -0400
Subject: fixed the fact that text, number, and boolean were ignoring input
types when accepting input
---
.../collectionSchema/CollectionSchemaCells.tsx | 114 +++++++++++++--------
1 file changed, 69 insertions(+), 45 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index a8d901f4d..8b7fb9be8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -214,6 +214,55 @@ export class CollectionSchemaCell extends React.Component {
positions.pop();
}
}
+
+ // handles input procedures for string cells
+ let stringInput = (value: string, retVal: boolean): void => {
+ let valueSansQuotes = value;
+ if (this._isEditing) {
+ const vsqLength = valueSansQuotes.length;
+ // get rid of outer quotes
+ valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
+ valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
+ }
+ let inputAsString = '"';
+ // escape any quotes in the string
+ for (const i of valueSansQuotes) {
+ if (i == '"') {
+ inputAsString += '\\"';
+ } else {
+ inputAsString += i;
+ }
+ }
+ // add a closing quote
+ inputAsString += '"';
+ //two options here: we can strip off outer quotes or we can figure out what's going on with the script
+ const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
+ // handles input procedure for number cells
+ let numberInput = (value: string, retVal: boolean): void => {
+ const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
+ // if commas are not stripped, the parser only considers the numbers after the last comma
+ let inputSansCommas = "";
+ for (let s of inputscript) {
+ if (!(s == ",")) {
+ inputSansCommas += s;
+ }
+ }
+ const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
+ // handles input procedure for boolean cells
+ let boolInput = (value: string, retVal: boolean): void => {
+ const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ }
+
const placeholder = type === "number" ? "0" : contents === "" ? "--" : "undefined";
return (
{
}
// check if the input is a boolean
let inputIsBool: boolean = value == "false" || value == "true";
- // what to do in the case
- if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
- // if it's not a number, it's a string, and should be processed as such
- // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
- // after each edit
- let valueSansQuotes = value;
- if (this._isEditing) {
- const vsqLength = valueSansQuotes.length;
- // get rid of outer quotes
- valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
- valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
- }
- let inputAsString = '"';
- // escape any quotes in the string
- for (const i of valueSansQuotes) {
- if (i == '"') {
- inputAsString += '\\"';
- } else {
- inputAsString += i;
- }
- }
- // add a closing quote
- inputAsString += '"';
- //two options here: we can strip off outer quotes or we can figure out what's going on with the script
- const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- // handle numbers and expressions
- } else if (inputIsNum || value.startsWith("=")) {
- //TODO: make accept numbers
- const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
- // if commas are not stripped, the parser only considers the numbers after the last comma
- let inputSansCommas = "";
- for (let s of inputscript) {
- if (!(s == ",")) {
- inputSansCommas += s;
- }
+
+ if (type == undefined) {
+ // what to do in the case
+ if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
+ // if it's not a number, it's a string, and should be processed as such
+ // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
+ // after each edit
+ stringInput(value, retVal);
+ // handle numbers and expressions
+ } else if (inputIsNum || value.startsWith("=")) {
+ numberInput(value, retVal);
+ // handle booleans
+ } else if (inputIsBool) {
+ boolInput(value, retVal);
}
- const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- // handle booleans
- } else if (inputIsBool) {
- const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ } else if (type == "string") {
+ stringInput(value, retVal);
+ } else if (type == "number" && inputIsNum) {
+ numberInput(value, retVal);
+ } else if (type == "boolean" && inputIsBool) {
+ boolInput(value, retVal);
}
}
if (retVal) {
--
cgit v1.2.3-70-g09d2
From ee0e2c6c53db65c5524b67ed09369cc0e0e6f173 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 21 Jul 2021 16:10:04 -0400
Subject: Fixed minor bugs
---
.../collectionSchema/CollectionSchemaCells.tsx | 27 ++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index 8b7fb9be8..f7dfaaeb4 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -300,8 +300,16 @@ export class CollectionSchemaCell extends React.Component {
inputIsNum = false;
}
}
+
+ let contentsAreNum = true;
+ for (let s of contents) {
+ if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
+ contentsAreNum = false;
+ }
+ }
// check if the input is a boolean
let inputIsBool: boolean = value == "false" || value == "true";
+ let contentsAreBool: boolean = contents == "false" || contents == "true";
if (type == undefined) {
// what to do in the case
@@ -317,12 +325,23 @@ export class CollectionSchemaCell extends React.Component {
} else if (inputIsBool) {
boolInput(value, retVal);
}
+ // if the cell type is a string
} else if (type == "string") {
stringInput(value, retVal);
- } else if (type == "number" && inputIsNum) {
- numberInput(value, retVal);
- } else if (type == "boolean" && inputIsBool) {
- boolInput(value, retVal);
+ // if the cell type is a number
+ } else if (type == "number") {
+ if (inputIsNum) {
+ numberInput(value, retVal);
+ } else if (!contentsAreNum) {
+ stringInput("", retVal);
+ }
+ // if the cell type is a boolean
+ } else if (type == "boolean") {
+ if (inputIsBool) {
+ boolInput(value, retVal);
+ } else if (!contentsAreBool) {
+ stringInput("", retVal);
+ }
}
}
if (retVal) {
--
cgit v1.2.3-70-g09d2
From 0b6a18bc445825ecf69f57b49b002ed5c8a13902 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Mon, 26 Jul 2021 16:39:06 -0400
Subject: comments
---
src/fields/Doc.ts | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index bd0ba3ad7..e51eb44db 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1251,6 +1251,7 @@ export namespace Doc {
if (typeof resolved === "object" && !(resolved instanceof Array)) {
output = convertObject(resolved, excludeEmptyObjects, title, appendToExisting?.targetDoc);
} else {
+ // give the proper types to the data extracted from the JSON
const result = toField(resolved, excludeEmptyObjects);
if (appendToExisting) {
(output = appendToExisting.targetDoc)[appendToExisting.fieldKey || defaultKey] = result;
--
cgit v1.2.3-70-g09d2
From 02336134cff5f5789380bf5950864f4b95583cf6 Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Mon, 16 Aug 2021 16:09:13 -0400
Subject: commented column code
---
.../collectionSchema/CollectionSchemaMovableColumn.tsx | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
index 456c38c68..2df95ffd8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaMovableColumn.tsx
@@ -21,27 +21,38 @@ export interface MovableColumnProps {
ScreenToLocalTransform: () => Transform;
}
export class MovableColumn extends React.Component {
+ // The header of the column
private _header?: React.RefObject = React.createRef();
+ // The container of the function that is responsible for moving the column over to a new plac
private _colDropDisposer?: DragManager.DragDropDisposer;
+ // initial column position
private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+ // sensitivity to being dragged, in pixels
private _sensitivity: number = 16;
+ // Column reference ID
private _dragRef: React.RefObject = React.createRef();
onPointerEnter = (e: React.PointerEvent): void => {
+ // if the column is left-clicked and it is being dragged
if (e.buttons === 1 && SnappingManager.GetIsDragging()) {
this._header!.current!.className = "collectionSchema-col-wrapper";
document.addEventListener("pointermove", this.onDragMove, true);
}
}
+
onPointerLeave = (e: React.PointerEvent): void => {
this._header!.current!.className = "collectionSchema-col-wrapper";
document.removeEventListener("pointermove", this.onDragMove, true);
!e.buttons && document.removeEventListener("pointermove", this.onPointerMove);
}
+
onDragMove = (e: PointerEvent): void => {
+ // only take into account the horizonal direction when a column is dragged
const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
const rect = this._header!.current!.getBoundingClientRect();
+ // Now store the point at the top center of the column when it was in its original position
const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+ // to be compared with its new horizontal position
const before = x[0] < bounds[0];
this._header!.current!.className = "collectionSchema-col-wrapper";
if (before) this._header!.current!.className += " col-before";
@@ -58,11 +69,15 @@ export class MovableColumn extends React.Component {
colDrop = (e: Event, de: DragManager.DropEvent) => {
document.removeEventListener("pointermove", this.onDragMove, true);
+ // we only care about whether the column is shifted to the side
const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+ // get the dimensions of the smallest rectangle that bounds the header
const rect = this._header!.current!.getBoundingClientRect();
const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+ // get whether the column was dragged before or after where it is now
const before = x[0] < bounds[0];
const colDragData = de.complete.columnDragData;
+ // if there is colDragData, which happen when the drag is complete, reorder the columns according to the established variables
if (colDragData) {
e.stopPropagation();
this.props.reorderColumns(colDragData.colKey, this.props.columnValue, before, this.props.allColumns);
@@ -85,8 +100,10 @@ export class MovableColumn extends React.Component {
document.removeEventListener("pointermove", onRowMove);
document.removeEventListener('pointerup', onRowUp);
};
+ // if the left mouse button is the one being held
if (e.buttons === 1) {
const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+ // If the movemnt of the drag exceeds the sensitivity value
if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
document.removeEventListener("pointermove", this.onPointerMove);
e.stopPropagation();
@@ -105,6 +122,7 @@ export class MovableColumn extends React.Component {
onPointerDown = (e: React.PointerEvent, ref: React.RefObject) => {
this._dragRef = ref;
const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY);
+ // If the cell thing dragged is not being edited
if (!(e.target as any)?.tagName.includes("INPUT")) {
this._startDragPosition = { x: dx, y: dy };
document.addEventListener("pointermove", this.onPointerMove);
--
cgit v1.2.3-70-g09d2
From c5e96c72fcf149b9bcfe5f7f7a9c714de1d5fd9a Mon Sep 17 00:00:00 2001
From: 0x85FB9C51 <77808164+0x85FB9C51@users.noreply.github.com>
Date: Wed, 25 Aug 2021 16:58:57 -0400
Subject: added comment, fixed path issue
---
.../collectionSchema/CollectionSchemaCells.tsx | 239 +++++++++++----------
.../collectionSchema/CollectionSchemaHeaders.tsx | 2 +-
2 files changed, 126 insertions(+), 115 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index f7dfaaeb4..c8638dd12 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -26,7 +26,7 @@ import { SnappingManager } from "../../../util/SnappingManager";
import { undoBatch } from "../../../util/UndoManager";
import '../../../views/DocumentDecorations.scss';
import { EditableView } from "../../EditableView";
-import { MAX_ROW_HEIGHT } from '../../globalCssVariables.scss';
+import { MAX_ROW_HEIGHT } from '../../../../client/views/globalCssVariables.scss';
import { DocumentIconContainer } from "../../nodes/DocumentIcon";
import { OverlayView } from "../../OverlayView";
import "./CollectionSchemaView.scss";
@@ -38,27 +38,35 @@ export interface CellProps {
row: number;
col: number;
rowProps: CellInfo;
+ // currently unused
CollectionView: Opt;
+ // currently unused
ContainingCollection: Opt;
Document: Doc;
+ // column name
fieldKey: string;
+ // currently unused
renderDepth: number;
+ // called when a button is pressed on the node itself
addDocTab: (document: Doc, where: string) => boolean;
pinToPres: (document: Doc) => void;
moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined,
addDocument: (document: Doc | Doc[]) => boolean) => boolean;
isFocused: boolean;
changeFocusedCellByIndex: (row: number, col: number) => void;
+ // set whether the cell is in the isEditing mode
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;
+ // currnetly unused
showDoc: (doc: Doc | undefined, dataDoc?: any, screenX?: number, screenY?: number) => void;
}
@observer
export class CollectionSchemaCell extends React.Component {
+ // return a field key that is corrected for whether it COMMENT
public static resolvedFieldKey(column: string, rowDoc: Doc) {
const fieldKey = column;
if (fieldKey.startsWith("*")) {
@@ -72,7 +80,9 @@ export class CollectionSchemaCell extends React.Component {
@observable protected _isEditing: boolean = false;
protected _focusRef = React.createRef();
protected _rowDoc = this.props.rowProps.original;
+ // Gets the serialized data in proto form of the base proto that this document's proto inherits from
protected _rowDataDoc = Doc.GetProto(this.props.rowProps.original);
+ // methods for dragging and dropping
protected _dropDisposer?: DragManager.DragDropDisposer;
@observable contents: string = "";
@@ -81,6 +91,7 @@ export class CollectionSchemaCell extends React.Component {
@action
onKeyDown = (e: KeyboardEvent): void => {
+ // If a cell is editable and clicked, hitting enter shoudl allow the user to edit it
if (this.props.isFocused && this.props.isEditable && e.keyCode === KeyCodes.ENTER) {
document.removeEventListener("keydown", this.onKeyDown);
this._isEditing = true;
@@ -90,7 +101,11 @@ export class CollectionSchemaCell extends React.Component {
@action
isEditingCallback = (isEditing: boolean): void => {
+ // a general method that takes a boolean that determines whether the cell should be in
+ // is-editing mode
+ // remove the event listener if it's there
document.removeEventListener("keydown", this.onKeyDown);
+ // it's not already in is-editing mode, re-add the event listener
isEditing && document.addEventListener("keydown", this.onKeyDown);
this._isEditing = isEditing;
this.props.setIsEditing(isEditing);
@@ -99,12 +114,16 @@ export class CollectionSchemaCell extends React.Component {
@action
onPointerDown = async (e: React.PointerEvent): Promise => {
+ // pan to the cell
this.onItemDown(e);
+ // focus on it
this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
this.props.setPreviewDoc(this.props.rowProps.original);
+ // console.log("click cell");
let url: string;
if (url = StrCast(this.props.rowProps.row.href)) {
+ // opens up the the doc in a new window, blurring the old one
try {
new URL(url);
const temp = window.open(url)!;
@@ -119,18 +138,25 @@ export class CollectionSchemaCell extends React.Component {
@undoBatch
applyToDoc = (doc: Doc, row: number, col: number, run: (args?: { [name: string]: any }) => any) => {
+ // apply a specified change to the cell
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;
+ // change what is rendered to this new changed cell content
doc[this.renderFieldKey] = res.result;
return true;
+ // return whether the change was successful
}
private drop = (e: Event, de: DragManager.DropEvent) => {
+ // if the drag has data at its completion
if (de.complete.docDragData) {
+ // if only one doc was dragged
if (de.complete.docDragData.draggedDocuments.length === 1) {
+ // update the renderFieldKey
this._rowDataDoc[this.renderFieldKey] = de.complete.docDragData.draggedDocuments[0];
}
else {
+ // create schema document reflecting the new column arrangement
const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.complete.docDragData.draggedDocuments, {});
this._rowDataDoc[this.renderFieldKey] = coll;
}
@@ -139,7 +165,9 @@ export class CollectionSchemaCell extends React.Component {
}
protected dropRef = (ele: HTMLElement | null) => {
+ // if the drop disposer is not undefined, run its function
this._dropDisposer?.();
+ // if ele is not null, give ele a non-undefined drop disposer
ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)));
}
@@ -163,33 +191,46 @@ export class CollectionSchemaCell extends React.Component {
return {contents ? contents?.valueOf() : "undefined"};
}
- @computed get renderFieldKey() { return CollectionSchemaCell.resolvedFieldKey(this.props.rowProps.column.id!, this.props.rowProps.original); }
+ @computed get renderFieldKey() {
+ // gets the resolved field key of this cell
+ return CollectionSchemaCell.resolvedFieldKey(this.props.rowProps.column.id!, this.props.rowProps.original);
+ }
+
onItemDown = async (e: React.PointerEvent) => {
+ // if the document is a document used to change UI for search results in schema view
if (this.props.Document._searchDoc) {
const aliasdoc = await SearchUtil.GetAliasesOfDocument(this._rowDataDoc);
const targetContext = aliasdoc.length <= 0 ? undefined : Cast(aliasdoc[0].context, Doc, null);
+ // Jump to the this document
DocumentManager.Instance.jumpToDocument(this._rowDoc, false, emptyFunction, targetContext,
undefined, undefined, undefined, () => this.props.setPreviewDoc(this._rowDoc));
}
}
+
renderCellWithType(type: string | undefined) {
const dragRef: React.RefObject = React.createRef();
+ // the column
const fieldKey = this.renderFieldKey;
+ // the exact cell
const field = this._rowDoc[fieldKey];
const onPointerEnter = (e: React.PointerEvent): void => {
+ // e.buttons === 1 means the left moue pointer is down
if (e.buttons === 1 && SnappingManager.GetIsDragging() && (type === "document" || type === undefined)) {
dragRef.current!.className = "collectionSchemaView-cellContainer doc-drag-over";
}
};
const onPointerLeave = (e: React.PointerEvent): void => {
+ // change the class name to indicate that the cell is no longer being dragged
dragRef.current!.className = "collectionSchemaView-cellContainer";
};
let contents = Field.toString(field as Field);
+ // display 2 hyphens instead of a blank box for empty cells
contents = contents === "" ? "--" : contents;
+ // classname reflects the tatus of the cell
let className = "collectionSchemaView-cellWrapper";
if (this._isEditing) className += " editing";
if (this.props.isFocused && this.props.isEditable) className += " focused";
@@ -197,72 +238,27 @@ export class CollectionSchemaCell extends React.Component {
const positions = [];
if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
+ // term is ...promise pending... if the field is a Promise, otherwise it is the cell's contents
let term = (field instanceof Promise) ? "...promise pending..." : contents.toLowerCase();
const search = StrCast(this.props.Document._searchString).toLowerCase();
let start = term.indexOf(search);
let tally = 0;
+ // if search is found in term
if (start !== -1) {
positions.push(start);
}
+ // if search is found in term, continue finding all instances of search in term
while (start < contents?.length && start !== -1) {
term = term.slice(start + search.length + 1);
tally += start + search.length + 1;
start = term.indexOf(search);
positions.push(tally + start);
}
+ // remove the last position
if (positions.length > 1) {
positions.pop();
}
}
-
- // handles input procedures for string cells
- let stringInput = (value: string, retVal: boolean): void => {
- let valueSansQuotes = value;
- if (this._isEditing) {
- const vsqLength = valueSansQuotes.length;
- // get rid of outer quotes
- valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
- valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength);
- }
- let inputAsString = '"';
- // escape any quotes in the string
- for (const i of valueSansQuotes) {
- if (i == '"') {
- inputAsString += '\\"';
- } else {
- inputAsString += i;
- }
- }
- // add a closing quote
- inputAsString += '"';
- //two options here: we can strip off outer quotes or we can figure out what's going on with the script
- const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
- // handles input procedure for number cells
- let numberInput = (value: string, retVal: boolean): void => {
- const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
- // if commas are not stripped, the parser only considers the numbers after the last comma
- let inputSansCommas = "";
- for (let s of inputscript) {
- if (!(s == ",")) {
- inputSansCommas += s;
- }
- }
- const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
- // handles input procedure for boolean cells
- let boolInput = (value: string, retVal: boolean): void => {
- const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
- const changeMade = value.length !== value.length || value.length - 2 !== value.length
- script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
- }
-
const placeholder = type === "number" ? "0" : contents === "" ? "--" : "undefined";
return (
{
} else {
// check if the input is a number
let inputIsNum = true;
- for (let s of value) {
- if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
+ for (const s of value) {
+ if (isNaN(parseInt(s)) && !(s === ".") && !(s === ",")) {
inputIsNum = false;
}
}
-
- let contentsAreNum = true;
- for (let s of contents) {
- if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) {
- contentsAreNum = false;
- }
- }
// check if the input is a boolean
- let inputIsBool: boolean = value == "false" || value == "true";
- let contentsAreBool: boolean = contents == "false" || contents == "true";
-
- if (type == undefined) {
- // what to do in the case
- if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
- // if it's not a number, it's a string, and should be processed as such
- // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
- // after each edit
- stringInput(value, retVal);
- // handle numbers and expressions
- } else if (inputIsNum || value.startsWith("=")) {
- numberInput(value, retVal);
- // handle booleans
- } else if (inputIsBool) {
- boolInput(value, retVal);
+ const inputIsBool: boolean = value === "false" || value === "true";
+ // what to do in the case
+ if (!inputIsNum && !inputIsBool && !value.startsWith("=")) {
+ // if it's not a number, it's a string, and should be processed as such
+ // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically
+ // after each edit
+ let valueSansQuotes = value;
+ if (this._isEditing) {
+ const vsqLength = valueSansQuotes.length;
+ // get rid of outer quotes
+ valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0,
+ valueSansQuotes.charAt(vsqLength - 1) === "\"" ? vsqLength - 1 : vsqLength);
}
- // if the cell type is a string
- } else if (type == "string") {
- stringInput(value, retVal);
- // if the cell type is a number
- } else if (type == "number") {
- if (inputIsNum) {
- numberInput(value, retVal);
- } else if (!contentsAreNum) {
- stringInput("", retVal);
+ let inputAsString = '"';
+ // escape any quotes in the string
+ for (const i of valueSansQuotes) {
+ if (i === '"') {
+ inputAsString += '\\"';
+ } else {
+ inputAsString += i;
+ }
}
- // if the cell type is a boolean
- } else if (type == "boolean") {
- if (inputIsBool) {
- boolInput(value, retVal);
- } else if (!contentsAreBool) {
- stringInput("", retVal);
+ // add a closing quote
+ inputAsString += '"';
+ //two options here: we can strip off outer quotes or we can figure out what's going on with the script
+ const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length;
+ // change it if a change is made, otherwise, just compile using the old cell conetnts
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ // handle numbers and expressions
+ } else if (inputIsNum || value.startsWith("=")) {
+ //TODO: make accept numbers
+ const inputscript = value.substring(value.startsWith("=") ? 1 : 0);
+ // if commas are not stripped, the parser only considers the numbers after the last comma
+ let inputSansCommas = "";
+ for (const s of inputscript) {
+ if (!(s === ",")) {
+ inputSansCommas += s;
+ }
}
+ const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length;
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
+ // handle booleans
+ } else if (inputIsBool) {
+ const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+ const changeMade = value.length !== value.length || value.length - 2 !== value.length;
+ script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run));
}
}
if (retVal) {
@@ -351,6 +354,7 @@ export class CollectionSchemaCell extends React.Component {
return retVal;
})}
OnFillDown={async (value: string) => {
+ // computes all of the value preceded by :=
const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
script.compiled && DocListCast(this.props.Document[this.props.fieldKey]).
forEach((doc, i) => value.startsWith(":=") ?
@@ -381,7 +385,10 @@ export class CollectionSchemaStringCell extends CollectionSchemaCell { render()
@observer
export class CollectionSchemaDateCell extends CollectionSchemaCell {
- @computed get _date(): Opt { return this._rowDoc[this.renderFieldKey] instanceof DateField ? DateCast(this._rowDoc[this.renderFieldKey]) : undefined; }
+ @computed get _date(): Opt {
+ // if the cell is a date field, cast then contents to a date. Otherrwwise, make the contents undefined.
+ return this._rowDoc[this.renderFieldKey] instanceof DateField ? DateCast(this._rowDoc[this.renderFieldKey]) : undefined;
+ }
@action
handleChange = (date: any) => {
@@ -394,16 +401,13 @@ export class CollectionSchemaDateCell extends CollectionSchemaCell {
//}
}
- // If the cell is not clicked on, render the date normally. Otherwise, render a date picker.
render() {
- return !this.props.isFocused ? {this._date ? Field.toString(this._date as Field) : "--"} :
-
+ return !this.props.isFocused ? {this._date ? Field.toString(this._date as Field) : "--"} :
+ this.handleChange(date)}
+ onChange={date => this.handleChange(date)}
+ />;
}
}
@@ -423,8 +427,9 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
typecheck: true,
transformer: DocumentIconContainer.getTransformer()
});
-
+ // compile the script
const results = script.compiled && script.run();
+ // if the script was compiled and run
if (results && results.success) {
this._rowDoc[this.renderFieldKey] = results.result;
return true;
@@ -442,6 +447,7 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
@action
isEditingCallback = (isEditing: boolean): void => {
+ // the isEditingCallback from a general CollectionSchemaCell
document.removeEventListener("keydown", this.onKeyDown);
isEditing && document.addEventListener("keydown", this.onKeyDown);
this._isEditing = isEditing;
@@ -450,6 +456,7 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
}
render() {
+ // if there's a doc, render it
return !this._doc ? this.renderCellWithType("document") :
Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url).filter(url => url).map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
+ // If there is a path, follow it; otherwise, follow a link to a default image icon
const url = paths.length ? paths : [Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png")];
- const aspect = Doc.NativeAspect(this._rowDoc);
- let width = Math.min(75, this.props.rowProps.width);
- const height = Math.min(75, width / aspect);
- width = height * aspect;
+ const aspect = Doc.NativeAspect(this._rowDoc); // aspect ratio
+ let width = Math.min(75, this.props.rowProps.width); // get a with that is no smaller than 75px
+ const height = Math.min(75, width / aspect); // get a height either proportional to that or 75 px
+ width = height * aspect; // increase the width of the image if necessary to maintain proportionality
const reference = React.createRef();
return
@@ -523,13 +531,13 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
@computed get _field() { return this._rowDoc[this.renderFieldKey]; }
@computed get _optionsList() { return this._field as List; }
- @observable private _opened = false;
+ @observable private _opened = false; // whether the list is opened
@observable private _text = "select an item";
- @observable private _selectedNum = 0;
+ @observable private _selectedNum = 0; // the index of the list item selected
@action
onSetValue = (value: string) => {
- // change if its a document
+ // change if it's a document
this._optionsList[this._selectedNum] = this._text = value;
(this._field as List).splice(this._selectedNum, 1, value);
@@ -537,6 +545,7 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
@action
onSelected = (element: string, index: number) => {
+ // if an item is selected, the private variables should update to reflect this
this._text = element;
this._selectedNum = index;
}
@@ -550,6 +559,7 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
const link = false;
const reference = React.createRef();
+ // if the list is not opened, don't display it; otherwise, do.
if (this._optionsList?.length) {
const options = !this._opened ? (null) :
@@ -617,6 +627,7 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
@observer
export class CollectionSchemaButtons extends CollectionSchemaCell {
+ // the navigation buttons for schema view when it is used for search.
render() {
return !this.props.Document._searchDoc || ![DocumentType.PDF, DocumentType.RTF].includes(StrCast(this._rowDoc.type) as DocumentType) ? <>> :
@@ -628,4 +639,4 @@ export class CollectionSchemaButtons extends CollectionSchemaCell {
;
}
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index b2115b22e..2da9409f2 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -25,6 +25,7 @@ export interface AddColumnHeaderProps {
@observer
export class CollectionSchemaAddColumnHeader extends React.Component {
+ // the button that allows the user to add a column
render() {
return (
@@ -32,7 +33,6 @@ export class CollectionSchemaAddColumnHeader extends React.Component