aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionTreeView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx177
1 files changed, 133 insertions, 44 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2b13d87ee..a7733ab5f 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,19 +1,22 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, untracked, runInAction } from "mobx";
+import { action, computed, observable, runInAction, untracked } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, Field, HeightSym, WidthSym } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
-import { emptyFunction, Utils, returnFalse, emptyPath } from '../../../Utils';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types';
+import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
+import { emptyFunction, emptyPath, returnFalse, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from "../../documents/DocumentTypes";
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
+import { makeTemplate } from '../../util/DropConverter';
+import { Scripting } from '../../util/Scripting';
import { SelectionManager } from '../../util/SelectionManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
@@ -21,13 +24,17 @@ import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from "../EditableView";
import { MainView } from '../MainView';
+import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
+import { ImageBox } from '../nodes/ImageBox';
import { KeyValueBox } from '../nodes/KeyValueBox';
+import { ScriptBox } from '../ScriptBox';
import { Templates } from '../Templates';
-import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
-import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
+import { CollectionViewType } from './CollectionView';
+import { RichTextField } from '../../../new_fields/RichTextField';
+import { ObjectField } from '../../../new_fields/ObjectField';
export interface TreeViewProps {
@@ -38,7 +45,6 @@ export interface TreeViewProps {
prevSibling?: Doc;
renderDepth: number;
deleteDoc: (doc: Doc) => boolean;
- ruleProvider: Doc | undefined;
moveDocument: DragManager.MoveFunction;
dropAction: "alias" | "copy" | undefined;
addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string, libraryPath?: Doc[]) => boolean;
@@ -51,12 +57,13 @@ export interface TreeViewProps {
outdentDocument?: () => void;
ScreenToLocalTransform: () => Transform;
outerXf: () => { translateX: number, translateY: number };
- treeViewId: string;
+ treeViewId: Doc;
parentKey: string;
active: (outsideReaction?: boolean) => boolean;
hideHeaderFields: () => boolean;
preventTreeViewOpen: boolean;
renderedIds: string[];
+ onCheckedClick?: ScriptField;
}
library.add(faTrashAlt);
@@ -173,8 +180,8 @@ class TreeView extends React.Component<TreeViewProps> {
SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)}
OnFillDown={undoBatch((value: string) => {
Doc.SetInPlace(this.props.document, key, value, false);
- const layoutDoc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
- const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+ const layoutDoc = this.props.document.layout_custom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layout_custom)) : undefined;
+ const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
TreeView.loadId = doc[Id];
return this.props.addDocument(doc);
})}
@@ -205,7 +212,7 @@ class TreeView extends React.Component<TreeViewProps> {
ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
}
- ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
+ ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { _width: 300, _height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" });
ContextMenu.Instance.displayMenu(e.pageX > 156 ? e.pageX - 156 : 0, e.pageY - 15);
e.stopPropagation();
@@ -232,8 +239,8 @@ class TreeView extends React.Component<TreeViewProps> {
if (inside) {
addDoc = (doc: Doc) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) || addDoc(doc);
}
- const movedDocs = (de.complete.docDragData.treeViewId === this.props.treeViewId ? de.complete.docDragData.draggedDocuments : de.complete.docDragData.droppedDocuments);
- return ((de.complete.docDragData.dropAction && (de.complete.docDragData.treeViewId !== this.props.treeViewId)) || de.complete.docDragData.userDropAction) ?
+ const movedDocs = (de.complete.docDragData.treeViewId === this.props.treeViewId[Id] ? de.complete.docDragData.draggedDocuments : de.complete.docDragData.droppedDocuments);
+ return ((de.complete.docDragData.dropAction && (de.complete.docDragData.treeViewId !== this.props.treeViewId[Id])) || de.complete.docDragData.userDropAction) ?
de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
: de.complete.docDragData.moveDocument ?
movedDocs.reduce((added, d) => de.complete.docDragData?.moveDocument?.(d, undefined, addDoc) || added, false)
@@ -251,21 +258,21 @@ class TreeView extends React.Component<TreeViewProps> {
}
docWidth = () => {
const layoutDoc = Doc.Layout(this.props.document);
- const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth);
+ const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth);
if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 20));
- return NumCast(layoutDoc.nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
+ return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
}
docHeight = () => {
const layoutDoc = Doc.Layout(this.props.document);
const bounds = this.boundsOfCollectionDocument;
return Math.min(this.MAX_EMBED_HEIGHT, (() => {
- const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth, 1);
+ const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth, 1);
if (aspect) return this.docWidth() * aspect;
if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x);
- return layoutDoc.fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection.height) :
- Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc.nativeHeight)) / NumCast(layoutDoc.nativeWidth,
- NumCast(this.props.containingCollection.height)))) :
- NumCast(layoutDoc.height) ? NumCast(layoutDoc.height) : 50;
+ return layoutDoc._fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection._height) :
+ Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+ NumCast(this.props.containingCollection._height)))) :
+ NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
})());
}
@@ -286,7 +293,7 @@ class TreeView extends React.Component<TreeViewProps> {
DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
- [...this.props.renderedIds, doc[Id]], this.props.libraryPath);
+ [...this.props.renderedIds, doc[Id]], this.props.libraryPath, this.props.onCheckedClick);
} else {
contentElement = <EditableView
key="editableView"
@@ -317,8 +324,6 @@ class TreeView extends React.Component<TreeViewProps> {
return rows;
}
- noOverlays = (doc: Doc) => ({ title: "", caption: "" });
-
@computed get renderContent() {
const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined;
if (expandKey !== undefined) {
@@ -331,7 +336,7 @@ class TreeView extends React.Component<TreeViewProps> {
this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
- [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath)}
+ [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath, this.props.onCheckedClick)}
</ul >;
} else if (this.treeViewExpandedView === "fields") {
return <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
@@ -345,8 +350,6 @@ class TreeView extends React.Component<TreeViewProps> {
DataDocument={this.templateDataDoc}
LibraryPath={emptyPath}
renderDepth={this.props.renderDepth + 1}
- showOverlays={this.noOverlays}
- ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
fitToBox={this.boundsOfCollectionDocument !== undefined}
PanelWidth={this.docWidth}
PanelHeight={this.docHeight}
@@ -359,16 +362,32 @@ class TreeView extends React.Component<TreeViewProps> {
active={this.props.active}
whenActiveChanged={emptyFunction}
addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- setPreviewScript={emptyFunction} />
+ pinToPres={this.props.pinToPres} />
</div>;
}
}
+ @action
+ bulletClick = (e: React.MouseEvent) => {
+ if (this.props.onCheckedClick && this.props.document.type !== DocumentType.COL) {
+ // this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check";
+ ScriptCast(this.props.onCheckedClick).script.run({
+ this: this.props.document.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.props.document,
+ heading: this.props.containingCollection.title,
+ checked: this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check",
+ containingTreeView: this.props.treeViewId,
+ }, console.log);
+ } else {
+ this.treeViewOpen = !this.treeViewOpen;
+ }
+ e.stopPropagation();
+ }
+
@computed
get renderBullet() {
- return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
- {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
+ const checked = this.props.document.type === DocumentType.COL ? undefined : this.props.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined;
+ return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "black"), opacity: 0.4 }}>
+ {<FontAwesomeIcon icon={checked === "check" ? "check" : (checked === "x" ? "times" : checked === "unchecked" ? "square" : !this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down"))} />}
</div>;
}
/**
@@ -377,7 +396,7 @@ class TreeView extends React.Component<TreeViewProps> {
@computed
get renderTitle() {
const reference = React.createRef<HTMLDivElement>();
- const onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId, true);
+ const onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true);
const headerElements = (
<span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
@@ -427,7 +446,7 @@ class TreeView extends React.Component<TreeViewProps> {
}
public static GetChildElements(
childDocs: Doc[],
- treeViewId: string,
+ treeViewId: Doc,
containingCollection: Doc,
dataDoc: Doc | undefined,
key: string,
@@ -448,7 +467,8 @@ class TreeView extends React.Component<TreeViewProps> {
hideHeaderFields: () => boolean,
preventTreeViewOpen: boolean,
renderedIds: string[],
- libraryPath: Doc[] | undefined
+ libraryPath: Doc[] | undefined,
+ onCheckedClick: ScriptField | undefined
) {
const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
if (viewSpecScript) {
@@ -496,7 +516,7 @@ class TreeView extends React.Component<TreeViewProps> {
const rowWidth = () => panelWidth() - 20;
return docs.map((child, i) => {
- const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, key, child);
+ const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child);
if (!pair.layout || pair.data instanceof Promise) {
return (null);
}
@@ -526,7 +546,7 @@ class TreeView extends React.Component<TreeViewProps> {
};
const childLayout = Doc.Layout(pair.layout);
const rowHeight = () => {
- const aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
+ const aspect = NumCast(childLayout._nativeWidth, 0) / NumCast(childLayout._nativeHeight, 0);
return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
};
return !(child instanceof Doc) ? (null) : <TreeView
@@ -536,10 +556,10 @@ class TreeView extends React.Component<TreeViewProps> {
containingCollection={containingCollection}
prevSibling={docs[i]}
treeViewId={treeViewId}
- ruleProvider={containingCollection.isRuleProvider && pair.layout.type !== DocumentType.TEXT ? containingCollection : containingCollection.ruleProvider as Doc}
key={child[Id]}
indentDocument={indent}
outdentDocument={outdent}
+ onCheckedClick={onCheckedClick}
renderDepth={renderDepth}
deleteDoc={remove}
addDocument={addDocument}
@@ -608,6 +628,49 @@ export class CollectionTreeView extends CollectionSubView(Document) {
layoutItems.push({ description: (this.props.Document.hideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.props.Document.hideHeaderFields = !this.props.Document.hideHeaderFields, icon: "paint-brush" });
ContextMenu.Instance.addItem({ description: "Treeview Options ...", subitems: layoutItems, icon: "eye" });
}
+ ContextMenu.Instance.addItem({
+ description: "Buxton Layout", icon: "eye", event: () => {
+ DocListCast(this.dataDoc[this.props.fieldKey]).map(d => {
+ DocListCast(d.data).map((img, i) => {
+ const caption = (d.captions as any)[i]?.data;
+ if (caption instanceof ObjectField) {
+ Doc.GetProto(img).caption = ObjectField.MakeCopy(caption as ObjectField);
+ }
+ img._hideSidebar = true;
+ d.captions = undefined;
+ });
+ });
+ const { TextDocument, ImageDocument, CarouselDocument } = Docs.Create;
+ const { Document } = this.props;
+ const fallbackImg = "http://www.cs.brown.edu/~bcz/face.gif";
+ const detailedTemplate = `{ "doc": { "type": "doc", "content": [ { "type": "paragraph", "content": [ { "type": "dashField", "attrs": { "fieldKey": "short_description" } } ] }, { "type": "paragraph", "content": [ { "type": "dashField", "attrs": { "fieldKey": "year" } } ] }, { "type": "paragraph", "content": [ { "type": "dashField", "attrs": { "fieldKey": "company" } } ] } ] }, "selection":{"type":"text","anchor":1,"head":1},"storedMarks":[] }`;
+
+ const textDoc = TextDocument("", { title: "details", _autoHeight: true });
+ const detailedLayout = Docs.Create.StackingDocument([
+ CarouselDocument([], { title: "data", _height: 350, _itemIndex: 0, backgroundColor: "#9b9b9b3F" }),
+ textDoc,
+ ], { _chromeStatus: "disabled", title: "detailed layout stack" });
+ textDoc.data = new RichTextField(detailedTemplate, "short_description year company");
+ detailedLayout.isTemplateDoc = makeTemplate(detailedLayout);
+
+ const cardLayout = ImageDocument(fallbackImg, { title: "cardLayout", isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
+ cardLayout.proto!.layout = ImageBox.LayoutString("hero");
+ cardLayout.showTitle = "title";
+ cardLayout.showTitleHover = "titlehover";
+
+ Document.childLayout = cardLayout;
+ Document.childDetailed = detailedLayout;
+ Document._viewType = CollectionViewType.Pivot;
+ Document.pivotField = "company";
+ }
+ });
+ const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+ const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+ onClicks.push({
+ description: "Edit onChecked Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Checked Changed ...", this.props.Document,
+ "onCheckedClick", obj.x, obj.y, { heading: "boolean", checked: "boolean", treeViewContainer: Doc.name })
+ });
+ !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
}
outerXf = () => Utils.GetScreenTransform(this._mainEle!);
onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
@@ -622,17 +685,17 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
render() {
- const dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
+ const dropAction = StrCast(this.props.Document._dropAction) as dropActionType;
const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
const moveDoc = (d: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
return !this.childDocs ? (null) : (
<div className="collectionTreeView-dropTarget" id="body"
- style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
+ style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document._yMargin, 20)}px` }}
onContextMenu={this.onContextMenu}
onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
- <EditableView
+ {(this.props.Document.treeViewHideTitle ? (null) : <EditableView
contents={this.dataDoc.title}
display={"block"}
maxHeight={72}
@@ -641,21 +704,47 @@ export class CollectionTreeView extends CollectionSubView(Document) {
SetValue={undoBatch((value: string) => Doc.SetInPlace(this.dataDoc, "title", value, false) || true)}
OnFillDown={undoBatch((value: string) => {
Doc.SetInPlace(this.dataDoc, "title", value, false);
- const layoutDoc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
- const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+ const layoutDoc = this.props.Document.layout_custom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layout_custom)) : undefined;
+ const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
TreeView.loadId = doc[Id];
Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
- })} />
+ })} />)}
{this.props.Document.allowClear ? this.renderClearButton : (null)}
<ul className="no-indent" style={{ width: "max-content" }} >
{
- TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
+ TreeView.GetChildElements(this.childDocs, this.props.Document, this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => BoolCast(this.props.Document.hideHeaderFields),
- BoolCast(this.props.Document.preventTreeViewOpen), [], this.props.LibraryPath)
+ BoolCast(this.props.Document.preventTreeViewOpen), [], this.props.LibraryPath, ScriptCast(this.props.Document.onCheckedClick))
}
</ul>
</div >
);
}
-} \ No newline at end of file
+}
+
+Scripting.addGlobal(function readFacetData(layoutDoc: Doc, dataDoc: Doc, dataKey: string, facetHeader: string) {
+ const allCollectionDocs = DocListCast(dataDoc[dataKey]);
+ const facetValues = Array.from(allCollectionDocs.reduce((set, child) =>
+ set.add(Field.toString(child[facetHeader] as Field)), new Set<string>()));
+
+ const facetValueDocSet = facetValues.sort().map(facetValue =>
+ Docs.Create.TextDocument("", {
+ title: facetValue.toString(),
+ treeViewChecked: ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)",
+ { layoutDoc: Doc.name, facetHeader: "string", facetValue: "string" },
+ { layoutDoc, facetHeader, facetValue })
+ }));
+ return new List<Doc>(facetValueDocSet);
+});
+
+Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: string, facetValue: string) {
+ const docFilters = Cast(layoutDoc._docFilter, listSpec("string"), []);
+ for (let i = 0; i < docFilters.length; i += 3) {
+ const [header, value, state] = docFilters.slice(i, i + 3);
+ if (header === facetHeader && value === facetValue) {
+ return state;
+ }
+ }
+ return undefined;
+}); \ No newline at end of file