diff options
-rw-r--r-- | src/client/util/RichTextRules.ts | 7 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 38 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 61 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 3 |
5 files changed, 57 insertions, 55 deletions
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index 851619f63..04a6fe21c 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -116,10 +116,11 @@ export class RichTextRules { }), // create an inline view of a document {{ <layoutKey> : <Doc> }} // {{:Doc}} => show default view of document {{<layout>}} => show layout for this doc {{<layout> : Doc}} => show layout for another doc new InputRule( - new RegExp(/\{\{([a-zA-Z_ \-0-9]*)(:[a-zA-Z_ \-0-9]+)?\}\}$/), + new RegExp(/\{\{([a-zA-Z_ \-0-9]*)(\([a-zA-Z_ \-0-9]*\))(:[a-zA-Z_ \-0-9]+)?\}\}$/), (state, match, start, end) => { const fieldKey = match[1]; - const docid = match[2]?.substring(1); + const fieldParam = match[2]; + const docid = match[3]?.substring(1); if (!fieldKey && !docid) return state.tr; docid && DocServer.GetRefField(docid).then(docx => { if (!(docx instanceof Doc && docx)) { @@ -128,7 +129,7 @@ export class RichTextRules { } }); const node = (state.doc.resolve(start) as any).nodeAfter; - const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid, fieldKey, float: "right", alias: Utils.GenerateGuid() }); + const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid, fieldKey: fieldKey + fieldParam, float: "right", alias: Utils.GenerateGuid() }); const sm = state.storedMarks || undefined; return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; }), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 44c811b76..5b3119d38 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -775,7 +775,8 @@ export class DashDocView { alias && DocServer.GetRefField(docid).then(async dashDocBase => { if (dashDocBase instanceof Doc) { const aliasedDoc = Doc.MakeAlias(dashDocBase, docid + alias); - aliasedDoc.layoutKey = node.attrs.fieldKey === "layout" ? "layout" : "layout" + (node.attrs.fieldKey ? "_" + node.attrs.fieldKey : ""); + aliasedDoc.layoutKey = "layout"; + node.attrs.fieldKey !== "layout" && DocumentView.makeCustomViewClicked(aliasedDoc, undefined, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); self.doRender(aliasedDoc, removeDoc, node, view, getPos); } }); @@ -888,7 +889,7 @@ export class DashFieldView { this._enumerables.onpointerdown = async (e) => { e.stopPropagation(); - const collview = await Doc.addFieldEnumerations(self._textBoxDoc, node.attrs.fieldKey, [{ title: self._fieldSpan.innerText }]); + const collview = await Doc.addFieldEnumerations(self._textBoxDoc, self._fieldKey, [{ title: self._fieldSpan.innerText }]); collview instanceof Doc && tbox.props.addDocTab(collview, "onRight"); }; const updateText = (forceMatch: boolean) => { @@ -898,12 +899,12 @@ export class DashFieldView { // look for a document whose id === the fieldKey being displayed. If there's a match, then that document // holds the different enumerated values for the field in the titles of its collected documents. // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down. - DocServer.GetRefField(node.attrs.fieldKey).then(options => { + DocServer.GetRefField(self._fieldKey).then(options => { let modText = ""; (options instanceof Doc) && DocListCast(options.data).forEach(opt => (forceMatch ? StrCast(opt.title).startsWith(newText) : StrCast(opt.title) === newText) && (modText = StrCast(opt.title))); if (modText) { self._fieldSpan.innerHTML = self._dashDoc![self._fieldKey] = modText; - Doc.addFieldEnumerations(self._textBoxDoc, node.attrs.fieldKey, []); + Doc.addFieldEnumerations(self._textBoxDoc, self._fieldKey, []); } else if (!self._fieldSpan.innerText.startsWith(":=") && !self._fieldSpan.innerText.startsWith("=:=")) { self._dashDoc![self._fieldKey] = newText; } @@ -922,14 +923,14 @@ export class DashFieldView { this._fieldCheck.id = Utils.GenerateGuid(); this._fieldCheck.type = "checkbox"; this._fieldCheck.style.position = "relative"; - this._fieldCheck.style.display = "inline-block"; + this._fieldCheck.style.display = "none"; this._fieldCheck.style.minWidth = "12px"; this._fieldCheck.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; this._fieldCheck.onchange = function (e: any) { // look for a document whose id === the fieldKey being displayed. If there's a match, then that document // holds the different enumerated values for the field in the titles of its collected documents. // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down. - DocServer.GetRefField(node.attrs.fieldKey).then(options => self._dashDoc![self._fieldKey] = e.target.checked); + DocServer.GetRefField(self._fieldKey).then(options => self._dashDoc![self._fieldKey] = e.target.checked); } @@ -937,7 +938,7 @@ export class DashFieldView { this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; this._fieldSpan.style.position = "relative"; - this._fieldSpan.style.display = "inline-block"; + this._fieldSpan.style.display = "none"; this._fieldSpan.style.minWidth = "12px"; this._fieldSpan.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); }; @@ -947,9 +948,15 @@ export class DashFieldView { const setDashDoc = (doc: Doc) => { self._dashDoc = doc; - if (self._dashDoc && self._options?.length && !self._dashDoc[node.attrs.fieldKey]) { - self._dashDoc[node.attrs.fieldKey] = StrCast(self._options[0].title); + if (self._dashDoc && self._options?.length && !self._dashDoc[self._fieldKey]) { + self._dashDoc[self._fieldKey] = StrCast(self._options[0].title); } + const layout = tbox.props.Document; + self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(layout[StrCast(self._fieldKey).substring(1)]) : self._fieldKey; + this._labelSpan.innerHTML = `${self._fieldKey}: `; + const fieldVal = Cast(this._dashDoc?.[self._fieldKey], "boolean", null); + this._fieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none"; + this._fieldSpan.style.display = !(fieldVal === true || fieldVal === false) ? "inline-block" : "none"; }; this._fieldSpan.onkeydown = function (e: any) { e.stopPropagation(); @@ -964,7 +971,7 @@ export class DashFieldView { } if (e.key === "Enter") { e.preventDefault(); - e.ctrlKey && Doc.addFieldEnumerations(self._textBoxDoc, node.attrs.fieldKey, [{ title: self._fieldSpan.innerText }]); + e.ctrlKey && Doc.addFieldEnumerations(self._textBoxDoc, self._fieldKey, [{ title: self._fieldSpan.innerText }]); updateText(true); } }; @@ -994,7 +1001,7 @@ export class DashFieldView { tbox.props.addDocTab(alias, "onRight"); } }; - this._labelSpan.innerHTML = `${node.attrs.fieldKey}: `; + this._labelSpan.innerHTML = `${self._fieldKey}: `; if (node.attrs.docid) { DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && runInAction(() => setDashDoc(dashDoc))); } else { @@ -1002,8 +1009,8 @@ export class DashFieldView { } this._reactionDisposer?.(); this._reactionDisposer = reaction(() => { // this reaction will update the displayed text whenever the document's fieldKey's value changes - const dashVal = this._dashDoc?.[node.attrs.fieldKey]; - return StrCast(dashVal).startsWith(":=") || !dashVal ? Doc.Layout(tbox.props.Document)[this._fieldKey] : dashVal; + const dashVal = this._dashDoc?.[self._fieldKey]; + return StrCast(dashVal).startsWith(":=") || !dashVal ? Doc.Layout(tbox.props.Document)[self._fieldKey] : dashVal; }, fval => { const boolVal = Cast(fval, "boolean", null); if (boolVal === true || boolVal === false) { @@ -1013,10 +1020,9 @@ export class DashFieldView { } }, { fireImmediately: true }); - const fieldVal = Cast(this._dashDoc?.[node.attrs.fieldKey], "boolean", null); this._fieldWrapper.appendChild(this._labelSpan); - (fieldVal === true || fieldVal === false) && this._fieldWrapper.appendChild(this._fieldCheck); - !(fieldVal === true || fieldVal === false) && this._fieldWrapper.appendChild(this._fieldSpan); + this._fieldWrapper.appendChild(this._fieldCheck); + this._fieldWrapper.appendChild(this._fieldSpan); this._fieldWrapper.appendChild(this._enumerables); (this as any).dom = this._fieldWrapper; updateText(false); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 239f414fd..a58115120 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -78,7 +78,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { return proto instanceof Promise ? undefined : proto; } get layoutDoc() { - return Doc.expandTemplateLayout(this.props.LayoutDoc?.() || Doc.Layout(this.props.Document), this.props.Document); + return Doc.expandTemplateLayout(this.props.LayoutDoc?.() || Doc.Layout(this.props.Document), this.props.Document, + StrCast(this.props.Document.layoutKey)); } CreateBindings(): JsxBindings { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 9a7568518..544c0a961 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -513,9 +513,29 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu undoBatch(() => Doc.setNativeView(doc))(); } - static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, name: string = "custom", docLayoutTemplate?: Doc) => { + static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { + const userDoc = Doc.UserDoc(); + const imgView = Cast(userDoc.iconView, Doc, null); + const iconImgView = Cast(userDoc.iconImageView, Doc, null); + const iconColView = Cast(userDoc.iconColView, Doc, null); + const iconViews = [imgView, iconImgView, iconColView]; + const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data); + const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data); + const allTemplates = iconViews.concat(templateButtons).concat(noteTypes); + const templateName = templateSignature.replace(/\(.*\)/, ""); + !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { + if (StrCast(tempDoc.title) === doc.type + "_" + templateName) { + docLayoutTemplate = tempDoc; + } + }); + !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { + if (StrCast(tempDoc.title) === templateName) { + docLayoutTemplate = tempDoc; + } + }); + const batch = UndoManager.StartBatch("CustomViewClicked"); - const customName = "layout_" + name; + const customName = "layout_" + templateSignature; if (doc[customName] === undefined) { const _width = NumCast(doc._width); const _height = NumCast(doc._height); @@ -626,39 +646,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu @undoBatch @action - setCustomView = - (custom: boolean, layout: string): void => { - // if (this.props.ContainingCollectionView?.props.DataDoc || this.props.ContainingCollectionView?.props.Document.isTemplateDoc) { - // Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.Document); - // } else - if (custom) { - DocumentView.makeNativeViewClicked(this.props.Document); - const userDoc = Doc.UserDoc(); - - const imgView = Cast(userDoc.iconView, Doc, null); - const iconImgView = Cast(userDoc.iconImageView, Doc, null); - const iconColView = Cast(userDoc.iconColView, Doc, null); - const iconViews = [imgView, iconImgView, iconColView]; - const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data); - const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data); - const allTemplates = iconViews.concat(templateButtons).concat(noteTypes); - let foundLayout: Opt<Doc>; - allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { - if (StrCast(tempDoc.title) === this.props.Document.type + "_" + layout) { - foundLayout = tempDoc; - } - }); - !foundLayout && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { - if (StrCast(tempDoc.title) === layout) { - foundLayout = tempDoc; - } - }); - DocumentView. - makeCustomViewClicked(this.props.Document, this.props.DataDoc, Docs.Create.StackingDocument, layout, foundLayout); - } else { - DocumentView.makeNativeViewClicked(this.props.Document); - } + setCustomView = (custom: boolean, layout: string): void => { + DocumentView.makeNativeViewClicked(this.props.Document); + if (custom) { + DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, Docs.Create.StackingDocument, layout, undefined); } + } @undoBatch @action diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 8447a4e93..2a7b08d44 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -463,7 +463,7 @@ export namespace Doc { // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties // of the original layout while allowing for individual layout properties to be overridden in the expanded layout. // - export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc) { + export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateParams?: string) { if (!WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc; const templateField = StrCast(templateLayoutDoc.isTemplateForField); // the field that the template renders @@ -484,6 +484,7 @@ export namespace Doc { if (!targetDoc[expandedLayoutFieldKey]) { const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]"); newLayoutDoc.expandedTemplate = targetDoc; + newLayoutDoc.params = templateParams?.match(/\(([a-zA-Z0-9_-]*)\)/)?.[1]; targetDoc[expandedLayoutFieldKey] = newLayoutDoc; const dataDoc = Doc.GetProto(targetDoc); newLayoutDoc.resolvedDataDoc = dataDoc; |