aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx8
-rw-r--r--src/client/views/collections/CollectionTimeView.scss1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx24
-rw-r--r--src/client/views/collections/CollectionView.tsx143
-rw-r--r--src/client/views/nodes/FieldView.tsx3
6 files changed, 99 insertions, 82 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 3786b4f6f..e3ec10dcd 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -498,7 +498,7 @@ export function setupMoveUpEvents(
};
const _upEvent = (e: PointerEvent): void => {
upEvent(e);
- if (Math.abs(e.clientX - (target as any)._downX) < 4 || Math.abs(e.clientY - (target as any)._downY) < 4) {
+ if (Math.abs(e.clientX - (target as any)._downX) < 4 && Math.abs(e.clientY - (target as any)._downY) < 4) {
clickEvent(e);
}
document.removeEventListener("pointermove", _moveEvent);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a5480d567..11f214625 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -48,8 +48,8 @@ export interface SubCollectionViewProps extends CollectionViewProps {
layoutEngine?: () => string;
}
-export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
- class CollectionSubView extends DocComponent<SubCollectionViewProps, T>(schemaCtor) {
+export function CollectionSubView<T,X>(schemaCtor: (doc: Doc) => T, moreProps?:X) {
+ class CollectionSubView extends DocComponent<X&SubCollectionViewProps, T>(schemaCtor) {
private dropDisposer?: DragManager.DragDropDisposer;
private gestureDisposer?: GestureUtils.GestureEventDisposer;
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
@@ -130,7 +130,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
- const filteredDocs = docFilters.length ? childDocs.filter(d => {
+ const filteredDocs = docFilters.length && !this.props.dontRegisterView ? childDocs.filter(d => {
for (const facetKey of Object.keys(filterFacets)) {
const facet = filterFacets[facetKey];
const satisfiesFacet = Object.keys(facet).some(value =>
@@ -195,7 +195,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
@undoBatch
@action
protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
- const docDragData = de.complete.docDragData;
+ const docDragData = de.complete.docDragData;
(this.props.Document.dropConverter instanceof ScriptField) &&
this.props.Document.dropConverter.script.run({ dragData: docDragData }); /// bcz: check this
if (docDragData) {
diff --git a/src/client/views/collections/CollectionTimeView.scss b/src/client/views/collections/CollectionTimeView.scss
index be745000e..fa7c87f4e 100644
--- a/src/client/views/collections/CollectionTimeView.scss
+++ b/src/client/views/collections/CollectionTimeView.scss
@@ -48,6 +48,7 @@
.collectionTimeView-flyout {
width: 400px;
display: block;
+ text-align: left;
.collectionTimeView-flyout-item {
background-color: lightgray;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index f8f8a0943..c02c4ac3f 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -6,7 +6,7 @@ import { observer } from "mobx-react";
import { Doc, DocListCast, Field, HeightSym, WidthSym, DataSym, Opt } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
-import { Document, listSpec } from '../../../new_fields/Schema';
+import { Document, listSpec, createSchema, makeInterface } from '../../../new_fields/Schema';
import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types';
import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
@@ -29,7 +29,7 @@ import { ImageBox } from '../nodes/ImageBox';
import { KeyValueBox } from '../nodes/KeyValueBox';
import { ScriptBox } from '../ScriptBox';
import { Templates } from '../Templates';
-import { CollectionSubView } from "./CollectionSubView";
+import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
import { CollectionViewType } from './CollectionView';
@@ -46,7 +46,7 @@ export interface TreeViewProps {
renderDepth: number;
deleteDoc: (doc: Doc) => boolean;
moveDocument: DragManager.MoveFunction;
- dropAction: "alias" | "copy" | undefined;
+ dropAction: dropActionType;
addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
pinToPres: (document: Doc) => void;
panelWidth: () => number;
@@ -632,8 +632,16 @@ class TreeView extends React.Component<TreeViewProps> {
}
}
+export type collectionTreeViewProps = {
+ treeViewHideTitle?: boolean;
+ treeViewHideHeaderFields?: boolean;
+ onCheckedClick?: ScriptField;
+};
+
+let xx: collectionTreeViewProps = {};
+
@observer
-export class CollectionTreeView extends CollectionSubView(Document) {
+export class CollectionTreeView extends CollectionSubView(Document, xx) {
private treedropDisposer?: DragManager.DragDropDisposer;
private _mainEle?: HTMLDivElement;
@@ -665,7 +673,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
const doAddDoc = () =>
Doc.AddDocToList(this.props.Document[DataSym], this.props.fieldKey, doc, relativeTo, before, false, false, false);
if (this.props.Document.resolvedDataDoc instanceof Promise) {
- this.props.Document.resolvedDataDoc.then(resolved => doAddDoc());
+ this.props.Document.resolvedDataDoc.then((resolved: any) => doAddDoc());
} else {
doAddDoc();
}
@@ -773,7 +781,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
- {(this.props.Document.treeViewHideTitle ? (null) : <EditableView
+ {(this.props.treeViewHideTitle || this.props.Document.treeViewHideTitle ? (null) : <EditableView
contents={this.dataDoc.title}
editing={false}
display={"block"}
@@ -792,8 +800,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
{
TreeView.GetChildElements(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.backgroundColor, this.props.ScreenToLocalTransform,
- this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => BoolCast(this.props.Document.treeViewHideHeaderFields),
- BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, ScriptCast(this.props.Document.onCheckedClick), this.props.ignoreFields)
+ this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.props.Document.treeViewHideHeaderFields),
+ BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, this.props.onCheckedClick || ScriptCast(this.props.Document.onCheckedClick), this.props.ignoreFields)
}
</ul>
</div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a1f173746..ab553b206 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -8,7 +8,7 @@ import * as React from 'react';
import Lightbox from 'react-image-lightbox-with-rotate';
import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app
import { DateField } from '../../../new_fields/DateField';
-import { DataSym, Doc, DocListCast, Field } from '../../../new_fields/Doc';
+import { DataSym, Doc, DocListCast, Field, Opt } from '../../../new_fields/Doc';
import { List } from '../../../new_fields/List';
import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
import { ImageField } from '../../../new_fields/URLField';
@@ -320,64 +320,63 @@ export class CollectionView extends Touchable<FieldViewProps> {
* Responds to clicking the check box in the flyout menu
*/
facetClick = (facetHeader: string) => {
- const facetCollection = this.props.Document._facetCollection;
- if (facetCollection instanceof Doc) {
- const found = DocListCast(facetCollection.data).findIndex(doc => doc.title === facetHeader);
- if (found !== -1) {
- (facetCollection.data as List<Doc>).splice(found, 1);
- const docFilter = Cast(this.props.Document._docFilters, listSpec("string"));
- if (docFilter) {
- let index: number;
- while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
- docFilter.splice(index, 3);
- }
+ const facetCollection = this.props.Document;
+ const found = DocListCast(facetCollection[this.props.fieldKey + "-filter"]).findIndex(doc => doc.title === facetHeader);
+ if (found !== -1) {
+ (facetCollection[this.props.fieldKey + "-filter"] as List<Doc>).splice(found, 1);
+ const docFilter = Cast(this.props.Document._docFilters, listSpec("string"));
+ if (docFilter) {
+ let index: number;
+ while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
+ docFilter.splice(index, 3);
}
- const docRangeFilters = Cast(this.props.Document._docRangeFilters, listSpec("string"));
- if (docRangeFilters) {
- let index: number;
- while ((index = docRangeFilters.findIndex(item => item === facetHeader)) !== -1) {
- docRangeFilters.splice(index, 3);
- }
+ }
+ const docRangeFilters = Cast(this.props.Document._docRangeFilters, listSpec("string"));
+ if (docRangeFilters) {
+ let index: number;
+ while ((index = docRangeFilters.findIndex(item => item === facetHeader)) !== -1) {
+ docRangeFilters.splice(index, 3);
}
- } else {
- const allCollectionDocs = DocListCast(this.dataDoc[this.props.fieldKey]);
- const facetValues = Array.from(allCollectionDocs.reduce((set, child) =>
- set.add(Field.toString(child[facetHeader] as Field)), new Set<string>()));
-
- let nonNumbers = 0;
- let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
- facetValues.map(val => {
- const num = Number(val);
- if (Number.isNaN(num)) {
- nonNumbers++;
- } else {
- minVal = Math.min(num, minVal);
- maxVal = Math.max(num, maxVal);
- }
- });
- if (nonNumbers / allCollectionDocs.length < .1) {
- const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader);
- const newFacet = Docs.Create.SliderDocument({ title: facetHeader });
- Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
- newFacet.treeViewExpandedView = "layout";
- newFacet.treeViewOpen = true;
- newFacet._sliderMin = ranged === undefined ? minVal : ranged[0];
- newFacet._sliderMax = ranged === undefined ? maxVal : ranged[1];
- newFacet._sliderMinThumb = minVal;
- newFacet._sliderMaxThumb = maxVal;
- newFacet.target = this.props.Document;
- const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`;
- newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" });
-
- Doc.AddDocToList(facetCollection, "data", newFacet);
+ }
+ } else {
+ const allCollectionDocs = DocListCast(this.dataDoc[this.props.fieldKey]);
+ const facetValues = Array.from(allCollectionDocs.reduce((set, child) =>
+ set.add(Field.toString(child[facetHeader] as Field)), new Set<string>()));
+
+ let nonNumbers = 0;
+ let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
+ facetValues.map(val => {
+ const num = Number(val);
+ if (Number.isNaN(num)) {
+ nonNumbers++;
} else {
- const newFacet = Docs.Create.TreeDocument([], { title: facetHeader, treeViewOpen: true, isFacetFilter: true });
- const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.dataDoc };
- const params = { layoutDoc: Doc.name, dataDoc: Doc.name, };
- newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, params, capturedVariables);
- Doc.AddDocToList(facetCollection, "data", newFacet);
+ minVal = Math.min(num, minVal);
+ maxVal = Math.max(num, maxVal);
}
+ });
+ let newFacet: Opt<Doc>;
+ if (nonNumbers / allCollectionDocs.length < .1) {
+ newFacet = Docs.Create.SliderDocument({ title: facetHeader });
+ const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader);
+ Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
+ newFacet.treeViewExpandedView = "layout";
+ newFacet.treeViewOpen = true;
+ newFacet._sliderMin = ranged === undefined ? minVal : ranged[0];
+ newFacet._sliderMax = ranged === undefined ? maxVal : ranged[1];
+ newFacet._sliderMinThumb = minVal;
+ newFacet._sliderMaxThumb = maxVal;
+ newFacet.target = this.props.Document;
+ const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`;
+ newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" });
+
+ Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
+ } else {
+ newFacet = Docs.Create.TreeDocument([], { title: facetHeader, treeViewOpen: true, isFacetFilter: true });
+ const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.dataDoc };
+ const params = { layoutDoc: Doc.name, dataDoc: Doc.name, };
+ newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, params, capturedVariables);
}
+ Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
}
}
@@ -388,27 +387,24 @@ export class CollectionView extends Touchable<FieldViewProps> {
return false;
}), returnFalse, action(() => this._facetWidth = this._facetWidth < 15 ? 200 : 0));
}
+ filterBackground = () => "dimGray";
+ @computed get scriptField() {
+ const scriptText = "setDocFilter(containingTreeView.target, heading, this.title, checked)";
+ return ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name });
+ }
@computed get filterView() {
- const facetCollection = Cast(this.props.Document?._facetCollection, Doc);
- if (this._facetWidth && facetCollection === undefined) setTimeout(() => {
- const scriptText = "setDocFilter(containingTreeView.target, heading, this.title, checked)";
- const facetCollection = Docs.Create.TreeDocument([], { title: "facetFilters", _yMargin: 0, treeViewHideTitle: true, treeViewHideHeaderFields: true });
- facetCollection.target = this.props.Document;
- facetCollection.onCheckedClick = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name });
- this.props.Document.excludeFields = new List<string>(["_facetCollection", "_docFilters"]);
-
- this.props.Document._facetCollection = facetCollection;
- }, 0);
+ const facetCollection = this.props.Document;
+ this._facetWidth && setTimeout(() => facetCollection.target = this.props.Document, 0);
const flyout = (
<div className="collectionTimeView-flyout" style={{ width: `${this._facetWidth}`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}>
{this._allFacets.map(facet => <label className="collectionTimeView-flyout-item" key={`${facet}`} onClick={e => this.facetClick(facet)}>
- <input type="checkbox" onChange={e => { }} checked={DocListCast((this.props.Document._facetCollection as Doc)?.data).some(d => d.title === facet)} />
+ <input type="checkbox" onChange={e => { }} checked={DocListCast(this.props.Document[this.props.fieldKey + "-filter"]).some(d => d.title === facet)} />
<span className="checkmark" />
{facet}
</label>)}
</div>
);
- return !facetCollection ? (null) :
+ return !this._facetWidth || this.props.dontRegisterView ? (null) :
<div className="collectionTimeView-treeView" style={{ width: `${this._facetWidth}px`, overflow: this._facetWidth < 15 ? "hidden" : undefined }}>
<div className="collectionTimeView-addFacet" style={{ width: `${this._facetWidth}px` }} onPointerDown={e => e.stopPropagation()}>
<Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}>
@@ -419,8 +415,19 @@ export class CollectionView extends Touchable<FieldViewProps> {
</Flyout>
</div>
<div className="collectionTimeView-tree" key="tree">
- <CollectionTreeView {...this.props} CollectionView={this} annotationsKey={""} PanelWidth={this.facetWidth}
- DataDoc={undefined} Document={facetCollection}
+ <CollectionTreeView {...this.props}
+ CollectionView={this}
+ treeViewHideTitle={true}
+ treeViewHideHeaderFields={true}
+ onCheckedClick={this.scriptField!}
+ ignoreFields={["_facetCollection", "_docFilters"]}
+ annotationsKey={""}
+ dontRegisterView={true}
+ PanelWidth={this.facetWidth}
+ DataDoc={facetCollection}
+ Document={facetCollection}
+ backgroundColor={this.filterBackground}
+ fieldKey={`${this.props.fieldKey}-filter`}
moveDocument={(doc: Doc) => false}
removeDocument={(doc: Doc) => false}
addDocument={(doc: Doc) => false} />
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 6619330a1..0305f43d5 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -10,6 +10,7 @@ import { Transform } from "../../util/Transform";
import { CollectionView } from "../collections/CollectionView";
import { AudioBox } from "./AudioBox";
import { VideoBox } from "./VideoBox";
+import { dropActionType } from "../../util/DragManager";
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
@@ -25,7 +26,7 @@ export interface FieldViewProps {
DataDoc?: Doc;
LibraryPath: Doc[];
onClick?: ScriptField;
- dropAction: dropAction;
+ dropAction: dropActionType;
isSelected: (outsideReaction?: boolean) => boolean;
select: (isCtrlPressed: boolean) => void;
renderDepth: number;