diff options
-rw-r--r-- | src/client/views/collections/CollectionPivotView.tsx | 37 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/CollectionViewChromes.tsx | 10 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 3 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 5 | ||||
-rw-r--r-- | src/new_fields/documentSchemas.ts | 7 | ||||
-rw-r--r-- | src/new_fields/util.ts | 4 |
9 files changed, 61 insertions, 20 deletions
diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx index ad2e05908..07ad5683c 100644 --- a/src/client/views/collections/CollectionPivotView.tsx +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -2,7 +2,7 @@ import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { computed, action, IReactionDisposer, reaction, runInAction, observable } from "mobx"; import { faEdit, faChevronCircleUp } from "@fortawesome/free-solid-svg-icons"; -import { Doc, DocListCast } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Field, DocCastAsync } from "../../../new_fields/Doc"; import "./CollectionPivotView.scss"; import { observer } from "mobx-react"; import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; @@ -15,10 +15,15 @@ import { anchorPoints, Flyout } from "../TemplateMenu"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { List } from "../../../new_fields/List"; import { Set } from "typescript-collections"; +import { PrefetchProxy } from "../../../new_fields/Proxy"; @observer export class CollectionPivotView extends CollectionSubView(doc => doc) { - componentDidMount = () => { + private _narrativeDisposer: IReactionDisposer | undefined; + componentWillUnmount() { + this._narrativeDisposer?.(); + } + componentDidMount() { this.props.Document.freeformLayoutEngine = "pivot"; if (true || !this.props.Document.facetCollection) { const facetCollection = Docs.Create.FreeformDocument([], { title: "facetFilters", yMargin: 0, treeViewHideTitle: true }); @@ -34,16 +39,24 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) { facetCollection.onCheckedClick = new ScriptField(script); } - const openDocText = "const alias = getAlias(this); alias.layoutKey = 'layout_detailed'; useRightSplit(alias); "; - const openDocScript = CompileScript(openDocText, { - params: { this: Doc.name, heading: "boolean", checked: "boolean", context: Doc.name }, - typecheck: false, - editable: true, - }); - if (openDocScript.compiled) { - this.props.Document.onChildClick = new ScriptField(openDocScript); - } - + this._narrativeDisposer = reaction(() => this.props.Document.childDetailed, + (childDetailed) => + DocCastAsync(childDetailed).then(childDetailed => { + if (childDetailed instanceof Doc) { + let captured: { [name: string]: Field } = {}; + captured["childDetailed"] = new PrefetchProxy(childDetailed); + const openDocText = "const alias = getAlias(this); Doc.ApplyTemplateTo(childDetailed, alias, 'layout_detailed'); useRightSplit(alias); "; + const openDocScript = CompileScript(openDocText, { + params: { this: Doc.name, heading: "boolean", context: Doc.name }, + typecheck: false, + editable: true, + capturedVariables: captured + }); + if (openDocScript.compiled) { + this.props.Document.onChildClick = new ScriptField(openDocScript); + } + } + }), { fireImmediately: true }); this.props.Document.facetCollection = facetCollection; this.props.Document.fitToBox = true; } diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 23a664359..229a23294 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -142,6 +142,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC const fieldKey = value.substring(1); const proto = Doc.GetProto(Document); const created = Docs.Get.DocumentFromField(Document, fieldKey, proto); + if (created) { + created.title = fieldKey; + if (this.props.parent.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this.props.parent.props.Document, true); + } + } return created ? addDocument(created) : false; } this._createAliasSelected = false; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a665b678b..cc8ae2ac1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -244,6 +244,12 @@ export class CollectionView extends Touchable<FieldViewProps> { const existing = ContextMenu.Instance.findByDescription("Layout..."); const layoutItems = existing && "subitems" in existing ? existing.subitems : []; layoutItems.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); + if (this.props.Document.childLayout instanceof Doc) { + layoutItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, undefined, "onRight"), icon: "project-diagram" }); + } + if (this.props.Document.childDetailed instanceof Doc) { + layoutItems.push({ description: "View Child Detailed Layout", event: () => this.props.addDocTab(this.props.Document.childDetailed as Doc, undefined, "onRight"), icon: "project-diagram" }); + } !existing && ContextMenu.Instance.addItem({ description: "Layout...", subitems: layoutItems, icon: "hand-point-right" }); const more = ContextMenu.Instance.findByDescription("More..."); diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 996c7671e..075c48134 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -39,10 +39,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) _templateCommand = { - title: "set template", script: "setChildLayout(this.target, this.source && this.source.length ? this.source[0]:undefined)", params: ["target", "source"], + title: "set template", script: "setChildLayout(this.target, this.source?.[0])", params: ["target", "source"], initialize: emptyFunction, immediate: (draggedDocs: Doc[]) => Doc.setChildLayout(this.props.CollectionView.props.Document, draggedDocs.length ? draggedDocs[0] : undefined) }; + _narrativeCommand = { + title: "set detailed template", script: "setChildLayout(this.target, this.source?.[0])", params: ["target", "source"], + initialize: emptyFunction, + immediate: (draggedDocs: Doc[]) => Doc.setChildDetailed(this.props.CollectionView.props.Document, draggedDocs.length ? draggedDocs[0] : undefined) + }; _contentCommand = { // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting... title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"], @@ -54,7 +59,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1; }, initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; } }; - _freeform_commands = [this._contentCommand, this._templateCommand, this._viewCommand]; + _freeform_commands = [this._contentCommand, this._templateCommand, this._narrativeCommand, this._viewCommand]; _stacking_commands = [this._contentCommand, this._templateCommand]; _masonry_commands = [this._contentCommand, this._templateCommand]; _tree_commands = []; @@ -64,6 +69,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro case CollectionViewType.Stacking: return this._stacking_commands; case CollectionViewType.Masonry: return this._stacking_commands; case CollectionViewType.Freeform: return this._freeform_commands; + case CollectionViewType.Pivot: return this._freeform_commands; } return []; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 01b978c81..7ed36df69 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -904,9 +904,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { onContextMenu = (e: React.MouseEvent) => { const layoutItems: ContextMenuProps[] = []; - if (this.childDocs.some(d => BoolCast(d.isTemplateDoc))) { - layoutItems.push({ description: "Template Layout Instance", event: () => this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" }); - } layoutItems.push({ description: "reset view", event: () => { this.props.Document.panX = this.props.Document.panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" }); layoutItems.push({ description: `${this.Document.LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document.LODdisable = !this.Document.LODdisable, icon: "table" }); layoutItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document.fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 63bb6b18c..e91013be4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -659,7 +659,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu @undoBatch @action - setCustomView = (custom: boolean): void => { + setCustomView = + (custom: boolean): void => { if (this.props.ContainingCollectionView?.props.DataDoc || this.props.ContainingCollectionView?.props.Document.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.Document); } else { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index e0ab5d97c..29834256a 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -746,6 +746,11 @@ export namespace Doc { source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory : source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined; } + export function setChildDetailed(target: Doc, source?: Doc) { + target.childDetailed = source && source.isTemplateDoc ? source : source && + source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory : + source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined; + } export function MakeDocFilter(docFilters: string[]) { let docFilterText = ""; diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts index d5c34e128..3683e5820 100644 --- a/src/new_fields/documentSchemas.ts +++ b/src/new_fields/documentSchemas.ts @@ -68,6 +68,13 @@ export const positionSchema = createSchema({ z: "number", }); +export const collectionSchema = createSchema({ + childLayout: Doc, // layout template for children of a collecion + childDetailed: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to use this field) + onChildClick: ScriptField, // script to run for each child when its clicked + onCheckedClick: ScriptField, // script to run when a checkbox is clicked next to a child in a tree view +}); + export type Document = makeInterface<[typeof documentSchema]>; export const Document = makeInterface(documentSchema); diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index 4147be278..3255c6172 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -1,7 +1,7 @@ import { UndoManager } from "../client/util/UndoManager"; import { Doc, Field, FieldResult, UpdatingFromServer } from "./Doc"; import { SerializationHelper } from "../client/util/SerializationHelper"; -import { ProxyField } from "./Proxy"; +import { ProxyField, PrefetchProxy } from "./Proxy"; import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; import { action, trace } from "mobx"; @@ -52,7 +52,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number value = new ProxyField(value); } if (value instanceof ObjectField) { - if (value[Parent] && value[Parent] !== receiver) { + if (value[Parent] && value[Parent] !== receiver && !(value instanceof PrefetchProxy)) { throw new Error("Can't put the same object in multiple documents at the same time"); } value[Parent] = receiver; |