From 0058f56fda4e9e6a70ec7c23e1c141927715f9c1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 11 Jul 2019 00:38:37 -0400 Subject: trying to make everything work the same way --- src/client/views/collections/CollectionBaseView.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (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 e4f9b5058..079a44b88 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -74,21 +74,27 @@ export class CollectionBaseView extends React.Component { this.props.whenActiveChanged(isActive); } + public get isAnnotationOverlay() { return this.props.fieldKey === "annotations" || this.props.fieldExt === "annotations"; } + @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.isAnnotationOverlay ? "dummy" : ""); } + @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { + let self = this; var curPage = NumCast(this.props.Document.curPage, -1); Doc.GetProto(doc).page = curPage; if (curPage >= 0) { Doc.GetProto(doc).annotationOn = this.props.Document; } allowDuplicates = true; - const value = Cast(this.dataDoc[this.dataField], listSpec(Doc)); + let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; + let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; + const value = Cast(targetDataDoc[targetField], listSpec(Doc)); if (value !== undefined) { if (allowDuplicates || !value.some(v => v instanceof Doc && v[Id] === doc[Id])) { value.push(doc); } } else { - Doc.GetProto(this.dataDoc)[this.dataField] = new List([doc]); + Doc.GetProto(targetDataDoc)[targetField] = new List([doc]); } return true; } @@ -98,7 +104,9 @@ export class CollectionBaseView extends React.Component { let docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView); docView && SelectionManager.DeselectDoc(docView); //TODO This won't create the field if it doesn't already exist - const value = Cast(this.dataDoc[this.dataField], listSpec(Doc), []); + let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; + let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; + let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); let index = value.reduce((p, v, i) => (v instanceof Doc && v[Id] === doc[Id]) ? i : p, -1); PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => annotationOn === this.dataDoc.Document && (doc.annotationOn = undefined) @@ -116,7 +124,10 @@ export class CollectionBaseView extends React.Component { @action.bound moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { - if (Doc.AreProtosEqual(this.dataDoc, targetCollection)) { + let self = this; + let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; + if (Doc.AreProtosEqual(targetDataDoc, targetCollection)) { + //if (Doc.AreProtosEqual(this.extensionDoc, targetCollection)) { return true; } if (this.removeDocument(doc)) { -- cgit v1.2.3-70-g09d2 From 1b203afbd297f8ae9400a47c9379df912f9ef3b5 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 11 Jul 2019 15:43:39 -0400 Subject: tweaks to annotationOverlay. --- src/client/views/collections/CollectionBaseView.tsx | 3 +-- src/client/views/collections/CollectionStackingView.tsx | 4 +++- src/client/views/collections/CollectionSubView.tsx | 3 +-- src/client/views/collections/CollectionView.tsx | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (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 079a44b88..2eb2a727c 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -74,8 +74,7 @@ export class CollectionBaseView extends React.Component { this.props.whenActiveChanged(isActive); } - public get isAnnotationOverlay() { return this.props.fieldKey === "annotations" || this.props.fieldExt === "annotations"; } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.isAnnotationOverlay ? "dummy" : ""); } + @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 9266fc8fd..62968821a 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -14,6 +14,7 @@ import { undoBatch } from "../../util/UndoManager"; import { DragManager } from "../../util/DragManager"; import { DocTypes } from "../../documents/Documents"; import { Transform } from "../../util/Transform"; +import { resolve } from "bluebird"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -54,13 +55,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDisplayDoc(layoutDoc: Doc, d: Doc, dxf: () => Transform) { + let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined; let dataDoc = d !== this.props.DataDoc ? this.props.DataDoc : undefined; let width = () => d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth; let height = () => this.getDocHeight(layoutDoc); let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]()); return (schemaCtor: (doc: Doc) => T) { this.createDropTarget(ele); } - public get isAnnotationOverlay() { return this.props.fieldKey === "annotations" || this.props.fieldExt === "annotations"; } - @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.isAnnotationOverlay ? "dummy" : ""); } + @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } get childDocs() { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e69696390..56750668d 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -43,7 +43,7 @@ export class CollectionView extends React.Component { return (null); } - get isAnnotationOverlay() { return this.props.fieldKey === "annotations" || this.props.fieldExt === "annotations"; } + get isAnnotationOverlay() { return this.props.fieldExt ? true : false; } onContextMenu = (e: React.MouseEvent): void => { if (!this.isAnnotationOverlay && !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 -- cgit v1.2.3-70-g09d2 From d7f84cf69a34d7f176d72452311183303a489eca Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 12 Jul 2019 14:01:03 -0400 Subject: changed a bunch of style/color things with treeView and toolbar --- src/client/views/Main.scss | 9 +++---- src/client/views/MainView.tsx | 28 +++++++++++----------- src/client/views/PreviewCursor.tsx | 7 +++--- .../views/collections/CollectionBaseView.scss | 3 ++- .../views/collections/CollectionBaseView.tsx | 6 +++-- .../views/collections/CollectionStackingView.tsx | 2 -- .../views/collections/CollectionTreeView.tsx | 5 ++-- .../collectionFreeForm/CollectionFreeFormView.scss | 1 - .../authentication/models/current_user_utils.ts | 5 ++++ 9 files changed, 37 insertions(+), 29 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index f52e3b658..a16123476 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -235,16 +235,17 @@ ul#add-options-list { } .mainView-libraryHandle { - opacity: 0.6; width: 20px; height: 40px; top: 50%; - border-radius: 20px; + border: 1px solid black; + border-radius: 5px; position: absolute; z-index: 1; - background: gray; } - +.svg-inline--fa { + vertical-align: unset; +} .mainView-workspace { height:200px; position:relative; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 935f00332..ec5ec6e8b 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 { faArrowDown, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; +import { faArrowDown, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; @@ -13,7 +13,7 @@ import { Id } from '../../new_fields/FieldSymbols'; import { InkTool } from '../../new_fields/InkField'; import { List } from '../../new_fields/List'; import { listSpec } from '../../new_fields/Schema'; -import { Cast, FieldValue, NumCast, BoolCast } from '../../new_fields/Types'; +import { Cast, FieldValue, NumCast, BoolCast, StrCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { RouteStore } from '../../server/RouteStore'; import { emptyFunction, returnOne, returnTrue } from '../../Utils'; @@ -105,7 +105,7 @@ export class MainView extends React.Component { library.add(faFont); library.add(faExclamation); - library.add(faImage); + library.add(faPortrait); library.add(faFilePdf); library.add(faObjectGroup); library.add(faTable); @@ -325,13 +325,15 @@ export class MainView extends React.Component { } @computed get mainContent() { + let sidebar = CurrentUserUtils.UserDocument.sidebar; + if (!(sidebar instanceof Doc)) return (null); return
-
+
{this.flyout}
{this.dockingContent} @@ -371,28 +373,21 @@ export class MainView extends React.Component { let addImportCollectionNode = action(() => Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })); let btns: [React.RefObject, IconName, string, () => Doc][] = [ - [React.createRef(), "image", "Add Image", addImageNode], + [React.createRef(), "portrait", "Add Cat Image", addImageNode], [React.createRef(), "object-group", "Add Collection", addColNode], - [React.createRef(), "tree", "Add Tree", addTreeNode], - [React.createRef(), "table", "Add Schema", addSchemaNode], // [React.createRef(), "clone", "Add Docking Frame", addDockingNode], [React.createRef(), "arrow-up", "Import Directory", addImportCollectionNode], ]; return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 5 }} > - +
  • -
  • {btns.map(btn =>
  • )}
  • +
  • diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 7c1d00eb0..ef68c4489 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -35,9 +35,10 @@ export class PreviewCursor extends React.Component<{}> { // DASHFormattedTextBoxHandled flag when a text box consumes a key press so that we can ignore // the keyPress here. //if not these keys, make a textbox if preview cursor is active! - if (e.key.startsWith("F") && !e.key.endsWith("F")) { - } else if (e.key !== "Escape" && e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { - if ((!e.ctrlKey && !e.metaKey) || (e.key >= "a" && e.key <= "z")) { + if (e.key !== "Escape" && e.key !== "Backspace" && e.key !== "Delete" && + e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && + !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { + if (!e.ctrlKey && !e.metaKey) {// /^[a-zA-Z0-9$*^%#@+-=_|}{[]"':;?/><.,}]$/.test(e.key)) { PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e); PreviewCursor.Visible = false; } diff --git a/src/client/views/collections/CollectionBaseView.scss b/src/client/views/collections/CollectionBaseView.scss index 1f5acb96a..34bcb705e 100644 --- a/src/client/views/collections/CollectionBaseView.scss +++ b/src/client/views/collections/CollectionBaseView.scss @@ -1,11 +1,12 @@ @import "../globalCssVariables"; #collectionBaseView { 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; border-radius: inherit; pointer-events: all; + width:100%; + height:100%; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 2eb2a727c..eba69b448 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -5,7 +5,7 @@ import { Doc } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; import { listSpec } from '../../../new_fields/Schema'; -import { BoolCast, Cast, NumCast, PromiseValue } from '../../../new_fields/Types'; +import { BoolCast, Cast, NumCast, PromiseValue, StrCast } from '../../../new_fields/Types'; import { DocumentManager } from '../../util/DocumentManager'; import { SelectionManager } from '../../util/SelectionManager'; import { ContextMenu } from '../ContextMenu'; @@ -145,7 +145,9 @@ export class CollectionBaseView extends React.Component { }; const viewtype = this.collectionViewType; return ( -
    {viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
    diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index c667b3f3c..a84fd9cfe 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -14,7 +14,6 @@ import { undoBatch } from "../../util/UndoManager"; import { DragManager } from "../../util/DragManager"; import { DocumentType } from "../../documents/Documents"; import { Transform } from "../../util/Transform"; -import { resolve } from "bluebird"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -56,7 +55,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { getDisplayDoc(layoutDoc: Doc, d: Doc, dxf: () => Transform) { let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined; - let dataDoc = d !== this.props.DataDoc ? this.props.DataDoc : undefined; let width = () => d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth; let height = () => this.getDocHeight(layoutDoc); let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]()); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 188b78d63..200e9558d 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -153,7 +153,8 @@ class TreeView extends React.Component { let docList = Cast(this.resolvedDataDoc[this.fieldKey], listSpec(Doc)); let doc = Cast(this.resolvedDataDoc[this.fieldKey], Doc); let isDoc = doc instanceof Doc || docList; - return
    this._collapsed = !this._collapsed)}> + let c + return
    this._collapsed = !this._collapsed)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> {}
    ; } @@ -532,7 +533,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); return !this.childDocs ? (null) : (
    (e.target as any).scrollHeight > (e.target as any).clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index ec0e446e9..00407d39a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -36,7 +36,6 @@ // linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px); // background-size: 30px 30px; // } - box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; opacity: 0.99; border: 0px solid $light-color-secondary; border-radius: inherit; diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 763693dd6..695ddc3ec 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -37,6 +37,7 @@ export class CurrentUserUtils { doc.gridGap = 5; doc.xMargin = 5; doc.yMargin = 5; + doc.boxShadow = "0 0"; doc.excludeFromLibrary = true; doc.optionalRightCollection = Docs.Create.StackingDocument([], { title: "New mobile uploads" }); // doc.library = Docs.Create.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` }); @@ -49,11 +50,13 @@ export class CurrentUserUtils { const workspaces = Docs.Create.TreeDocument([], { title: "Workspaces", height: 100 }); workspaces.excludeFromLibrary = true; workspaces.workspaceLibrary = true; + workspaces.boxShadow = "0 0"; doc.workspaces = workspaces; } if (doc.recentlyClosed === undefined) { const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 }); recentlyClosed.excludeFromLibrary = true; + recentlyClosed.boxShadow = "0 0"; doc.recentlyClosed = recentlyClosed; } if (doc.sidebar === undefined) { @@ -62,6 +65,8 @@ export class CurrentUserUtils { sidebar.gridGap = 5; sidebar.xMargin = 5; sidebar.yMargin = 5; + Doc.GetProto(sidebar).backgroundColor = "lightGray"; + sidebar.boxShadow = "1 1 3"; doc.sidebar = sidebar; } -- cgit v1.2.3-70-g09d2 From 3442776999d1d7b7bced9bbed601ead637a43cc7 Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 22 Jul 2019 10:24:37 -0400 Subject: merged stacking sections branch. --- src/client/views/DocumentDecorations.tsx | 10 +- .../views/collections/CollectionBaseView.tsx | 6 +- .../views/collections/CollectionStackingView.scss | 13 +- .../views/collections/CollectionStackingView.tsx | 247 --------------------- src/client/views/collections/CollectionView.tsx | 28 ++- src/client/views/nodes/WebBox.tsx | 16 -- src/new_fields/Doc.ts | 33 ++- 7 files changed, 64 insertions(+), 289 deletions(-) delete mode 100644 src/client/views/collections/CollectionStackingView.tsx (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index fb5104915..2f7bea365 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -28,6 +28,7 @@ import { RichTextField } from '../../new_fields/RichTextField'; import { LinkManager } from '../util/LinkManager'; import { ObjectField } from '../../new_fields/ObjectField'; import { MetadataEntryMenu } from './MetadataEntryMenu'; +import { ImageBox } from './nodes/ImageBox'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -85,8 +86,13 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> SelectionManager.DeselectAll(); let fieldTemplate = fieldTemplateView.props.Document; let docTemplate = fieldTemplateView.props.ContainingCollectionView!.props.Document; - let metaKey = text.slice(1, text.length); - Doc.MakeTemplate(fieldTemplate, metaKey, Doc.GetProto(docTemplate)); + let metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length); + let proto = Doc.GetProto(docTemplate); + Doc.MakeTemplate(fieldTemplate, metaKey, proto); + if (text.startsWith(">>")) { + proto.detailedLayout = proto.layout; + proto.miniLayout = ImageBox.LayoutString(metaKey); + } } else { if (SelectionManager.SelectedDocuments().length > 0) { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index eba69b448..72faf52c4 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -18,7 +18,8 @@ export enum CollectionViewType { Schema, Docking, Tree, - Stacking + Stacking, + Masonry } export interface CollectionRenderProps { @@ -78,7 +79,6 @@ export class CollectionBaseView extends React.Component { @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { - let self = this; var curPage = NumCast(this.props.Document.curPage, -1); Doc.GetProto(doc).page = curPage; if (curPage >= 0) { @@ -146,7 +146,7 @@ export class CollectionBaseView extends React.Component { const viewtype = this.collectionViewType; return (
    {viewtype !== undefined ? this.props.children(viewtype, props) : (null)} diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 7e886304d..7ebf5f77c 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -1,7 +1,9 @@ @import "../globalCssVariables"; .collectionStackingView { + height: 100%; + width: 100%; + position: absolute; overflow-y: auto; - .collectionStackingView-docView-container { width: 45%; margin: 5% 2.5%; @@ -71,4 +73,13 @@ grid-column-end: span 1; height: 100%; } + .collectionStackingView-sectionHeader { + width: 90%; + background: gray; + text-align: center; + margin-left: 5%; + margin-right: 5%; + color: white; + margin-top: 10px; + } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx deleted file mode 100644 index 6d9e942c9..000000000 --- a/src/client/views/collections/CollectionStackingView.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import React = require("react"); -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, IReactionDisposer, reaction, untracked, observable, runInAction } from "mobx"; -import { observer } from "mobx-react"; -import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc"; -import { Id } from "../../../new_fields/FieldSymbols"; -import { BoolCast, NumCast, Cast } from "../../../new_fields/Types"; -import { emptyFunction, Utils } from "../../../Utils"; -import { ContextMenu } from "../ContextMenu"; -import { CollectionSchemaPreview } from "./CollectionSchemaView"; -import "./CollectionStackingView.scss"; -import { CollectionSubView } from "./CollectionSubView"; -import { undoBatch } from "../../util/UndoManager"; -import { DragManager } from "../../util/DragManager"; -import { DocumentType } from "../../documents/Documents"; -import { Transform } from "../../util/Transform"; -import { CursorProperty } from "csstype"; - -@observer -export class CollectionStackingView extends CollectionSubView(doc => doc) { - _masonryGridRef: HTMLDivElement | null = null; - _draggerRef = React.createRef(); - _heightDisposer?: IReactionDisposer; - _gridSize = 1; - _docXfs: any[] = []; - @observable private cursor: CursorProperty = "grab"; - @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); } - @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); } - @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); } - @computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); } - @computed get columnWidth() { return this.singleColumn ? (this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin) : Math.min(this.props.PanelWidth() - 2 * this.xMargin, NumCast(this.props.Document.columnWidth, 250)); } - @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); } - - componentDidMount() { - this._heightDisposer = reaction(() => [this.yMargin, this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])], - () => this.singleColumn && - (this.props.Document.height = this.filteredChildren.reduce((height, d, i) => - height + this.getDocHeight(d) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap), this.yMargin)) - , { fireImmediately: true }); - } - componentWillUnmount() { - if (this._heightDisposer) this._heightDisposer(); - } - - @action - moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { - return this.props.removeDocument(doc) && addDocument(doc); - } - createRef = (ele: HTMLDivElement | null) => { - this._masonryGridRef = ele; - this.createDropTarget(ele!); - } - - overlays = (doc: Doc) => { - return doc.type === DocumentType.IMG || doc.type === DocumentType.VID ? { title: "title", caption: "caption" } : {}; - } - - getDisplayDoc(layoutDoc: Doc, d: Doc, dxf: () => Transform) { - let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined; - let width = () => d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth; - let height = () => this.getDocHeight(layoutDoc); - let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]()); - return - ; - } - getDocHeight(d: Doc) { - let nw = NumCast(d.nativeWidth); - let nh = NumCast(d.nativeHeight); - let aspect = nw && nh ? nh / nw : 1; - let wid = Math.min(d[WidthSym](), this.columnWidth); - return (nw && nh) ? wid * aspect : d[HeightSym](); - } - - - offsetTransform(doc: Doc, translateX: number, translateY: number) { - 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.columnWidth); - } - getDocTransform(doc: Doc, dref: HTMLDivElement) { - let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); - return this.offsetTransform(doc, translateX, translateY); - } - getSingleDocTransform(doc: Doc, ind: number, width: number) { - let localY = this.filteredChildren.reduce((height, d, i) => - height + (i < ind ? this.getDocHeight(Doc.expandTemplateLayout(d, this.props.DataDoc)) + this.gridGap : 0), this.yMargin); - let translate = this.props.ScreenToLocalTransform().inverse().transformPoint((this.props.PanelWidth() - width) / 2, localY); - return this.offsetTransform(doc, translate[0], translate[1]); - } - - @computed - get children() { - this._docXfs.length = 0; - return this.filteredChildren.map((d, i) => { - let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc); - let width = () => d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth; - let height = () => this.getDocHeight(layoutDoc); - if (this.singleColumn) { - let dxf = () => this.getSingleDocTransform(layoutDoc, i, width()); - let rowHgtPcnt = height() / (this.props.Document[HeightSym]() - 2 * this.yMargin) * 100; - this._docXfs.push({ dxf: dxf, width: width, height: height }); - return
    - {this.getDisplayDoc(layoutDoc, d, dxf)} -
    ; - } else { - let dref = React.createRef(); - let dxf = () => this.getDocTransform(layoutDoc, dref.current!); - let rowSpan = Math.ceil((height() + this.gridGap) / (this._gridSize + this.gridGap)); - this._docXfs.push({ dxf: dxf, width: width, height: height }); - return
    - {this.getDisplayDoc(layoutDoc, d, dxf)} -
    ; - } - }); - } - - _columnStart: number = 0; - columnDividerDown = (e: React.PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - runInAction(() => this.cursor = "grabbing"); - document.addEventListener("pointermove", this.onDividerMove); - document.addEventListener('pointerup', this.onDividerUp); - this._columnStart = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; - } - @action - onDividerMove = (e: PointerEvent): void => { - let dragPos = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; - let delta = dragPos - this._columnStart; - this._columnStart = dragPos; - - this.props.Document.columnWidth = this.columnWidth + delta; - } - - @action - onDividerUp = (e: PointerEvent): void => { - runInAction(() => this.cursor = "grab"); - document.removeEventListener("pointermove", this.onDividerMove); - document.removeEventListener('pointerup', this.onDividerUp); - } - - @computed get columnDragger() { - return
    - -
    ; - } - onContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // 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: "Toggle multi-column", - event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, true), icon: "file-pdf" - }); - } - } - - @undoBatch - @action - drop = (e: Event, de: DragManager.DropEvent) => { - let targInd = -1; - let where = [de.x, de.y]; - if (de.data instanceof DragManager.DocumentDragData) { - this._docXfs.map((cd, i) => { - let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap); - let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height()); - if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) { - targInd = i; - } - }); - } - if (super.drop(e, de)) { - let newDoc = de.data.droppedDocuments[0]; - let docs = this.childDocList; - if (docs) { - if (targInd === -1) targInd = docs.length; - else targInd = docs.indexOf(this.filteredChildren[targInd]); - let srcInd = docs.indexOf(newDoc); - docs.splice(srcInd, 1); - docs.splice(targInd > srcInd ? targInd - 1 : targInd, 0, newDoc); - } - } - return false; - } - @undoBatch - @action - onDrop = (e: React.DragEvent): void => { - let where = [e.clientX, e.clientY]; - let targInd = -1; - this._docXfs.map((cd, i) => { - let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap); - let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height()); - if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) { - targInd = i; - } - }); - super.onDrop(e, {}, () => { - if (targInd !== -1) { - let newDoc = this.childDocs[this.childDocs.length - 1]; - let docs = this.childDocList; - if (docs) { - docs.splice(docs.length - 1, 1); - docs.splice(targInd, 0, newDoc); - } - } - }); - } - render() { - let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.filteredChildren.length, - Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap)))); - let templatecols = ""; - for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `; - return ( -
    e.stopPropagation()} > -
    - {this.children} - {this.singleColumn ? (null) : this.columnDragger} -
    -
    - ); - } -} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 56750668d..045c8531e 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,11 +1,10 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree } from '@fortawesome/free-solid-svg-icons'; +import { faProjectDiagram, faSignature, faColumns, faSquare, faTh, faImage, faThList, faTree, faEllipsisV } from '@fortawesome/free-solid-svg-icons'; import { observer } from "mobx-react"; import * as React from 'react'; -import { Doc } from '../../../new_fields/Doc'; +import { Doc, DocListCast, WidthSym, HeightSym } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; -import { Docs } from '../../documents/Documents'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; @@ -16,6 +15,8 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionStackingView } from './CollectionStackingView'; import { CollectionTreeView } from "./CollectionTreeView"; +import { StrCast, PromiseValue } from '../../../new_fields/Types'; +import { DocumentType } from '../../documents/Documents'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh); @@ -24,6 +25,9 @@ library.add(faSquare); library.add(faProjectDiagram); library.add(faSignature); library.add(faThList); +library.add(faColumns); +library.add(faEllipsisV); +library.add(faImage); @observer export class CollectionView extends React.Component { @@ -35,7 +39,8 @@ export class CollectionView extends React.Component { case CollectionViewType.Schema: return (); case CollectionViewType.Docking: return (); case CollectionViewType.Tree: return (); - case CollectionViewType.Stacking: return (); + case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (); } + case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } case CollectionViewType.Freeform: default: return (); @@ -45,6 +50,7 @@ export class CollectionView extends React.Component { get isAnnotationOverlay() { return this.props.fieldExt ? true : false; } + static _applyCount: number = 0; onContextMenu = (e: React.MouseEvent): void => { if (!this.isAnnotationOverlay && !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 let subItems: ContextMenuProps[] = []; @@ -54,15 +60,19 @@ export class CollectionView extends React.Component { } subItems.push({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema), icon: "th-list" }); subItems.push({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" }); - subItems.push({ description: "Stacking", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Stacking), icon: "th-list" }); + subItems.push({ description: "Stacking", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Stacking), icon: "ellipsis-v" }); + subItems.push({ description: "Masonry", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Masonry), icon: "columns" }); ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems }); ContextMenu.Instance.addItem({ description: "Apply Template", event: undoBatch(() => { let otherdoc = new Doc(); - otherdoc.width = 100; - otherdoc.height = 50; - Doc.GetProto(otherdoc).title = "applied(" + this.props.Document.title + ")"; - Doc.GetProto(otherdoc).layout = Doc.MakeDelegate(this.props.Document); + otherdoc.width = this.props.Document[WidthSym](); + otherdoc.height = this.props.Document[HeightSym](); + otherdoc.title = this.props.Document.title + "(..." + CollectionView._applyCount++ + ")"; // previously "applied" + otherdoc.layout = Doc.MakeDelegate(this.props.Document); + otherdoc.miniLayout = StrCast(this.props.Document.miniLayout); + otherdoc.detailedLayout = otherdoc.layout; + otherdoc.type = DocumentType.TEMPLATE; this.props.addDocTab && this.props.addDocTab(otherdoc, undefined, "onRight"); }), icon: "project-diagram" }); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index f0a9ec6d8..162ac1d98 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -9,22 +9,6 @@ import React = require("react"); import { InkTool } from "../../../new_fields/InkField"; import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; -export function onYouTubeIframeAPIReady() { - console.log("player"); - return; - let player = new YT.Player('player', { - events: { - 'onReady': onPlayerReady - } - }); -} -// must cast as any to set property on window -const _global = (window /* browser */ || global /* node */) as any; -_global.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady; - -function onPlayerReady(event: any) { - event.target.playVideo(); -} @observer export class WebBox extends React.Component { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 59e61023f..2ad6ae5f0 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -10,6 +10,7 @@ import { RefField, FieldId } from "./RefField"; import { ToScriptString, SelfProxy, Parent, OnUpdate, Self, HandleUpdate, Update, Id } from "./FieldSymbols"; import { scriptingGlobal } from "../client/util/Scripting"; import { List } from "./List"; +import { DocumentType } from "../client/documents/Documents"; import { ComputedField } from "./ScriptField"; export namespace Field { @@ -317,7 +318,7 @@ export namespace Doc { if (extensionDoc === undefined) { setTimeout(() => { let docExtensionForField = new Doc(doc[Id] + fieldKey, true); - docExtensionForField.title = "Extension of " + doc.title + "'s field:" + fieldKey; + docExtensionForField.title = doc.title + ":" + fieldKey + ".ext"; docExtensionForField.extendsDoc = doc; let proto: Doc | undefined = doc; while (proto && !Doc.IsPrototype(proto)) { @@ -345,20 +346,23 @@ export namespace Doc { // ... which means we change the layout to be an expanded view of the template layout. // This allows the view override the template's properties and be referenceable as its own document. - let expandedTemplateLayout = templateLayoutDoc["_expanded_" + dataDoc[Id]]; + let expandedTemplateLayout = dataDoc[templateLayoutDoc[Id]]; if (expandedTemplateLayout instanceof Doc) { return expandedTemplateLayout; } if (expandedTemplateLayout === undefined && BoolCast(templateLayoutDoc.isTemplate)) { setTimeout(() => { - templateLayoutDoc["_expanded_" + dataDoc[Id]] = Doc.MakeDelegate(templateLayoutDoc); - (templateLayoutDoc["_expanded_" + dataDoc[Id]] as Doc).title = templateLayoutDoc.title + " applied to " + dataDoc.title; - (templateLayoutDoc["_expanded_" + dataDoc[Id]] as Doc).isExpandedTemplate = templateLayoutDoc; + let expandedDoc = Doc.MakeDelegate(templateLayoutDoc); + expandedDoc.title = templateLayoutDoc.title + "[" + StrCast(dataDoc.title).match(/\.\.\.[0-9]*/) + "]"; + expandedDoc.isExpandedTemplate = templateLayoutDoc; + dataDoc[templateLayoutDoc[Id]] = expandedDoc; }, 0); } - return templateLayoutDoc; + return templateLayoutDoc; // use the templateLayout when it's not a template or the expandedTemplate is pending. } + let _pendingExpansions: Map = new Map(); + export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc { const copy = new Doc; Object.keys(doc).forEach(key => { @@ -386,12 +390,12 @@ export namespace Doc { export function MakeDelegate(doc: Doc, id?: string): Doc; export function MakeDelegate(doc: Opt, id?: string): Opt; export function MakeDelegate(doc: Opt, id?: string): Opt { - if (!doc) { - return undefined; + if (doc) { + const delegate = new Doc(id, true); + delegate.proto = doc; + return delegate; } - const delegate = new Doc(id, true); - delegate.proto = doc; - return delegate; + return undefined; } export function MakeTemplate(fieldTemplate: Doc, metaKey: string, proto: Doc) { @@ -421,4 +425,11 @@ export namespace Doc { fieldTemplate.showTitle = "title"; setTimeout(() => fieldTemplate.proto = proto); } + + export async function ToggleDetailLayout(d: Doc) { + let miniLayout = await PromiseValue(d.miniLayout); + let detailLayout = await PromiseValue(d.detailedLayout); + d.layout !== miniLayout ? miniLayout && (d.layout = d.miniLayout) : detailLayout && (d.layout = detailLayout); + if (d.layout === detailLayout) Doc.GetProto(d).nativeWidth = Doc.GetProto(d).nativeHeight = undefined; + } } \ No newline at end of file -- cgit v1.2.3-70-g09d2