aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2020-02-29 15:26:58 -0500
committerSam Wilkins <samwilkins333@gmail.com>2020-02-29 15:26:58 -0500
commit99a23aea54f1430594e70724b252da8f8693a24e (patch)
tree7ff95f302766d1fbb8b1dee3797a7dcbb95148b0 /src/new_fields
parent8c39fb5678bfdd414249f10b0b80e823370f7228 (diff)
parentbb2f6955bef4f079c0fa7213e80fde7a76847799 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
Diffstat (limited to 'src/new_fields')
-rw-r--r--src/new_fields/Doc.ts64
-rw-r--r--src/new_fields/FieldSymbols.ts3
-rw-r--r--src/new_fields/RichTextField.ts9
-rw-r--r--src/new_fields/ScriptField.ts4
-rw-r--r--src/new_fields/documentSchemas.ts13
5 files changed, 76 insertions, 17 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 6142ebb36..dcd97f079 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -17,7 +17,7 @@ import { listSpec } from "./Schema";
import { ComputedField } from "./ScriptField";
import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types";
import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, updateFunction } from "./util";
-import { DocumentManager } from "../client/util/DocumentManager";
+import { Docs } from "../client/documents/Documents";
export namespace Field {
export function toKeyValueString(doc: Doc, key: string): string {
@@ -48,7 +48,7 @@ export namespace Field {
} else if (field instanceof RefField) {
return field[ToString]();
}
- return "(null)";
+ return "";
}
export function IsField(field: any): field is Field;
export function IsField(field: any, includeUndefined: true): field is Field | undefined;
@@ -355,6 +355,10 @@ export namespace Doc {
const proto = doc && (Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc));
return proto === doc ? proto : Doc.GetProto(proto);
}
+ export function GetDataDoc(doc: Doc): Doc {
+ const proto = Doc.GetProto(doc);
+ return proto === doc ? proto : Doc.GetDataDoc(proto);
+ }
export function allKeys(doc: Doc): string[] {
const results: Set<string> = new Set;
@@ -572,7 +576,7 @@ export namespace Doc {
export function ApplyTemplate(templateDoc: Doc) {
if (templateDoc) {
const applied = ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), "layout", templateDoc.title + "(..." + _applyCount++ + ")");
- applied && (Doc.GetProto(applied).layout = applied.layout);
+ applied && (Doc.GetProto(applied).type = templateDoc.type);
return applied;
}
return undefined;
@@ -612,16 +616,21 @@ export namespace Doc {
templateField.isTemplateForField = metadataFieldKey;
templateField.title = metadataFieldKey;
+ const templateFieldValue = templateField[metadataFieldKey] || templateField.data;
+ const templateCaptionValue = templateField.caption;
// move any data that the template field had been rendering over to the template doc so that things will still be rendered
// when the template field is adjusted to point to the new metadatafield key.
// note 1: if the template field contained a list of documents, each of those documents will be converted to templates as well.
// note 2: this will not overwrite any field that already exists on the template doc at the field key
- if (!templateDoc?.[metadataFieldKey] && templateField.data instanceof ObjectField) {
- Cast(templateField.data, listSpec(Doc), [])?.map(d => d instanceof Doc && MakeMetadataFieldTemplate(d, templateDoc));
- (Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateField.data));
+ if (!templateDoc?.[metadataFieldKey] && templateFieldValue instanceof ObjectField) {
+ Cast(templateFieldValue, listSpec(Doc), [])?.map(d => d instanceof Doc && MakeMetadataFieldTemplate(d, templateDoc));
+ (Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateFieldValue));
}
- if (templateField.data instanceof RichTextField && (templateField.data.Text || templateField.data.Data.toString().includes("dashField"))) {
- templateField._textTemplate = ComputedField.MakeFunction(`copyField(this.${metadataFieldKey})`, { this: Doc.name });
+ if (templateCaptionValue instanceof RichTextField && (templateCaptionValue.Text || templateCaptionValue.Data.toString().includes("dashField"))) {
+ templateField["caption-textTemplate"] = ComputedField.MakeFunction(`copyField(this.caption)`, { this: Doc.name });
+ }
+ if (templateFieldValue instanceof RichTextField && (templateFieldValue.Text || templateFieldValue.Data.toString().includes("dashField"))) {
+ templateField[metadataFieldKey + "-textTemplate"] = ComputedField.MakeFunction(`copyField(this.${metadataFieldKey})`, { this: Doc.name });
}
// get the layout string that the template uses to specify its layout
@@ -838,6 +847,45 @@ export namespace Doc {
DocServer.GetRefField(id).then(layout => layout instanceof Doc && (doc[field] = layout));
return id;
}
+
+ // setup a document to use enumerated values for a specified field name:
+ // doc: text document
+ // layoutString: species which text field receives the document's main text (e.g., FormattedTextBox.LayoutString("Todo") )
+ // enumeratedFieldKey : specifies which enumerated field of the document is displayed in the caption (e.g., taskStatus)
+ // captionKey: specifies which field holds the caption template (e.g., caption) -- ideally this wouldn't be needed but would be derived from the layoutString's target field key
+ //
+ export function enumeratedTextTemplate(doc: Doc, layoutString: string, enumeratedFieldKey: string, enumeratedDocs: Doc[], captionKey: string = "caption") {
+ doc.caption = RichTextField.DashField(enumeratedFieldKey);
+ doc._showCaption = captionKey;
+ doc.layout = layoutString;
+
+ Doc.addEnumerationToTextField(doc, enumeratedFieldKey, enumeratedDocs);
+ }
+
+ export async function getEnumerationTextField(enumeratedFieldKey: string) {
+ return (await DocServer.GetRefField(enumeratedFieldKey)) as Doc;
+ }
+
+ export function addEnumerationToTextField(doc: Opt<Doc>, enumeratedFieldKey: string, enumeratedDocs: Doc[]) {
+ DocServer.GetRefField(enumeratedFieldKey).then(optionsCollection => {
+ if (!(optionsCollection instanceof Doc)) {
+ optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set` }, enumeratedFieldKey);
+ Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc);
+ }
+ const options = optionsCollection as Doc;
+ doc && (Doc.GetProto(doc).backgroundColor = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey})?._backgroundColor || "white"`, undefined, { options }));
+ doc && (Doc.GetProto(doc).color = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey}).color || "black"`, undefined, { options }));
+ enumeratedDocs.map(enumeratedDoc => {
+ const found = DocListCast(options.data).find(d => d.title === enumeratedDoc.title);
+ if (found) {
+ found._backgroundColor = enumeratedDoc._backgroundColor || found._backgroundColor;
+ found._color = enumeratedDoc._color || found._color;
+ } else {
+ Doc.AddDocToList(options, "data", enumeratedDoc);
+ }
+ });
+ });
+ }
}
Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
diff --git a/src/new_fields/FieldSymbols.ts b/src/new_fields/FieldSymbols.ts
index 4aadb81a2..8d040f493 100644
--- a/src/new_fields/FieldSymbols.ts
+++ b/src/new_fields/FieldSymbols.ts
@@ -8,4 +8,5 @@ export const OnUpdate = Symbol("OnUpdate");
export const Parent = Symbol("Parent");
export const Copy = Symbol("Copy");
export const ToScriptString = Symbol("ToScriptString");
-export const ToString = Symbol("ToString"); \ No newline at end of file
+export const ToPlainText = Symbol("ToPlainText");
+export const ToString = Symbol("ToString");
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
index a0f21f45e..ad4a5a252 100644
--- a/src/new_fields/RichTextField.ts
+++ b/src/new_fields/RichTextField.ts
@@ -1,9 +1,12 @@
import { ObjectField } from "./ObjectField";
import { serializable } from "serializr";
import { Deserializable } from "../client/util/SerializationHelper";
-import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+import { Copy, ToScriptString, ToPlainText, ToString } from "./FieldSymbols";
import { scriptingGlobal } from "../client/util/Scripting";
+const delimiter = "\n";
+const joiner = "";
+
@scriptingGlobal
@Deserializable("RichTextField")
export class RichTextField extends ObjectField {
@@ -30,4 +33,8 @@ export class RichTextField extends ObjectField {
return this.Text;
}
+ public static DashField(fieldKey: string) {
+ return new RichTextField(`{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`, "");
+ }
+
} \ No newline at end of file
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
index 4c78ea3aa..9288fea9e 100644
--- a/src/new_fields/ScriptField.ts
+++ b/src/new_fields/ScriptField.ts
@@ -106,7 +106,7 @@ export class ScriptField extends ObjectField {
}
public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) {
const compiled = CompileScript(script, {
- params: { this: Doc.name, _last_: "any", ...params },
+ params: { this: Doc.name, source: Doc.name, _last_: "any", ...params },
typecheck: false,
editable: true,
addReturn: addReturn,
@@ -130,7 +130,7 @@ export class ScriptField extends ObjectField {
export class ComputedField extends ScriptField {
_lastComputedResult: any;
//TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
- value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, _last_: this._lastComputedResult }, console.log).result);
+ value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ source: doc.expandedTemplate || doc, this: doc, _last_: this._lastComputedResult }, console.log).result);
public static MakeScript(script: string, params: object = {}) {
const compiled = ScriptField.CompileScript(script, params, false);
return compiled.compiled ? new ComputedField(compiled) : undefined;
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index f3726cb5a..7006163e0 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -15,9 +15,14 @@ export const documentSchema = createSchema({
_nativeHeight: "number", // "
_width: "number", // width of document in its container's coordinate system
_height: "number", // "
- _showCaption: "string", // whether editable caption text is overlayed at the bottom of the document
- _showTitle: "string", // the fieldkey whose contents should be displayed at the top of the document
- _showTitleHover: "string", // the showTitle should be shown only on hover
+ _xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
+ _yPadding: "number", // pixels of padding on top/bottom of collectionfreeformview contents when fitToBox is set
+ _xMargin: "number", // margin added on left/right of most documents to add separation from their container
+ _yMargin: "number", // margin added on top/bottom of most documents to add separation from their container
+ _showCaption: "string", // whether editable caption text is overlayed at the bottom of the document
+ _showTitle: "string", // the fieldkey whose contents should be displayed at the top of the document
+ _showTitleHover: "string", // the showTitle should be shown only on hover
+ _showAudio: "boolean", // whether to show the audio record icon on documents
_freeformLayoutEngine: "string",// the string ID for the layout engine to use to layout freeform view documents
_LODdisable: "boolean", // whether to disbale LOD switching for CollectionFreeFormViews
_pivotField: "string", // specifies which field should be used as the timeline/pivot axis
@@ -53,8 +58,6 @@ export const documentSchema = createSchema({
strokeWidth: "number",
fontSize: "string",
fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view
- xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
- yPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
letterSpacing: "string",
textTransform: "string"
});