From d818ef151ca65008e5c6bb5e92b709decb3026d8 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 14 Apr 2025 18:35:49 -0400
Subject: fixed how templates are expanded to avoid template sub-component
 conflicts by changing how field keys are named.   fixed various Cast
 functions to be more typesafe by including undefined as part of return type. 
 overhaul of Doc.MakeClone, MakeCopy, FindRefernces - makeClone is no longer
 async.  fixed inlined docs in text docs.

---
 src/client/views/collections/CollectionSubView.tsx | 37 +++++++++++++---------
 1 file changed, 22 insertions(+), 15 deletions(-)

(limited to 'src/client/views/collections/CollectionSubView.tsx')

diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 375c0fe53..bc7d6f897 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -3,7 +3,7 @@ import * as React from 'react';
 import * as rp from 'request-promise';
 import { ClientUtils, DashColor, returnFalse } from '../../../ClientUtils';
 import CursorField from '../../../fields/CursorField';
-import { Doc, DocListCast, GetDocFromUrl, GetHrefFromHTML, Opt, RTFIsFragment, StrListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, expandedFieldName, GetDocFromUrl, GetHrefFromHTML, Opt, RTFIsFragment, StrListCast } from '../../../fields/Doc';
 import { AclPrivate, DocData } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
@@ -132,16 +132,23 @@ export function CollectionSubView<X>() {
 
         hasChildDocs = () => this.childLayoutPairs.map(pair => pair.layout);
         @computed get childLayoutPairs(): { layout: Doc; data: Doc }[] {
-            const { TemplateDataDocument } = this._props;
-            const validPairs = this.childDocs
-                .map(doc => Doc.GetLayoutDataDocPair(this.Document, !this._props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc))
-                .filter(
-                    pair =>
-                        // filter out any documents that have a proto that we don't have permissions to
-                        !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate))
-                )
-                .filter(pair => !this._filterFunc?.(pair.layout!));
-            return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types
+            const lastEle = this.DocumentView?.();
+            if (!lastEle?.IsInvalid(this.Document)) {
+                const rootTemplate = lastEle && Doc.LayoutDoc(lastEle.rootDoc).isTemplateDoc && Doc.LayoutDoc(lastEle.rootDoc);
+                const templateFieldKey = rootTemplate &&
+                    [expandedFieldName(rootTemplate),
+                        ...this._props.docViewPath()
+                            .filter(dv => dv.Document.isTemplateForField)
+                            .map(dv => dv.Document.title),
+                    ].join('_'); // prettier-ignore
+                return this.childDocs
+                    .map(doc => Doc.GetLayoutDataDocPair(this.Document, !this._props.isAnnotationOverlay ? this._props.TemplateDataDocument : undefined, doc, templateFieldKey || ""))
+                    .filter(pair => // filter out any documents that have a proto that we don't have permissions to
+                        !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate)))
+                    .filter(pair => !this._filterFunc?.(pair.layout!))
+                    .map(({ data, layout }) => ({ data: data!, layout: layout! })); // prettier-ignore
+            }
+            return [];
         }
         /**
          * This is the raw, stored list of children on a collection.  If you modify this list, the database will be updated
@@ -161,7 +168,7 @@ export function CollectionSubView<X>() {
         };
 
         collectionFilters = () => this._focusFilters ?? StrListCast(this.Document._childFilters);
-        collectionRangeDocFilters = () => this._focusRangeFilters ?? Cast(this.Document._childFiltersByRanges, listSpec('string'), []);
+        collectionRangeDocFilters = () => this._focusRangeFilters ?? StrListCast(this.Document._childFiltersByRanges);
         // child filters apply to the descendants of the documents in this collection
         childDocFilters = () => [...(this._props.childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f)) || []), ...this.collectionFilters()];
         // unrecursive filters apply to the documents in the collection, but no their children.  See Utils.noRecursionHack
@@ -178,7 +185,7 @@ export function CollectionSubView<X>() {
                 rawdocs = [this.dataField];
             } else if (Cast(this.dataField, listSpec(Doc), null)) {
                 // otherwise, if the collection data is a list, then use it.
-                rawdocs = Cast(this.dataField, listSpec(Doc), null);
+                rawdocs = DocListCast(this.dataField);
             } else if (this.dataField) {
                 // Finally, if it's not a doc or a list and the document is a template, we try to render the root doc.
                 // For example, if an image doc is rendered with a slide template, the template will try to render the data field as a collection.
@@ -206,7 +213,7 @@ export function CollectionSubView<X>() {
                 let notFiltered = d.z || Doc.IsSystem(d) || DocUtils.FilterDocs([d], this.unrecursiveDocFilters(), childFiltersByRanges, this.Document).length > 0;
                 if (notFiltered) {
                     notFiltered = (!searchDocs.length || searchDocs.includes(d)) && DocUtils.FilterDocs([d], childDocFilters, childFiltersByRanges, this.Document).length > 0;
-                    const fieldKey = Doc.LayoutFieldKey(d);
+                    const fieldKey = Doc.LayoutDataKey(d);
                     const isAnnotatableDoc = d[fieldKey] instanceof List && !(d[fieldKey] as List<Doc>)?.some(ele => !(ele instanceof Doc));
                     const docChildDocs = d[isAnnotatableDoc ? fieldKey + '_annotations' : fieldKey];
                     const sidebarDocs = isAnnotatableDoc && d[fieldKey + '_sidebar'];
@@ -219,7 +226,7 @@ export function CollectionSubView<X>() {
                                 newarray = [];
                                 // eslint-disable-next-line no-loop-func
                                 subDocs.forEach(t => {
-                                    const docFieldKey = Doc.LayoutFieldKey(t);
+                                    const docFieldKey = Doc.LayoutDataKey(t);
                                     const isSubDocAnnotatable = t[docFieldKey] instanceof List && !(t[docFieldKey] as List<Doc>)?.some(ele => !(ele instanceof Doc));
                                     notFiltered =
                                         notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !childFiltersByRanges.length) || DocUtils.FilterDocs([t], childDocFilters, childFiltersByRanges, d).length));
-- 
cgit v1.2.3-70-g09d2

