From af2346983eae1145167b70faf96a9aec0ca82427 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 20 May 2019 00:09:47 -0400 Subject: Fixed a bunch of demo bugs Moved Field Symbols to separate file Editing is mostly working in debug viewer --- src/client/views/collections/CollectionBaseView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 84ffbac36..5686ccfef 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -7,8 +7,8 @@ import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Typ import { Doc, FieldResult, Opt, DocListCast } from '../../../new_fields/Doc'; import { listSpec } from '../../../new_fields/Schema'; import { List } from '../../../new_fields/List'; -import { Id } from '../../../new_fields/RefField'; import { SelectionManager } from '../../util/SelectionManager'; +import { Id } from '../../../new_fields/FieldSymbols'; export enum CollectionViewType { Invalid, -- cgit v1.2.3-70-g09d2 From ab001ffd9749814c3f0b0f30e9f86f65e2f8ac0c Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 21 May 2019 20:49:49 -0400 Subject: "Rebased" Stanley's image upload changes --- src/client/documents/Documents.ts | 3 ++ src/client/views/Main.scss | 15 ++++++ src/client/views/MainView.tsx | 33 ++++++++++--- .../views/collections/CollectionBaseView.tsx | 1 + .../views/collections/CollectionStackingView.scss | 44 ++++++++++++++++++ .../views/collections/CollectionStackingView.tsx | 54 ++++++++++++++++++++++ src/client/views/collections/CollectionView.tsx | 3 ++ src/mobile/ImageUpload.scss | 21 ++++++++- src/mobile/ImageUpload.tsx | 1 + .../authentication/models/current_user_utils.ts | 2 +- 10 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 src/client/views/collections/CollectionStackingView.scss create mode 100644 src/client/views/collections/CollectionStackingView.tsx (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3d65826a9..b17544229 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -292,6 +292,9 @@ export namespace Docs { export function TreeDocument(documents: Array, options: DocumentOptions) { return CreateInstance(collProto, new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Tree }); } + export function StackingDocument(documents: Array, options: DocumentOptions) { + return CreateInstance(collProto, new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Stacking }); + } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id); } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index d63b0147b..302c49c10 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -97,6 +97,21 @@ button:hover { right: 0px; } +.main-notifs-badge { + position: absolute; + top: -10px; + right: -10px; + color: white; + background: #f44b42; + font-weight: 300; + border-radius: 100%; + width: 25px; + height: 25px; + text-align: center; + padding-top: 4px; + font-size: 12px; +} + //toolbar stuff #toolbar { position: absolute; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index af224747d..1d491d11f 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,5 +1,5 @@ import { IconName, library } from '@fortawesome/fontawesome-svg-core'; -import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; +import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, runInAction, trace } from 'mobx'; import { observer } from 'mobx-react'; @@ -25,7 +25,7 @@ import { DocumentView } from './nodes/DocumentView'; import { PreviewCursor } from './PreviewCursor'; import { SearchBox } from './SearchBox'; import { SelectionManager } from '../util/SelectionManager'; -import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc'; +import { FieldResult, Field, Doc, Opt, DocListCast } from '../../new_fields/Doc'; import { Cast, FieldValue, StrCast } from '../../new_fields/Types'; import { DocServer } from '../DocServer'; import { listSpec } from '../../new_fields/Schema'; @@ -137,12 +137,14 @@ export class MainView extends React.Component { // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container) setTimeout(() => { this.openWorkspace(mainDoc); - let pendingDocument = Docs.SchemaDocument(["title"], [], { title: "New Mobile Uploads" }); - mainDoc.optionalRightCollection = pendingDocument; + // let pendingDocument = Docs.StackingDocument([], { title: "New Mobile Uploads" }); + // mainDoc.optionalRightCollection = pendingDocument; }, 0); } } + @observable _notifsCol: Opt; + @action openWorkspace = async (doc: Doc, fromHistory = false) => { CurrentUserUtils.MainDocId = doc[Id]; @@ -153,12 +155,19 @@ export class MainView extends React.Component { setTimeout(async () => { if (col) { const l = Cast(col.data, listSpec(Doc)); - if (l && l.length > 0) { - CollectionDockingView.Instance.AddRightSplit(col); + if (l) { + runInAction(() => this._notifsCol = col); } } }, 100); } + + openNotifsCol = () => { + if (this._notifsCol) { + CollectionDockingView.Instance.AddRightSplit(this._notifsCol); + } + } + @action onResize = (r: any) => { this.pwidth = r.offset.width; @@ -254,11 +263,23 @@ export class MainView extends React.Component { /* @TODO this should really be moved into a moveable toolbar component, but for now let's put it here to meet the deadline */ @computed get miscButtons() { + const length = this._notifsCol ? DocListCast(this._notifsCol.data).length : 0; + const notifsRef = React.createRef(); + const dragNotifs = action(() => this._notifsCol!); let logoutRef = React.createRef(); return [ ,
+
+ +
0 ? { "display": "initial" } : { "display": "none" }}> + {length} +
+
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 5686ccfef..2bccde241 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -16,6 +16,7 @@ export enum CollectionViewType { Schema, Docking, Tree, + Stacking } export interface CollectionRenderProps { diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss new file mode 100644 index 000000000..803e680e5 --- /dev/null +++ b/src/client/views/collections/CollectionStackingView.scss @@ -0,0 +1,44 @@ +@import "../globalCssVariables"; + +.collectionStackingView { + top: 0; + left: 0; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + position: absolute; + overflow-y: scroll; + min-width: 250px; + border-width: 0; + box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; + border-color: $light-color-secondary; + border-style: solid; + border-radius: 0 0 $border-radius $border-radius; + box-sizing: border-box; + + .collectionStackingView-docView-container { + width: 45%; + margin: 5% 2.5%; + padding-left: 2.5%; + height: auto; + } + + .collectionStackingView-flexCont { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + } + + .collectionStackingView-description { + font-size: 100%; + margin-bottom: 1vw; + padding: 10px; + height: 2vw; + width: 100%; + font-family: $sans-serif; + background: $dark-color; + color: $light-color; + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx new file mode 100644 index 000000000..a1cb73123 --- /dev/null +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -0,0 +1,54 @@ +import React = require("react"); +import { observer } from "mobx-react"; +import { CollectionSubView } from "./CollectionSubView"; +import Measure from "react-measure"; +import { Doc, WidthSym, HeightSym } from "../../../new_fields/Doc"; +import { DocumentView } from "../nodes/DocumentView"; +import { Transform } from "../../util/Transform"; +import { emptyFunction, returnOne } from "../../../Utils"; +import "./CollectionStackingView.scss"; +import { runInAction, action, observable, computed } from "mobx"; +import { StrCast } from "../../../new_fields/Types"; + +@observer +export class CollectionStackingView extends CollectionSubView(doc => doc) { + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform(); + + @action + moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { + this.props.removeDocument(doc); + addDocument(doc); + return true; + } + + render() { + const docs = this.childDocs; + return ( +
e.stopPropagation()}> +
{StrCast(this.props.Document.documentText, StrCast(this.props.Document.title, "stacking collection"))}
+
+ {docs.map(d => { + return (
+ +
); + })} +
+
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index bfdef8e8c..39c8af4ab 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -12,6 +12,7 @@ import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionTreeView } from "./CollectionTreeView"; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import { CollectionStackingView } from './CollectionStackingView'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh); @@ -31,6 +32,7 @@ export class CollectionView extends React.Component { case CollectionViewType.Schema: return (); case CollectionViewType.Docking: return (); case CollectionViewType.Tree: return (); + case CollectionViewType.Stacking: return (); case CollectionViewType.Freeform: default: return (); @@ -48,6 +50,7 @@ export class CollectionView extends React.Component { } ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema), icon: "th-list" }); ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" }); + ContextMenu.Instance.addItem({ description: "Stacking", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Stacking), icon: "th-list" }); } } diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss index d0b7d4e41..65305dd04 100644 --- a/src/mobile/ImageUpload.scss +++ b/src/mobile/ImageUpload.scss @@ -1,7 +1,13 @@ +@import "../client/views/globalCssVariables.scss"; + .imgupload_cont { - height: 100vh; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; width: 100vw; - align-content: center; + height: 100vh; + .button_file { text-align: center; height: 50%; @@ -10,4 +16,15 @@ color: grey; font-size: 3em; } + + .upload_label { + width: 80vw; + height: 40vh; + background: $dark-color; + font-size: 10vw; + font-family: $sans-serif; + text-align: center; + padding-top: 20vh; + color: white; + } } \ No newline at end of file diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index 690937339..84bbfeb14 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -71,6 +71,7 @@ const onFileLoad = async (file: React.ChangeEvent) => { ReactDOM.render((
{/* */} +
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index b947f5e01..e85aa2c74 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -37,7 +37,7 @@ export class CurrentUserUtils { doc.title = this.email; doc.data = new List(); doc.excludeFromLibrary = true; - doc.optionalRightCollection = Docs.SchemaDocument(["title"], [], { title: "Pending documents" }); + doc.optionalRightCollection = Docs.StackingDocument([], { title: "New mobile uploads" }); // doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` }); // (doc.library as Doc).excludeFromLibrary = true; return doc; -- cgit v1.2.3-70-g09d2 From 37e16bb59a38c000ba80312a0661e1f54c93f3c6 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 30 May 2019 10:51:00 -0400 Subject: cleaned up event handling for documentviews. fixed context menu closing. --- src/client/documents/Documents.ts | 2 +- src/client/views/ContextMenu.tsx | 7 +- src/client/views/ContextMenuItem.tsx | 34 +++-- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/MainView.tsx | 1 - .../views/collections/CollectionBaseView.tsx | 1 + .../views/collections/CollectionDockingView.tsx | 1 - .../views/collections/CollectionSchemaView.tsx | 1 - .../views/collections/CollectionStackingView.tsx | 28 +---- .../views/collections/CollectionTreeView.tsx | 22 ++-- .../CollectionFreeFormLinksView.tsx | 1 - .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - .../views/nodes/CollectionFreeFormDocumentView.tsx | 119 ------------------ src/client/views/nodes/DocumentView.tsx | 140 ++++++++++++++++----- src/client/views/nodes/FieldView.tsx | 1 - 15 files changed, 153 insertions(+), 208 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fffada459..ab61b915c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -295,7 +295,7 @@ export namespace Docs { return CreateInstance(webProto, new HtmlField(html), options); } export function KVPDocument(document: Doc, options: DocumentOptions = {}) { - return CreateInstance(kvpProto, document, options); + return CreateInstance(kvpProto, document, { title: document.title + ".kvp", ...options }); } export function FreeformDocument(documents: Array, options: DocumentOptions, makePrototype: boolean = true) { if (!makePrototype) { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 542d259d6..da374455e 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -81,6 +81,11 @@ export class ContextMenu extends React.Component { return false; } + @action + closeMenu = () => { + this.clearItems(); + } + render() { let style = this._yRelativeToTop ? { left: this._pageX, top: this._pageY, display: this._display } : { left: this._pageX, bottom: this._pageY, display: this._display }; @@ -95,7 +100,7 @@ export class ContextMenu extends React.Component { {this._items.filter(prop => prop.description.toLowerCase().indexOf(this._searchString.toLowerCase()) !== -1). - map(prop => )} + map(prop => )}
); } diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index b9239dac9..63347e076 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -8,11 +8,13 @@ export interface OriginalMenuProps { description: string; event: (e: React.MouseEvent) => void; icon?: IconProp; //maybe should be optional (icon?) + closeMenu?: () => void; } export interface SubmenuProps { description: string; subitems: ContextMenuProps[]; + closeMenu?: () => void; } export interface ContextMenuItemProps { @@ -32,30 +34,36 @@ export class ContextMenuItem extends React.Component { } } + handleEvent = (e: React.MouseEvent) => { + if ("event" in this.props) { + this.props.event(e); + this.props.closeMenu && this.props.closeMenu(); + } + } + render() { if ("event" in this.props) { return ( -
+
{this.props.icon ? : } -
{this.props.description}
+
+ {this.props.description} +
); } else { - let submenu = null; - if (this.overItem) { - submenu = ( -
- {this._items.map(prop => )} -
- ); - } + let submenu = !this.overItem ? (null) : +
+ {this._items.map(prop => )} +
; return ( -
{ this.overItem = true; })} - onMouseLeave={action(() => this.overItem = false)}> -
{this.props.description}
+
{ this.overItem = true; })} onMouseLeave={action(() => this.overItem = false)}> +
+ {this.props.description} +
{submenu}
); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 319e91337..e06fd6119 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -251,7 +251,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } if (!this._removeIcon) { if (selectedDocs.length === 1) { - this.getIconDoc(selectedDocs[0]).then(icon => selectedDocs[0].props.toggleMinimized()); + this.getIconDoc(selectedDocs[0]).then(icon => selectedDocs[0].toggleMinimized()); } else if (Math.abs(e.pageX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.pageY - this._downY) < Utils.DRAG_THRESHOLD) { let docViews = SelectionManager.ViewsSortedVertically(); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 438607157..74dafadc4 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -184,7 +184,6 @@ export class MainView extends React.Component { let mainCont = this.mainContainer; let content = !mainCont ? (null) : { @action.bound removeDocument(doc: Doc): boolean { + SelectionManager.DeselectAll(); const props = this.props; //TODO This won't create the field if it doesn't already exist const value = Cast(props.Document[props.fieldKey], listSpec(Doc), []); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 180a8be46..b6076b5f7 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -466,7 +466,6 @@ export class DockedFrameRenderer extends React.Component {
doc) { - + _masonryGridRef: HTMLDivElement | null = null; get gridGap() { return 10; } get gridSize() { return 20; } get itemWidth() { return NumCast(this.props.Document.itemWidth, 250); } - constructor(props: SubCollectionViewProps) { - super(props); - } - @action moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { this.props.removeDocument(doc); @@ -31,13 +27,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDocTransform(doc: Doc, dref: HTMLDivElement) { let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); - let outerXf = Utils.GetScreenTransform(this.masonryGridRef!); + let outerXf = Utils.GetScreenTransform(this._masonryGridRef!); let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); return this.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.itemWidth); } - masonryGridRef: HTMLDivElement | null = null; createRef = (ele: HTMLDivElement | null) => { - this.masonryGridRef = ele; + this._masonryGridRef = ele; this.createDropTarget(ele!); } @computed @@ -77,32 +72,17 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { parentActive={this.props.active} addDocTab={this.props.addDocTab} bringToFront={emptyFunction} - toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} />
); }) } - onClick = (e: React.MouseEvent) => { - let hitBackground = (e.target as any).className === "collectionStackingView-masonryGrid" || - (e.target as any).className === "collectionStackingView"; - if (this.props.active()) { - if (!hitBackground) - e.stopPropagation(); - } - if (hitBackground) { - if (!this.props.active() && this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.active()) { - e.stopPropagation(); - } - this.props.select(false); - } - } render() { let leftMargin = 20; let topMargin = 20; let itemCols = Math.ceil(this.itemWidth / (this.gridSize + this.gridGap)); let cells = Math.floor((this.props.PanelWidth() - leftMargin) / (itemCols * (this.gridSize + this.gridGap))); return ( -
e.stopPropagation()}> +
e.stopPropagation()}>
void; moveDocument: DragManager.MoveFunction; dropAction: "alias" | "copy" | undefined; + addDocTab: (doc: Doc, where: string) => void; } export enum BulletType { @@ -140,19 +141,12 @@ class TreeView extends React.Component { onWorkspaceContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Open as Workspace", event: undoBatch(() => MainView.Instance.openWorkspace(this.props.document)) }); - ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.document) }); - ContextMenu.Instance.addItem({ - description: "Open Fields", event: () => CollectionDockingView.Instance.AddRightSplit(Docs.KVPDocument(this.props.document, - { title: this.props.document.title + ".kvp", width: 300, height: 300 })) - }); + ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, "onRight") }); + ContextMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.KVPDocument(this.props.document, { width: 300, height: 300 }), "onRight") }); if (DocumentManager.Instance.getDocumentViews(this.props.document).length) { ContextMenu.Instance.addItem({ description: "Focus", event: () => DocumentManager.Instance.getDocumentViews(this.props.document).map(view => view.props.focus(this.props.document)) }); } - ContextMenu.Instance.addItem({ - description: "Delete", event: undoBatch(() => { - this.props.deleteDoc(this.props.document); - }) - }); + ContextMenu.Instance.addItem({ description: "Delete", event: undoBatch(() => this.props.deleteDoc(this.props.document)) }); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); e.stopPropagation(); } @@ -180,7 +174,7 @@ class TreeView extends React.Component { {(key === "data") ? (null) : {key}}
- {TreeView.GetChildElements(doc instanceof Doc ? [doc] : docList, key !== "data", (doc: Doc) => this.remove(doc, key), this.move, this.props.dropAction)} + {TreeView.GetChildElements(doc instanceof Doc ? [doc] : docList, key !== "data", (doc: Doc) => this.remove(doc, key), this.move, this.props.dropAction, this.props.addDocTab)}
); } else { @@ -197,9 +191,9 @@ class TreeView extends React.Component {
; } - public static GetChildElements(docs: Doc[], allowMinimized: boolean, remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType) { + public static GetChildElements(docs: Doc[], allowMinimized: boolean, remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType, addDocTab: (doc: Doc, where: string) => void) { return docs.filter(child => !child.excludeFromLibrary && (allowMinimized || !child.isMinimized)).map(child => - ); + ); } } @@ -225,7 +219,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { if (!this.childDocs) { return (null); } - let childElements = TreeView.GetChildElements(this.childDocs, false, this.remove, this.props.moveDocument, dropAction); + let childElements = TreeView.GetChildElements(this.childDocs, false, this.remove, this.props.moveDocument, dropAction, this.props.addDocTab); return (
{ let srcViews = this.documentAnchors(connection.a); let targetViews = this.documentAnchors(connection.b); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d1c4fb72d..1a1614ac7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -279,7 +279,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getDocumentViewProps(document: Doc): DocumentViewProps { return { Document: document, - toggleMinimized: emptyFunction, addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, moveDocument: this.props.moveDocument, diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 5d11e051d..411e8c059 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -30,9 +30,6 @@ const FreeformDocument = makeInterface(schema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(FreeformDocument) { private _mainCont = React.createRef(); - private _downX: number = 0; - private _downY: number = 0; - private _doubleTap = false; _bringToFrontDisposer?: IReactionDisposer; @computed get transform() { @@ -62,7 +59,6 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); - toggleMinimized = async () => this.toggleIcon(await DocListCastAsync(this.props.Document.maximizedDocs)); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) .scale(1 / this.contentScaling()).scale(1 / this.zoom) @@ -70,7 +66,6 @@ export class CollectionFreeFormDocumentView extends DocComponent => { - SelectionManager.DeselectAll(); - let isMinimized: boolean | undefined; - let minimizedDoc: Doc | undefined = this.props.Document; - if (!maximizedDocs) { - minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc); - if (minimizedDoc) maximizedDocs = await DocListCastAsync(minimizedDoc.maximizedDocs); - } - if (minimizedDoc && maximizedDocs) { - let minimizedTarget = minimizedDoc; - if (!CollectionFreeFormDocumentView._undoBatch) { - CollectionFreeFormDocumentView._undoBatch = UndoManager.StartBatch("iconAnimating"); - } - maximizedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => { - let iconAnimating = Cast(maximizedDoc.isIconAnimating, List); - if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) { - if (isMinimized === undefined) { - isMinimized = BoolCast(maximizedDoc.isMinimized, false); - } - let minx = NumCast(minimizedTarget.x, undefined) + NumCast(minimizedTarget.width, undefined) / 2; - let miny = NumCast(minimizedTarget.y, undefined) + NumCast(minimizedTarget.height, undefined) / 2; - if (minx !== undefined && miny !== undefined) { - let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(minx, miny); - maximizedDoc.willMaximize = isMinimized; - maximizedDoc.isMinimized = false; - maximizedDoc.isIconAnimating = new List([scrpt[0], scrpt[1], Date.now(), isMinimized ? 1 : 0]); - } - } - }); - setTimeout(() => { - CollectionFreeFormDocumentView._undoBatch && CollectionFreeFormDocumentView._undoBatch.end(); - CollectionFreeFormDocumentView._undoBatch = undefined; - }, 500); - } - } - static _undoBatch?: UndoManager.Batch = undefined; - onPointerDown = (e: React.PointerEvent): void => { - this._downX = e.clientX; - this._downY = e.clientY; - this._doubleTap = false; - if (e.button === 0 && e.altKey) { - e.stopPropagation(); // prevents panning from happening on collection if shift is pressed after a document drag has started - } // allow pointer down to go through otherwise so that marquees can be drawn starting over a document - - if (e.button === 0) { - e.preventDefault(); // prevents Firefox from dragging images (we want to do that ourself) - } - } - onClick = async (e: React.MouseEvent) => { - e.stopPropagation(); - let altKey = e.altKey; - let ctrlKey = e.ctrlKey; - if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && - Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { - let isExpander = (e.target as any).id === "isExpander"; - if (BoolCast(this.props.Document.isButton, false) || isExpander) { - SelectionManager.DeselectAll(); - let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs); - let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs); - let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs); - let linkedToDocs = await DocListCastAsync(this.props.Document.linkedToDocs, []); - let linkedFromDocs = await DocListCastAsync(this.props.Document.linkedFromDocs, []); - let expandedDocs: Doc[] = []; - expandedDocs = subBulletDocs ? [...subBulletDocs, ...expandedDocs] : expandedDocs; - expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs; - expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs; - // let expandedDocs = [...(subBulletDocs ? subBulletDocs : []), ...(maximizedDocs ? maximizedDocs : []), ...(summarizedDocs ? summarizedDocs : []),]; - if (expandedDocs.length) { // bcz: need a better way to associate behaviors with click events on widget-documents - let expandedProtoDocs = expandedDocs.map(doc => Doc.GetProto(doc)); - let maxLocation = StrCast(this.props.Document.maximizeLocation, "inPlace"); - let getDispDoc = (target: Doc) => Object.getOwnPropertyNames(target).indexOf("isPrototype") === -1 ? target : Doc.MakeDelegate(target); - if (altKey) { - maxLocation = this.props.Document.maximizeLocation = (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"); - if (!maxLocation || maxLocation === "inPlace") { - let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); - let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false); - expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false); - let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); - if (!hasView) { - this.props.addDocument && expandedDocs.forEach(async maxDoc => this.props.addDocument!(getDispDoc(maxDoc), false)); - } - expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); - } - } - if (maxLocation && maxLocation !== "inPlace") { - let dataDocs = DocListCast(CollectionDockingView.Instance.props.Document.data); - if (dataDocs) { - expandedDocs.forEach(maxDoc => - (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) && - this.props.addDocTab(getDispDoc(maxDoc), maxLocation))); - } - } else { - this.toggleIcon(expandedProtoDocs); - } - } - else if (linkedToDocs.length || linkedFromDocs.length) { - let linkedFwdDocs = [ - linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0], - linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]]; - - let linkedFwdPage = [ - linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined, - linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined]; - if (!linkedFwdDocs.some(l => l instanceof Promise)) { - let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); - DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]); - } - } - } - } - } borderRounding = () => { let br = NumCast(this.props.Document.borderRounding); @@ -261,8 +144,6 @@ export class CollectionFreeFormDocumentView extends DocComponent boolean; whenActiveChanged: (isActive: boolean) => void; - toggleMinimized: () => void; bringToFront: (doc: Doc) => void; addDocTab: (doc: Doc, where: string) => void; + whenClicked?: () => void; } const schema = createSchema({ @@ -103,6 +103,9 @@ const Document = makeInterface(schema); export class DocumentView extends DocComponent(Document) { private _downX: number = 0; private _downY: number = 0; + private _lastTap: number = 0; + private _doubleTap = false; + private _hitExpander = false; private _mainCont = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; @@ -182,23 +185,112 @@ export class DocumentView extends DocComponent(Docu }); } } + toggleMinimized = async () => { + let minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc); + if (minimizedDoc) { + let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint( + NumCast(minimizedDoc.x) - NumCast(this.Document.x), NumCast(minimizedDoc.y) - NumCast(this.Document.y)); + this.collapseToPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)); + } + } - _doubleTap = false; - onClick = (e: React.MouseEvent): void => { + static _undoBatch?: UndoManager.Batch = undefined; + @action + public collapseToPoint = async (scrpt: number[], expandedDocs: Doc[] | undefined): Promise => { + SelectionManager.DeselectAll(); + if (expandedDocs) { + if (!DocumentView._undoBatch) { + DocumentView._undoBatch = UndoManager.StartBatch("iconAnimating"); + } + let isMinimized: boolean | undefined; + expandedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => { + let iconAnimating = Cast(maximizedDoc.isIconAnimating, List); + if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) { + if (isMinimized === undefined) { + isMinimized = BoolCast(maximizedDoc.isMinimized, false); + } + maximizedDoc.willMaximize = isMinimized; + maximizedDoc.isMinimized = false; + maximizedDoc.isIconAnimating = new List([scrpt[0], scrpt[1], Date.now(), isMinimized ? 1 : 0]); + } + }); + setTimeout(() => { + DocumentView._undoBatch && DocumentView._undoBatch.end(); + DocumentView._undoBatch = undefined; + }, 500); + } + } + onClick = async (e: React.MouseEvent) => { + e.stopPropagation(); + let altKey = e.altKey; + let ctrlKey = e.ctrlKey; if (this._doubleTap && !this.props.isTopMost) { this.props.addDocTab(this.props.Document, "inTab"); SelectionManager.DeselectAll(); this.props.Document.libraryBrush = false; - e.stopPropagation(); } else if (CurrentUserUtils.MainDocId !== this.props.Document[Id] && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { SelectionManager.SelectDoc(this, e.ctrlKey); + let isExpander = (e.target as any).id === "isExpander"; + if (BoolCast(this.props.Document.isButton, false) || isExpander) { + SelectionManager.DeselectAll(); + let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs); + let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs); + let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs); + let linkedToDocs = await DocListCastAsync(this.props.Document.linkedToDocs, []); + let linkedFromDocs = await DocListCastAsync(this.props.Document.linkedFromDocs, []); + let expandedDocs: Doc[] = []; + expandedDocs = subBulletDocs ? [...subBulletDocs, ...expandedDocs] : expandedDocs; + expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs; + expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs; + // let expandedDocs = [...(subBulletDocs ? subBulletDocs : []), ...(maximizedDocs ? maximizedDocs : []), ...(summarizedDocs ? summarizedDocs : []),]; + if (expandedDocs.length) { // bcz: need a better way to associate behaviors with click events on widget-documents + let expandedProtoDocs = expandedDocs.map(doc => Doc.GetProto(doc)); + let maxLocation = StrCast(this.props.Document.maximizeLocation, "inPlace"); + let getDispDoc = (target: Doc) => Object.getOwnPropertyNames(target).indexOf("isPrototype") === -1 ? target : Doc.MakeDelegate(target); + if (altKey) { + maxLocation = this.props.Document.maximizeLocation = (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"); + if (!maxLocation || maxLocation === "inPlace") { + let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); + let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false); + expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false); + let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); + if (!hasView) { + this.props.addDocument && expandedDocs.forEach(async maxDoc => this.props.addDocument!(getDispDoc(maxDoc), false)); + } + expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); + } + } + if (maxLocation && maxLocation !== "inPlace") { + let dataDocs = DocListCast(CollectionDockingView.Instance.props.Document.data); + if (dataDocs) { + expandedDocs.forEach(maxDoc => + (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) && + this.props.addDocTab(getDispDoc(maxDoc), maxLocation))); + } + } else { + let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2); + this.collapseToPoint(scrpt, expandedProtoDocs); + } + } + else if (linkedToDocs.length || linkedFromDocs.length) { + let linkedFwdDocs = [ + linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0], + linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]]; + + let linkedFwdPage = [ + linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined, + linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined]; + if (!linkedFwdDocs.some(l => l instanceof Promise)) { + let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); + DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]); + } + } + } } } - private _lastTap: number = 0; - _hitExpander = false; onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; @@ -206,8 +298,8 @@ export class DocumentView extends DocComponent(Docu if (e.shiftKey && e.buttons === 1) { CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e); e.stopPropagation(); - } else if (this.active) { - //e.stopPropagation(); // bcz: doing this will block click events from CollectionFreeFormDocumentView which are needed for iconifying,etc + } else { + if (this.active) e.stopPropagation(); // events stop at the lowest document that is active. document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -215,7 +307,7 @@ export class DocumentView extends DocComponent(Docu } } onPointerMove = (e: PointerEvent): void => { - if (!e.cancelBubble) { + if (!e.cancelBubble && this.active) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -234,32 +326,22 @@ export class DocumentView extends DocComponent(Docu this._lastTap = Date.now(); } - deleteClicked = (): void => { - this.props.removeDocument && this.props.removeDocument(this.props.Document); - } - fieldsClicked = (e: React.MouseEvent): void => { - let kvp = Docs.KVPDocument(this.props.Document, { title: this.props.Document.title + ".kvp", width: 300, height: 300 }); - CollectionDockingView.Instance.AddRightSplit(kvp); - } - makeButton = (e: React.MouseEvent): void => { - let doc = this.props.Document.proto ? this.props.Document.proto : this.props.Document; + deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } + fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.Document, { width: 300, height: 300 }), "onRight") }; + makeBtnClicked = (): void => { + let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); if (StrCast(doc.layout).indexOf("Formatted") !== -1) { // only need to freeze the dimensions of text boxes since they don't have a native width and height naturally if (doc.isButton && !doc.nativeWidth) { doc.nativeWidth = this.props.Document[WidthSym](); doc.nativeHeight = this.props.Document[HeightSym](); } else { - doc.nativeWidth = doc.nativeHeight = undefined; } } } - fullScreenClicked = (e: React.MouseEvent): void => { - const doc = Doc.MakeCopy(this.props.Document, false); - if (doc) { - CollectionDockingView.Instance.OpenFullScreen(doc); - } - ContextMenu.Instance.clearItems(); + fullScreenClicked = (): void => { + CollectionDockingView.Instance.OpenFullScreen(Doc.MakeCopy(this.props.Document, false)); SelectionManager.DeselectAll(); } @@ -332,7 +414,7 @@ export class DocumentView extends DocComponent(Docu cm.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document), icon: "caret-square-right" }); cm.addItem({ description: "Fields", event: this.fieldsClicked, icon: "layer-group" }); cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" }); - cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeButton, icon: "concierge-bell" }); + cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" }); cm.addItem({ description: "Find aliases", event: async () => { const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index d3d765eed..7b642b299 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -102,7 +102,6 @@ export class FieldView extends React.Component { layoutKey={"layout"} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} bringToFront={emptyFunction} /> ); -- cgit v1.2.3-70-g09d2 From d1b0f462ced168f3a9ac5d007ba1219e98a3b6cf Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 31 May 2019 18:18:05 -0400 Subject: stacking views and more.. --- src/client/views/MainOverlayTextBox.tsx | 11 +++++++-- .../views/collections/CollectionBaseView.tsx | 2 +- .../views/collections/CollectionStackingView.scss | 2 +- .../views/collections/CollectionStackingView.tsx | 28 +++++++++++++++------- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 13 ++++------ 6 files changed, 36 insertions(+), 22 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 6e8e6f8ce..24327b995 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -7,6 +7,8 @@ import { Transform } from '../util/Transform'; import "normalize.css"; import "./MainOverlayTextBox.scss"; import { FormattedTextBox } from './nodes/FormattedTextBox'; +import { CollectionDockingView } from './collections/CollectionDockingView'; +import { Doc } from '../../new_fields/Doc'; interface MainOverlayTextBoxProps { } @@ -82,6 +84,11 @@ export class MainOverlayTextBox extends React.Component document.removeEventListener('pointerup', this.textBoxUp); } + addDocTab = (doc: Doc, location: string) => { + if (true) { // location === "onRight") { need to figure out stack to add "inTab" + CollectionDockingView.Instance.AddRightSplit(doc); + } + } render() { if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); @@ -91,10 +98,10 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${textRect.width * s}px`, height: `${textRect.height * s}px` }}> + ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyFunction} addDocTab={this.addDocTab} />
; } - else return (null); + else return (null); Z } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index e89b8be0f..734669893 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -120,7 +120,7 @@ export class CollectionBaseView extends React.Component { // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) { let zoom = NumCast(this.props.Document.scale, 1); - Doc.SetOnPrototype(doc, "zoomBasis", zoom); + // Doc.GetProto(doc).zoomBasis = zoom; } } return true; diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 1bb0b2674..1ab335cc3 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -6,7 +6,7 @@ display: flex; flex-direction: column; width: 100%; - height: 100%; + height: auto; position: absolute; overflow-y: auto; border-width: 0; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index bf246d4ec..a616b5ac7 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -1,24 +1,36 @@ import React = require("react"); +import { action, computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; -import { CollectionSubView, CollectionViewProps, SubCollectionViewProps } from "./CollectionSubView"; -import { Doc, WidthSym, HeightSym, DocListCast } from "../../../new_fields/Doc"; -import { DocumentView } from "../nodes/DocumentView"; -import { Transform } from "../../util/Transform"; +import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc"; +import { Id } from "../../../new_fields/FieldSymbols"; +import { NumCast } from "../../../new_fields/Types"; import { emptyFunction, returnOne, Utils } from "../../../Utils"; +import { DocumentView } from "../nodes/DocumentView"; import "./CollectionStackingView.scss"; -import { action, reaction, trace, computed } from "mobx"; -import { StrCast, NumCast } from "../../../new_fields/Types"; -import { Id } from "../../../new_fields/FieldSymbols"; +import { CollectionSubView } from "./CollectionSubView"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { _masonryGridRef: HTMLDivElement | null = null; + _heightDisposer?: IReactionDisposer; get gridGap() { return 10; } get gridSize() { return 20; } get itemWidth() { return NumCast(this.props.Document.itemWidth, 250); } + componentDidMount() { + this._heightDisposer = reaction(() => [this.childDocs.map(d => d[HeightSym]()), this.props.PanelWidth()], + () => { + let hgt = (this.props.PanelWidth() > 500) ? this.props.Document[HeightSym]() : + this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => height + d[HeightSym]() + this.gridGap, this.gridGap + 20 /* top margin */); + this.props.Document.height = hgt; + }, { fireImmediately: true }); + } + componentWillUnmount() { + if (this._heightDisposer) this._heightDisposer(); + } + @action moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { this.props.removeDocument(doc); @@ -37,7 +49,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } @computed get children() { - return this.childDocs.map(d => { + return this.childDocs.filter(d => !d.isMinimized).map(d => { let colSpan = Math.ceil((this.itemWidth + this.gridGap) / (this.gridSize + this.gridGap)); let rowSpan = Math.ceil((this.itemWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this.gridSize + this.gridGap)); let dref = React.createRef(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 69691b6f3..f3a596558 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -328,7 +328,7 @@ export class DocumentView extends DocComponent(Docu } deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } - fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.Document, { width: 300, height: 300 }), "onRight") }; + fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight") }; makeBtnClicked = (): void => { let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5d93edaac..3b61c68dd 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -230,20 +230,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._toolTipTextMenu.tooltip.style.opacity = "0"; } } + let ctrlKey = e.ctrlKey; if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey) { if (e.target && (e.target as any).href) { let href = (e.target as any).href; if (href.indexOf(DocServer.prepend("/doc/")) === 0) { let docid = href.replace(DocServer.prepend("/doc/"), "").split("?")[0]; - DocServer.GetRefField(docid).then(action((f: Opt) => { - if (f instanceof Doc) { - if (DocumentManager.Instance.getDocumentView(f)) { - DocumentManager.Instance.getDocumentView(f)!.props.focus(f); - } else { - this.props.addDocTab && this.props.addDocTab(f, "onRight"); - } - } - })); + DocServer.GetRefField(docid).then(f => { + (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab")) + }); } e.stopPropagation(); e.preventDefault(); -- cgit v1.2.3-70-g09d2