From 6c3482a17839928818abaf82bc5be3c794174f4d Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 20 Apr 2023 11:26:48 -0400
Subject: allow repl to edit documents

---
 src/client/views/nodes/KeyValueBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/KeyValueBox.tsx')

diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 57018fb93..2f5760699 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -75,7 +75,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         value = eq ? value.substring(1) : value;
         const dubEq = value.startsWith(':=') ? 'computed' : value.startsWith('$=') ? 'script' : false;
         value = dubEq ? value.substring(2) : value;
-        const options: ScriptOptions = { addReturn: true, typecheck: false, params: { this: Doc.name, self: Doc.name, _last_: 'any', _readOnly_: 'boolean' }, editable: false };
+        const options: ScriptOptions = { addReturn: true, typecheck: false, params: { this: Doc.name, self: Doc.name, _last_: 'any', _readOnly_: 'boolean' }, editable: true };
         if (dubEq) options.typecheck = false;
         const script = CompileScript(value, options);
         return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq };
-- 
cgit v1.2.3-70-g09d2


From 223dde9f35408c229a4da583083d10cbf81fc264 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 27 Apr 2023 22:23:42 -0400
Subject: fixed some undo issues with schema fill down.  added bool cell view. 
 added UI for showing/setting values on layout vs data docs.

---
 .../collections/collectionSchema/SchemaRowBox.tsx  |   3 +-
 .../collectionSchema/SchemaTableCell.tsx           | 156 ++++++++++++---------
 src/client/views/nodes/KeyValueBox.tsx             |   2 -
 3 files changed, 89 insertions(+), 72 deletions(-)

(limited to 'src/client/views/nodes/KeyValueBox.tsx')

diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 9772ce118..ca9e0bda0 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -90,6 +90,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
     deselectCell = () => this.schemaView?.deselectCell();
     selectedCell = () => this.schemaView?._selectedCell;
     setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false;
+    columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth);
     render() {
         return (
             <div
@@ -131,7 +132,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             Document={this.rootDoc}
                             col={index}
                             fieldKey={key}
-                            columnWidth={this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth}
+                            columnWidth={this.columnWidth(index)}
                             isRowActive={this.props.isContentActive}
                             getFinfo={this.getFinfo}
                             selectCell={this.selectCell}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 4f4986b90..1fa4312e1 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -5,10 +5,13 @@ import { extname } from 'path';
 import DatePicker from 'react-datepicker';
 import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field } from '../../../../fields/Doc';
-import { Cast, DateCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DateCast } from '../../../../fields/Types';
 import { ImageField } from '../../../../fields/URLField';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero, Utils } from '../../../../Utils';
+import { FInfo } from '../../../documents/Documents';
+import { dropActionType } from '../../../util/DragManager';
 import { Transform } from '../../../util/Transform';
+import { undoBatch } from '../../../util/UndoManager';
 import { EditableView } from '../../EditableView';
 import { Colors } from '../../global/globalEnums';
 import { FieldView, FieldViewProps } from '../../nodes/FieldView';
@@ -16,7 +19,6 @@ import { KeyValueBox } from '../../nodes/KeyValueBox';
 import { DefaultStyleProvider } from '../../StyleProvider';
 import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSchemaView';
 import './CollectionSchemaView.scss';
