From 12f3a4a1bfce522c7e647317035ec0deda5c73d5 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 17 Jan 2020 10:28:52 -0500 Subject: moving things around. changed multiColumnView to not use intermediate config docs. --- src/client/views/CollectionLinearView.scss | 75 --------------- src/client/views/CollectionLinearView.tsx | 106 --------------------- src/client/views/CollectionMulticolumnView.tsx | 85 +++++------------ src/client/views/MainView.tsx | 2 +- .../views/collections/CollectionLinearView.scss | 75 +++++++++++++++ .../views/collections/CollectionLinearView.tsx | 106 +++++++++++++++++++++ .../views/collections/CollectionPivotView.tsx | 1 - src/client/views/collections/CollectionView.tsx | 43 ++++----- 8 files changed, 227 insertions(+), 266 deletions(-) delete mode 100644 src/client/views/CollectionLinearView.scss delete mode 100644 src/client/views/CollectionLinearView.tsx create mode 100644 src/client/views/collections/CollectionLinearView.scss create mode 100644 src/client/views/collections/CollectionLinearView.tsx (limited to 'src') diff --git a/src/client/views/CollectionLinearView.scss b/src/client/views/CollectionLinearView.scss deleted file mode 100644 index 81210d7ae..000000000 --- a/src/client/views/CollectionLinearView.scss +++ /dev/null @@ -1,75 +0,0 @@ -@import "globalCssVariables"; -@import "nodeModuleOverrides"; - -.collectionLinearView-outer{ - overflow: hidden; - height:100%; - .collectionLinearView { - display:flex; - height: 100%; - >label { - background: $dark-color; - color: $light-color; - display: inline-block; - border-radius: 18px; - font-size: 12.5px; - width: 18px; - height: 18px; - margin-top:auto; - margin-bottom:auto; - margin-right: 3px; - cursor: pointer; - transition: transform 0.2s; - } - - label p { - padding-left:5px; - } - - label:hover { - background: $main-accent; - transform: scale(1.15); - } - - >input { - display: none; - } - >input:not(:checked)~.collectionLinearView-content { - display: none; - } - - >input:checked~label { - transform: rotate(45deg); - transition: transform 0.5s; - cursor: pointer; - } - - .collectionLinearView-content { - display: flex; - opacity: 1; - position: relative; - margin-top: auto; - - .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable { - position:relative; - margin:auto; - margin-left: 3px; - transform-origin: center 80%; - } - .collectionLinearView-docBtn-scalable:hover { - transform: scale(1.15); - } - - .collectionLinearView-round-button { - width: 18px; - height: 18px; - border-radius: 18px; - font-size: 15px; - } - - .collectionLinearView-round-button:hover { - transform: scale(1.15); - } - } - } -} diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx deleted file mode 100644 index 5ca861f71..000000000 --- a/src/client/views/CollectionLinearView.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { action, IReactionDisposer, observable, reaction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc, HeightSym, WidthSym } from '../../new_fields/Doc'; -import { makeInterface } from '../../new_fields/Schema'; -import { BoolCast, NumCast, StrCast } from '../../new_fields/Types'; -import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils'; -import { DragManager } from '../util/DragManager'; -import { Transform } from '../util/Transform'; -import "./CollectionLinearView.scss"; -import { CollectionViewType } from './collections/CollectionView'; -import { CollectionSubView } from './collections/CollectionSubView'; -import { DocumentView } from './nodes/DocumentView'; -import { documentSchema } from '../../new_fields/documentSchemas'; -import { Id } from '../../new_fields/FieldSymbols'; - - -type LinearDocument = makeInterface<[typeof documentSchema,]>; -const LinearDocument = makeInterface(documentSchema); - -@observer -export class CollectionLinearView extends CollectionSubView(LinearDocument) { - @observable public addMenuToggle = React.createRef(); - private _dropDisposer?: DragManager.DragDropDisposer; - private _widthDisposer?: IReactionDisposer; - - componentWillUnmount() { - this._dropDisposer && this._dropDisposer(); - this._widthDisposer && this._widthDisposer(); - } - - componentDidMount() { - // is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported). - this._widthDisposer = reaction(() => NumCast(this.props.Document.height, 0) + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0), - () => this.props.Document.width = 5 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10), - { fireImmediately: true } - ); - } - protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view - this._dropDisposer && this._dropDisposer(); - if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); - } - } - - public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } - - dimension = () => NumCast(this.props.Document.height); // 2 * the padding - getTransform = (ele: React.RefObject) => () => { - if (!ele.current) return Transform.Identity(); - const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current); - return new Transform(-translateX, -translateY, 1 / scale); - } - - render() { - const guid = Utils.GenerateGuid(); - return
-
- this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} /> - - -
- {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => { - const nested = pair.layout.viewType === CollectionViewType.Linear; - const dref = React.createRef(); - const nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension()); - const deltaSize = nativeWidth * .15 / 2; - return
- this.dimension()}// ugh - need to get rid of this inline function to avoid recomputing - PanelHeight={nested ? pair.layout[HeightSym] : () => this.dimension()} - renderDepth={this.props.renderDepth + 1} - focus={emptyFunction} - backgroundColor={returnEmptyString} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} - bringToFront={emptyFunction} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} - zoomToScale={emptyFunction} - getScale={returnOne}> - -
; - })} -
-
-
; - } -} \ No newline at end of file diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index 0b2ca82f1..99242e8be 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -4,9 +4,8 @@ import { documentSchema } from '../../new_fields/documentSchemas'; import { CollectionSubView } from './collections/CollectionSubView'; import { DragManager } from '../util/DragManager'; import * as React from "react"; -import { Doc, DocListCast } from '../../new_fields/Doc'; +import { Doc } from '../../new_fields/Doc'; import { NumCast, StrCast } from '../../new_fields/Types'; -import { List } from '../../new_fields/List'; import { ContentFittingDocumentView } from './nodes/ContentFittingDocumentView'; import { Utils } from '../../Utils'; import "./collectionMulticolumnView.scss"; @@ -16,14 +15,12 @@ type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); interface Unresolved { - config: Doc; target: Doc; magnitude: number; unit: string; } interface Resolved { - config: Doc; target: Doc; pixels: number; } @@ -40,43 +37,24 @@ const resizerWidth = 2; @observer export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { - private _dropDisposer?: DragManager.DragDropDisposer; - - /** - * Returns the list of so-called configuration documents. - * Each one is a wrapper around what we typically think of as - * the child document, just also encoding the magnitude and unit - * of the specified width. - */ - private get configuration() { - const { Document } = this.props; - if (!Document.multicolumnData) { - Document.multicolumnData = new List(); - } - return DocListCast(this.Document.multicolumnData); - } - @computed private get resolvedLayoutInformation(): LayoutData { const unresolved: Unresolved[] = []; let starSum = 0, numFixed = 0, numRatio = 0; - for (const config of this.configuration) { - const { target, widthMagnitude, widthUnit } = config; - if (target instanceof Doc) { - const unit = StrCast(widthUnit); - const magnitude = NumCast(widthMagnitude); - if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { - if (unit === "*") { - starSum += magnitude; - numRatio++; - } else { - numFixed++; - } - unresolved.push({ config, target, magnitude, unit }); + for (const target of this.childDocs) { + const unit = StrCast(target.widthUnit); + const magnitude = NumCast(target.widthMagnitude); + if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { + if (unit === "*") { + starSum += magnitude; + numRatio++; + } else { + numFixed++; } - // otherwise, the particular configuration entry is ignored and the remaining - // space is allocated as if the document were absent from the configuration list + unresolved.push({ target, magnitude, unit }); } + // otherwise, the particular configuration entry is ignored and the remaining + // space is allocated as if the document were absent from the configuration list } return { unresolved, numRatio, numFixed, starSum }; } @@ -91,17 +69,8 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico */ @computed private get totalFixedAllocation(): number | undefined { - const layout = this.resolvedLayoutInformation; - if (!layout) { - return undefined; - } - let sum = 0; - for (const { magnitude, unit } of layout.unresolved) { - if (unit === "px") { - sum += magnitude; - } - } - return sum; + return this.resolvedLayoutInformation?.unresolved.reduce( + (sum, { magnitude, unit }) => sum + (unit === "px" ? magnitude : 0), 0); } /** @@ -115,12 +84,9 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico */ @computed private get totalRatioAllocation(): number | undefined { - const { totalFixedAllocation } = this; - const layout = this.resolvedLayoutInformation; - if (!layout) { - return undefined; - } - return totalFixedAllocation !== undefined ? this.props.PanelWidth() - (totalFixedAllocation + resizerWidth * (layout.unresolved.length - 1)) : undefined; + const layoutInfoLen = this.resolvedLayoutInformation?.unresolved.length; + if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) + return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)); } /** @@ -137,12 +103,9 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico */ @computed private get columnUnitLength(): number | undefined { - const layout = this.resolvedLayoutInformation; - const { totalRatioAllocation } = this; - if (layout === null || totalRatioAllocation === undefined) { - return undefined; + if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) { + return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum; } - return totalRatioAllocation / layout.starSum; } @computed @@ -163,7 +126,7 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico }); const collector: JSX.Element[] = []; for (let i = 0; i < resolved.length; i++) { - const { target, pixels, config } = resolved[i]; + const { target, pixels } = resolved[i]; collector.push(
pixels} getTransform={this.props.ScreenToLocalTransform} /> - {NumCast(config.widthMagnitude).toFixed(3)} {StrCast(config.widthUnit)} + {NumCast(target.widthMagnitude).toFixed(3)} {StrCast(target.widthUnit)}
, ); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 91c7f909b..3648ddccf 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -22,7 +22,7 @@ import { Docs, DocumentOptions } from '../documents/Documents'; import { HistoryUtil } from '../util/History'; import SharingManager from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { CollectionLinearView } from './CollectionLinearView'; +import { CollectionLinearView } from './collections/CollectionLinearView'; import { CollectionViewType, CollectionView } from './collections/CollectionView'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { ContextMenu } from './ContextMenu'; diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss new file mode 100644 index 000000000..eae9e0220 --- /dev/null +++ b/src/client/views/collections/CollectionLinearView.scss @@ -0,0 +1,75 @@ +@import "../globalCssVariables"; +@import "../_nodeModuleOverrides"; + +.collectionLinearView-outer{ + overflow: hidden; + height:100%; + .collectionLinearView { + display:flex; + height: 100%; + >label { + background: $dark-color; + color: $light-color; + display: inline-block; + border-radius: 18px; + font-size: 12.5px; + width: 18px; + height: 18px; + margin-top:auto; + margin-bottom:auto; + margin-right: 3px; + cursor: pointer; + transition: transform 0.2s; + } + + label p { + padding-left:5px; + } + + label:hover { + background: $main-accent; + transform: scale(1.15); + } + + >input { + display: none; + } + >input:not(:checked)~.collectionLinearView-content { + display: none; + } + + >input:checked~label { + transform: rotate(45deg); + transition: transform 0.5s; + cursor: pointer; + } + + .collectionLinearView-content { + display: flex; + opacity: 1; + position: relative; + margin-top: auto; + + .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable { + position:relative; + margin:auto; + margin-left: 3px; + transform-origin: center 80%; + } + .collectionLinearView-docBtn-scalable:hover { + transform: scale(1.15); + } + + .collectionLinearView-round-button { + width: 18px; + height: 18px; + border-radius: 18px; + font-size: 15px; + } + + .collectionLinearView-round-button:hover { + transform: scale(1.15); + } + } + } +} diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx new file mode 100644 index 000000000..9191bf822 --- /dev/null +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -0,0 +1,106 @@ +import { action, IReactionDisposer, observable, reaction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc'; +import { makeInterface } from '../../../new_fields/Schema'; +import { BoolCast, NumCast, StrCast } from '../../../new_fields/Types'; +import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../../Utils'; +import { DragManager } from '../../util/DragManager'; +import { Transform } from '../../util/Transform'; +import "./CollectionLinearView.scss"; +import { CollectionViewType } from './CollectionView'; +import { CollectionSubView } from './CollectionSubView'; +import { DocumentView } from '../nodes/DocumentView'; +import { documentSchema } from '../../../new_fields/documentSchemas'; +import { Id } from '../../../new_fields/FieldSymbols'; + + +type LinearDocument = makeInterface<[typeof documentSchema,]>; +const LinearDocument = makeInterface(documentSchema); + +@observer +export class CollectionLinearView extends CollectionSubView(LinearDocument) { + @observable public addMenuToggle = React.createRef(); + private _dropDisposer?: DragManager.DragDropDisposer; + private _widthDisposer?: IReactionDisposer; + + componentWillUnmount() { + this._dropDisposer && this._dropDisposer(); + this._widthDisposer && this._widthDisposer(); + } + + componentDidMount() { + // is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported). + this._widthDisposer = reaction(() => NumCast(this.props.Document.height, 0) + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0), + () => this.props.Document.width = 5 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10), + { fireImmediately: true } + ); + } + protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view + this._dropDisposer && this._dropDisposer(); + if (ele) { + this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + } + } + + public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } + + dimension = () => NumCast(this.props.Document.height); // 2 * the padding + getTransform = (ele: React.RefObject) => () => { + if (!ele.current) return Transform.Identity(); + const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current); + return new Transform(-translateX, -translateY, 1 / scale); + } + + render() { + const guid = Utils.GenerateGuid(); + return
+
+ this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} /> + + +
+ {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => { + const nested = pair.layout.viewType === CollectionViewType.Linear; + const dref = React.createRef(); + const nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension()); + const deltaSize = nativeWidth * .15 / 2; + return
+ this.dimension()}// ugh - need to get rid of this inline function to avoid recomputing + PanelHeight={nested ? pair.layout[HeightSym] : () => this.dimension()} + renderDepth={this.props.renderDepth + 1} + focus={emptyFunction} + backgroundColor={returnEmptyString} + parentActive={returnTrue} + whenActiveChanged={emptyFunction} + bringToFront={emptyFunction} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + zoomToScale={emptyFunction} + getScale={returnOne}> + +
; + })} +
+
+
; + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx index d6261c7ee..6af7cce70 100644 --- a/src/client/views/collections/CollectionPivotView.tsx +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -75,7 +75,6 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) { Object.keys(Doc.GetProto(child)).forEach(key => child[key] instanceof Doc && facetValues.add((child[key] as Doc)[facet]?.toString() || "(null)")); facetValues.add(child[facet]?.toString() || "(null)"); }); - this.childDocs const newFacetVals = facetValues.toArray().map(val => Docs.Create.TextDocument({ title: val.toString() })); const newFacet = Docs.Create.FreeformDocument(newFacetVals, { title: facet, treeViewOpen: true, isFacetFilter: true }); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 022fc8f48..ce3aab579 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -4,39 +4,38 @@ import { faColumns, faCopy, faEllipsisV, faFingerprint, faImage, faProjectDiagra import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from "mobx-react"; import * as React from 'react'; +import Lightbox from 'react-image-lightbox-with-rotate'; +import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app +import { DateField } from '../../../new_fields/DateField'; +import { Doc, DocListCast } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; -import { StrCast, BoolCast, Cast } from '../../../new_fields/Types'; +import { listSpec } from '../../../new_fields/Schema'; +import { BoolCast, Cast, StrCast } from '../../../new_fields/Types'; +import { ImageField } from '../../../new_fields/URLField'; +import { TraceMobx } from '../../../new_fields/util'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; +import { Utils } from '../../../Utils'; +import { DocumentType } from '../../documents/DocumentTypes'; +import { DocumentManager } from '../../util/DocumentManager'; +import { ImageUtils } from '../../util/Import & Export/ImageUtils'; +import { SelectionManager } from '../../util/SelectionManager'; +import CollectionMulticolumnView from '../CollectionMulticolumnView'; import { ContextMenu } from "../ContextMenu"; +import { FieldView, FieldViewProps } from '../nodes/FieldView'; +import { ScriptBox } from '../ScriptBox'; +import { Touchable } from '../Touchable'; import { CollectionDockingView } from "./CollectionDockingView"; import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import { CollectionLinearView } from './CollectionLinearView'; +import { CollectionPivotView } from './CollectionPivotView'; import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionStackingView } from './CollectionStackingView'; +import { CollectionStaffView } from './CollectionStaffView'; import { CollectionTreeView } from "./CollectionTreeView"; +import './CollectionView.scss'; import { CollectionViewBaseChrome } from './CollectionViewChromes'; -import { ImageUtils } from '../../util/Import & Export/ImageUtils'; -import { CollectionLinearView } from '../CollectionLinearView'; -import { CollectionStaffView } from './CollectionStaffView'; -import { DocumentType } from '../../documents/DocumentTypes'; -import { ImageField } from '../../../new_fields/URLField'; -import { DocListCast } from '../../../new_fields/Doc'; -import Lightbox from 'react-image-lightbox-with-rotate'; -import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app export const COLLECTION_BORDER_WIDTH = 2; -import { DateField } from '../../../new_fields/DateField'; -import { Doc, } from '../../../new_fields/Doc'; -import { listSpec } from '../../../new_fields/Schema'; -import { DocumentManager } from '../../util/DocumentManager'; -import { SelectionManager } from '../../util/SelectionManager'; -import './CollectionView.scss'; -import { FieldViewProps, FieldView } from '../nodes/FieldView'; -import { Touchable } from '../Touchable'; -import { TraceMobx } from '../../../new_fields/util'; -import { Utils } from '../../../Utils'; -import { ScriptBox } from '../ScriptBox'; -import CollectionMulticolumnView from '../CollectionMulticolumnView'; -import { CollectionPivotView } from './CollectionPivotView'; const path = require('path'); library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); -- cgit v1.2.3-70-g09d2