aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionPivotView.tsx37
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx6
-rw-r--r--src/client/views/collections/CollectionView.tsx6
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx10
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx3
-rw-r--r--src/new_fields/Doc.ts5
-rw-r--r--src/new_fields/documentSchemas.ts7
-rw-r--r--src/new_fields/util.ts4
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;