aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/KeyValueBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/KeyValueBox.tsx')
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx68
1 files changed, 43 insertions, 25 deletions
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 40c687b7e..aa66b5ba9 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -9,7 +9,7 @@ import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { DocCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { DocumentType } from '../../documents/DocumentTypes';
-import { Docs } from '../../documents/Documents';
+import { Docs, DocumentOptions } from '../../documents/Documents';
import { SetupDrag } from '../../util/DragManager';
import { CompiledScript } from '../../util/Scripting';
import { undoable } from '../../util/UndoManager';
@@ -22,6 +22,7 @@ import './KeyValueBox.scss';
import { KeyValuePair } from './KeyValuePair';
import { OpenWhere } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
+import { DocLayout } from '../../../fields/DocSymbols';
export type KVPScript = {
script: CompiledScript;
@@ -54,16 +55,12 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable private rows: KeyValuePair[] = [];
@observable _splitPercentage = 50;
- get fieldDocToLayout() {
- return DocCast(this.Document);
- }
-
@action
onEnterKey = (e: React.KeyboardEvent): void => {
if (e.key === 'Enter') {
e.stopPropagation();
- if (this._keyInput.current?.value && this._valInput.current?.value && this.fieldDocToLayout) {
- if (KeyValueBox.SetField(this.fieldDocToLayout, this._keyInput.current.value, this._valInput.current.value)) {
+ if (this._keyInput.current?.value && this._valInput.current?.value && this.Document) {
+ if (KeyValueBox.SetField(this.Document, this._keyInput.current.value, this._valInput.current.value)) {
this._keyInput.current.value = '';
this._valInput.current.value = '';
document.body.focus();
@@ -95,10 +92,11 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
return !script.compiled ? undefined : { script, type, onDelegate };
};
- public static ApplyKVPScript = (doc: Doc, key: string, kvpScript: KVPScript, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => {
+ public static ApplyKVPScript = (doc: Doc, keyIn: string, kvpScript: KVPScript, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => {
const { script, type, onDelegate } = kvpScript;
- // const target = onDelegate ? Doc.Layout(doc.layout) : Doc.GetProto(doc); // bcz: TODO need to be able to set fields on layout templates
- const target = forceOnDelegate || onDelegate || key.startsWith('_') ? doc : DocCast(doc.proto, doc);
+ const chooseDelegate = forceOnDelegate || onDelegate || keyIn.startsWith('_');
+ const key = chooseDelegate && keyIn.startsWith('$') ? keyIn.slice(1) : keyIn;
+ const target = chooseDelegate ? doc : DocCast(doc.proto, doc)!;
let field: FieldType | undefined;
switch (type) {
case 'computed': field = new ComputedField(script); break; // prettier-ignore
@@ -106,15 +104,15 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
default: {
const _setCacheResult_ = (value: FieldResult) => {
field = value as FieldType;
- if (setResult) setResult?.(value);
+ if (setResult) setResult(value);
else target[key] = field;
};
- const res = script.run({ this: Doc.Layout(doc), _setCacheResult_ }, console.log);
+ const res = script.run({ this: doc, _setCacheResult_ }, console.log);
if (!res.success) {
if (key) target[key] = script.originalScript;
return false;
}
- field === undefined && (field = res.result instanceof Array ? new List<FieldType>(res.result) : (typeof res.result === 'function' ? res.result.name : res.result as FieldType));
+ field === undefined && (field = res.result instanceof Array ? new List<FieldType>(res.result) : typeof res.result === 'function' ? res.result.name : (res.result as FieldType));
}
}
if (!key) return false;
@@ -125,10 +123,16 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
return false;
};
- public static SetField = undoable((doc: Doc, key: string, value: string, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => {
+ public static SetField = undoable((doc: Doc, key: string, value: string, forceOnDelegateIn?: boolean, setResult?: (value: FieldResult) => void) => {
const script = KeyValueBox.CompileKVPScript(value);
if (!script) return false;
- return KeyValueBox.ApplyKVPScript(doc, key, script, forceOnDelegate, setResult);
+ const ldoc = key.startsWith('_') ? doc[DocLayout] : doc;
+ const forceOnDelegate = forceOnDelegateIn || (ldoc !== doc && !value.startsWith('='));
+ // an '=' value redirects a key targeting the render template to the root document.
+ // also, if ldoc and doc are equal, allow redirecting to data document when not using an equal
+ // in either case, get rid of initial '_' which forces writing to layout
+ const setKey = value.startsWith('=') || ldoc === doc ? key.replace(/^_/, '') : key;
+ return KeyValueBox.ApplyKVPScript(doc, setKey, script, forceOnDelegate, setResult);
}, 'Set Doc Field');
onPointerDown = (e: React.PointerEvent): void => {
@@ -141,7 +145,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
rowHeight = () => 30;
@computed get createTable() {
- const doc = this.fieldDocToLayout;
+ const doc = this.Document;
if (!doc) {
return (
<tr>
@@ -149,25 +153,39 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
</tr>
);
}
- const realDoc = doc;
const ids: { [key: string]: string } = {};
const protos = Doc.GetAllPrototypes(doc);
protos.forEach(proto => {
Object.keys(proto).forEach(key => {
- if (!(key in ids) && realDoc[key] !== ComputedField.undefined) {
+ if (!(key in ids) && doc[key] !== ComputedField.undefined) {
ids[key] = key;
}
});
});
+ const docinfos = new DocumentOptions();
+
+ const layoutProtos = this.layoutDoc !== doc ? Doc.GetAllPrototypes(this.layoutDoc) : [];
+ layoutProtos.forEach(proto => {
+ Object.keys(proto)
+ .filter(key => !(key in ids) || docinfos['_' + key]) // if '_key' is in docinfos (as opposed to just 'key'), then the template Doc's value should be displayed instead of the root document's value
+ .map(key => '_' + key)
+ .forEach(key => {
+ if (doc[key] !== ComputedField.undefined) {
+ if (key.replace(/^_/, '') in ids) delete ids[key.replace(/^_/, '')];
+ ids[key] = key;
+ }
+ });
+ });
+
const rows: JSX.Element[] = [];
let i = 0;
const keys = Object.keys(ids).slice();
// for (const key of [...keys.filter(id => id !== 'layout' && !id.includes('_')).sort(), ...keys.filter(id => id === 'layout' || id.includes('_')).sort()]) {
const sortedKeys = keys.sort((a: string, b: string) => {
- const a_ = a.split('_')[0];
- const b_ = b.split('_')[0];
+ const a_ = a.replace(/^_/, '').split('_')[0];
+ const b_ = b.replace(/^_/, '').split('_')[0];
if (a_ < b_) return -1;
if (a_ > b_) return 1;
if (a === a_) return -1;
@@ -177,7 +195,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
sortedKeys.forEach(key => {
rows.push(
<KeyValuePair
- doc={realDoc}
+ doc={doc}
addDocTab={this._props.addDocTab}
PanelWidth={this._props.PanelWidth}
PanelHeight={this.rowHeight}
@@ -243,15 +261,15 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
getFieldView = () => {
const rows = this.rows.filter(row => row.isChecked);
if (rows.length > 1) {
- const parent = Docs.Create.StackingDocument([], { _layout_autoHeight: true, _width: 300, title: `field views for ${DocCast(this.Document).title}`, _chromeHidden: true });
+ const parent = Docs.Create.StackingDocument([], { _layout_autoHeight: true, _width: 300, title: `field views for ${this.Document.title}`, _chromeHidden: true });
rows.forEach(row => {
- const field = this.createFieldView(DocCast(this.Document), row);
+ const field = this.createFieldView(this.Document, row);
field && Doc.AddDocToList(parent, 'data', field);
row.uncheck();
});
return parent;
}
- return rows.length ? this.createFieldView(DocCast(this.Document), rows.lastElement()) : undefined;
+ return rows.length ? this.createFieldView(this.Document, rows.lastElement()) : undefined;
};
createFieldView = (templateDoc: Doc, row: KeyValuePair) => {
@@ -300,7 +318,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
description: 'Default Perspective',
event: () => {
this._props.addDocTab(this.Document, OpenWhere.close);
- this._props.addDocTab(this.fieldDocToLayout, OpenWhere.addRight);
+ this._props.addDocTab(this.Document, OpenWhere.addRight);
},
icon: 'image',
});