diff options
| author | Sam Wilkins <samwilkins333@gmail.com> | 2019-10-14 13:38:31 -0400 |
|---|---|---|
| committer | Sam Wilkins <samwilkins333@gmail.com> | 2019-10-14 13:38:31 -0400 |
| commit | cc84f5620b3f3ef801e3b0696f817e4fb74f58fc (patch) | |
| tree | a743f02dd80daea6ea37040ec2371db7acd1b7b8 /src/client/views/collections | |
| parent | fb3d1a66100e9ecf573031cfcafeb983f4ad5d5b (diff) | |
| parent | 9d877a5d38a5574b6ab99c20d0c1718e0af964b5 (diff) | |
merged with master
Diffstat (limited to 'src/client/views/collections')
9 files changed, 36 insertions, 48 deletions
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 61919427a..7798964ea 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -23,6 +23,7 @@ export enum CollectionViewType { Stacking, Masonry, Pivot, + Linear, } export namespace CollectionViewType { @@ -35,7 +36,8 @@ export namespace CollectionViewType { ["tree", CollectionViewType.Tree], ["stacking", CollectionViewType.Stacking], ["masonry", CollectionViewType.Masonry], - ["pivot", CollectionViewType.Pivot] + ["pivot", CollectionViewType.Pivot], + ["linear", CollectionViewType.Linear] ]); export const valueOf = (value: string) => { @@ -177,7 +179,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> { <div id="collectionBaseView" style={{ pointerEvents: this.props.Document.isBackground ? "none" : "all", - boxShadow: this.props.Document.isBackground ? undefined : `#9c9396 ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}` + boxShadow: this.props.Document.isBackground || viewtype === CollectionViewType.Linear ? undefined : `#9c9396 ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}` }} className={this.props.className || "collectionView-cont"} onContextMenu={this.props.onContextMenu} ref={this.props.contentRef}> diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index fe805a980..1f78c8c97 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -37,7 +37,8 @@ const _global = (window /* browser */ || global /* node */) as any; @observer export class CollectionDockingView extends React.Component<SubCollectionViewProps> { - @observable public static Instance: CollectionDockingView; + @observable public static Instances: CollectionDockingView[] = []; + @computed public static get Instance() { return CollectionDockingView.Instances[0]; } public static makeDocumentConfig(document: Doc, dataDoc: Doc | undefined, width?: number) { return { type: 'react-component', @@ -65,7 +66,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp constructor(props: SubCollectionViewProps) { super(props); - !CollectionDockingView.Instance && runInAction(() => CollectionDockingView.Instance = this); + runInAction(() => !CollectionDockingView.Instances ? CollectionDockingView.Instances = [this] : CollectionDockingView.Instances.push(this)); //Why is this here? (window as any).React = React; (window as any).ReactDOM = ReactDOM; @@ -317,13 +318,14 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp } catch (e) { } - if (this._goldenLayout) this._goldenLayout.destroy(); - runInAction(() => this._goldenLayout = null); + this._goldenLayout && this._goldenLayout.destroy(); + runInAction(() => { + CollectionDockingView.Instances.splice(CollectionDockingView.Instances.indexOf(this), 1); + this._goldenLayout = null; + }); window.removeEventListener('resize', this.onResize); - if (this.reactionDisposer) { - this.reactionDisposer(); - } + this.reactionDisposer && this.reactionDisposer(); } @action onResize = (event: any) => { diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 6251d7114..1709b9c99 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -353,7 +353,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr </div > : (null); const background = this._background; //to account for observables in Measure const collapsed = this.collapsed; - let chromeStatus = this.props.parent.props.ContainingCollectionDoc && this.props.parent.props.ContainingCollectionDoc.chromeStatus; + let chromeStatus = this.props.parent.props.Document.chromeStatus; return ( <Measure offset onResize={this.handleResize}> {({ measureRef }) => { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 0dfd1d9cf..a0dbeeb93 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -119,8 +119,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0); } else { let sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0); - sum += 30; - return this.props.ContentScaling() * (sum + (this.Sections.size ? 50 : 0)); + return this.props.ContentScaling() * (sum + (this.Sections.size ? 85 : -22)); } } return -1; @@ -197,7 +196,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { if (!(d.nativeWidth && !d.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(d[WidthSym](), wid); return wid * aspect; } - return d.fitWidth ? Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym](); + return d.fitWidth ? !d.nativeHeight ? this.props.PanelHeight() - 2 * this.yMargin : Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym](); } columnDividerDown = (e: React.PointerEvent) => { @@ -399,13 +398,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))} {!this.showAddAGroup ? (null) : <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton" - style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> + style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> <EditableView {...editableViewProps} /> </div>} - {this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled' ? <Switch + {this.props.Document.chromeStatus !== 'disabled' ? <Switch onChange={this.onToggle} onClick={this.onToggle} - defaultChecked={this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode'} + defaultChecked={this.props.Document.chromeStatus !== 'view-mode'} checkedChildren="edit" unCheckedChildren="view" /> : null} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 815b28586..7e54b0f29 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -335,11 +335,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC </div> </div> : (null); for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `; - let chromeStatus = this.props.parent.props.ContainingCollectionDoc && this.props.parent.props.ContainingCollectionDoc.chromeStatus; + let chromeStatus = this.props.parent.props.Document.chromeStatus; return ( <div className="collectionStackingViewFieldColumn" key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }} ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}> - {headingView} + {this.props.parent.Document.hideHeadings ? (null) : headingView} { this.collapsed ? (null) : <div> diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 06d048383..6e8e4fa12 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -33,6 +33,7 @@ export interface CollectionViewProps extends FieldViewProps { VisibleHeight?: () => number; chromeCollapsed: boolean; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; + showHiddenControls?: boolean; // hack for showing the undo/redo/ink controls in a linear view -- needs to be redone } export interface SubCollectionViewProps extends CollectionViewProps { @@ -275,7 +276,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { let full = { ...options, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300, width: 300, title: dropFileName }; let pathname = Utils.prepend(file.path); Docs.Get.DocumentFromType(type, pathname, full).then(doc => { - doc && (doc.fileUpload = path.basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, "")); + doc && (Doc.GetProto(doc).fileUpload = path.basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, "")); doc && this.props.addDocument(doc); }); })); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 882a0f144..abaa9662c 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -28,6 +28,7 @@ import { CollectionSchemaPreview } from './CollectionSchemaView'; import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import React = require("react"); +import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; export interface TreeViewProps { @@ -187,7 +188,7 @@ class TreeView extends React.Component<TreeViewProps> { onWorkspaceContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 - if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking) { + if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking && this.props.document !== CurrentUserUtils.UserDocument.workspaces) { ContextMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.document), icon: "tv" }); ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "inTab"), icon: "folder" }); ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "onRight"), icon: "caret-square-right" }); @@ -198,6 +199,7 @@ class TreeView extends React.Component<TreeViewProps> { } else { ContextMenu.Instance.addItem({ description: "Open as Workspace", event: () => MainView.Instance.openWorkspace(this.dataDoc), icon: "caret-square-right" }); ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" }); + ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" }); } ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" }); ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" }); @@ -217,7 +219,7 @@ class TreeView extends React.Component<TreeViewProps> { if (de.data instanceof DragManager.LinkDragData) { let sourceDoc = de.data.linkSourceDocument; let destDoc = this.props.document; - DocUtils.MakeLink({doc:sourceDoc}, {doc:destDoc}); + DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc }); e.stopPropagation(); } if (de.data instanceof DragManager.DocumentDragData) { @@ -258,7 +260,10 @@ class TreeView extends React.Component<TreeViewProps> { let aspect = NumCast(this.props.document.nativeHeight) / NumCast(this.props.document.nativeWidth); if (aspect) return this.docWidth() * aspect; if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x); - return NumCast(this.props.document.height) ? NumCast(this.props.document.height) : 50; + return this.props.document.fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection.height) : + Math.min(this.docWidth() * NumCast(this.props.document.scrollHeight, NumCast(this.props.document.nativeHeight)) / NumCast(this.props.document.nativeWidth, + NumCast(this.props.containingCollection.height)))) : + NumCast(this.props.document.height) ? NumCast(this.props.document.height) : 50; })()); } @@ -512,8 +517,6 @@ export class CollectionTreeView extends CollectionSubView(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _mainEle?: HTMLDivElement; - @observable static NotifsCol: Opt<Doc>; - @computed get resolvedDataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document; } protected createTreeDropTarget = (ele: HTMLDivElement) => { @@ -538,7 +541,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { } onContextMenu = (e: React.MouseEvent): void => { // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout - if (!e.isPropagationStopped() && this.props.Document.workspaceLibrary) { + if (!e.isPropagationStopped() && this.props.Document === CurrentUserUtils.UserDocument.workspaces) { ContextMenu.Instance.addItem({ description: "Create Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" }); ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.remove(this.props.Document), icon: "minus" }); e.stopPropagation(); @@ -552,31 +555,10 @@ export class CollectionTreeView extends CollectionSubView(Document) { } outerXf = () => Utils.GetScreenTransform(this._mainEle!); onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {}); - openNotifsCol = () => { - if (CollectionTreeView.NotifsCol) { - this.props.addDocTab(CollectionTreeView.NotifsCol, undefined, "onRight"); - } - } - @computed get renderNotifsButton() { - const length = CollectionTreeView.NotifsCol ? DocListCast(CollectionTreeView.NotifsCol.data).length : 0; - const notifsRef = React.createRef<HTMLDivElement>(); - const dragNotifs = action(() => CollectionTreeView.NotifsCol!); - return <div id="toolbar" key="toolbar"> - <div ref={notifsRef}> - <button className="toolbar-button round-button" title="Notifs" - onClick={this.openNotifsCol} onPointerDown={CollectionTreeView.NotifsCol ? SetupDrag(notifsRef, dragNotifs) : emptyFunction}> - <FontAwesomeIcon icon={faBell} size="sm" /> - </button> - <div className="main-notifs-badge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}> - {length} - </div> - </div> - </div >; - } @computed get renderClearButton() { return <div id="toolbar" key="toolbar"> - <button className="toolbar-button round-button" title="Notifs" + <button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.props.Document)[this.props.fieldKey] = undefined))}> <FontAwesomeIcon icon={faTrash} size="sm" /> </button> @@ -609,7 +591,6 @@ export class CollectionTreeView extends CollectionSubView(Document) { TreeView.loadId = doc[Id]; Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false); })} /> - {this.props.Document.workspaceLibrary ? this.renderNotifsButton : (null)} {this.props.Document.allowClear ? this.renderClearButton : (null)} <ul className="no-indent" style={{ width: "max-content" }} > { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 893763840..3d5b4e562 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -19,6 +19,7 @@ import { CollectionStackingView } from './CollectionStackingView'; import { CollectionTreeView } from "./CollectionTreeView"; import { CollectionViewBaseChrome } from './CollectionViewChromes'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; +import { CollectionLinearView } from '../CollectionLinearView'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); @@ -66,6 +67,7 @@ export class CollectionView extends React.Component<FieldViewProps> { case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); } case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); } case CollectionViewType.Pivot: { this.props.Document.freeformLayoutEngine = "pivot"; return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); } + case CollectionViewType.Linear: { return (<CollectionLinearView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); } case CollectionViewType.Freeform: default: this.props.Document.freeformLayoutEngine = undefined; diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 72f3514b6..3a66c05f4 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -399,6 +399,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option> <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View</option> <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="7">Pivot View</option> + <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="8">Linear View</option> </select> <div className="collectionViewBaseChrome-viewSpecs" style={{ display: collapsed ? "none" : "grid" }}> <input className="collectionViewBaseChrome-viewSpecsInput" |
