aboutsummaryrefslogtreecommitdiff
path: root/src/fields/Doc.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-04-10 14:06:59 -0400
committerbobzel <zzzman@gmail.com>2025-04-10 14:06:59 -0400
commitaff4fff58655ff48613b2519b55787955a766667 (patch)
tree589286f293737e60edc23b95b8ea63ff7e0b5d8b /src/fields/Doc.ts
parentb6823909532bdc727a51b8bda266cf62dd5dff6d (diff)
parent463cd15186a3463897d977bfa11af5c4929798ae (diff)
Merge branch 'master' into aarav_edit
Diffstat (limited to 'src/fields/Doc.ts')
-rw-r--r--src/fields/Doc.ts75
1 files changed, 29 insertions, 46 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 4bf04da5c..e48337651 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -43,10 +43,10 @@ export namespace Field {
* @param doc doc containing key
* @param key field key to display
* @param showComputedValue whether copmuted function should display its value instead of its function
+ * @param schemaCell
* @returns string representation of the field
*/
export function toKeyValueString(doc: Doc, key: string, showComputedValue?: boolean, schemaCell?: boolean): string {
- const isOnDelegate = !Doc.IsDataProto(doc) && Object.keys(doc).includes(key.replace(/^_/, ''));
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
const valFunc = (field: FieldType): string => {
const res =
@@ -64,7 +64,9 @@ export namespace Field {
.trim()
.replace(/^new List\((.*)\)$/, '$1');
};
- return !Field.IsField(cfield) ? (key.startsWith('_') ? '=' : '') : (isOnDelegate ? '=' : '') + valFunc(cfield);
+ const notOnTemplate = !key.startsWith('_') || doc[DocLayout] === doc;
+ const isOnDelegate = notOnTemplate && !Doc.IsDataProto(doc) && ((key.startsWith('_') && !Field.IsField(cfield)) || Object.keys(doc).includes(key.replace(/^_/, '')));
+ return (isOnDelegate ? '=' : '') + (!Field.IsField(cfield) ? '' : valFunc(cfield));
}
export function toScriptString(field: FieldType, schemaCell?: boolean) {
switch (typeof field) {
@@ -405,9 +407,9 @@ export class Doc extends RefField {
}
@computed get __DATA__(): Doc {
const self = this[SelfProxy];
- return self.resolvedDataDoc && !self.isTemplateForField ? self : Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
+ return self.rootDocument && !self.isTemplateForField ? self : Doc.GetProto(Cast(self[DocLayout].rootDocument, Doc, null) || self);
}
- @computed get __LAYOUT__(): Doc | undefined {
+ @computed get __LAYOUT__(): Doc {
const self = this[SelfProxy];
const templateLayoutDoc = Cast(Doc.LayoutField(self), Doc, null);
if (templateLayoutDoc) {
@@ -420,7 +422,7 @@ export class Doc extends RefField {
}
return Cast(self['layout_' + templateLayoutDoc.title + '(' + renderFieldKey + ')'], Doc, null) || templateLayoutDoc;
}
- return undefined;
+ return self;
}
public async [HandleUpdate](diff: { $set: { [key: string]: FieldType } } | { $unset?: unknown }) {
@@ -685,15 +687,11 @@ export namespace Doc {
}
export function MakeEmbedding(doc: Doc, id?: string) {
- const embedding = (!GetT(doc, 'isDataDoc', 'boolean', true) && doc.proto) || doc.type === DocumentType.CONFIG ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
- const layout = Doc.LayoutField(embedding);
- if (layout instanceof Doc && layout !== embedding && layout === Doc.Layout(embedding)) {
- Doc.SetLayout(embedding, Doc.MakeEmbedding(layout));
- }
+ const embedding = (!Doc.IsDataProto(doc) && doc.proto) || doc.type === DocumentType.CONFIG ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
embedding.createdFrom = doc;
- embedding.proto_embeddingId = doc.$proto_embeddingId = Doc.GetEmbeddings(doc).length - 1;
- !Doc.GetT(embedding, 'title', 'string', true) && (embedding.title = ComputedField.MakeFunction(`renameEmbedding(this)`));
embedding.author = ClientUtils.CurrentUserEmail();
+ embedding.proto_embeddingId = doc.$proto_embeddingId = Doc.GetEmbeddings(doc).length - 1;
+ embedding.title = ComputedField.MakeFunction(`renameEmbedding(this)`);
return embedding;
}
@@ -766,9 +764,8 @@ export namespace Doc {
// prune doc and do nothing
} else if (
!Doc.IsSystem(docAtKey) &&
- (key.includes('layout[') ||
- key.startsWith('layout') || //
- ['embedContainer', 'annotationOn', 'proto'].includes(key) ||
+ (key.startsWith('layout') ||
+ ['embedContainer', 'annotationOn', 'proto'].includes(key) || //
(['link_anchor_1', 'link_anchor_2'].includes(key) && doc.author === ClientUtils.CurrentUserEmail()))
) {
assignKey(await Doc.makeClone(docAtKey, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates));
@@ -871,15 +868,15 @@ export namespace Doc {
const expandedLayoutFieldKey = 'layout_' + templateLayoutDoc.title + '(' + templateField + ')';
let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey];
- if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
+ if (templateLayoutDoc.rootDocument instanceof Promise) {
expandedTemplateLayout = undefined;
_pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
} else if (expandedTemplateLayout === undefined && !_pendingMap.has(targetDoc[Id] + expandedLayoutFieldKey)) {
- if (templateLayoutDoc.resolvedDataDoc === targetDoc[DocData]) {
+ if (DocCast(templateLayoutDoc.rootDocument)?.[DocData] === targetDoc[DocData]) {
expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params
} else {
// eslint-disable-next-line no-param-reassign
- templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = DocCast(templateLayoutDoc.proto, templateLayoutDoc)); // if the template has already been applied (ie, a nested template), then use the template's prototype
+ templateLayoutDoc.rootDocument && (templateLayoutDoc = DocCast(templateLayoutDoc.proto, templateLayoutDoc)); // if the template has already been applied (ie, a nested template), then use the template's prototype
if (!targetDoc[expandedLayoutFieldKey]) {
_pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
setTimeout(
@@ -888,7 +885,6 @@ export namespace Doc {
const dataDoc = Doc.GetProto(targetDoc);
newLayoutDoc.rootDocument = targetDoc;
newLayoutDoc.embedContainer = targetDoc;
- newLayoutDoc.resolvedDataDoc = dataDoc;
newLayoutDoc.acl_Guest = SharingPermissions.Edit;
if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as List<Doc>)?.length) {
dataDoc[templateField] = ObjectField.MakeCopy(templateLayoutDoc[templateField] as List<Doc>);
@@ -912,9 +908,9 @@ export namespace Doc {
console.log('Warning: GetLayoutDataDocPair childDoc not defined');
return { layout: childDoc, data: childDoc };
}
- const resolvedDataDoc = Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!Doc.isTemplateDoc(childDoc) && !Doc.isTemplateForField(childDoc)) ? undefined : containerDataDoc;
+ const data = Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!Doc.isTemplateDoc(childDoc) && !Doc.isTemplateForField(childDoc)) ? undefined : containerDataDoc;
const templateRoot = DocCast(containerDoc?.rootDocument);
- return { layout: Doc.expandTemplateLayout(childDoc, templateRoot), data: resolvedDataDoc };
+ return { layout: Doc.expandTemplateLayout(childDoc, templateRoot), data };
}
export function FindReferences(infield: Doc | List<Doc>, references: Set<Doc>, system: boolean | undefined) {
@@ -1083,7 +1079,7 @@ export namespace Doc {
export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) {
if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) {
- if (target.resolvedDataDoc) {
+ if (target.rootDocument) {
target[targetKey] = new PrefetchProxy(templateDoc);
} else {
titleTarget && (Doc.GetProto(target).title = titleTarget);
@@ -1116,10 +1112,10 @@ export namespace Doc {
Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateFieldValue);
}
// get the layout string that the template uses to specify its layout
- const templateFieldLayoutString = StrCast(Doc.LayoutField(Doc.Layout(templateField)));
+ const templateFieldLayoutString = StrCast(Doc.LayoutField(templateField[DocLayout]));
// change it to render the target metadata field instead of what it was rendering before and assign it to the template field layout document.
- Doc.Layout(templateField).layout = templateFieldLayoutString.replace(/fieldKey={'[^']*'}/, `fieldKey={'${metadataFieldKey}'}`);
+ templateField[DocLayout].layout = templateFieldLayoutString.replace(/fieldKey={'[^']*'}/, `fieldKey={'${metadataFieldKey}'}`);
return true;
}
@@ -1154,18 +1150,15 @@ export namespace Doc {
// the document containing the view layout information - will be the Document itself unless the Document has
// a layout field or 'layout' is given.
- export function Layout(doc: Doc, layout?: Doc): Doc {
- const overrideLayout = layout && Cast(doc[layout.title + '(' + StrCast(layout.isTemplateForField, 'data') + ')'], Doc, null);
- return overrideLayout || doc[DocLayout] || doc;
- }
- export function SetLayout(doc: Doc, layout: Doc | string) {
- doc[StrCast(doc.layout_fieldKey, 'layout')] = layout;
+ export function Layout(doc: Doc, template?: Doc): Doc {
+ const expandedTemplate = template && Cast(doc['layout_' + template.title + '(' + StrCast(template.isTemplateForField, 'data') + ')'], Doc, null);
+ return expandedTemplate || doc[DocLayout];
}
export function LayoutField(doc: Doc) {
return doc[StrCast(doc.layout_fieldKey, 'layout')];
}
export function LayoutFieldKey(doc: Doc, templateLayoutString?: string): string {
- const match = StrCast(templateLayoutString || Doc.Layout(doc).layout).match(/fieldKey={'([^']+)'}/);
+ const match = StrCast(templateLayoutString || doc[DocLayout].layout).match(/fieldKey={'([^']+)'}/);
return match?.[1] || ''; // bcz: TODO check on this . used to always reference 'layout', now it uses the layout speicfied by the current layout_fieldKey
}
export function NativeAspect(doc: Doc, dataDoc?: Doc, useDim?: boolean) {
@@ -1301,7 +1294,7 @@ export namespace Doc {
highlightedDocs.add(doc);
doc[Highlight] = true;
doc[Animation] = presentationEffect;
- if (dataAndDisplayDocs && !doc.resolvedDataDoc) {
+ if (dataAndDisplayDocs && !doc.rootDocument) {
// if doc is a layout template then we don't want to highlight the proto since that will be the entire template, not just the specific layout field
highlightedDocs.add(doc[DocData]);
doc[DocData][Highlight] = true;
@@ -1324,17 +1317,7 @@ export namespace Doc {
}
export function getDocTemplate(doc?: Doc) {
- return !doc
- ? undefined
- : doc.isTemplateDoc
- ? doc
- : Cast(doc.dragFactory, Doc, null)?.isTemplateDoc
- ? doc.dragFactory
- : Cast(Doc.Layout(doc), Doc, null)?.isTemplateDoc
- ? Cast(Doc.Layout(doc), Doc, null).resolvedDataDoc
- ? Doc.Layout(doc).proto
- : Doc.Layout(doc)
- : undefined;
+ return !doc ? undefined : doc.isTemplateDoc ? doc : Cast(doc.dragFactory, Doc, null)?.isTemplateDoc ? doc.dragFactory : doc[DocLayout].isTemplateDoc ? (doc[DocLayout].rootDocument ? doc[DocLayout].proto : doc[DocLayout]) : undefined;
}
export function toggleLockedPosition(doc: Doc) {
@@ -1478,9 +1461,9 @@ export namespace Doc {
const docText = (async (tdoc:Doc) => {
switch (tdoc.type) {
case DocumentType.PDF: return curDescription || StrCast(tdoc.text).split(/\s+/).slice(0, 50).join(' '); // first 50 words of pdf text
- case DocumentType.IMG: return curDescription || imageUrlToBase64(ImageCastWithSuffix(Doc.LayoutField(tdoc), '_o') ?? '')
+ case DocumentType.IMG: return curDescription || imageUrlToBase64(ImageCastWithSuffix(tdoc[Doc.LayoutFieldKey(tdoc)], '_o') ?? '')
.then(hrefBase64 => gptImageLabel(hrefBase64, 'Give three to five labels to describe this image.'));
- case DocumentType.RTF: return RTFCast(tdoc[Doc.LayoutFieldKey(tdoc)]).Text;
+ case DocumentType.RTF: return RTFCast(tdoc[Doc.LayoutFieldKey(tdoc)])?.Text ?? StrCast(tdoc[Doc.LayoutFieldKey(tdoc)]);
default: return StrCast(tdoc.title).startsWith("Untitled") ? "" : StrCast(tdoc.title);
}}); // prettier-ignore
return docText(doc).then(text => (doc['$' + Doc.LayoutFieldKey(doc) + '_description'] = text));
@@ -1736,7 +1719,7 @@ ScriptingGlobals.add(function idToDoc(id: string): Doc {
});
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function renameEmbedding(doc: Doc) {
- return StrCast(doc.$title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`;
+ return StrCast(doc.title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`;
});
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function getProto(doc: Doc) {