aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/SelectionManager.ts24
-rw-r--r--src/client/views/MainView.scss38
-rw-r--r--src/client/views/MainView.tsx65
-rw-r--r--src/client/views/PropertiesButtons.tsx39
-rw-r--r--src/client/views/collections/CollectionView.scss34
-rw-r--r--src/client/views/collections/CollectionView.tsx49
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx193
7 files changed, 262 insertions, 180 deletions
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 9a968aeda..6fb758eac 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -12,9 +12,14 @@ export namespace SelectionManager {
@observable IsDragging: boolean = false;
SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
+
+ @observable public lastSelection: DocumentView | undefined;
+
@action
SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
+ this.lastSelection = docView;
+
// if doc is not in SelectedDocuments, add it
if (!manager.SelectedDocuments.get(docView)) {
if (!ctrlPressed) {
@@ -33,6 +38,15 @@ export namespace SelectionManager {
}
@action
DeselectDoc(docView: DocumentView): void {
+
+ if (this.lastSelection === docView) {
+ const list = Array.from(manager.SelectedDocuments.keys());
+ if (list.length > 0) {
+ this.lastSelection = list[list.length - 1];
+ } else {
+ this.lastSelection = undefined;
+ }
+ }
if (manager.SelectedDocuments.get(docView)) {
manager.SelectedDocuments.delete(docView);
docView.props.whenActiveChanged(false);
@@ -41,10 +55,16 @@ export namespace SelectionManager {
}
@action
DeselectAll(): void {
+ this.lastSelection = undefined;
Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
manager.SelectedDocuments.clear();
Doc.UserDoc().activeSelection = new List<Doc>([]);
}
+
+ @action
+ getLast(): DocumentView | undefined {
+ return this.lastSelection;
+ }
}
const manager = new Manager();
@@ -56,6 +76,10 @@ export namespace SelectionManager {
manager.SelectDoc(docView, ctrlPressed);
}
+ export function LastSelection(): DocumentView | undefined {
+ return manager.getLast();
+ }
+
// computed functions, such as used in IsSelected generate errors if they're called outside of a
// reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature
// to avoid unnecessary mobx invalidations when running inside a reaction.
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 55280b231..f64129600 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -102,6 +102,44 @@
user-select: none;
}
+.mainView-propertiesDragger {
+ background-color: rgb(140, 139, 139);
+ height: 55px;
+ width: 15.5px;
+ position: absolute;
+ top: 55%;
+ border: 1px black solid;
+ border-radius: 0;
+ border-top-left-radius: 10px;
+ border-bottom-left-radius: 10px;
+ border-right: unset;
+ z-index: 2;
+
+ .mainView-propertiesDragger-icon {
+ width: 10px;
+ height: 10px;
+ float: left;
+ margin-left: 3px;
+ padding-top: 19px;
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+}
+
+.mainiView-propertiesView {
+ display: flex;
+ flex-direction: column;
+ width: 200px;
+ height: 100%;
+ position: absolute;
+ right: 0;
+ top: 0;
+ border-left: solid 1px;
+ z-index: 10;
+}
+
.mainView-flyoutContainer {
display: flex;
flex-direction: column;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 766626a82..88f072493 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -21,10 +21,10 @@ import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, FieldValue, StrCast, NumCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter } from '../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter, setupMoveUpEvents } from '../../Utils';
import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
import { DocServer } from '../DocServer';
import { Docs, DocumentOptions } from '../documents/Documents';
@@ -66,7 +66,9 @@ import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
import CollectionMenu from './collections/CollectionMenu';
-import { Tooltip } from '@material-ui/core';
+import { Tooltip, AccordionActions } from '@material-ui/core';
+import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
+import { SelectionManager } from '../util/SelectionManager';
@observer
export class MainView extends React.Component {
@@ -90,9 +92,24 @@ export class MainView extends React.Component {
@observable public sidebarContent: any = this.userDoc?.["tabs-panelContainer"];
@observable public panelContent: string = "none";
+ @observable public showProperties: boolean = false;
+ @computed get selectedDocumentView() { return SelectionManager.LastSelection(); }
+ @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+ @observable selectedDataDoc: Doc | undefined = this.selectedDocumentView?.props.DataDoc ? this.selectedDocumentView.props.DataDoc : this.selectedDoc;
public isPointerDown = false;
+ @observable _propertiesWidth: number = 0;
+ propertiesWidth = () => Math.max(0, Math.min(this._panelWidth - 50, this._propertiesWidth));
+
+ @computed get propertiesIcon() {
+ if (this.propertiesWidth() < 10) {
+ return "chevron-left";
+ } else {
+ return "chevron-right";
+ }
+ }
+
componentDidMount() {
DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's
@@ -216,7 +233,7 @@ export class MainView extends React.Component {
const freeformOptions: DocumentOptions = {
x: 0,
y: 400,
- _width: this._panelWidth * .7,
+ _width: this._panelWidth * .7 - this._propertiesWidth,
_height: this._panelHeight,
title: "Collection " + workspaceCount,
};
@@ -282,10 +299,13 @@ export class MainView extends React.Component {
@action
onResize = (r: any) => {
- this._panelWidth = r.offset.width;
+ this._panelWidth = r.offset.width - this._propertiesWidth;
this._panelHeight = r.offset.height;
}
- getPWidth = () => this._panelWidth;
+
+ @action
+ getPWidth = () => this._panelWidth - this._propertiesWidth;
+
getPHeight = () => this._panelHeight;
getContentsHeight = () => this._panelHeight - this._buttonBarHeight;
@@ -329,7 +349,6 @@ export class MainView extends React.Component {
NativeWidth={returnZero}
PanelWidth={this.getPWidth}
PanelHeight={this.getPHeight}
- renderDepth={0}
focus={emptyFunction}
parentActive={returnTrue}
whenActiveChanged={emptyFunction}
@@ -570,6 +589,30 @@ export class MainView extends React.Component {
}
}
+ @action
+ onDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+ this._propertiesWidth = this._panelWidth - Math.max(Transform.Identity().transformPoint(e.clientX, 0)[0], 0);
+ return false;
+ }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._panelWidth - 50, 200) : 0), false);
+ }
+
+ @computed get propertiesView() {
+ TraceMobx();
+ return this._propertiesWidth === 0 ? (null) :
+ <div className="mainView-propertiesView" style={{
+ width: `${this.propertiesWidth()}px`,
+ overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
+ }}>
+ <PropertiesView
+ width={this._propertiesWidth}
+ height={this._panelHeight}
+ renderDepth={1}
+ ScreenToLocalTransform={Transform.Identity}
+ />
+ </div>;
+ }
+
@computed get mainContent() {
const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0);
const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`;
@@ -606,6 +649,14 @@ export class MainView extends React.Component {
</div>
</div>
{this.dockingContent}
+ {this.showProperties ? (null) :
+ <div className="mainView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onDown}
+ style={{ right: this._propertiesWidth - 1, top: "45%" }}>
+ <div className="mainView-propertiesDragger-icon">
+ <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
+ </div>
+ }
+ {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
</div>
</div>);
}
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 842d0320f..1b06a41fa 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -22,6 +22,7 @@ import { TemplateMenu } from "./TemplateMenu";
import { Template, Templates } from "./Templates";
import React = require("react");
import { Tooltip } from '@material-ui/core';
+import { SelectionManager } from '../util/SelectionManager';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -49,7 +50,7 @@ enum UtilityButtonState {
}
@observer
-export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
+export class PropertiesButtons extends React.Component<{}, {}> {
private _dragRef = React.createRef<HTMLDivElement>();
private _pullAnimating = false;
private _pushAnimating = false;
@@ -67,6 +68,9 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
public static hasPushedHack = false;
public static hasPulledHack = false;
+ @observable selectedDocumentView: DocumentView | undefined = SelectionManager.LastSelection();
+ @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+
public startPullOutcome = action((success: boolean) => {
if (!this._pullAnimating) {
this._pullAnimating = true;
@@ -108,7 +112,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
@computed
get considerGoogleDocsPush() {
- const targetDoc = this.props.doc;
+ const targetDoc = this.selectedDoc;
const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${published ? "Push" : "Publish"} to Google Docs`}</div></>}>
@@ -127,7 +131,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
@computed
get considerGoogleDocsPull() {
- const targetDoc = this.props.doc;
+ const targetDoc = this.selectedDoc;
const dataDoc = targetDoc && Doc.GetProto(targetDoc);
const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
@@ -188,7 +192,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
}
@computed
get pinButton() {
- const targetDoc = this.props.doc;
+ const targetDoc = this.selectedDoc;
const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
<div className="propertiesButtons-linker"
@@ -202,15 +206,20 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
@computed
get metadataButton() {
//const view0 = this.view0;
- return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
- <div className="propertiesButtons-linkFlyout">
- <Flyout anchorPoint={anchorPoints.LEFT_TOP}
- content={<MetadataEntryMenu docs={[this.props.doc]} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}>
- <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
- {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
- </div>
- </Flyout>
- </div></Tooltip>;
+ if (this.selectedDoc) {
+ return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
+ <div className="propertiesButtons-linkFlyout">
+ <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+ content={<MetadataEntryMenu docs={[this.selectedDoc]} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}>
+ <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+ {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
+ </div>
+ </Flyout>
+ </div></Tooltip>;
+ } else {
+ return null;
+ }
+
}
// @computed
@@ -267,9 +276,9 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
// }
render() {
- if (!this.props.doc) return (null);
+ if (!this.selectedDoc) return (null);
- const isText = this.props.doc[Doc.LayoutFieldKey(this.props.doc)] instanceof RichTextField;
+ const isText = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField;
const considerPull = isText && this.considerGoogleDocsPull;
const considerPush = isText && this.considerGoogleDocsPush;
return <div className="propertiesButtons">
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index 585f6865e..a5aef86de 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -25,40 +25,6 @@
z-index: 2;
}
- .collectionView-propertiesDragger {
- background-color: rgb(140, 139, 139);
- height: 55px;
- width: 15.5px;
- position: absolute;
- top: 55%;
- border: 1px black solid;
- border-radius: 0;
- border-top-left-radius: 10px;
- border-bottom-left-radius: 10px;
- border-right: unset;
- z-index: 2;
-
- .collectionView-propertiesDragger-icon {
- width: 10px;
- height: 10px;
- float: left;
- margin-left: 3px;
- padding-top: 19px;
- }
- }
-
- .collectionView-propertiesView {
- display: flex;
- flex-direction: column;
- width: 200px;
- height: 100%;
- position: absolute;
- right: 0;
- top: 0;
- border-left: solid 1px;
- z-index: 10;
- }
-
.collectionTimeView-treeView {
display: flex;
flex-direction: column;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 853321d3c..19a82a113 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -49,7 +49,6 @@ import { CollectionTreeView } from "./CollectionTreeView";
import './CollectionView.scss';
import CollectionMenu from './CollectionMenu';
import { SharingPermissions } from '../../util/SharingManager';
-import { PropertiesView } from './collectionFreeForm/PropertiesView';
import { DocumentView } from '../nodes/DocumentView';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
@@ -369,22 +368,9 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
get _facetWidth() { return NumCast(this.props.Document._facetWidth); }
set _facetWidth(value) { this.props.Document._facetWidth = value; }
- get _propertiesWidth() { return NumCast(this.props.Document._propertiesWidth); }
- set _propertiesWidth(value) { this.props.Document._propertiesWidth = value; }
-
- bodyPanelWidth = () => this.props.PanelWidth() - this.propertiesWidth();
+ bodyPanelWidth = () => this.props.PanelWidth();
facetWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._facetWidth));
- propertiesWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._propertiesWidth));
-
- @computed get propertiesIcon() {
- if (this.propertiesWidth() < 10) {
- return "chevron-left";
- } else {
- return "chevron-right";
- }
- }
-
@computed get dataDoc() {
return (this.props.DataDoc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) :
this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document)); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
@@ -505,13 +491,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
}), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
}
- onDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
- this._propertiesWidth = this.props.PanelWidth() - Math.max(this.props.ScreenToLocalTransform().transformPoint(e.clientX, 0)[0], 0);
- return false;
- }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
- }
-
filterBackground = () => "rgba(105, 105, 105, 0.432)";
get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves)
@computed get scriptField() {
@@ -582,23 +561,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
</div>;
}
- @computed get propertiesView() {
- TraceMobx();
- return !this._propertiesWidth || this.props.dontRegisterView ? (null) :
- <div className="collectionView-propertiesView" style={{
- width: `${this.propertiesWidth()}px`,
- overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
- }}>
- <PropertiesView dataDoc={this.dataDoc} Document={this.props.Document}
- docView={CollectionView as unknown as DocumentView}
- width={this._propertiesWidth}
- height={this.props.PanelHeight()}
- renderDepth={this.props.renderDepth}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- />
- </div>;
- }
-
childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString);
@@ -634,15 +596,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
}
{this.facetWidth() < 10 ? (null) : this.filterView} */}
-
- {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
- <div className="collectionView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onDown}
- style={{ right: this.propertiesWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }}>
- <div className="collectionView-propertiesDragger-icon">
- <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
- </div>
- }
- {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
</div>);
}
}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 5242aa8fd..5aa0066d2 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -14,121 +14,162 @@ import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZer
import { Id } from "../../../../fields/FieldSymbols";
import { Transform } from "../../../util/Transform";
import { PropertiesButtons } from "../../PropertiesButtons";
+import { SelectionManager } from "../../../util/SelectionManager";
interface PropertiesViewProps {
- dataDoc: Doc;
- Document: Doc;
width: number;
height: number;
renderDepth: number;
ScreenToLocalTransform: () => Transform;
- docView: DocumentView;
}
@observer
export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get MAX_EMBED_HEIGHT() { return 200; }
+ @observable numSelected: number = SelectionManager.SelectedDocuments().length;
+ @computed get selectedDocumentView() { return SelectionManager.LastSelection(); }
+ @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+ @observable dataDoc: Doc | undefined = this.selectedDocumentView?.props.DataDoc ? this.selectedDocumentView.props.DataDoc : this.selectedDoc;
- rtfWidth = () => Math.min(this.props.Document?.[WidthSym](), this.props.width - 20);
- rtfHeight = () => this.rtfWidth() <= this.props.Document?.[WidthSym]() ? Math.min(this.props.Document?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+ @action
+ rtfWidth = () => {
+ if (this.selectedDoc) {
+ return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
+ } else {
+ return 0;
+ }
+ }
+ @action
+ rtfHeight = () => {
+ if (this.selectedDoc) {
+ return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+ } else {
+ return 0;
+ }
+ }
+ @action
docWidth = () => {
- const layoutDoc = this.props.Document;
- const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
- if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
- return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+ if (this.selectedDoc) {
+ const layoutDoc = this.selectedDoc;
+ const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+ if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
+ return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+ } else {
+ return 0;
+ }
}
+
+ @action
docHeight = () => {
- const layoutDoc = this.props.Document;
- return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
- const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
- if (aspect) return this.docWidth() * aspect;
- return layoutDoc._fitWidth ? (!this.props.dataDoc._nativeHeight ? NumCast(this.props.height) :
- Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
- NumCast(this.props.height)))) :
- NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
- })()));
+ if (this.selectedDoc && this.dataDoc) {
+ const layoutDoc = this.selectedDoc;
+ return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
+ const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+ if (aspect) return this.docWidth() * aspect;
+ return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) :
+ Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+ NumCast(this.props.height)))) :
+ NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
+ })()));
+ } else {
+ return 0;
+ }
}
@computed get expandedField() {
- const ids: { [key: string]: string } = {};
- const doc = this.props.dataDoc;
- doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+ if (this.dataDoc) {
+ const ids: { [key: string]: string } = {};
+ const doc = this.dataDoc;
+ doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
- const rows: JSX.Element[] = [];
- for (const key of Object.keys(ids).slice().sort()) {
- const contents = doc[key];
- let contentElement: (JSX.Element | null)[] | JSX.Element = [];
- contentElement = <EditableView key="editableView"
- contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
- height={13}
- fontSize={10}
- GetValue={() => Field.toKeyValueString(doc, key)}
- SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
- />;
+ const rows: JSX.Element[] = [];
+ for (const key of Object.keys(ids).slice().sort()) {
+ const contents = doc[key];
+ let contentElement: (JSX.Element | null)[] | JSX.Element = [];
+ contentElement = <EditableView key="editableView"
+ contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+ height={13}
+ fontSize={10}
+ GetValue={() => Field.toKeyValueString(doc, key)}
+ SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+ />;
- rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
- <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
- &nbsp;
- {contentElement}
- </div>);
+ rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+ <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+ &nbsp;
+ {contentElement}
+ </div>);
+ }
+ return rows;
}
- return rows;
}
@computed get layoutPreview() {
- const layoutDoc = Doc.Layout(this.props.Document);
- const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
- const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
- return <div style={{ display: "inline-block", height: panelHeight() }} key={this.props.dataDoc[Id]}>
- <ContentFittingDocumentView
- Document={layoutDoc}
- DataDoc={this.props.dataDoc}
- LibraryPath={emptyPath}
- renderDepth={this.props.renderDepth + 1}
- rootSelected={returnFalse}
- treeViewDoc={undefined}
- backgroundColor={() => "lightgrey"}
- fitToBox={false}
- FreezeDimensions={true}
- NativeWidth={layoutDoc.type ===
- StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
- NativeHeight={layoutDoc.type ===
- StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
- PanelWidth={panelWidth}
- PanelHeight={panelHeight}
- focus={returnFalse}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- docFilters={returnEmptyFilter}
- ContainingCollectionDoc={undefined}
- ContainingCollectionView={undefined}
- addDocument={returnFalse}
- moveDocument={undefined}
- removeDocument={returnFalse}
- parentActive={() => false}
- whenActiveChanged={emptyFunction}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- bringToFront={returnFalse}
- ContentScaling={returnOne}
- />
- </div>;
+ if (this.selectedDoc) {
+ const layoutDoc = Doc.Layout(this.selectedDoc);
+ const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
+ const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
+ return <div style={{ display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
+ <ContentFittingDocumentView
+ Document={layoutDoc}
+ DataDoc={this.dataDoc}
+ LibraryPath={emptyPath}
+ renderDepth={this.props.renderDepth + 1}
+ rootSelected={returnFalse}
+ treeViewDoc={undefined}
+ backgroundColor={() => "lightgrey"}
+ fitToBox={false}
+ FreezeDimensions={true}
+ NativeWidth={layoutDoc.type ===
+ StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
+ NativeHeight={layoutDoc.type ===
+ StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
+ PanelWidth={panelWidth}
+ PanelHeight={panelHeight}
+ focus={returnFalse}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ docFilters={returnEmptyFilter}
+ ContainingCollectionDoc={undefined}
+ ContainingCollectionView={undefined}
+ addDocument={returnFalse}
+ moveDocument={undefined}
+ removeDocument={returnFalse}
+ parentActive={() => false}
+ whenActiveChanged={emptyFunction}
+ addDocTab={returnFalse}
+ pinToPres={emptyFunction}
+ bringToFront={returnFalse}
+ ContentScaling={returnOne}
+ />
+ </div>;
+ } else {
+ return null;
+ }
}
render() {
+
+ if (!this.selectedDocumentView || !this.selectedDoc || !this.dataDoc) {
+ return <div className="propertiesView" >
+ <div className="propertiesView-title">
+ No Document Selected
+ </div> </div>;
+ }
+
return <div className="propertiesView" >
<div className="propertiesView-title">
Properties
</div>
<div className="propertiesView-name">
- Collection
+ {this.dataDoc.title}
</div>
<div className="propertiesView-settings">
<div className="propertiesView-settings-title"> Settings</div>
<div className="propertiesView-settings-content">
- <PropertiesButtons doc={this.props.Document} />
+ <PropertiesButtons />
</div>
</div>
<div className="propertiesView-fields">