diff options
12 files changed, 82 insertions, 56 deletions
diff --git a/src/Utils.ts b/src/Utils.ts index 23b59ac9d..732f74bfc 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -313,14 +313,18 @@ export namespace Utils { } } -export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void): { omit: any, extract: any } { +export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any, extract: any } { const omit: any = { ...obj }; const extract: any = {}; keys.forEach(key => { extract[key] = omit[key]; delete omit[key]; }); - addKeyFunc && addKeyFunc(omit); + pattern && Array.from(Object.keys(omit)).filter(key => key.match(pattern)).forEach(key => { + extract[key] = omit[key]; + delete omit[key]; + }) + addKeyFunc?.(omit); return { omit, extract }; } diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f5d6cd7f6..a87a77e1d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -58,6 +58,8 @@ export interface DocumentOptions { _height?: number; _nativeWidth?: number; _nativeHeight?: number; + _dimMagnitude?: number; // magnitude of collectionMulti{row,col} view element + _dimUnit?: string; // "px" or "*" (default = "*") _fitWidth?: boolean; _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents _LODdisable?: boolean; @@ -455,10 +457,7 @@ export namespace Docs { Scripting.addGlobal(Buxton); - const delegateKeys = ["x", "y", "layoutKey", "_width", "_height", "_panX", "_panY", "_viewType", "_nativeWidth", "_nativeHeight", "dropAction", "childDropAction", "_annotationOn", - "_chromeStatus", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_showSidebar", "_showTitle", "_showCaption", "_showTitleHover", "_backgroundColor", - "_xMargin", "_yMargin", "_xPadding", "_yPadding", "_singleLine", "_scrollTop", - "_color", "isLinkButton", "isBackground", "removeDropProperties", "treeViewOpen"]; + const delegateKeys = ["x", "y", "layoutKey", "dropAction", "childDropAction", "isLinkButton", "isBackground", "removeDropProperties", "treeViewOpen"]; /** * This function receives the relevant document prototype and uses @@ -479,7 +478,7 @@ export namespace Docs { * main document. */ export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data") { - const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys); + const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys, "^_"); if (!("author" in protoProps)) { protoProps.author = Doc.CurrentUserEmail; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 38b16e184..a09124304 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -46,12 +46,12 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu */ @computed private get ratioDefinedDocs() { - return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout.dimUnit, "*") === DimUnit.Ratio); + return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout._dimUnit, "*") === DimUnit.Ratio); } /** - * This loops through all childLayoutPairs and extracts the values for dimUnit - * and dimMagnitude, ignoring any that are malformed. Additionally, it then + * This loops through all childLayoutPairs and extracts the values for _dimUnit + * and _dimMagnitude, ignoring any that are malformed. Additionally, it then * normalizes the ratio values so that one * value is always 1, with the remaining * values proportionate to that easily readable metric. * @returns the list of the resolved width specifiers (unit and magnitude pairs) @@ -62,8 +62,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu let starSum = 0; const widthSpecifiers: WidthSpecifier[] = []; this.childLayoutPairs.map(pair => { - const unit = StrCast(pair.layout.dimUnit, "*"); - const magnitude = NumCast(pair.layout.dimMagnitude, 1); + const unit = StrCast(pair.layout._dimUnit, "*"); + const magnitude = NumCast(pair.layout._dimMagnitude, 1); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); widthSpecifiers.push({ magnitude, unit }); @@ -83,9 +83,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu setTimeout(() => { const { ratioDefinedDocs } = this; if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(doc => NumCast(doc.dimMagnitude, 1))); + const minimum = Math.min(...ratioDefinedDocs.map(doc => NumCast(doc._dimMagnitude, 1))); if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude, 1) / minimum, 1); + ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum, 1); } } }); @@ -161,8 +161,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu if (columnUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let width = NumCast(layout.dimMagnitude, 1); - if (StrCast(layout.dimUnit, "*") === DimUnit.Ratio) { + let width = NumCast(layout._dimMagnitude, 1); + if (StrCast(layout._dimUnit, "*") === DimUnit.Ratio) { width *= columnUnitLength; } return width; @@ -194,8 +194,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (super.onInternalDrop(e, de)) { de.complete.docDragData?.droppedDocuments.forEach(action((d: Doc) => { - d.dimUnit = "*"; - d.dimMagnitude = 1; + d._dimUnit = "*"; + d._dimMagnitude = 1; })); } return false; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index b55b67a9e..4326723b1 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -46,12 +46,12 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) */ @computed private get ratioDefinedDocs() { - return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout.dimUnit, "*") === DimUnit.Ratio); + return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout._dimUnit, "*") === DimUnit.Ratio); } /** - * This loops through all childLayoutPairs and extracts the values for dimUnit - * and dimUnit, ignoring any that are malformed. Additionally, it then + * This loops through all childLayoutPairs and extracts the values for _dimUnit + * and _dimUnit, ignoring any that are malformed. Additionally, it then * normalizes the ratio values so that one * value is always 1, with the remaining * values proportionate to that easily readable metric. * @returns the list of the resolved width specifiers (unit and magnitude pairs) @@ -62,8 +62,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) let starSum = 0; const heightSpecifiers: HeightSpecifier[] = []; this.childLayoutPairs.map(pair => { - const unit = StrCast(pair.layout.dimUnit, "*"); - const magnitude = NumCast(pair.layout.dimMagnitude, 1); + const unit = StrCast(pair.layout._dimUnit, "*"); + const magnitude = NumCast(pair.layout._dimMagnitude, 1); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); heightSpecifiers.push({ magnitude, unit }); @@ -83,9 +83,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) setTimeout(() => { const { ratioDefinedDocs } = this; if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(layout => NumCast(layout.dimMagnitude, 1))); + const minimum = Math.min(...ratioDefinedDocs.map(layout => NumCast(layout._dimMagnitude, 1))); if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude, 1) / minimum); + ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum); } } }); @@ -161,8 +161,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) if (rowUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let height = NumCast(layout.dimMagnitude, 1); - if (StrCast(layout.dimUnit, "*") === DimUnit.Ratio) { + let height = NumCast(layout._dimMagnitude, 1); + if (StrCast(layout._dimUnit, "*") === DimUnit.Ratio) { height *= rowUnitLength; } return height; @@ -194,8 +194,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (super.onInternalDrop(e, de)) { de.complete.docDragData?.droppedDocuments.forEach(action((d: Doc) => { - d.dimUnit = "*"; - d.dimMagnitude = 1; + d._dimUnit = "*"; + d._dimMagnitude = 1; })); } return false; diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index e1e604686..a24eb1631 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -43,12 +43,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { const unitLength = columnUnitLength(); if (unitLength) { if (toNarrow) { - const scale = StrCast(toNarrow.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; - toNarrow.dimMagnitude = Math.max(0.05, NumCast(toNarrow.dimMagnitude, 1) - Math.abs(movementX) / scale); + const scale = StrCast(toNarrow._dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toNarrow._dimMagnitude = Math.max(0.05, NumCast(toNarrow._dimMagnitude, 1) - Math.abs(movementX) / scale); } if (toWiden) { - const scale = StrCast(toWiden.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; - toWiden.dimMagnitude = Math.max(0.05, NumCast(toWiden.dimMagnitude, 1) + Math.abs(movementX) / scale); + const scale = StrCast(toWiden._dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toWiden._dimMagnitude = Math.max(0.05, NumCast(toWiden._dimMagnitude, 1) + Math.abs(movementX) / scale); } } } @@ -56,17 +56,17 @@ export default class ResizeBar extends React.Component<ResizerProps> { private get isActivated() { const { toLeft, toRight } = this.props; if (toLeft && toRight) { - if (StrCast(toLeft.dimUnit, "*") === DimUnit.Pixel && StrCast(toRight.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toLeft._dimUnit, "*") === DimUnit.Pixel && StrCast(toRight._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toLeft) { - if (StrCast(toLeft.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toLeft._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toRight) { - if (StrCast(toRight.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toRight._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index 9df8cc3e2..5f00b18b9 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -41,12 +41,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { const unitLength = columnUnitLength(); if (unitLength) { if (toNarrow) { - const scale = StrCast(toNarrow.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; - toNarrow.dimMagnitude = Math.max(0.05, NumCast(toNarrow.dimMagnitude, 1) - Math.abs(movementY) / scale); + const scale = StrCast(toNarrow._dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toNarrow._dimMagnitude = Math.max(0.05, NumCast(toNarrow._dimMagnitude, 1) - Math.abs(movementY) / scale); } if (toWiden) { - const scale = StrCast(toWiden.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; - toWiden.dimMagnitude = Math.max(0.05, NumCast(toWiden.dimMagnitude, 1) + Math.abs(movementY) / scale); + const scale = StrCast(toWiden._dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toWiden._dimMagnitude = Math.max(0.05, NumCast(toWiden._dimMagnitude, 1) + Math.abs(movementY) / scale); } } } @@ -54,17 +54,17 @@ export default class ResizeBar extends React.Component<ResizerProps> { private get isActivated() { const { toTop, toBottom } = this.props; if (toTop && toBottom) { - if (StrCast(toTop.dimUnit, "*") === DimUnit.Pixel && StrCast(toBottom.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toTop._dimUnit, "*") === DimUnit.Pixel && StrCast(toBottom._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toTop) { - if (StrCast(toTop.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toTop._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toBottom) { - if (StrCast(toBottom.dimUnit, "*") === DimUnit.Pixel) { + if (StrCast(toBottom._dimUnit, "*") === DimUnit.Pixel) { return false; } return true; diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 395a6e0b2..2fc82e524 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -135,7 +135,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { CreateBindings(onClick: Opt<ScriptField>, onInput: Opt<ScriptField>): JsxBindings { const list = { - ...OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit, + ...OmitKeys(this.props, ['parentActive'], "", (obj: any) => obj.active = this.props.parentActive).omit, RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc, Document: this.layoutDoc, DataDoc: this.dataDoc, diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index d87d6e424..f28057fd7 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -34,6 +34,7 @@ export class DashFieldView { docid={node.attrs.docid} width={node.attrs.width} height={node.attrs.height} + hideKey={node.attrs.hideKey} tbox={tbox} />, this._fieldWrapper); (this as any).dom = this._fieldWrapper; @@ -47,6 +48,7 @@ export class DashFieldView { interface IDashFieldViewInternal { fieldKey: string; docid: string; + hideKey: boolean; tbox: FormattedTextBox; width: number; height: number; @@ -80,7 +82,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna // set the display of the field's value (checkbox for booleans, span of text for strings) @computed get fieldValueContent() { if (this._dashDoc) { - const dashVal = this._dashDoc[this._fieldKey]; + const dashVal = this._dashDoc![this._fieldKey] || (this._fieldKey === "PARAMS" ? this._textBoxDoc[this._fieldKey] : ""); const fval = StrCast(dashVal).startsWith(":=") || dashVal === "" ? Doc.Layout(this._textBoxDoc)[this._fieldKey] : dashVal; const boolVal = Cast(fval, "boolean", null); const strVal = Field.toString(fval as Field) || ""; @@ -151,7 +153,8 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna } else if (nodeText.startsWith("=:=")) { Doc.Layout(this._textBoxDoc)[this._fieldKey] = ComputedField.MakeFunction(nodeText.substring(3)); } else { - this._dashDoc![this._fieldKey] = newText; + if (this._fieldKey !== "PARAMS" || !this._textBoxDoc[this._fieldKey] || this._dashDoc?.PARAMS) + this._dashDoc![this._fieldKey] = newText; } }); } @@ -192,9 +195,10 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna width: this.props.width, height: this.props.height, }}> - <span className="dashFieldView-labelSpan" title="click to see related tags" onPointerDown={this.onPointerDownLabelSpan}> - {this._fieldKey} - </span> + {this.props.hideKey ? (null) : + <span className="dashFieldView-labelSpan" title="click to see related tags" onPointerDown={this.onPointerDownLabelSpan}> + {this._fieldKey} + </span>} <div className="dashFieldView-fieldSpan"> {this.fieldValueContent} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 658a55f51..f5c28b350 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -205,7 +205,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) { this._applyingChange = true; this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); - if ((!curTemp && !curProto) || curText) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) + if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) if (curText !== curLayout?.Text) { this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText); this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index e7bcf444a..af39ef9c7 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -166,7 +166,8 @@ export const nodes: { [index: string]: NodeSpec } = { inline: true, attrs: { fieldKey: { default: "" }, - docid: { default: "" } + docid: { default: "" }, + hideKey: { default: false } }, group: "inline", draggable: false, diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 9f75b5ffe..b41007e9c 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -467,6 +467,7 @@ export namespace Doc { return (layoutDoc.isTemplateForField || layoutDoc.isTemplateDoc) && dataDoc && layoutDoc !== dataDoc; } + const _pendingMap: Map<string, boolean> = new Map(); // // Returns an expanded template layout for a target data document if there is a template relationship // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties @@ -492,13 +493,16 @@ export namespace Doc { const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc); const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + (args ? `(${args})` : "") + "]"; let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey]; + if (templateLayoutDoc.resolvedDataDoc instanceof Promise) { expandedTemplateLayout = undefined; + _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true); } - else if (expandedTemplateLayout === undefined) { - if (templateLayoutDoc.resolvedDataDoc === Doc.GetProto(targetDoc) && templateLayoutDoc.PARAMS === StrCast(targetDoc.PARAMS)) { + else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey + args)) { + if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument || Doc.GetProto(targetDoc)) && templateLayoutDoc.PARAMS === StrCast(targetDoc.PARAMS)) { expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params } else { + _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey + args, true); templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = Cast(templateLayoutDoc.proto, Doc, null) || templateLayoutDoc); // if the template has already been applied (ie, a nested template), then use the template's prototype setTimeout(action(() => { if (!targetDoc[expandedLayoutFieldKey]) { @@ -513,6 +517,7 @@ export namespace Doc { if (dataDoc[templateField] === undefined && templateLayoutDoc[templateField] instanceof List) { dataDoc[templateField] = ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"] as List)`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc }); } + _pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey + args); } }), 0); } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index b10c6f119..d3e085b21 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -22,6 +22,7 @@ import { MainView } from "../../../client/views/MainView"; import { DocumentType } from "../../../client/documents/DocumentTypes"; import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { faBoxOpen } from "@fortawesome/free-solid-svg-icons"; +import { CollectionMulticolumnView, DimUnit } from "../../../client/views/collections/collectionMulticolumn/CollectionMulticolumnView"; export class CurrentUserUtils { private static curr_id: string; @@ -87,16 +88,28 @@ export class CurrentUserUtils { } if (doc["template-button-switch"] === undefined) { - const { FreeformDocument, MulticolumnDocument } = Docs.Create; + const { FreeformDocument, MulticolumnDocument, TextDocument } = Docs.Create; - const yes = FreeformDocument([], { title: "yes", _height: 100, _width: 100, _LODdisable: true }); + const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _LODdisable: true, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40 }); + const name = TextDocument("name", { title: "name", _height: 35, _width: 70, _dimMagnitude: 1 }); const no = FreeformDocument([], { title: "no", _height: 100, _width: 100, _LODdisable: true }); + const labelTemplate = { + doc: { + type: "doc", content: [{ + type: "paragraph", + content: [{ type: "dashField", attrs: { fieldKey: "PARAMS", hideKey: true } }] + }] + }, + selection: { type: "text", anchor: 1, head: 1 }, + storedMarks: [] + }; + Doc.GetProto(name).text = new RichTextField(JSON.stringify(labelTemplate), "PARAMS"); Doc.GetProto(yes).backgroundColor = ComputedField.MakeFunction("self[this.PARAMS] ? 'green':'red'"); // Doc.GetProto(no).backgroundColor = ComputedField.MakeFunction("!self[this.PARAMS] ? 'red':'white'"); // Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = true"); Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = !self[this.PARAMS]"); // Doc.GetProto(no).onClick = ScriptField.MakeScript("self[this.PARAMS] = false"); - const box = MulticolumnDocument([/*no, */ yes], { title: "value", _width: 40, _height: 40, }); + const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, }); box.isTemplateDoc = makeTemplate(box, true, "switch"); doc["template-button-switch"] = CurrentUserUtils.ficon({ |