-import { FInfo } from '../../../documents/Documents';
 
 export interface SchemaTableCellProps {
     Document: Doc;
@@ -25,7 +27,7 @@ export interface SchemaTableCellProps {
     selectCell: (doc: Doc, col: number) => void;
     selectedCell: () => [Doc, number] | undefined;
     fieldKey: string;
-    columnWidth: number;
+    columnWidth: () => number;
     isRowActive: () => boolean | undefined;
     getFinfo: (fieldKey: string) => FInfo | undefined;
     setColumnValues: (field: string, value: string) => boolean;
@@ -33,95 +35,78 @@ export interface SchemaTableCellProps {
 
 @observer
 export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
-    private _editorRef: EditableView | null = null;
-
-    @computed get readOnly() {
-        return this.props.getFinfo(this.props.fieldKey)?.readOnly ?? false;
-    }
-
-    @computed get selected() {
-        const selected: [Doc, number] | undefined = this.props.selectedCell();
-        return this.props.isRowActive() && selected && selected[0] == this.props.Document && selected[1] == this.props.col;
+    public static colRowHeightFunc() {
+        return CollectionSchemaView._rowHeight;
     }
-
-    componentDidUpdate() {
-        if (!this.selected) {
-            this._editorRef?.setIsFocused(false);
-            document.removeEventListener('keydown', this.onKeyDown);
-        } else if (!this.readOnly) {
-            document.addEventListener('keydown', this.onKeyDown);
-        }
-    }
-
-    @action
-    onKeyDown = (e: KeyboardEvent) => {
-        e.stopPropagation();
-        if (e.key == 'Enter') {
-            this._editorRef?.setIsFocused(true);
-        }
-        if (e.key == 'Escape') {
-            this.props.deselectCell();
+    public static renderProps(props: SchemaTableCellProps) {
+        const { Document, fieldKey, getFinfo, columnWidth, isRowActive } = props;
+        let protoCount = 0;
+        let doc: Doc | undefined = Document;
+        while (doc) {
+            if (Object.keys(doc).includes(fieldKey.replace(/^_/, ''))) {
+                break;
+            }
+            protoCount++;
+            doc = doc.proto;
         }
-    };
-    colWidthFunc = () => this.props.columnWidth;
-    colRowHeightFunc = () => CollectionSchemaView._rowHeight;
-    @computed get defaultCellContent() {
-        const props: FieldViewProps = {
-            Document: this.props.Document,
+        const parenCount = Math.max(0, protoCount - 1);
+        const color = protoCount === 0 || (fieldKey.startsWith('_') && Document[fieldKey] === undefined) ? 'black' : 'blue';
+        const textDecoration = color !== 'black' && parenCount ? 'underline' : '';
+        const fieldProps: FieldViewProps = {
             docFilters: returnEmptyFilter,
             docRangeFilters: returnEmptyFilter,
             searchFilterDocs: returnEmptyDoclist,
             styleProvider: DefaultStyleProvider,
             docViewPath: returnEmptyDoclist,
-            fieldKey: this.props.fieldKey,
             rootSelected: returnFalse,
             isSelected: returnFalse,
             setHeight: returnFalse,
             select: emptyFunction,
-            dropAction: 'alias',
+            dropAction: 'alias' as dropActionType,
             bringToFront: emptyFunction,
             renderDepth: 1,
             isContentActive: returnFalse,
             whenChildContentsActiveChanged: emptyFunction,
             ScreenToLocalTransform: Transform.Identity,
             focus: emptyFunction,
-            PanelWidth: this.colWidthFunc,
-            PanelHeight: this.colRowHeightFunc,
             addDocTab: returnFalse,
             pinToPres: returnZero,
+            Document,
+            fieldKey,
+            PanelWidth: columnWidth,
+            PanelHeight: SchemaTableCell.colRowHeightFunc,
         };
-        let protoCount = 0;
-        let doc: Doc | undefined = this.props.Document;
-        while (doc) {
-            if (Object.keys(doc).includes(this.props.fieldKey.replace(/^_/, ''))) {
-                break;
-            }
-            protoCount++;
-            doc = doc.proto;
-        }
-        const parenCount = Math.max(0, protoCount - 1);
-        const color = protoCount === 0 ? 'black' : 'blue';
+        const readOnly = getFinfo(fieldKey)?.readOnly ?? false;
+        const cursor = !readOnly ? 'text' : 'default';
+        const pointerEvents: 'all' | 'none' = !readOnly && isRowActive() ? 'all' : 'none';
+        return { color, textDecoration, fieldProps, cursor, pointerEvents };
+    }
+
+    @computed get selected() {
+        const selected: [Doc, number] | undefined = this.props.selectedCell();
+        return this.props.isRowActive() && selected?.[0] === this.props.Document && selected[1] === this.props.col;
+    }
+
+    @computed get defaultCellContent() {
+        const { color, textDecoration, fieldProps } = SchemaTableCell.renderProps(this.props);
 
         return (
             <div
                 className="schemacell-edit-wrapper"
                 style={{
                     color,
-                    textDecoration: parenCount ? 'underline' : undefined,
-                    cursor: !this.readOnly ? 'text' : 'default',
-                    pointerEvents: !this.readOnly && this.props.isRowActive() ? 'all' : 'none',
+                    textDecoration,
                 }}>
                 <EditableView
-                    ref={ref => (this._editorRef = ref)}
-                    contents={<FieldView {...props} />}
+                    contents={<FieldView {...fieldProps} />}
+                    editing={this.selected ? undefined : false}
                     GetValue={() => Field.toKeyValueString(this.props.Document, this.props.fieldKey)}
-                    SetValue={(value: string, shiftDown?: boolean, enterKey?: boolean) => {
+                    SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => {
                         if (shiftDown && enterKey) {
                             this.props.setColumnValues(this.props.fieldKey, value);
                         }
                         return KeyValueBox.SetField(this.props.Document, this.props.fieldKey, value);
-                    }}
-                    editing={this.selected ? undefined : false}
+                    })}
                 />
             </div>
         );
@@ -146,13 +131,12 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
 
     get content() {
         const cellType: ColumnType = this.getCellType;
+        // prettier-ignore
         switch (cellType) {
-            case ColumnType.Image:
-                return <SchemaImageCell {...this.props} />;
-            case ColumnType.Date:
-            // return <SchemaDateCell {...this.props} />;
-            default:
-                return this.defaultCellContent;
+            case ColumnType.Image: return <SchemaImageCell {...this.props} />;
+            case ColumnType.Boolean: return <SchemaBoolCell {...this.props} />;
+            case ColumnType.Date: // return <SchemaDateCell {...this.props} />;
+            default:  return this.defaultCellContent;
         }
     }
 
@@ -160,10 +144,8 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
         return (
             <div
                 className="schema-table-cell"
-                onPointerDown={action(e => {
-                    if (!this.selected) this.props.selectCell(this.props.Document, this.props.col);
-                })}
-                style={{ width: this.props.columnWidth, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}>
+                onPointerDown={action(e => !this.selected && this.props.selectCell(this.props.Document, this.props.col))}
+                style={{ width: this.props.columnWidth(), border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}>
                 {this.content}
             </div>
         );
@@ -257,3 +239,39 @@ export class SchemaDateCell extends React.Component<SchemaTableCellProps> {
         return <DatePicker dateFormat={'Pp'} selected={this.date.date} onChange={(date: any) => this.handleChange(date)} />;
     }
 }
+@observer
+export class SchemaBoolCell extends React.Component<SchemaTableCellProps> {
+    @computed get selected() {
+        const selected: [Doc, number] | undefined = this.props.selectedCell();
+        return this.props.isRowActive() && selected?.[0] === this.props.Document && selected[1] === this.props.col;
+    }
+    render() {
+        const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this.props);
+        return (
+            <div className="schemaBoolCell" style={{ display: 'flex', color, textDecoration, cursor, pointerEvents }}>
+                <input
+                    style={{ marginRight: 4 }}
+                    type="checkbox"
+                    checked={BoolCast(this.props.Document[this.props.fieldKey])}
+                    onChange={undoBatch((value: React.ChangeEvent<HTMLInputElement> | undefined) => {
+                        if ((value?.nativeEvent as any).shiftKey) {
+                            this.props.setColumnValues(this.props.fieldKey, (color === 'black' ? '=' : '') + value?.target?.checked.toString());
+                        }
+                        KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
+                    })}
+                />
+                <EditableView
+                    contents={<FieldView {...fieldProps} />}
+                    editing={this.selected ? undefined : false}
+                    GetValue={() => (color === 'black' ? '=' : '') + Field.toKeyValueString(this.props.Document, this.props.fieldKey)}
+                    SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => {
+                        if (shiftDown && enterKey) {
+                            this.props.setColumnValues(this.props.fieldKey, value);
+                        }
+                        return KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value);
+                    })}
+                />
+            </div>
+        );
+    }
+}
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 57018fb93..11220c300 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -20,14 +20,12 @@ import { ImageBox } from './ImageBox';
 import './KeyValueBox.scss';
 import { KeyValuePair } from './KeyValuePair';
 import React = require('react');
-import e = require('express');
 
 export type KVPScript = {
     script: CompiledScript;
     type: 'computed' | 'script' | false;
     onDelegate: boolean;
 };
-
 @observer
 export class KeyValueBox extends React.Component<FieldViewProps> {
     public static LayoutString() {
-- 
cgit v1.2.3-70-g09d2


From becc884883df07635f4619f908747598b3eb86ee Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 28 Apr 2023 09:57:53 -0400
Subject: added RTF cell type for schema.  fixed formatting DateFields so that
 they can be set from kvp/schema.  prevented on infinite loop possibility when
 setting proto to itself.

---
 src/Utils.ts                                       |  3 ++
 .../collectionSchema/CollectionSchemaView.tsx      | 15 ++++----
 .../collectionSchema/SchemaTableCell.tsx           | 40 ++++++++++++++++------
 src/client/views/nodes/KeyValueBox.tsx             |  2 +-
 src/fields/DateField.ts                            | 14 ++++----
 5 files changed, 48 insertions(+), 26 deletions(-)

(limited to 'src/client/views/nodes/KeyValueBox.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 0c7deaf5d..73de6d754 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -513,6 +513,9 @@ export function returnTrue() {
     return true;
 }
 
+export function returnIgnore(): 'ignore' {
+    return 'ignore';
+}
 export function returnAlways(): 'always' {
     return 'always';
 }
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 3f7e037d4..a59d7e5a3 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -8,7 +8,7 @@ import { Id } from '../../../../fields/FieldSymbols';
 import { List } from '../../../../fields/List';
 import { listSpec } from '../../../../fields/Schema';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnDefault, returnEmptyDoclist, returnEmptyString, returnFalse, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
+import { emptyFunction, returnDefault, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
 import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { DragManager } from '../../../util/DragManager';
@@ -32,6 +32,7 @@ export enum ColumnType {
     Boolean,
     Date,
     Image,
+    RTF,
     Any,
 }
 
@@ -41,6 +42,7 @@ export const FInfotoColType: { [key: string]: ColumnType } = {
     boolean: ColumnType.Boolean,
     date: ColumnType.Date,
     image: ColumnType.Image,
+    rtf: ColumnType.RTF,
 };
 
 const defaultColumnKeys: string[] = ['title', 'type', 'author', 'creationDate', 'text'];
@@ -410,14 +412,10 @@ export class CollectionSchemaView extends CollectionSubView() {
     };
 
     @action
-    selectCell = (doc: Doc, index: number) => {
-        this._selectedCell = [doc, index];
-    };
+    selectCell = (doc: Doc, index: number) => (this._selectedCell = [doc, index]);
 
     @action
-    deselectCell = () => {
-        this._selectedCell = undefined;
-    };
+    deselectCell = () => (this._selectedCell = undefined);
 
     sortedSelectedDocs = () => this.sortedDocs.docs.filter(doc => this._selectedDocs.includes(doc));
 
@@ -891,6 +889,7 @@ export class CollectionSchemaView extends CollectionSubView() {
                                 dontCenter={'y'}
                                 onClickScriptDisable="always"
                                 focus={emptyFunction}
+                                defaultDoubleClick={returnIgnore}
                                 renderDepth={this.props.renderDepth + 1}
                                 rootSelected={this.rootSelected}
                                 PanelWidth={this.previewWidthFunc}
@@ -949,7 +948,7 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP
                                 PanelHeight={this.rowHeightFunc}
                                 styleProvider={DefaultStyleProvider}
                                 waitForDoubleClickToClick={returnNever}
-                                defaultDoubleClick={returnDefault}
+                                defaultDoubleClick={returnIgnore}
                                 enableDragWhenActive={true}
                                 onClickScriptDisable="always"
                                 focus={this.props.schema.focusDocument}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index f17f4a73c..712bd4491 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -5,7 +5,7 @@ import { extname } from 'path';
 import DatePicker from 'react-datepicker';
 import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field } from '../../../../fields/Doc';
-import { BoolCast, Cast, DateCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DateCast, FieldValue } from '../../../../fields/Types';
 import { ImageField } from '../../../../fields/URLField';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero, Utils } from '../../../../Utils';
 import { FInfo } from '../../../documents/Documents';
@@ -19,6 +19,8 @@ import { KeyValueBox } from '../../nodes/KeyValueBox';
 import { DefaultStyleProvider } from '../../StyleProvider';
 import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSchemaView';
 import './CollectionSchemaView.scss';
+import { RichTextField } from '../../../../fields/RichTextField';
+import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 
 export interface SchemaTableCellProps {
     Document: Doc;
@@ -113,18 +115,18 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
     }
 
     get getCellType() {
-        const columnTypeStr = this.props.getFinfo(this.props.fieldKey)?.fieldType;
-        if (columnTypeStr) {
-            if (columnTypeStr in FInfotoColType) {
-                return FInfotoColType[columnTypeStr];
-            }
-
-            return ColumnType.Any;
-        }
-
         const cellValue = this.props.Document[this.props.fieldKey];
         if (cellValue instanceof ImageField) return ColumnType.Image;
         if (cellValue instanceof DateField) return ColumnType.Date;
+        if (cellValue instanceof RichTextField) return ColumnType.RTF;
+        if (typeof cellValue === 'number') return ColumnType.Any;
+        if (typeof cellValue === 'string') return ColumnType.Any;
+        if (typeof cellValue === 'boolean') return ColumnType.Any;
+
+        const columnTypeStr = this.props.getFinfo(this.props.fieldKey)?.fieldType;
+        if (columnTypeStr && columnTypeStr in FInfotoColType) {
+            return FInfotoColType[columnTypeStr];
+        }
 
         return ColumnType.Any;
     }
@@ -135,6 +137,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
         switch (cellType) {
             case ColumnType.Image: return <SchemaImageCell {...this.props} />;
             case ColumnType.Boolean: return <SchemaBoolCell {...this.props} />;
+            case ColumnType.RTF: return <SchemaRTFCell {...this.props} />;
             case ColumnType.Date: // return <SchemaDateCell {...this.props} />;
             default:  return this.defaultCellContent;
         }
@@ -240,6 +243,23 @@ export class SchemaDateCell extends React.Component<SchemaTableCellProps> {
     }
 }
 @observer
+export class SchemaRTFCell extends React.Component<SchemaTableCellProps> {
+    @computed get selected() {
+        const selected: [Doc, number] | undefined = this.props.selectedCell();
+        return this.props.isRowActive() && selected?.[0] === this.props.Document && selected[1] === this.props.col;
+    }
+    selectedFunc = () => this.selected;
+    render() {
+        const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this.props);
+        fieldProps.isContentActive = this.selectedFunc;
+        return (
+            <div className="schemaRTFCell" style={{ display: 'flex', fontStyle: this.selected ? undefined : 'italic', width: '100%', height: '100%', position: 'relative', color, textDecoration, cursor, pointerEvents }}>
+                {this.selected ? <FormattedTextBox {...fieldProps} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+            </div>
+        );
+    }
+}
+@observer
 export class SchemaBoolCell extends React.Component<SchemaTableCellProps> {
     @computed get selected() {
         const selected: [Doc, number] | undefined = this.props.selectedCell();
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index b54364332..e317de11e 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -96,7 +96,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
             }
             field = res.result;
         }
-        if (Field.IsField(field, true)) {
+        if (Field.IsField(field, true) && (key !== 'proto' || field !== target)) {
             target[key] = field;
             return true;
         }
diff --git a/src/fields/DateField.ts b/src/fields/DateField.ts
index 26f51b2d3..2ea619bd9 100644
--- a/src/fields/DateField.ts
+++ b/src/fields/DateField.ts
@@ -1,11 +1,11 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, date } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString } from "./FieldSymbols";
-import { scriptingGlobal, ScriptingGlobals } from "../client/util/ScriptingGlobals";
+import { Deserializable } from '../client/util/SerializationHelper';
+import { serializable, date } from 'serializr';
+import { ObjectField } from './ObjectField';
+import { Copy, ToScriptString, ToString } from './FieldSymbols';
+import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
 
 @scriptingGlobal
-@Deserializable("date")
+@Deserializable('date')
 export class DateField extends ObjectField {
     @serializable(date())
     readonly date: Date;
@@ -24,7 +24,7 @@ export class DateField extends ObjectField {
     }
 
     [ToScriptString]() {
-        return `new DateField(new Date(${this.date.toISOString()}))`;
+        return `new DateField(new Date("${this.date.toISOString()}"))`;
     }
     [ToString]() {
         return this.date.toLocaleString();
-- 
cgit v1.2.3-70-g09d2

