diff options
author | bobzel <zzzman@gmail.com> | 2025-04-10 14:06:59 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2025-04-10 14:06:59 -0400 |
commit | aff4fff58655ff48613b2519b55787955a766667 (patch) | |
tree | 589286f293737e60edc23b95b8ea63ff7e0b5d8b /src/fields/Doc.ts | |
parent | b6823909532bdc727a51b8bda266cf62dd5dff6d (diff) | |
parent | 463cd15186a3463897d977bfa11af5c4929798ae (diff) |
Merge branch 'master' into aarav_edit
Diffstat (limited to 'src/fields/Doc.ts')
-rw-r--r-- | src/fields/Doc.ts | 75 |
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) { |