aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorFawn <fangrui_tong@brown.edu>2019-11-14 23:39:52 -0500
committerFawn <fangrui_tong@brown.edu>2019-11-14 23:39:52 -0500
commitf108bc9f9f1ff9cad2db4b794e3b433768c342a1 (patch)
treea2603e85291d118bbea3370ce823ab833e63281a /src/client/views/collections
parente3f06e390f98cc5b97d63fc287daff994d5fef6f (diff)
parentc9fbdb9cfd5fcf35f7a599706cb41d4e7e586e19 (diff)
merged with master
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionMasonryViewFieldRow.tsx164
-rw-r--r--src/client/views/collections/CollectionSchemaMovableTableHOC.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaView.scss27
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx425
-rw-r--r--src/client/views/collections/CollectionStackingView.scss40
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx15
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx23
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx17
12 files changed, 236 insertions, 485 deletions
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 4259e948b..52ebfafd3 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -20,6 +20,7 @@ import { anchorPoints, Flyout } from "../DocumentDecorations";
import { EditableView } from "../EditableView";
import { CollectionStackingView } from "./CollectionStackingView";
import "./CollectionStackingView.scss";
+import { undo } from "prosemirror-history";
library.add(faPalette);
@@ -40,27 +41,28 @@ interface CMVFieldRowProps {
export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowProps> {
@observable private _background = "inherit";
@observable private _createAliasSelected: boolean = false;
+ @observable private _collapsed: boolean = false;
+ @observable private _headingsHack: number = 1;
+ @observable private _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
+ @observable private _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
- private _dropRef: HTMLDivElement | null = null;
- private dropDisposer?: DragManager.DragDropDisposer;
+ private _dropDisposer?: DragManager.DragDropDisposer;
private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
private _contRef: React.RefObject<HTMLDivElement> = React.createRef();
private _sensitivity: number = 16;
+ private _counter: number = 0;
- @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
- @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
createRowDropRef = (ele: HTMLDivElement | null) => {
- this._dropRef = ele;
- this.dropDisposer && this.dropDisposer();
+ this._dropDisposer && this._dropDisposer();
if (ele) {
- this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
+ this._dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
}
}
getTrueHeight = () => {
- if (this.collapsed) {
+ if (this._collapsed) {
this.props.setDocHeight(this._heading, 20);
} else {
let rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
@@ -74,14 +76,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
rowDrop = action((e: Event, de: DragManager.DropEvent) => {
this._createAliasSelected = false;
if (de.data instanceof DragManager.DocumentDragData) {
+ (this.props.parent.Document.dropConverter instanceof ScriptField) &&
+ this.props.parent.Document.dropConverter.script.run({ dragData: de.data });
let key = StrCast(this.props.parent.props.Document.sectionFilter);
let castedValue = this.getValue(this._heading);
- if (castedValue) {
- de.data.droppedDocuments.forEach(d => d[key] = castedValue);
- }
- else {
- de.data.droppedDocuments.forEach(d => d[key] = undefined);
- }
+ de.data.droppedDocuments.forEach(d => d[key] = castedValue);
this.props.parent.drop(e, de);
e.stopPropagation();
}
@@ -89,15 +88,9 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
getValue = (value: string): any => {
let parsed = parseInt(value);
- if (!isNaN(parsed)) {
- return parsed;
- }
- if (value.toLowerCase().indexOf("true") > -1) {
- return true;
- }
- if (value.toLowerCase().indexOf("false") > -1) {
- return false;
- }
+ if (!isNaN(parsed)) return parsed;
+ if (value.toLowerCase().indexOf("true") > -1) return true;
+ if (value.toLowerCase().indexOf("false") > -1) return false;
return value;
}
@@ -131,12 +124,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
}
}
- @action
- pointerEnteredRow = () => {
- if (SelectionManager.GetIsDragging()) {
- this._background = "#b4b4b4";
- }
- }
+ pointerEnteredRow = action(() => SelectionManager.GetIsDragging() && (this._background = "#b4b4b4"));
@action
pointerLeaveRow = () => {
@@ -154,8 +142,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
return this.props.parent.props.addDocument(newDoc);
}
- @action
- deleteRow = () => {
+ deleteRow = undoBatch(action(() => {
this._createAliasSelected = false;
let key = StrCast(this.props.parent.props.Document.sectionFilter);
this.props.docList.forEach(d => d[key] = undefined);
@@ -163,7 +150,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
let index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
this.props.parent.sectionHeaders.splice(index, 1);
}
- }
+ }));
@action
collapseSection = () => {
@@ -205,6 +192,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
document.removeEventListener("pointerup", this.pointerUp);
}
+ @action
headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
e.stopPropagation();
e.preventDefault();
@@ -251,48 +239,31 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
);
}
- @action
- toggleAlias = () => {
- this._createAliasSelected = true;
- }
+ toggleAlias = action(() => this._createAliasSelected = true);
+ toggleVisibility = action(() => this._collapsed = !this._collapsed);
renderMenu = () => {
let selected = this._createAliasSelected;
- return (
- <div className="collectionStackingView-optionPicker">
- <div className="optionOptions">
- <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.toggleAlias}>Create Alias</div>
- </div>
+ return (<div className="collectionStackingView-optionPicker">
+ <div className="optionOptions">
+ <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.toggleAlias}>Create Alias</div>
+ <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.deleteRow}>Delete</div>
</div>
- );
+ </div>);
}
- @observable private collapsed: boolean = false;
-
- private toggleVisibility = action(() => {
- this.collapsed = !this.collapsed;
- });
-
- @observable _headingsHack: number = 1;
-
handleResize = (size: any) => {
- this.counter += 1;
- if (this.counter !== 1) {
+ if (++this._counter !== 1) {
this.getTrueHeight();
}
}
- private counter: number = 0;
render() {
- let cols = this.props.rows();
let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
let key = StrCast(this.props.parent.props.Document.sectionFilter);
- let templatecols = "";
- let headings = this.props.headings();
let heading = this._heading;
let style = this.props.parent;
- let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
let headerEditableViewProps = {
GetValue: () => evContents,
@@ -313,45 +284,46 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
toggle: this.toggleVisibility,
color: this._color
};
- let headingView = this.props.headingObject ?
- <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
- <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
- <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
- title={evContents === `NO ${key.toUpperCase()} VALUE` ?
- `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
- style={{
- width: "100%",
- background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
- color: "grey"
- }}>
- {<EditableView {...headerEditableViewProps} />}
- {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
- <div className="collectionStackingView-sectionColor">
- <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
- <button className="collectionStackingView-sectionColorButton">
- <FontAwesomeIcon icon="palette" size="lg" />
- </button>
- </ Flyout >
- </div>
- }
- {evContents === `NO ${key.toUpperCase()} VALUE` ?
- (null) :
- <button className="collectionStackingView-sectionDelete" onClick={this.deleteRow}>
- <FontAwesomeIcon icon="trash" size="lg" />
- </button>}
- {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
- <div className="collectionStackingView-sectionOptions">
- <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
- <button className="collectionStackingView-sectionOptionButton">
- <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
- </button>
- </Flyout>
- </div>
- }
- </div>
- </div > : (null);
+ let headingView = this.props.parent.props.Document.miniHeaders ?
+ <div className="collectionStackingView-miniHeader" style={{ width: "100%" }}>
+ {<EditableView {...headerEditableViewProps} />}
+ </div> :
+ this.props.headingObject ?
+ <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
+ <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
+ title={evContents === `NO ${key.toUpperCase()} VALUE` ?
+ `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
+ style={{
+ width: "100%",
+ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
+ color: "grey"
+ }}>
+ {<EditableView {...headerEditableViewProps} />}
+ {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+ <div className="collectionStackingView-sectionColor">
+ <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
+ <button className="collectionStackingView-sectionColorButton">
+ <FontAwesomeIcon icon="palette" size="lg" />
+ </button>
+ </ Flyout >
+ </div>
+ }
+ <button className="collectionStackingView-sectionDelete" onClick={this.collapseSection}>
+ <FontAwesomeIcon icon={this._collapsed ? "chevron-down" : "chevron-up"} size="lg" />
+ </button>
+ {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+ <div className="collectionStackingView-sectionOptions">
+ <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
+ <button className="collectionStackingView-sectionOptionButton">
+ <FontAwesomeIcon icon="ellipsis-v" size="lg" />
+ </button>
+ </Flyout>
+ </div>
+ }
+ </div>
+ </div > : (null);
const background = this._background; //to account for observables in Measure
- const collapsed = this.collapsed;
+ const collapsed = this._collapsed;
let chromeStatus = this.props.parent.props.Document.chromeStatus;
return (
<Measure offset onResize={this.handleResize}>
@@ -366,7 +338,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
>
{headingView}
{collapsed ? (null) :
- < div >
+ < div style={{ position: "relative" }}>
<div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
ref={this._contRef}
style={{
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 39abc41ec..274c8b6d1 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -229,7 +229,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
<div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
<ReactTableDefaults.TrComponent>
<div className="row-dragger">
- <div className="row-option" onClick={() => this.props.removeDoc(this.props.rowInfo.original)}><FontAwesomeIcon icon="trash" size="sm" /></div>
+ <div className="row-option" onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div>
<div className="row-option" style={{ cursor: "grab" }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div>
</div>
{children}
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index e0cedc210..cb95dcbbc 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -10,6 +10,7 @@
top: 0;
width: 100%;
height: 100%;
+ margin-top: 0;
transition: top 0.5s;
display: flex;
justify-content: space-between;
@@ -38,30 +39,6 @@
}
}
-.collectionSchemaView-previewRegion {
- position: relative;
- background: $light-color;
- height: auto !important;
-
- .collectionSchemaView-previewDoc {
- height: 100%;
- width: 100%;
- position: absolute;
- }
-
- .collectionSchemaView-input {
- position: absolute;
- max-width: 150px;
- width: 100%;
- bottom: 0px;
- }
-
- .documentView-node:first-child {
- position: relative;
- background: $light-color;
- }
-}
-
.ReactTable {
width: 100%;
background: white;
@@ -470,7 +447,7 @@ button.add-column {
overflow: visible;
}
-.sub {
+.reactTable-sub {
padding: 10px 30px;
background-color: rgb(252, 252, 252);
width: calc(100% - 50px);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 34f642f80..ebd47fd19 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,37 +1,34 @@
import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCog, faPlus, faTable, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons';
+import { faCog, faPlus, faSortDown, faSortUp, faTable } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, trace, untracked } from "mobx";
+import { action, computed, observable, untracked } from "mobx";
import { observer } from "mobx-react";
-import ReactTable, { CellInfo, ComponentPropsGetterR, Column, RowInfo, ResizedChangeFunction, Resize } from "react-table";
+import ReactTable, { CellInfo, Column, ComponentPropsGetterR, Resize, SortingRule } from "react-table";
import "react-table/react-table.css";
-import { emptyFunction, returnOne, returnEmptyString } from "../../../Utils";
import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
-import { Docs, DocumentOptions } from "../../documents/Documents";
+import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { ComputedField } from "../../../new_fields/ScriptField";
import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
+import { Docs, DocumentOptions } from "../../documents/Documents";
+import { DocumentType } from "../../documents/DocumentTypes";
import { Gateway } from "../../northstar/manager/Gateway";
-import { DragManager } from "../../util/DragManager";
-import { CompileScript, ts, Transformer } from "../../util/Scripting";
+import { CompileScript, Transformer, ts } from "../../util/Scripting";
import { Transform } from "../../util/Transform";
+import { undoBatch } from "../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss';
import { ContextMenu } from "../ContextMenu";
import '../DocumentDecorations.scss';
-import { DocumentView } from "../nodes/DocumentView";
+import { CellProps, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell, CollectionSchemaNumberCell, CollectionSchemaStringCell } from "./CollectionSchemaCells";
+import { CollectionSchemaAddColumnHeader, CollectionSchemaHeader } from "./CollectionSchemaHeaders";
+import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
import { CollectionView } from "./CollectionView";
-import { undoBatch } from "../../util/UndoManager";
-import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders";
-import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell } from "./CollectionSchemaCells";
-import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { DocumentType } from "../../documents/DocumentTypes";
-
+import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
library.add(faCog, faPlus, faSortUp, faSortDown);
library.add(faTable);
@@ -73,20 +70,14 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
super.CreateDropTarget(ele);
}
- isFocused = (doc: Doc): boolean => {
- if (!this.props.isSelected()) return false;
- return doc === this._focusedTable;
- }
+ isFocused = (doc: Doc): boolean => this.props.isSelected() && doc === this._focusedTable;
- @action
- setFocused = (doc: Doc): void => {
- this._focusedTable = doc;
- }
+ @action setFocused = (doc: Doc) => this._focusedTable = doc;
- @action
- setPreviewDoc = (doc: Doc): void => {
- this.previewDoc = doc;
- }
+ @action setPreviewDoc = (doc: Doc) => this.previewDoc = doc;
+
+ @undoBatch
+ @action setPreviewScript = (script: string) => this.previewScript = script
//toggles preview side-panel of schema
@action
@@ -128,17 +119,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
}
}
- onWheel = (e: React.WheelEvent): void => {
- if (this.props.active()) {
- e.stopPropagation();
- }
- }
-
@computed
get previewDocument(): Doc | undefined {
- let selected = this.previewDoc;
- let pdc = selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined;
- return pdc;
+ return this.previewDoc ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(this.previewDoc[this.previewScript], Doc)) : this.previewDoc) : undefined;
}
getPreviewTransform = (): Transform => {
@@ -155,10 +138,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
get previewPanel() {
let layoutDoc = this.previewDocument ? Doc.expandTemplateLayout(this.previewDocument, this.props.DataDoc) : undefined;
return <div ref={this.createTarget}>
- <CollectionSchemaPreview
+ <ContentFittingDocumentView
Document={layoutDoc}
DataDocument={this.previewDocument !== this.props.DataDoc ? this.props.DataDoc : undefined}
- fieldKey={this.props.fieldKey}
childDocs={this.childDocs}
renderDepth={this.props.renderDepth}
ruleProvider={this.props.Document.isRuleProvider && layoutDoc && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
@@ -180,62 +162,51 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
</div>;
}
- @undoBatch
- @action
- setPreviewScript = (script: string) => {
- this.previewScript = script;
- }
-
@computed
get schemaTable() {
- return (
- <SchemaTable
- Document={this.props.Document}
- PanelHeight={this.props.PanelHeight}
- PanelWidth={this.props.PanelWidth}
- childDocs={this.childDocs}
- CollectionView={this.props.CollectionView}
- ContainingCollectionView={this.props.ContainingCollectionView}
- ContainingCollectionDoc={this.props.ContainingCollectionDoc}
- fieldKey={this.props.fieldKey}
- renderDepth={this.props.renderDepth}
- moveDocument={this.props.moveDocument}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- active={this.props.active}
- onDrop={this.onDrop}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- isSelected={this.props.isSelected}
- isFocused={this.isFocused}
- setFocused={this.setFocused}
- setPreviewDoc={this.setPreviewDoc}
- deleteDocument={this.props.removeDocument}
- dataDoc={this.props.DataDoc}
- />
- );
+ return <SchemaTable
+ Document={this.props.Document}
+ PanelHeight={this.props.PanelHeight}
+ PanelWidth={this.props.PanelWidth}
+ childDocs={this.childDocs}
+ CollectionView={this.props.CollectionView}
+ ContainingCollectionView={this.props.ContainingCollectionView}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+ fieldKey={this.props.fieldKey}
+ renderDepth={this.props.renderDepth}
+ moveDocument={this.props.moveDocument}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ active={this.props.active}
+ onDrop={this.onDrop}
+ addDocTab={this.props.addDocTab}
+ pinToPres={this.props.pinToPres}
+ isSelected={this.props.isSelected}
+ isFocused={this.isFocused}
+ setFocused={this.setFocused}
+ setPreviewDoc={this.setPreviewDoc}
+ deleteDocument={this.props.removeDocument}
+ addDocument={this.props.addDocument}
+ dataDoc={this.props.DataDoc}
+ />;
}
@computed
public get schemaToolbar() {
- return (
- <div className="collectionSchemaView-toolbar">
- <div className="collectionSchemaView-toolbar-item">
- <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={this.previewWidth() !== 0} onChange={this.toggleExpander} />Show Preview</div>
- </div>
+ return <div className="collectionSchemaView-toolbar">
+ <div className="collectionSchemaView-toolbar-item">
+ <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={this.previewWidth() !== 0} onChange={this.toggleExpander} />Show Preview</div>
</div>
- );
+ </div>;
}
render() {
- return (
- <div className="collectionSchemaView-container" style={{ height: "100%", marginTop: "0", }}>
- <div className="collectionSchemaView-tableContainer" onPointerDown={this.onPointerDown} onWheel={this.onWheel} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createTarget}>
- {this.schemaTable}
- </div>
- {this.dividerDragger}
- {!this.previewWidth() ? (null) : this.previewPanel}
+ return <div className="collectionSchemaView-container">
+ <div className="collectionSchemaView-tableContainer" onPointerDown={this.onPointerDown} onWheel={e => this.props.active() && e.stopPropagation()} onDrop={e => this.onDrop(e, {})} ref={this.createTarget}>
+ {this.schemaTable}
</div>
- );
+ {this.dividerDragger}
+ {!this.previewWidth() ? (null) : this.previewPanel}
+ </div>;
}
}
@@ -251,6 +222,7 @@ export interface SchemaTableProps {
fieldKey: string;
renderDepth: number;
deleteDocument: (document: Doc) => boolean;
+ addDocument: (document: Doc) => boolean;
moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
ScreenToLocalTransform: () => Transform;
active: () => boolean;
@@ -307,11 +279,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
return resized;
}, [] as { id: string, value: number }[]);
}
- @computed get sorted(): { id: string, desc: boolean }[] {
+ @computed get sorted(): SortingRule[] {
return this.columns.reduce((sorted, shf) => {
shf.desc && sorted.push({ id: shf.heading, desc: shf.desc });
return sorted;
- }, [] as { id: string, desc: boolean }[]);
+ }, [] as SortingRule[]);
}
@computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
@@ -321,11 +293,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
let tableIsFocused = this.props.isFocused(this.props.Document);
let focusedRow = this._focusedCell.row;
let focusedCol = this._focusedCell.col;
- let isEditable = !this._headerIsEditing;// && this.props.isSelected();
+ let isEditable = !this._headerIsEditing;
- let children = this.childDocs;
-
- if (children.reduce((found, doc) => found || doc.type === "collection", false)) {
+ if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) {
columns.push(
{
expander: true,
@@ -433,26 +403,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
return Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
}
- tableRemoveDoc = (document: Doc): boolean => {
-
- let children = this.childDocs;
- if (children.indexOf(document) !== -1) {
- children.splice(children.indexOf(document), 1);
- this.childDocs = children;
- return true;
- }
- return false;
- }
-
private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
- const that = this;
- if (!rowInfo) {
- return {};
- }
- return {
+ return !rowInfo ? {} : {
ScreenToLocalTransform: this.props.ScreenToLocalTransform,
addDoc: this.tableAddDoc,
- removeDoc: this.tableRemoveDoc,
+ removeDoc: this.props.deleteDocument,
rowInfo,
rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
textWrapRow: this.toggleTextWrapRow,
@@ -461,14 +416,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
private getTdProps: ComponentPropsGetterR = (state, rowInfo, column, instance) => {
- if (!rowInfo) return {};
- if (!column) return {};
+ if (!rowInfo || column) return {};
let row = rowInfo.index;
//@ts-ignore
let col = this.columns.map(c => c.heading).indexOf(column!.id);
let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
- let isEditing = this.props.isFocused(this.props.Document) && this._cellIsEditing;
// TODO: editing border doesn't work :(
return {
style: {
@@ -478,113 +431,68 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
@action
- onExpandCollection = (collection: Doc): void => {
- this._openCollections.push(collection[Id]);
- }
-
- @action
onCloseCollection = (collection: Doc): void => {
let index = this._openCollections.findIndex(col => col === collection[Id]);
if (index > -1) this._openCollections.splice(index, 1);
}
- @action
- setCellIsEditing = (isEditing: boolean): void => {
- this._cellIsEditing = isEditing;
- }
-
- @action
- setHeaderIsEditing = (isEditing: boolean): void => {
- this._headerIsEditing = isEditing;
- }
+ @action onExpandCollection = (collection: Doc) => this._openCollections.push(collection[Id]);
+ @action setCellIsEditing = (isEditing: boolean) => this._cellIsEditing = isEditing;
+ @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing;
onPointerDown = (e: React.PointerEvent): void => {
this.props.setFocused(this.props.Document);
- if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) {
- if (this.props.isSelected()) e.stopPropagation();
- }
- }
-
- onWheel = (e: React.WheelEvent): void => {
- if (this.props.active()) {
+ if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected()) {
e.stopPropagation();
}
}
+ @action
onKeyDown = (e: KeyboardEvent): void => {
if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) {
let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
- this.changeFocusedCellByDirection(direction);
+ this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
- let children = this.childDocs;
- const pdoc = FieldValue(children[this._focusedCell.row]);
+ const pdoc = FieldValue(this.childDocs[this._focusedCell.row]);
pdoc && this.props.setPreviewDoc(pdoc);
}
}
- @action
- changeFocusedCellByDirection = (direction: string): void => {
- let children = this.childDocs;
+ changeFocusedCellByDirection = (direction: string, curRow: number, curCol: number) => {
switch (direction) {
- case "tab":
- if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === children.length) {
- this._focusedCell = { row: 0, col: 0 };
- } else if (this._focusedCell.col + 1 === this.columns.length) {
- this._focusedCell = { row: this._focusedCell.row + 1, col: 0 };
- } else {
- this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 };
- }
- break;
- case "right":
- this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 === this.columns.length ? this._focusedCell.col : this._focusedCell.col + 1 };
- break;
- case "left":
- this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col === 0 ? this._focusedCell.col : this._focusedCell.col - 1 };
- break;
- case "up":
- this._focusedCell = { row: this._focusedCell.row === 0 ? this._focusedCell.row : this._focusedCell.row - 1, col: this._focusedCell.col };
- break;
- case "down":
- this._focusedCell = { row: this._focusedCell.row + 1 === children.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col };
- break;
+ case "tab": return { row: (curRow + 1 === this.childDocs.length ? 0 : curRow + 1), col: curCol + 1 === this.columns.length ? 0 : curCol + 1 };
+ case "right": return { row: curRow, col: curCol + 1 === this.columns.length ? curCol : curCol + 1 };
+ case "left": return { row: curRow, col: curCol === 0 ? curCol : curCol - 1 };
+ case "up": return { row: curRow === 0 ? curRow : curRow - 1, col: curCol };
+ case "down": return { row: curRow + 1 === this.childDocs.length ? curRow : curRow + 1, col: curCol };
}
+ return this._focusedCell;
}
@action
changeFocusedCellByIndex = (row: number, col: number): void => {
- this._focusedCell = { row: row, col: col };
+ if (this._focusedCell.row !== row || this._focusedCell.col !== col) {
+ this._focusedCell = { row: row, col: col };
+ }
this.props.setFocused(this.props.Document);
}
@undoBatch
createRow = () => {
- let children = this.childDocs;
-
- let newDoc = Docs.Create.TextDocument({ width: 100, height: 30 });
- let proto = Doc.GetProto(newDoc);
- proto.title = "";
- children.push(newDoc);
-
- this.childDocs = children;
+ let newDoc = Docs.Create.TextDocument({ title: "", width: 100, height: 30 });
+ this.props.addDocument(newDoc);
}
@undoBatch
@action
createColumn = () => {
let index = 0;
- let columns = this.columns;
- let found = columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
- if (!found) {
- columns.push(new SchemaHeaderField("New field", "#f1efeb"));
- this.columns = columns;
- return;
- }
+ let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
while (found) {
index++;
- found = columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
+ found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
}
- columns.push(new SchemaHeaderField("New field (" + index + ")", "#f1efeb"));
- this.columns = columns;
+ this.columns.push(new SchemaHeaderField(`New field ${index ? "(" + index + ")" : ""}`, "#f1efeb"));
}
@undoBatch
@@ -677,9 +585,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
@action
- setColumns = (columns: SchemaHeaderField[]) => {
- this.columns = columns;
- }
+ setColumns = (columns: SchemaHeaderField[]) => this.columns = columns
@undoBatch
reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
@@ -725,11 +631,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
let textWrapped = this.textWrappedRows;
let index = textWrapped.findIndex(id => doc[Id] === id);
- if (index > -1) {
- textWrapped.splice(index, 1);
- } else {
- textWrapped.push(doc[Id]);
- }
+ index > -1 ? textWrapped.splice(index, 1) : textWrapped.push(doc[Id]);
this.textWrappedRows = textWrapped;
}
@@ -759,13 +661,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
expanded={expanded}
resized={this.resized}
onResizedChange={this.onResizedChange}
- SubComponent={hasCollectionChild ?
- row => {
- if (row.original.type === "collection") {
- return <div className="sub"><SchemaTable {...this.props} Document={row.original} childDocs={undefined} /></div>;
- }
- }
- : undefined}
+ SubComponent={!hasCollectionChild ? undefined : row => (row.original.type !== "collection") ? (null) :
+ <div className="reactTable-sub"><SchemaTable {...this.props} Document={row.original} childDocs={undefined} /></div>}
/>;
}
@@ -881,145 +778,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
render() {
- return (
- <div className="collectionSchemaView-table" onPointerDown={this.onPointerDown} onWheel={this.onWheel}
- onDrop={(e: React.DragEvent) => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
- {this.reactTable}
- <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
- </div>
- );
- }
-}
-
-
-interface CollectionSchemaPreviewProps {
- Document?: Doc;
- DataDocument?: Doc;
- childDocs?: Doc[];
- renderDepth: number;
- fitToBox?: boolean;
- fieldKey: string;
- PanelWidth: () => number;
- PanelHeight: () => number;
- ruleProvider: Doc | undefined;
- focus?: (doc: Doc) => void;
- showOverlays?: (doc: Doc) => { title?: string, caption?: string };
- CollectionView?: CollectionView;
- CollectionDoc?: Doc;
- onClick?: ScriptField;
- getTransform: () => Transform;
- addDocument: (document: Doc) => boolean;
- moveDocument: (document: Doc, target: Doc, addDoc: ((doc: Doc) => boolean)) => boolean;
- removeDocument: (document: Doc) => boolean;
- active: () => boolean;
- whenActiveChanged: (isActive: boolean) => void;
- addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
- pinToPres: (document: Doc) => void;
- setPreviewScript: (script: string) => void;
- previewScript?: string;
-}
-
-@observer
-export class CollectionSchemaPreview extends React.Component<CollectionSchemaPreviewProps>{
- private dropDisposer?: DragManager.DragDropDisposer;
- _mainCont?: HTMLDivElement;
- private get layoutDoc() { return this.props.Document && Doc.Layout(this.props.Document); }
- private get nativeWidth() { return NumCast(this.layoutDoc!.nativeWidth, this.props.PanelWidth()); }
- private get nativeHeight() { return NumCast(this.layoutDoc!.nativeHeight, this.props.PanelHeight()); }
- private contentScaling = () => {
- let wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth());
- if (wscale * this.nativeHeight > this.props.PanelHeight()) {
- return this.props.PanelHeight() / (this.nativeHeight ? this.nativeHeight : this.props.PanelHeight());
- }
- return wscale;
- }
- protected createDropTarget = (ele: HTMLDivElement) => {
- }
- private createTarget = (ele: HTMLDivElement) => {
- this._mainCont = ele;
- this.dropDisposer && this.dropDisposer();
- if (ele) {
- this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
- }
- }
-
- @undoBatch
- @action
- drop = (e: Event, de: DragManager.DropEvent) => {
- if (de.data instanceof DragManager.DocumentDragData) {
- this.props.childDocs && this.props.childDocs.map(otherdoc => {
- let target = Doc.GetProto(otherdoc);
- target.layout = ComputedField.MakeFunction("this.image_data[0]");
- target.layoutCustom = Doc.MakeDelegate(de.data.draggedDocuments[0]);
- });
- e.stopPropagation();
- }
- return true;
- }
- private PanelWidth = () => this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth();
- private PanelHeight = () => this.nativeHeight && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight();
- private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling());
- get centeringOffset() { return this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; }
- @action
- onPreviewScriptChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- this.props.setPreviewScript(e.currentTarget.value);
- }
- @computed get borderRounding() {
- let br = StrCast(this.props.Document!.borderRounding);
- if (br.endsWith("%")) {
- let percent = Number(br.substr(0, br.length - 1)) / 100;
- let nativeDim = Math.min(NumCast(this.layoutDoc!.nativeWidth), NumCast(this.layoutDoc!.nativeHeight));
- let minDim = percent * (nativeDim ? nativeDim : Math.min(this.PanelWidth(), this.PanelHeight()));
- return minDim;
- }
- return undefined;
- }
-
-
- render() {
- let input = this.props.previewScript === undefined ? (null) :
- <div ref={this.createTarget}><input className="collectionSchemaView-input" value={this.props.previewScript} onChange={this.onPreviewScriptChange}
- style={{ left: `calc(50% - ${Math.min(75, (this.props.Document ? this.PanelWidth() / 2 : 75))}px)` }} /></div>;
- return (<div className="collectionSchemaView-previewRegion"
- style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}>
- {!this.props.Document || !this.props.PanelWidth ? (null) : (
- <div className="collectionSchemaView-previewDoc"
- style={{
- transform: `translate(${this.centeringOffset}px, 0px)`,
- borderRadius: this.borderRounding,
- display: "inline",
- height: this.props.PanelHeight(),
- width: this.props.PanelWidth()
- }}>
- <DocumentView {...this.props}
- DataDoc={this.props.DataDocument}
- Document={this.props.Document}
- fitToBox={this.props.fitToBox}
- onClick={this.props.onClick}
- ruleProvider={this.props.ruleProvider}
- showOverlays={this.props.showOverlays}
- addDocument={this.props.addDocument}
- removeDocument={this.props.removeDocument}
- moveDocument={this.props.moveDocument}
- whenActiveChanged={this.props.whenActiveChanged}
- ContainingCollectionView={this.props.CollectionView}
- ContainingCollectionDoc={this.props.CollectionDoc}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- parentActive={this.props.active}
- ScreenToLocalTransform={this.getTransform}
- renderDepth={this.props.renderDepth + 1}
- ContentScaling={this.contentScaling}
- PanelWidth={this.PanelWidth}
- PanelHeight={this.PanelHeight}
- focus={this.props.focus || emptyFunction}
- backgroundColor={returnEmptyString}
- bringToFront={emptyFunction}
- zoomToScale={emptyFunction}
- getScale={returnOne}
- />
- </div>)}
- {input}
- </div>);
+ return <div className="collectionSchemaView-table" onPointerDown={this.onPointerDown} onWheel={e => this.props.active() && e.stopPropagation()} onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
+ {this.reactTable}
+ <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
+ </div>;
}
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 3f4b678c7..29178b909 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -21,6 +21,10 @@
overflow-y: auto;
flex-wrap: wrap;
transition: top .5s;
+ >div {
+ position: relative;
+ display: block;
+ }
.collectionSchemaView-previewDoc {
height: 100%;
@@ -120,7 +124,38 @@
background: red;
}
}
-
+ .collectionStackingView-miniHeader {
+ width: 100%;
+ .editableView-container-editing-oneLine {
+ min-height: 20px;
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ }
+ span::before , span::after{
+ content: "";
+ width: 50%;
+ border-top: dashed gray 1px;
+ position: relative;
+ display: inline-block;
+ }
+ span::before {
+ margin-right: 10px;
+ }
+ span::after{
+ margin-left: 10px;
+ }
+ span {
+ position: relative;
+ text-align: center;
+ white-space: nowrap;
+ overflow: visible;
+ width: 100%;
+ display: flex;
+ color:gray;
+ align-items: center;
+ }
+ }
.collectionStackingView-sectionHeader {
text-align: center;
margin-left: 2px;
@@ -222,7 +257,6 @@
}
.collectionStackingView-optionPicker {
- width: 78px;
.optionOptions {
display: inline;
@@ -230,10 +264,10 @@
.optionPicker {
cursor: pointer;
- width: 20px;
height: 20px;
border-radius: 10px;
margin: 3px;
+ width:max-content;
&.active {
color: red;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7af56500e..be3bfca0a 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -16,7 +16,7 @@ import { DragManager } from "../../util/DragManager";
import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
import { EditableView } from "../EditableView";
-import { CollectionSchemaPreview } from "./CollectionSchemaView";
+import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
import "./CollectionStackingView.scss";
import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
import { CollectionSubView } from "./CollectionSubView";
@@ -44,7 +44,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
@computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
- @computed get showAddAGroup() { return (this.sectionFilter && this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode' && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled')); }
+ @computed get showAddAGroup() { return (this.sectionFilter && (this.props.Document.chromeStatus !== 'view-mode' && this.props.Document.chromeStatus !== 'disabled')); }
@computed get columnWidth() {
return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin,
this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250));
@@ -121,14 +121,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
return res;
} else {
let sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0);
- return this.props.ContentScaling() * (sum + (this.Sections.size ? 85 : -15));
+ return this.props.ContentScaling() * (sum + (this.Sections.size ? (this.props.Document.miniHeaders ? 20 : 85) : -15));
}
}
return -1;
},
(hgt: number) => {
let doc = hgt === -1 ? undefined : this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
- doc && (Doc.Layout(doc).height = hgt);
+ doc && hgt > 0 && (Doc.Layout(doc).height = hgt);
},
{ fireImmediately: true }
);
@@ -165,10 +165,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
let layoutDoc = Doc.Layout(doc);
let height = () => this.getDocHeight(doc);
let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
- return <CollectionSchemaPreview
+ return <ContentFittingDocumentView
Document={doc}
DataDocument={dataDoc}
- fieldKey={this.props.fieldKey}
showOverlays={this.overlays}
renderDepth={this.props.renderDepth}
ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
@@ -189,7 +188,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
pinToPres={this.props.pinToPres}
setPreviewScript={emptyFunction}
previewScript={undefined}>
- </CollectionSchemaPreview>;
+ </ContentFittingDocumentView>;
}
getDocHeight(d?: Doc) {
if (!d) return 0;
@@ -363,7 +362,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
}
onToggle = (checked: Boolean) => {
- this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.chromeStatus = checked ? "collapsed" : "view-mode");
+ this.props.Document.chromeStatus = checked ? "collapsed" : "view-mode";
}
onContextMenu = (e: React.MouseEvent): void => {
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index fec3d90b9..b9d334b10 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -295,7 +295,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
style={{
width: (style.columnWidth) /
((uniqueHeadings.length +
- ((this.props.parent.props.ContainingCollectionDoc && this.props.parent.props.ContainingCollectionDoc.chromeStatus !== 'view-mode' && this.props.parent.props.ContainingCollectionDoc.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
+ ((this.props.parent.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
}}>
<div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
{/* the default bucket (no key value) has a tooltip that describes what it is.
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 55365de8c..d7e9494a3 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -74,7 +74,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
this._childLayoutDisposer && this._childLayoutDisposer();
}
- @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc!) : Doc.GetProto(this.props.Document); }
+ @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc) : Doc.GetProto(this.props.Document); }
@computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
// The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc.
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 47c355fc8..0e3f0d1a9 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -23,8 +23,7 @@ import { EditableView } from "../EditableView";
import { MainView } from '../MainView';
import { KeyValueBox } from '../nodes/KeyValueBox';
import { Templates } from '../Templates';
-import { CollectionViewType } from './CollectionView';
-import { CollectionSchemaPreview } from './CollectionSchemaView';
+import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
@@ -177,8 +176,10 @@ class TreeView extends React.Component<TreeViewProps> {
/>)
onWorkspaceContextMenu = (e: React.MouseEvent): void => {
- if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
- if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking && this.props.document !== CurrentUserUtils.UserDocument.workspaces) {
+ if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view
+ if (this.props.document === CurrentUserUtils.UserDocument.recentlyClosed) {
+ ContextMenu.Instance.addItem({ description: "Clear All", event: () => Doc.GetProto(CurrentUserUtils.UserDocument.recentlyClosed as Doc).data = new List<Doc>(), icon: "plus" });
+ } else if (this.props.document !== CurrentUserUtils.UserDocument.workspaces) {
ContextMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.document), icon: "tv" });
ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "inTab"), icon: "folder" });
ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight"), icon: "caret-square-right" });
@@ -221,10 +222,10 @@ class TreeView extends React.Component<TreeViewProps> {
}
let movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
return (de.data.dropAction || de.data.userDropAction) ?
- de.data.droppedDocuments.reduce((added, d) => this.props.addDocument(d, undefined, before) || added, false)
+ de.data.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
: de.data.moveDocument ?
movedDocs.reduce((added, d) => de.data.moveDocument(d, undefined, addDoc) || added, false)
- : de.data.droppedDocuments.reduce((added, d) => this.props.addDocument(d, undefined, before), false);
+ : de.data.droppedDocuments.reduce((added, d) => addDoc(d), false);
}
return false;
}
@@ -314,10 +315,9 @@ class TreeView extends React.Component<TreeViewProps> {
} else {
let layoutDoc = Doc.Layout(this.props.document);
return <div ref={this._dref} style={{ display: "inline-block", height: this.docHeight() }} key={this.props.document[Id] + this.props.document.title}>
- <CollectionSchemaPreview
+ <ContentFittingDocumentView
Document={layoutDoc}
DataDocument={this.templateDataDoc}
- fieldKey={this.fieldKey}
renderDepth={this.props.renderDepth}
showOverlays={this.noOverlays}
ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
@@ -474,7 +474,7 @@ class TreeView extends React.Component<TreeViewProps> {
let aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
};
- return <TreeView
+ return !(child instanceof Doc) ? (null) : <TreeView
document={pair.layout}
dataDoc={pair.data}
containingCollection={containingCollection}
@@ -538,6 +538,11 @@ export class CollectionTreeView extends CollectionSubView(Document) {
e.stopPropagation();
e.preventDefault();
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+ } else if (!e.isPropagationStopped() && this.props.Document === CurrentUserUtils.UserDocument.recentlyClosed) {
+ ContextMenu.Instance.addItem({ description: "Clear All", event: () => CurrentUserUtils.UserDocument.recentlyClosed = new List<Doc>(), icon: "plus" });
+ e.stopPropagation();
+ e.preventDefault();
+ ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
} else {
let layoutItems: ContextMenuProps[] = [];
layoutItems.push({ description: this.props.Document.preventTreeViewOpen ? "Persist Treeview State" : "Abandon Treeview State", event: () => this.props.Document.preventTreeViewOpen = !this.props.Document.preventTreeViewOpen, icon: "paint-brush" });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
index 1f1bca2f2..75af11537 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
@@ -3,6 +3,7 @@
opacity: 0.8;
pointer-events: all;
stroke-width: 3px;
+ transition: opacity 0.5s ease-in;
}
.collectionfreeformlinkview-linkCircle {
stroke: rgb(0,0,0);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 962fe2a1c..837413842 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -17,10 +17,12 @@ export interface CollectionFreeFormLinkViewProps {
@observer
export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> {
@observable _alive: number = 0;
+ @observable _opacity: number = 1;
@action
componentDidMount() {
this._alive = 1;
setTimeout(this.rerender, 50);
+ setTimeout(action(() => this._opacity = 0.05), 50);
}
@action
componentWillUnmount() {
@@ -42,6 +44,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
let pt1 = Utils.getNearestPointInPerimeter(a.left, a.top, a.width, a.height, b.left + b.width / 2, b.top + b.height / 2);
let pt2 = Utils.getNearestPointInPerimeter(b.left, b.top, b.width, b.height, a.left + a.width / 2, a.top + a.height / 2);
return (<line key="linkLine" className="collectionfreeformlinkview-linkLine"
+ style={{ opacity: this._opacity }}
x1={`${pt1[0]}`} y1={`${pt1[1]}`}
x2={`${pt2[0]}`} y2={`${pt2[1]}`} />);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index f6518a01d..0c5f4ec80 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -333,7 +333,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@action
onPointerWheel = (e: React.WheelEvent): void => {
- if (this.props.Document.lockedPosition || this.props.Document.inOverlay) return;
+ if (this.props.Document.lockedTransform || this.props.Document.inOverlay) return;
if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
e.stopPropagation();
}
@@ -354,14 +354,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
@action
- setPan(panX: number, panY: number) {
- if (!this.props.Document.lockedPosition || this.props.Document.inOverlay) {
- this.props.Document.panTransformType = "None";
+ setPan(panX: number, panY: number, panType: string = "None") {
+ if (!this.Document.lockedTransform || this.Document.inOverlay) {
+ this.Document.panTransformType = panType;
var scale = this.getLocalTransform().inverse().Scale;
const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
- const newPanY = Math.min((this.props.Document.scrollHeight !== undefined ? NumCast(this.props.Document.scrollHeight) : (1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
- this.props.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
- this.props.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
+ const newPanY = Math.min((this.props.Document.scrollHeight !== undefined ? NumCast(this.Document.scrollHeight) : (1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
+ this.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
+ this.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
}
}
@@ -415,8 +415,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
- this.setPan(newPanX, newPanY);
- this.Document.panTransformType = "Ease";
+ this.setPan(newPanX, newPanY, "Ease");
Doc.BrushDoc(this.props.Document);
this.props.focus(this.props.Document);
willZoom && this.setScaleToZoom(layoutdoc, scale);