aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-03-27 23:30:03 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-03-27 23:30:03 -0400
commitf80aee53be8582956a1f39519938700c3e90cb53 (patch)
tree8de6544a3970565fd8625fd4bf30292b6d88fe5f /src
parent692381503f2af93dba2a4f30495a17b7b4deed36 (diff)
fixed up embedded document view layout references in text boxes to 1) create the template if it doesn't exist and 2) to allow parameters to be passed to templates
Diffstat (limited to 'src')
-rw-r--r--src/client/util/RichTextRules.ts7
-rw-r--r--src/client/util/RichTextSchema.tsx38
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx61
-rw-r--r--src/new_fields/Doc.ts3
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;