From 9ea2fdf4c127ba2715159209327e2a51f0482dee Mon Sep 17 00:00:00 2001 From: geireann Date: Wed, 25 Aug 2021 06:54:48 -0400 Subject: ui updates --- .../collectionSchema/CollectionSchemaHeaders.tsx | 8 +- .../CollectionSchemaMovableRow.tsx | 6 +- .../collectionSchema/CollectionSchemaView.scss | 120 ++++++++++++++------- .../collections/collectionSchema/SchemaTable.tsx | 4 +- 4 files changed, 92 insertions(+), 46 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx index aaa50ba67..b28c32e0e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx @@ -413,7 +413,7 @@ export class KeysDropdown extends React.Component { bool = fields ? fields[1] === "check" : false; } return
@@ -489,8 +489,10 @@ export class KeysDropdown extends React.Component { } render() { return ( -
- { this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} /> +
+
{ this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }}> + +
{/* { runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx index f48906ba5..0e19ef3d9 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx @@ -134,9 +134,9 @@ export class MovableRow extends React.Component {
-
this.props.removeDoc(this.props.rowInfo.original))}>
-
-
this.props.addDocTab(this.props.rowInfo.original, "add:right")}>
+
this.props.removeDoc(this.props.rowInfo.original))}>
+
+
this.props.addDocTab(this.props.rowInfo.original, "add:right")}>
{children}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 40cdcd14b..3074ce66e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -108,9 +108,7 @@ } .rt-th { padding: 0; - border: solid lightgray; - border-width: 0 1px; - border-bottom: 2px solid lightgray; + border-left: solid 1px $light-gray; } } .rt-th { @@ -213,6 +211,8 @@ } } + + .collectionSchemaView-header { height: 100%; color: gray; @@ -227,6 +227,15 @@ button.add-column { width: 28px; } +.collectionSchemaView-menuOptions-wrapper { + background: rgb(241, 239, 235); + display: flex; + cursor: default; + height: 100%; + align-content: center; + align-items: center; +} + .collectionSchema-header-menuOptions { color: black; width: 180px; @@ -272,6 +281,9 @@ button.add-column { width: 10px; } } + + + .keys-dropdown { position: relative; //width: 100%; @@ -287,26 +299,7 @@ button.add-column { font-weight: normal; } } - .keys-options-wrapper { - width: 100%; - max-height: 150px; - overflow-y: scroll; - position: absolute; - top: 28px; - box-shadow: 0 10px 16px rgba(0, 0, 0, 0.1); - background-color: white; - .key-option { - background-color: white; - border: 1px solid lightgray; - padding: 2px 3px; - &:not(:first-child) { - border-top: 0; - } - &:hover { - background-color: $light-gray; - } - } - } + } .columnMenu-colors { display: flex; @@ -325,11 +318,53 @@ button.add-column { } } +.schema-icon { + cursor: pointer; + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + align-content: center; + background-color: $medium-blue; + color: white; + margin-right: 5px; + font-size: 10px; + border-radius: 3px; + +} + +.keys-options-wrapper { + position: absolute; + text-align: left; + height: fit-content; + top: 100%; + z-index: 21; + background-color: #ffffff; + box-shadow: 0px 3px 4px rgba(0,0,0,30%); + padding: 1px; + .key-option { + cursor: pointer; + color: #000000; + width: 100%; + height: 25px; + font-weight: 400; + display: flex; + justify-content: left; + align-items: center; + padding-left: 5px; + &:hover { + background-color: $light-gray; + } + } +} + .collectionSchema-row { height: 100%; background-color: white; &.row-focused .rt-td { - background-color: #bfffc0; //$light-gray; + background-color: $light-blue; //$light-gray; + overflow: visible; } &.row-wrapped { .rt-td { @@ -338,39 +373,40 @@ button.add-column { } .row-dragger { display: flex; - justify-content: space-around; - //flex: 50 0 auto; - width: 0; - max-width: 50px; - //height: 100%; + justify-content: space-evenly; + width: 58px; + position: absolute; + /* max-width: 50px; */ min-height: 30px; align-items: center; color: lightgray; background-color: white; transition: color 0.1s ease; .row-option { - // padding: 5px; + color: black; cursor: pointer; - position: absolute; + position: relative; transition: color 0.1s ease; display: flex; flex-direction: column; justify-content: center; z-index: 2; + border-radius: 3px; + padding: 3px; &:hover { - color: gray; + background-color: $light-gray; } } } .collectionSchema-row-wrapper { &.row-above { - border-top: 1px solid red; + border-top: 1px solid $medium-blue; } &.row-below { - border-bottom: 1px solid red; + border-bottom: 1px solid $medium-blue; } &.row-inside { - border: 1px solid red; + border: 2px dashed $medium-blue; } .row-dragging { background-color: blue; @@ -383,24 +419,32 @@ button.add-column { height: unset; } +.collectionSchemaView-cellContents { + width: 100%; +} + .collectionSchemaView-cellWrapper { + display: flex; height: 100%; - padding: 4px; text-align: left; padding-left: 19px; position: relative; + align-items: center; + align-content: center; &:focus { outline: none; } &.editing { padding: 0; + box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3); + transform: scale(1.1); + z-index: 40; input { outline: 0; border: none; - background-color: rgb(255, 217, 217); + background-color: $white; width: 100%; height: 100%; - padding: 2px 3px; min-height: 26px; } } diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index abe549072..1cf466cba 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -194,10 +194,10 @@ export class SchemaTable extends React.Component { const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up"; const header =
{keysDropdown} -
this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}> +
this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "pointer" }}>
- {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined :
+ new
} + {/* {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined :
+ new
} */}
; return { -- cgit v1.2.3-70-g09d2 From c42f909188aff5398de31e443500eb64b8690ac4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 26 Aug 2021 08:57:20 -0400 Subject: fixed warnings/errors --- src/client/util/SelectionManager.ts | 2 +- src/client/views/MainView.tsx | 1 + src/client/views/TemplateMenu.tsx | 1 + .../views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 1 + .../CollectionFreeFormLinkView.tsx | 8 ++-- .../collections/collectionSchema/SchemaTable.tsx | 4 +- src/client/views/linking/LinkEditor.tsx | 6 +-- .../views/linking/LinkRelationshipSearch.tsx | 12 ++--- src/client/views/nodes/FilterBox.tsx | 1 + src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/LinkBox.tsx | 1 + src/client/views/pdf/AnchorMenu.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 2 +- src/client/views/search/SearchBox.tsx | 56 ++++++++++------------ 15 files changed, 50 insertions(+), 51 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index dbcc49f3d..0cfaebbf2 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,10 +1,10 @@ import { action, observable, ObservableMap } from "mobx"; import { computedFn } from "mobx-utils"; import { Doc, Opt } from "../../fields/Doc"; +import { DocumentType } from "../documents/DocumentTypes"; import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView"; import { CollectionViewType } from "../views/collections/CollectionView"; import { DocumentView } from "../views/nodes/DocumentView"; -import { DocumentType } from "../documents/DocumentTypes"; export namespace SelectionManager { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 6a388c5b4..8b5e18fb2 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -473,6 +473,7 @@ export class MainView extends React.Component { bringToFront={emptyFunction} select={emptyFunction} isContentActive={returnFalse} + isAnyChildContentActive={returnFalse} isSelected={returnFalse} docViewPath={returnEmptyDoclist} moveDocument={this.moveButtonDoc} diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 5491a81e6..ff3f92364 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -141,6 +141,7 @@ export class TemplateMenu extends React.Component { onCheckedClick={this.scriptField} onChildClick={this.scriptField} dropAction={undefined} + isAnyChildContentActive={returnFalse} isContentActive={returnTrue} bringToFront={emptyFunction} focus={emptyFunction} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 1efea96be..6bdeaf722 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -18,6 +18,7 @@ import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss'; +import { SchemaTable } from "../collections/collectionSchema/SchemaTable"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import '../DocumentDecorations.scss'; @@ -25,7 +26,6 @@ import { DocumentView } from "../nodes/DocumentView"; import { DefaultStyleProvider } from "../StyleProvider"; import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; -import { SchemaTable } from "../collections/collectionSchema/SchemaTable"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 export enum ColumnType { diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 3ee9dbf59..566083e7e 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -698,6 +698,7 @@ export class TreeView extends React.Component { isDocumentActive={asText ? this.props.isContentActive : returnFalse} styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} hideTitle={asText} + treeViewDoc={this.props.treeView?.props.Document} fitContentsToDoc={returnTrue} hideDecorationTitle={this.props.treeView.outlineMode} hideResizeHandles={this.props.treeView.outlineMode} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 59891b7a1..16258404d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -2,15 +2,15 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx" import { observer } from "mobx-react"; import { Doc } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; +import { List } from "../../../../fields/List"; import { NumCast, StrCast } from "../../../../fields/Types"; import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; import { DocumentType } from "../../../documents/DocumentTypes"; +import { LinkManager } from "../../../util/LinkManager"; import { SnappingManager } from "../../../util/SnappingManager"; import { DocumentView } from "../../nodes/DocumentView"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); -import { LinkManager } from "../../../util/LinkManager"; -import { List } from "../../../fields/List"; export interface CollectionFreeFormLinkViewProps { @@ -177,11 +177,11 @@ export class CollectionFreeFormLinkView extends React.Component; const linkColorList = Doc.UserDoc().linkColorList as List; //access stroke color using index of the relationship in the color list (default black) - const strokeColor = linkRelationshipList.indexOf(linkRelationship) == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; + const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)]; return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index abe549072..631f623c6 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -197,7 +197,7 @@ export class SchemaTable extends React.Component {
this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
- {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined :
+ new
} + {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined :
+ new
}
; return { @@ -562,7 +562,7 @@ export class SchemaTable extends React.Component { onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} > {this.reactTable} - {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined :
+ new
} + {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined :
+ new
} {!this._showDoc ? (null) :
{ if (linkRelationshipList && !linkRelationshipList.includes(value)) { linkRelationshipList.push(value); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; - linkColorList.push(randColor) + linkColorList.push(randColor); } this.relationshipButtonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.relationshipButtonColor = ""), 750); @@ -62,7 +62,7 @@ export class LinkEditor extends React.Component { @action getRelationshipResults = () => { const query = this.relationship; //current content in input box - const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList) + const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); if (linkRelationshipList) { return linkRelationshipList.filter(rel => rel.includes(query)); } @@ -73,7 +73,7 @@ export class LinkEditor extends React.Component { */ @action toggleRelationshipResults = () => { - this.relationshipSearchVisibility = this.relationshipSearchVisibility == "none" ? "block" : "none"; + this.relationshipSearchVisibility = this.relationshipSearchVisibility === "none" ? "block" : "none"; } @undoBatch diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx index 8f83f0e6e..53da880e4 100644 --- a/src/client/views/linking/LinkRelationshipSearch.tsx +++ b/src/client/views/linking/LinkRelationshipSearch.tsx @@ -15,7 +15,7 @@ export class LinkRelationshipSearch extends React.Component { const relationship = (e.target as HTMLParagraphElement).textContent; if (relationship) { - this.props.handleRelationshipSearchChange(relationship) + this.props.handleRelationshipSearchChange(relationship); } } @@ -31,8 +31,8 @@ export class LinkRelationshipSearch extends React.Component { - if (this.props.results && this.props.results.length > 2 && this.props.display == "block") { - return
+ if (this.props.results && this.props.results.length > 2 && this.props.display === "block") { + return
; } } @@ -47,9 +47,9 @@ export class LinkRelationshipSearch extends React.Component { - return (

+ return

{result} -

) +

; }) :

No matching relationships

} @@ -58,6 +58,6 @@ export class LinkRelationshipSearch extends React.Component - ) + ); } } \ No newline at end of file diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 1e13d1b5a..7ad03e055 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -417,6 +417,7 @@ export class FilterBox extends ViewBoxBaseComponent { if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) { setupMoveUpEvents(this, e, action(e => { - MarqueeAnnotator.clearAnnotations(this._savedAnnotations) + MarqueeAnnotator.clearAnnotations(this._savedAnnotations); this._marqueeing = [e.clientX, e.clientY]; return true; }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false); diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index c65ba9c69..55ea45bb8 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -30,6 +30,7 @@ export class LinkBox extends ViewBoxBaseComponent( dontRegisterView={true} renderDepth={this.props.renderDepth + 1} CollectionView={undefined} + isAnyChildContentActive={returnFalse} isContentActive={this.isContentActiveFunc} addDocument={returnFalse} removeDocument={returnFalse} diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 42bec38da..95e318738 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -69,7 +69,7 @@ export class AnchorMenu extends AntimodeMenu { this._disposer = reaction(() => SelectionManager.Views(), selected => { this._showLinkPopup = false; - AnchorMenu.Instance.fadeOut(true) + AnchorMenu.Instance.fadeOut(true); }); } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index bc35d2126..e77fdde3d 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -525,7 +525,7 @@ export class PDFViewer extends React.Component { CollectionView={undefined} ScreenToLocalTransform={this.overlayTransform} renderDepth={this.props.renderDepth + 1} - childPointerEvents={true} /> + childPointerEvents={true} />; return
{ - console.log("[makeLink-1] got here!") console.log(linkTo.title); - if (this.props.linkFrom){ + if (this.props.linkFrom) { const linkFrom = this.props.linkFrom(); - if (linkFrom){ + if (linkFrom) { console.log(linkFrom.title); - DocUtils.MakeLink({doc: linkFrom}, {doc:linkTo}); + DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo }); } } }); @@ -177,10 +176,10 @@ export class SearchBox extends ViewBoxBaseComponent { const dtype = StrCast(doc.type, "string") as DocumentType; if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth > 0) { const hlights = new Set(); SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key)); - blockedKeys.forEach(key => { - hlights.delete(key); - }) + blockedKeys.forEach(key => hlights.delete(key)); Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys())]); } - docIDs.push(doc[Id]) + docIDs.push(doc[Id]); }); } } @@ -245,7 +241,7 @@ export class SearchBox extends ViewBoxBaseComponent { this.resetSearch(); - let query = StrCast(this._searchString); + const query = StrCast(this._searchString); Doc.SetSearchQuery(query); this._results = []; @@ -282,11 +278,9 @@ export class SearchBox extends ViewBoxBaseComponent { - return - }) + return selectValues.map(value => ); } /** @@ -295,17 +289,17 @@ export class SearchBox extends ViewBoxBaseComponent { var className = "searchBox-results-scroll-view-result"; - if (this._selectedResult == result[0]) { - className += " searchBox-results-scroll-view-result-selected" + if (this._selectedResult === result[0]) { + className += " searchBox-results-scroll-view-result-selected"; } - if (this._docTypeString == "all" || this._docTypeString == result[0].type) { + if (this._docTypeString === "all" || this._docTypeString === result[0].type) { validResults++; return (
this.makeLink(result[0]) : () => this.onResultClick(result[0])} className={className}> @@ -319,25 +313,25 @@ export class SearchBox extends ViewBoxBaseComponent
- ) + ); } return null; - }) + }); results.filter(result => result); return (
-
- {isLinkSearch ? (null) : {this.selectOptions} } - +
- {`${validResults}` + " result" + (validResults == 1 ? "" : "s")} + {`${validResults}` + " result" + (validResults === 1 ? "" : "s")}
{results} -- cgit v1.2.3-70-g09d2 From 12d8267533d9b646247914e965b3cf7c32019e4b Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 2 Sep 2021 04:45:01 -0400 Subject: Many updates - Fixed image uploads so it clones rather than makes an alias - Updated context menu - Removed tools panel from novice mode in favour of ":" menu - Added explainers to menus in novice mode - Re-added the trails button - Changed UI for text, PDF & websites so that it is more consistent --- src/client/documents/Documents.ts | 52 +++++---- src/client/util/CurrentUserUtils.ts | 93 ++++++++-------- src/client/views/ContextMenu.scss | 2 +- src/client/views/ContextMenuItem.tsx | 4 +- src/client/views/MainViewModal.scss | 3 +- src/client/views/PropertiesButtons.scss | 41 +++++-- src/client/views/PropertiesButtons.tsx | 53 +++++---- src/client/views/SidebarAnnos.tsx | 3 +- src/client/views/StyleProvider.tsx | 4 +- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionStackingView.scss | 24 +++++ .../views/collections/CollectionStackingView.tsx | 119 +++++++++++++++------ .../views/collections/CollectionTreeView.tsx | 95 ++++++++++++---- src/client/views/collections/TabDocView.tsx | 3 +- src/client/views/collections/TreeView.tsx | 5 +- .../collectionLinearView/CollectionLinearView.scss | 6 +- .../collectionSchema/CollectionSchemaHeaders.tsx | 2 +- .../collectionSchema/CollectionSchemaView.tsx | 2 +- src/client/views/nodes/AudioBox.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/PDFBox.scss | 16 ++- src/client/views/nodes/PDFBox.tsx | 13 ++- src/client/views/nodes/WebBox.scss | 9 +- src/client/views/nodes/WebBox.tsx | 13 ++- src/client/views/nodes/button/FontIconBox.scss | 29 ++++- src/client/views/nodes/button/FontIconBox.tsx | 15 +-- .../nodes/formattedText/FormattedTextBox.scss | 21 +++- .../views/nodes/formattedText/FormattedTextBox.tsx | 16 ++- src/client/views/search/SearchBox.tsx | 2 +- src/client/views/topbar/TopBar.scss | 4 +- src/client/views/topbar/TopBar.tsx | 3 +- 31 files changed, 460 insertions(+), 202 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index c4a713dc6..bd247bd01 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -59,6 +59,7 @@ import { WebBox } from "../views/nodes/WebBox"; import { SearchBox } from "../views/search/SearchBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); @@ -272,7 +273,12 @@ export class DocumentOptions { treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items. - treeViewShowClearButton?: boolean; // whether a clear button should be displayed + + // Action Button + buttonMenu?: boolean; // whether a action button should be displayed + buttonMenuDoc?: Doc; + explainer?:string; + treeViewOpenIsTransient?: boolean; // ignores the treeViewOpen Doc flag, allowing a treeViewItem's expand/collapse state to be independent of other views of the same document in the same or any other tree view _treeViewOpen?: boolean; // whether this document is expanded in a tree view (note: need _ and regular versions since this can be specified for both proto and layout docs) treeViewOpen?: boolean; // whether this document is expanded in a tree view @@ -1165,7 +1171,7 @@ export namespace DocUtils { export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false): void { !simpleMenu && ContextMenu.Instance.addItem({ - description: "Add Note ...", + description: "Quick Notes", subitems: DocListCast((Doc.UserDoc()["template-notes"] as Doc).data).map((note, i) => ({ description: ":" + StrCast(note.title), event: undoBatch((args: { x: number, y: number }) => { @@ -1178,12 +1184,12 @@ export namespace DocUtils { textDoc[textDoc.layoutKey] = note; docTextAdder(textDoc); }), - icon: "eye" + icon: StrCast(note.icon) as IconProp })) as ContextMenuProps[], - icon: "eye" + icon: "sticky-note" }); - ContextMenu.Instance.addItem({ - description: ":=math", event: () => { + const math:ContextMenuProps = ({ + description: ":Math", event: () => { const created = Docs.Create.EquationDocument(); if (created) { created.author = Doc.CurrentUserEmail; @@ -1194,25 +1200,27 @@ export namespace DocUtils { EquationBox.SelectOnLoad = created[Id]; docAdder?.(created); } - }, icon: "compress-arrows-alt" + }, icon: "calculator" }); + const documentList:ContextMenuProps[] = DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({ + description: ":" + StrCast(dragDoc.title), + event: undoBatch((args: { x: number, y: number }) => { + const newDoc = Doc.copyDragFactory(dragDoc); + if (newDoc) { + newDoc.author = Doc.CurrentUserEmail; + newDoc.x = x; + newDoc.y = y; + if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id]; + docAdder?.(newDoc); + } + }), + icon: Doc.toIcon(dragDoc), + })) as ContextMenuProps[]; + documentList.push(math) ContextMenu.Instance.addItem({ description: "Create document", - subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({ - description: ":" + StrCast(dragDoc.title), - event: undoBatch((args: { x: number, y: number }) => { - const newDoc = Doc.copyDragFactory(dragDoc); - if (newDoc) { - newDoc.author = Doc.CurrentUserEmail; - newDoc.x = x; - newDoc.y = y; - if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id]; - docAdder?.(newDoc); - } - }), - icon: Doc.toIcon(dragDoc), - })) as ContextMenuProps[], - icon: "eye" + subitems: documentList, + icon: "file" }); }// applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView) export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f12ac02f3..f6ec74482 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -84,7 +84,7 @@ export class CurrentUserUtils { title: "NEW MOBILE BUTTON", onClick: undefined, }, - [this.ficon({ + [this.createToolButton({ ignoreClick: true, icon: "mobile", btnType: ButtonType.ToolButton, @@ -92,7 +92,7 @@ export class CurrentUserUtils { }), this.mobileTextContainer({}, [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]); - doc["template-mobile-button"] = CurrentUserUtils.ficon({ + doc["template-mobile-button"] = CurrentUserUtils.createToolButton({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile", btnType: ButtonType.ToolButton, }); @@ -107,7 +107,7 @@ export class CurrentUserUtils { { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true } ); slideTemplate.isTemplateDoc = makeTemplate(slideTemplate); - doc["template-button-slides"] = CurrentUserUtils.ficon({ + doc["template-button-slides"] = CurrentUserUtils.createToolButton({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card", btnType: ButtonType.ToolButton @@ -154,7 +154,7 @@ export class CurrentUserUtils { }; linkTemplate.header = new RichTextField(JSON.stringify(rtf2), ""); - doc["template-button-link"] = CurrentUserUtils.ficon({ + doc["template-button-link"] = CurrentUserUtils.createToolButton({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true, btnType: ButtonType.ToolButton @@ -186,7 +186,7 @@ export class CurrentUserUtils { const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, system: true }); box.isTemplateDoc = makeTemplate(box, true, "switch"); - doc["template-button-switch"] = CurrentUserUtils.ficon({ + doc["template-button-switch"] = CurrentUserUtils.createToolButton({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true, btnType: ButtonType.ToolButton @@ -236,7 +236,7 @@ export class CurrentUserUtils { short.title = "A Short Description"; long.title = "Long Description"; - doc["template-button-detail"] = CurrentUserUtils.ficon({ + doc["template-button-detail"] = CurrentUserUtils.createToolButton({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), dragFactory: new PrefetchProxy(detailView) as any as Doc, title: "detailView", @@ -275,7 +275,7 @@ export class CurrentUserUtils { static setupNoteTemplates(doc: Doc) { if (doc["template-note-Note"] === undefined) { const noteView = Docs.Create.TextDocument("", { - title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true, + title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true, icon: "sticky-note", _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Note"); @@ -283,7 +283,7 @@ export class CurrentUserUtils { } if (doc["template-note-Idea"] === undefined) { const noteView = Docs.Create.TextDocument("", { - title: "text", backgroundColor: "pink", system: true, + title: "text", backgroundColor: "pink", system: true, icon: "lightbulb", _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea"); @@ -291,7 +291,7 @@ export class CurrentUserUtils { } if (doc["template-note-Topic"] === undefined) { const noteView = Docs.Create.TextDocument("", { - title: "text", backgroundColor: "lightblue", system: true, + title: "text", backgroundColor: "lightblue", system: true, icon: "book-open", _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic"); @@ -467,7 +467,7 @@ export class CurrentUserUtils { ((doc.emptyHeader as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.emptyComparison === undefined) { - doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300, system: true, cloneFieldFilter: new List(["system"]) }); + doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "comparison box", _width: 300, _height: 300, system: true, cloneFieldFilter: new List(["system"]) }); } if (doc.emptyScript === undefined) { doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250, title: "script", system: true, cloneFieldFilter: new List(["system"]) }); @@ -512,7 +512,7 @@ export class CurrentUserUtils { { toolTip: "Tap to create a progressive slide", title: "Slide", icon: "file", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySlide as Doc }, { toolTip: "Tap to create a cat image in a new pane, drag for a cat image", title: "Image", icon: "cat", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyImage as Doc }, { toolTip: "Tap to create a comparison box in a new pane, drag for a comparison box", title: "Compare", icon: "columns", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyComparison as Doc, noviceMode: true }, - { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc, noviceMode: true }, + { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc }, { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc }, { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true }, { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc }, @@ -561,7 +561,7 @@ export class CurrentUserUtils { if (dragCreatorSet === undefined) { doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, { title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, - _forceActive: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, + _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); } else { @@ -574,29 +574,31 @@ export class CurrentUserUtils { return [ { title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' }, { title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' }, - { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' }, - { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' }, - { title: "Import", target: Cast(doc.myImportDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, + { title: "File Manager", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' }, + { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" }, + { title: "Uploads", target: Cast(doc.myUploadDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' }, { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, { title: "Trails", target: Cast(doc.myTrails, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' }, - { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' }, + { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" }, ]; } static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) { if (doc.menuStack === undefined) { await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId); // sets up the right sidebar collection for mobile upload documents and sharing - const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments }) => + const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments, hidden }) => Docs.Create.FontIconDocument({ icon, btnType: ButtonType.MenuButton, _stayInCollection: true, _hideContextMenu: true, + _chromeHidden: true, system: true, dontUndo: true, title, target, + hidden: hidden ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined, _dropAction: "alias", _removeDropProperties: new List(["dropAction", "_stayInCollection"]), _width: 60, @@ -611,8 +613,6 @@ export class CurrentUserUtils { this.searchBtn = menuBtn; } }); - // hack -- last button is assumed to be the userDoc - menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()"); menuBtns.forEach(menuBtn => { if (menuBtn.title === "Search") { @@ -684,7 +684,7 @@ export class CurrentUserUtils { onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, backgroundColor: data.backgroundColor, system: true }, - [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]) + [this.createToolButton({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]) ); } @@ -820,6 +820,7 @@ export class CurrentUserUtils { const removeDashboard = ScriptField.MakeScript('removeDashboard(self)'); (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, shareDashboard!, removeDashboard!]); (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]); + (doc.myDashboards as any as Doc).childContextMenuIcons = new List(["plus", "share", "times"]); // (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]); // (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]); } @@ -860,18 +861,21 @@ export class CurrentUserUtils { } static setupRecentlyClosedDocs(doc: Doc) { - // setup Recently Closed library item if (doc.myRecentlyClosedDocs === undefined) { - const clearDocs = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript(`getProto(self).data = new List([])`), toolTip: "Empty", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.TextButton, _width: 200, buttonText: "Empty Recently Closed", icon: "trash", system: true }); - doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([clearDocs], { - title: "My Recently Closed", _showTitle: "title", treeViewShowClearButton: true, childHideLinkButton: true, + const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); + const clearDocsButton:Doc = Docs.Create.FontIconDocument({ onClick: clearAll, _forceActive: true, toolTip: "Empty recently closed", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "Empty", icon: "trash", system: true }); + doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], { + title: "My Recently Closed", _showTitle: "title", buttonMenu: true, buttonMenuDoc: clearDocsButton, childHideLinkButton: true, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true, + explainer: "Documents that you close will appear here so you can easily access them again. You can choose to clear this menu in which case you might lose these documents." + })); - const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List([clearAll!]); - (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List(["Clear All"]); + (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List(["Empty recently closed"]); + (doc.myRecentlyClosedDocs as any as Doc).contextMenuIcons = new List(["trash"]); + } } @@ -916,7 +920,7 @@ export class CurrentUserUtils { static async setupSidebarButtons(doc: Doc) { CurrentUserUtils.setupSidebarContainer(doc); await CurrentUserUtils.setupToolsBtnPanel(doc); - CurrentUserUtils.setupImportSidebar(doc); + CurrentUserUtils.setupUploadSidebar(doc); CurrentUserUtils.setupDashboards(doc); CurrentUserUtils.setupPresentations(doc); CurrentUserUtils.setupFilesystem(doc); @@ -930,17 +934,17 @@ export class CurrentUserUtils { _lockedPosition: true, system: true, flexDirection: "row" })) as any as Doc - static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({ - ...opts, _dropAction: "alias", _removeDropProperties: new List(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true + static createToolButton = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({ + ...opts, btnType: ButtonType.ToolButton, _forceActive: true, _dropAction: "alias", _removeDropProperties: new List(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true })) as any as Doc /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window static setupDockedButtons(doc: Doc) { if (doc["dockedBtn-undo"] === undefined) { - doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true }); + doc["dockedBtn-undo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("undo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true }); } if (doc["dockedBtn-redo"] === undefined) { - doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true }); + doc["dockedBtn-redo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("redo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true }); } if (doc.dockedBtns === undefined) { doc.dockedBtns = CurrentUserUtils.linearButtonList({ title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]); @@ -1039,7 +1043,7 @@ export class CurrentUserUtils { // { title: "Alias", btnType: ButtonType.ClickButton, icon: "copy", hidden: 'selectedDocumentType()' }, // Only when a document is selected { title: "Text", type: "textTools", subMenu: true, expanded: 'selectedDocumentType("rtf")' }, // Always available { title: "Ink", type: "inkTools", subMenu: true, expanded: 'selectedDocumentType("ink")' }, // Always available - // { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected + { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected { title: "Schema", type: "schemaTools", subMenu: true, hidden: 'selectedDocumentType(undefined, "schema")' } // Only when Schema is selected ]; } @@ -1172,13 +1176,15 @@ export class CurrentUserUtils { } doc.myLinkDatabase = new PrefetchProxy(linkDocs); } + // TODO:glr NOTE: treeViewHideTitle & _showTitle may be confusing, treeViewHideTitle is for the editable title (just for tree view), _showTitle is to show the Document title for any document if (doc.mySharedDocs === undefined) { let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer"); if (!sharedDocs) { sharedDocs = Docs.Create.TreeDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment, + _showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment, _chromeHidden: true, boxShadow: "0 0", + explainer: "All of the documents that you receive will appear here. They must be shared by other users. If you receive a Dashboard you can add it to your Dashboards by right clicking and clicking 'Add to Dashboards'" }, sharingDocumentId + "outer", sharingDocumentId); (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment; } @@ -1189,18 +1195,21 @@ export class CurrentUserUtils { sharedDocs.childContextMenuFilters = new List([dashboardFilter!,]); sharedDocs.childContextMenuScripts = new List([addToDashboards!,]); sharedDocs.childContextMenuLabels = new List(["Add to Dashboards",]); + sharedDocs.childContextMenuIcons = new List(["user-plus",]); + } doc.mySharedDocs = new PrefetchProxy(sharedDocs); } } // Import sidebar is where shared documents are contained - static setupImportSidebar(doc: Doc) { - if (doc.myImportDocs === undefined) { - const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Upload from computer", _width: 100, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.TextButton, buttonText: "Upload from computer", icon: "upload", system: true }); - doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([newUpload], { - title: "My Uploads", _forceActive: true, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, - childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true, + static setupUploadSidebar(doc: Doc) { + if (doc.myUploadDocs === undefined) { + const newUploadButton:Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Upload from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.ClickButton, buttonText: "Upload", icon: "upload", system: true }); + doc.myUploadDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { + title: "My Uploads", _forceActive: true, buttonMenu: true, buttonMenuDoc: newUploadButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, + childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true, + explainer: "All of the documents that are imported into Dash will go here and stay here unless they are explicitly removed." })); } } @@ -1303,7 +1312,7 @@ export class CurrentUserUtils { doc.filterDocCount = 0; this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon this.setupDocTemplates(doc); // sets up the template menu of templates - this.setupImportSidebar(doc); // sets up the import sidebar + this.setupUploadSidebar(doc); // sets up the import sidebar this.setupSearchSidebar(doc); // sets up the search sidebar this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile this.setupOverlays(doc); // documents in overlay layer @@ -1430,7 +1439,7 @@ export class CurrentUserUtils { } } } else if (input.files && input.files.length !== 0) { - const importDocs = Cast(Doc.UserDoc().myImportDocs, Doc, null); + const importDocs = Cast(Doc.UserDoc().myUploadDocs, Doc, null); const disposer = OverlayView.ShowSpinner(); DocListCastAsync(importDocs.data).then(async list => { const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index 41a6dc569..47ae0424b 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -130,7 +130,7 @@ } .contextMenu-inlineMenu { - border-top: solid 1px; + // border-top: solid 1px; //TODO:glr clean } .contextMenu-item:hover { diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 168fcb888..c3921d846 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -116,12 +116,12 @@ export class ContextMenuItem extends React.Component {this.props.icon ? ( - + ) : null}
+ style={{ alignItems: "center", alignSelf: "center" }} > {this.props.description}
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss index 03cb5cc84..0648e31c5 100644 --- a/src/client/views/MainViewModal.scss +++ b/src/client/views/MainViewModal.scss @@ -6,6 +6,7 @@ height: 100%; .dialogue-box { + padding: 10px; position: absolute; z-index: 1000; text-align: center; @@ -13,7 +14,7 @@ align-self: center; align-content: center; background: white; - border-radius: 10px; + // border-radius: 10px; box-shadow: #00000044 5px 5px 10px; transform: translate(-50%, -50%); top: 50%; diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss index 484522bc7..77686a710 100644 --- a/src/client/views/PropertiesButtons.scss +++ b/src/client/views/PropertiesButtons.scss @@ -67,10 +67,12 @@ $linkGap : 3px; } .onClickFlyout-editScript { + cursor: pointer; text-align: center; - border: 0.5px solid grey; + margin-top: 5px; + border: 0.5px solid $medium-gray; background-color: rgb(230, 230, 230); - border-radius: 9px; + border-radius: 5px; padding: 4px; } @@ -84,9 +86,32 @@ $linkGap : 3px; margin-bottom: 8px; } +.propertiesButton-dropdownList { + width: 100%; + height: fit-content; + top: 100%; + z-index: 21; + + .list-item { + cursor: pointer; + color: $black; + width: 100%; + height: 25px; + font-weight: 400; + display: flex; + justify-content: left; + align-items: center; + padding-left: 5px; + } + + .list-item:hover { + background-color: lightgrey; + } +} + .propertiesButtons-title { - background: #121721; - color: white; + background: $dark-gray; + color: $white; font-size: 6px; width: 37px; padding: 3px; @@ -111,17 +136,11 @@ $linkGap : 3px; margin-left: 4px; &:hover { - background: $medium-gray; - transform: scale(1.05); + filter:brightness(0.85); cursor: pointer; } } -.propertiesButtons-linker:hover { - cursor: pointer; - transform: scale(1.05); -} - @-moz-keyframes spin { 100% { diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index dcab9bc1e..4fde1124f 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -15,6 +15,7 @@ import { InkingStroke } from './InkingStroke'; import { DocumentView } from './nodes/DocumentView'; import './PropertiesButtons.scss'; import React = require("react"); +import { Colors } from "./global/globalEnums"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -128,11 +129,11 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action - handleOptionChange = (e: any) => { - this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value); + handleOptionChange = (onClick: string) => { + this.selectedDoc && (this.selectedDoc.onClickBehavior = onClick); SelectionManager.Views().filter(dv => dv.docView).map(dv => dv.docView!).forEach(docView => { docView.noOnClick(); - switch (e.target.value) { + switch (onClick) { case "enterPortal": docView.makeIntoPortal(); break; case "toggleDetail": docView.setToggleDetail(); break; case "linkInPlace": docView.toggleFollowLink("inPlace", true, false); break; @@ -149,20 +150,34 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get onClickFlyout() { - const makeLabel = (value: string, label: string) =>
- -
; + const buttonList = [ + ["nothing", "Select Document"], + ["enterPortal", "Enter Portal"], + ["toggleDetail", "Toggle Detail"], + ["linkInPlace", "Follow Link"], + ["linkOnRight", "Open Link on Right"] + ] + const currentSelection = this.selectedDoc.onClickBehavior; + // Get items to place into the list + + const list = buttonList.map((value) => { + const click = () => { + this.handleOptionChange(value[0]); + }; + return
+ {value[1]} +
; + }); return
-
- {makeLabel("nothing", "Select Document")} - {makeLabel("enterPortal", "Enter Portal")} - {makeLabel("toggleDetail", "Toggle Detail")} - {makeLabel("linkInPlace", "Follow Link")} - {makeLabel("linkOnRight", "Open Link on Right")} -
+
+
+ {list} +
+
{Doc.UserDoc().noviceMode ? (null) :
Edit onClick Script
}
; } @@ -190,7 +205,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform; const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree; const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) =>
{ele}
; - + const isNovice = Doc.UserDoc().noviceMode; return !this.selectedDoc ? (null) :
{toggle(this.titleButton)} @@ -198,7 +213,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.lockButton)} {toggle(this.dictationButton)} {toggle(this.onClickButton)} - {toggle(this.fitWidthButton)} + {toggle(this.fitWidthButton, { display: isNovice ? "none" : "" })} {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })} {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })} {toggle(this.maskButton, { display: !isInk ? "none" : "" })} @@ -207,7 +222,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.snapButton, { display: isCollection ? "" : "none" })} {toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })} {toggle(this.panButton, { display: !isFreeForm ? "none" : "" })} - {toggle(this.perspectiveButton, { display: !isCollection ? "none" : "" })} + {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? "none" : "" })}
; } } \ No newline at end of file diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 0e3663f65..01b79ffd2 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -106,9 +106,10 @@ export class SidebarAnnos extends React.Component { {user}
; }; + // TODO: Calculation of the topbar is hardcoded and different for text nodes - it should all be the same and all be part of SidebarAnnos return !this.props.showSidebar ? (null) :
, props: Opt, props: Opt (props?.PanelHeight() || 0) ? 5 : 10) : 0; - case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || + case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; case StyleProp.BackgroundColor: { if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 6bdeaf722..6a22acae8 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { {this.renderColors(this._col)}
+ >Hide Column
; } diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 4b123c8b6..2f002736d 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -14,6 +14,30 @@ width: 100%; } +// TODO:glr Turn this into a seperate class +.documentButtonMenu { + position: relative; + height: fit-content; + border-bottom: $standard-border; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + align-content: center; + padding: 5px 0 5px 0; + + .documentExplanation { + width: 90%; + margin: 5px; + font-size: 11px; + background-color: $light-blue; + color: $medium-blue; + padding: 10px; + border-radius: 10px; + border: solid 2px $medium-blue; + } +} + .collectionStackingView, .collectionMasonryView { height: 100%; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 4fedda1bd..3c9084f64 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { CursorProperty } from "csstype"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { DataSym, Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; @@ -11,7 +11,7 @@ import { listSpec, makeInterface } from "../../../fields/Schema"; import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils"; +import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils, returnTrue, returnEmptyDoclist, returnEmptyFilter } from "../../../Utils"; import { DocUtils, Docs } from "../../documents/Documents"; import { DragManager, dropActionType } from "../../util/DragManager"; import { SnappingManager } from "../../util/SnappingManager"; @@ -23,12 +23,14 @@ import { EditableView } from "../EditableView"; import { LightboxView } from "../LightboxView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView"; -import { StyleProp } from "../StyleProvider"; +import { StyleProp, DefaultStyleProvider } from "../StyleProvider"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; +import { FontIconBox } from "../nodes/button/FontIconBox"; +import { CurrentUserUtils } from "../../util/CurrentUserUtils"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -514,6 +516,47 @@ export class CollectionStackingView extends CollectionSubView this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0)); } + @computed get buttonMenu() { + const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null); + // TODO:glr Allow support for multiple buttons + if (menuDoc){ + const width: number = NumCast(menuDoc._width, 30); + const height: number = NumCast(menuDoc._height, 30); + console.log(menuDoc.title, width, height); + return (
+ 35} + PanelHeight={() => 35} + renderDepth={this.props.renderDepth} + focus={emptyFunction} + styleProvider={this.props.styleProvider} + layerProvider={this.props.layerProvider} + docViewPath={returnEmptyDoclist} + whenChildContentsActiveChanged={emptyFunction} + bringToFront={emptyFunction} + docFilters={this.props.docFilters} + docRangeFilters={this.props.docRangeFilters} + searchFilterDocs={this.props.searchFilterDocs} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + /> +
+ ); + } + } + @computed get nativeWidth() { return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc); } @computed get nativeHeight() { return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc); } @@ -529,34 +572,50 @@ export class CollectionStackingView extends CollectionSubView -
this._scroll = e.currentTarget.scrollTop)} - onDrop={this.onExternalDrop.bind(this)} - onContextMenu={this.onContextMenu} - onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} > - {this.renderedSections} - {!this.showAddAGroup ? (null) : -
- -
} - {/* {this.chromeHidden || !this.props.isSelected() ? (null) : - } */} -
+ <> + {buttonMenu || noviceExplainer ?
+ {buttonMenu ? this.buttonMenu : null} + {Doc.UserDoc().isNovice && noviceExplainer ? +
+ {noviceExplainer} +
+ : null + } +
: null} +
+
this._scroll = e.currentTarget.scrollTop)} + onDrop={this.onExternalDrop.bind(this)} + onContextMenu={this.onContextMenu} + onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} > + {this.renderedSections} + {!this.showAddAGroup ? (null) : +
+ +
} + {/* {this.chromeHidden || !this.props.isSelected() ? (null) : + } */} +
+
+ + ); } } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 89d42439e..4d62a1af4 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -8,7 +8,7 @@ import { Document, listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; +import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, emptyFunction } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { DocumentManager } from '../../util/DocumentManager'; @@ -26,6 +26,7 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); +import { Transform } from '../../util/Transform'; const _global = (window /* browser */ || global /* node */) as any; export type collectionTreeViewProps = { @@ -221,8 +222,9 @@ export class CollectionTreeView extends CollectionSubView { const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []); - const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []); - return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label })); + const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []); + const icons = StrListCast(this.doc.childContextMenuIcons); + return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label })); } @computed get treeViewElements() { TraceMobx(); @@ -265,13 +267,48 @@ export class CollectionTreeView extends CollectionSubView - -
; + @computed get buttonMenu() { + const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null); + // To create a multibutton menu add a CollectionLinearView + if (menuDoc){ + + const width: number = NumCast(menuDoc._width, 30); + const height: number = NumCast(menuDoc._height, 30); + console.log(menuDoc.title, width, height); + return (
+ 35} + PanelHeight={() => 35} + renderDepth={this.props.renderDepth + 1} + focus={emptyFunction} + styleProvider={this.props.styleProvider} + layerProvider={this.props.layerProvider} + docViewPath={returnEmptyDoclist} + whenChildContentsActiveChanged={emptyFunction} + bringToFront={emptyFunction} + docFilters={this.props.docFilters} + docRangeFilters={this.props.docRangeFilters} + searchFilterDocs={this.props.searchFilterDocs} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + /> +
); + } } + + @computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); } @computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); } @@ -295,22 +332,34 @@ export class CollectionTreeView extends CollectionSubView this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined; + const buttonMenu = this.rootDoc.buttonMenu; + const noviceExplainer = this.rootDoc.explainer; return !(this.doc instanceof Doc) || !this.treeChildren ? (null) : -
-
e.stopPropagation()} - onDrop={this.onTreeDrop} - ref={this.createTreeDropTarget}> + <> {this.titleBar} - {this.renderClearButton} -
    - {this.treeViewElements} -
-
-
; +
+ {buttonMenu || noviceExplainer ?
+ {buttonMenu ? this.buttonMenu : null} + {Doc.UserDoc().noviceMode && noviceExplainer ? +
+ {noviceExplainer} +
+ : null + } +
: null} +
e.stopPropagation()} + onDrop={this.onTreeDrop} + ref={this.createTreeDropTarget}> +
    + {this.treeViewElements} +
+
+
+ ; } } \ No newline at end of file diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 889db1ef6..34cb6ec55 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -387,9 +387,10 @@ export class TabDocView extends React.Component { background={this.miniMapColor} document={this._document} tabView={this.tabView} /> - {this._document.hideMinimap ? "Open minimap" : "Close minimap"}
}> + {this._document.hideMinimap ? "Open minimap" : "Close minimap"}
}>
{ childContextMenuItems = () => { const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []); const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []); - return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], label })); + const icons = StrListCast(this.doc.childContextMenuIcons); + return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label })); } onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); @@ -835,7 +836,7 @@ export class TreeView extends React.Component { dontRegisterView: boolean | undefined, observerHeight: (ref: any) => void, unobserveHeight: (ref: any) => void, - contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string }[]) + contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string, icon: string }[]) ) { const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField); if (viewSpecScript) { diff --git a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss index f249eb1f5..8fe804466 100644 --- a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss +++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss @@ -98,7 +98,11 @@ transition: transform 0.2s; align-items: center; justify-content: center; - transition: 0.15s; + transition: 0.2s; + + &:hover{ + filter: brightness(0.85); + } } >input { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx index b28c32e0e..a25f962df 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx @@ -191,7 +191,7 @@ export class CollectionSchemaColumnMenu extends React.Component {this.renderSorting()} {this.renderColors()}
- +
} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index fed64b620..dfe99ffc8 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { {this.renderColors(this._col)}
+ >Hide Column
; } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index f5a7e61aa..8962d29f0 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -638,12 +638,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
) : ( - +
)}
) : ( diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7463e192f..98ae279db 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -635,7 +635,7 @@ export class DocumentViewInternal extends DocComponent { const portalLink = this.allLinks.find(d => d.anchor1 === this.props.Document); if (!portalLink) { - const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + ".portal" }); + const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + " [Portal]" }); DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to"); } this.Document.followLinkLocation = "inPlace"; @@ -679,7 +679,7 @@ export class DocumentViewInternal extends DocComponent this.props.addDocTab(templateDoc, "add:right"), icon: "eye" }); - appearanceItems.push({ + !Doc.UserDoc().noviceMode && appearanceItems.push({ description: "Add a Field", event: () => { const alias = Doc.MakeAlias(this.rootDoc); alias.layout = FormattedTextBox.LayoutString("newfield"); diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 72dec6e4c..f44355929 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -1,3 +1,5 @@ +@import "../global/globalCssVariables.scss"; + .pdfBox, .pdfBox-interactive { display: inline-block; @@ -18,12 +20,13 @@ top: 0; left: 0; + // glr: This should really be the same component as text and PDFs .pdfBox-sidebarBtn { - background: #121721; + background: $black; height: 25px; width: 25px; - right: 0; - color: white; + right: 5px; + color: $white; display: flex; position: absolute; align-items: center; @@ -31,6 +34,13 @@ border-radius: 3px; pointer-events: all; z-index: 1; // so it appears on top of the document's title, if shown + + box-shadow: $standard-box-shadow; + transition: 0.2s; + + &:hover{ + filter: brightness(0.85); + } } .pdfBox-pageNums { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 5e07229c1..3a399bfdb 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -24,6 +24,7 @@ import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); import { AnchorMenu } from '../pdf/AnchorMenu'; +import { Colors } from '../global/globalEnums'; type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @@ -208,11 +209,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._pageControls = !this._pageControls)} /> {this._pageControls ? pageBtns : (null)}
- + +
; } sidebarWidth = () => !this.SidebarShown ? 0 : diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index 19b69ff5a..417a17d96 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -10,7 +10,7 @@ background: #121721; height: 25px; width: 25px; - right: 0; + right: 5px; display: flex; position: absolute; align-items: center; @@ -18,6 +18,13 @@ border-radius: 3px; pointer-events: all; z-index: 1; // so it appears on top of the document's title, if shown + + box-shadow: $standard-box-shadow; + transition: 0.2s; + + &:hover{ + filter: brightness(0.85); + } } .pdfViewerDash-dragAnnotationBox { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 719e5a796..1f85219d6 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -33,6 +33,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; import "./WebBox.scss"; import React = require("react"); +import { Colors } from "../global/globalEnums"; const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); @@ -590,11 +591,15 @@ export class WebBox extends ViewBoxAnnotatableComponent - + + ); } } diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss index 48fb2c8dc..a2da35fe1 100644 --- a/src/client/views/nodes/button/FontIconBox.scss +++ b/src/client/views/nodes/button/FontIconBox.scss @@ -7,6 +7,7 @@ align-items: center; font-size: 80%; border-radius: $standard-border-radius; + transition: 0.15s; .menuButton-wrap { grid-column: 1; @@ -29,6 +30,9 @@ font-family: 'ROBOTO'; text-transform: uppercase; font-weight: bold; + transition: 0.15s; + + } .fontIconBox-icon { @@ -50,7 +54,18 @@ } &.textBtn { + display: grid; + /* grid-row: auto; */ + grid-auto-flow: column; + cursor: pointer; width: 100%; + justify-content: center; + align-items: center; + justify-items: center; + + &:hover { + filter:brightness(0.85) !important; + } } &.tglBtn { @@ -127,13 +142,13 @@ } &:hover { - background-color: rgba(0, 0, 0, 0.3) !important; + background-color: rgba(0, 0, 0, 0.3); } } &.toolBtn { cursor: pointer; - width: 40px; + width: 100%; border-radius: 100%; svg { @@ -143,7 +158,7 @@ } &.menuBtn { - cursor: pointer; + cursor: pointer !important; border-radius: 0px; flex-direction: column; @@ -151,6 +166,10 @@ width: 45% !important; height: 45%; } + + &:hover{ + filter: brightness(0.85); + } } @@ -163,8 +182,8 @@ .colorButton-color { margin-top: 3px; - width: 90%; - height: 6px; + width: 80%; + height: 3px; } .menuButton-dropdownBox { diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index bccf733f0..1b27d562a 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -253,11 +253,12 @@ export class FontIconBox extends DocComponent(Fon } else if (selected) { dropdown = false; text = StrCast(selected.Document.type); + if (text === DocumentType.RTF) text = "Text"; icon = Doc.toIcon(selected.Document); } else { dropdown = false; - noneSelected = true; - text = "None selected"; + icon = "globe-asia"; + text = "User Default"; } noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking]; } else if (script === 'setFont') { @@ -302,7 +303,7 @@ export class FontIconBox extends DocComponent(Fon
this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}> - {dropdown || noneSelected ? (null) : } + {dropdown || noneSelected ? (null) : }
{text && text[0].toUpperCase() + text.slice(1)}
@@ -487,7 +488,7 @@ export class FontIconBox extends DocComponent(Fon
; const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) : -
+
{this.label}
; @@ -508,7 +509,7 @@ export class FontIconBox extends DocComponent(Fon switch (this.type) { case ButtonType.TextButton: button = ( -
+
{buttonText ?
@@ -558,7 +559,7 @@ export class FontIconBox extends DocComponent(Fon break; case ButtonType.MenuButton: const trailsIcon = ; + style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />; button = (
{this.icon === "pres-trail" ? trailsIcon : } @@ -605,7 +606,7 @@ Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: bo Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (checkResult && selected) { - if (NumCast(selected.Document.z) === 1) return Colors.MEDIUM_BLUE; + if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE; else return "transparent"; } selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed"); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 3cedab1a4..56f5c5631 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -66,14 +66,25 @@ audiotag:hover { .formattedTextBox-sidebar-handle { position: absolute; - top: 0; + top: 5px; //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views - width: 10px; + width: 25px; height: 100%; - max-height: 35px; - background: lightgray; - border-radius: 20px; + max-height: 25px; + color: white; + background: $medium-gray; + border-radius: 5px; + display: flex; + justify-content: center; + align-items: center; cursor:grabbing; + box-shadow: $standard-box-shadow; + // transition: 0.2s; + + &:hover{ + filter: brightness(0.85); + } + } .formattedTextBox-sidebar, diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f45b9de7a..468edf6cc 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -63,6 +63,8 @@ import { SummaryView } from "./SummaryView"; import applyDevTools = require("prosemirror-dev-tools"); import React = require("react"); import { SidebarAnnos } from '../../SidebarAnnos'; +import { Colors } from '../../global/globalEnums'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; const translateGoogleApi = require("translate-google-api"); export interface FormattedTextBoxProps { @@ -574,11 +576,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp changeItems.push({ description: "plain", event: undoBatch(() => Doc.setNativeView(this.rootDoc)), icon: "eye" }); const noteTypesDoc = Cast(Doc.UserDoc()["template-notes"], Doc, null); DocListCast(noteTypesDoc?.data).forEach(note => { + const icon: IconProp = StrCast(note.icon) as IconProp; changeItems.push({ description: StrCast(note.title), event: undoBatch(() => { Doc.setNativeView(this.rootDoc); DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.TreeDocument, StrCast(note.title), note); - }), icon: "eye" + }), icon: icon }); }); !Doc.UserDoc().noviceMode && changeItems.push({ description: "FreeForm", event: () => DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), icon: "eye" }); @@ -1481,11 +1484,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarHandle() { TraceMobx(); const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length; + const color = !annotated ? Colors.WHITE : Colors.BLACK; + const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : "")); return (!annotated && !this.props.isContentActive()) ? (null) :
; + left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${"- 30px"}))`, + backgroundColor: backgroundColor, + color: color + }} > + +
; } @computed get sidebarCollection() { const renderComponent = (tag: string) => { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 260ddfc90..e70b2bc19 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -114,7 +114,7 @@ export class SearchBox extends ViewBoxBaseComponent
-
+
window.open( + "https://brown-dash.github.io/Dash-Documentation/", "_blank")}> {"Help"}
SettingsManager.Instance.open()}> -- cgit v1.2.3-70-g09d2 From f4b3781cf2250477482d8260e7137d9cbdfcb8e4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 14 Sep 2021 16:44:35 -0400 Subject: fixed height of maincontent. fixed warnings. --- src/client/views/MainView.tsx | 19 +++++++++++-------- .../collectionSchema/CollectionSchemaCells.tsx | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 39a14285a..b102c9a1f 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -11,7 +11,6 @@ import * as ReactDOM from 'react-dom'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; -import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, PromiseValue, StrCast } from '../../fields/Types'; import { TraceMobx } from '../../fields/util'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils'; @@ -37,7 +36,6 @@ import { CollectionLinearView } from './collections/collectionLinear'; import { CollectionMenu } from './collections/CollectionMenu'; import { CollectionViewType } from './collections/CollectionView'; import "./collections/TreeView.scss"; -import { ComponentDecorations } from './ComponentDecorations'; import { ContextMenu } from './ContextMenu'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; @@ -50,11 +48,9 @@ import { LightboxView } from './LightboxView'; import { LinkMenu } from './linking/LinkMenu'; import "./MainView.scss"; import { AudioBox } from './nodes/AudioBox'; -import { ButtonType } from './nodes/button/FontIconBox'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { DocumentView } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; -import { RichTextMenu } from './nodes/formattedText/RichTextMenu'; import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; import { LinkDocPreview } from './nodes/LinkDocPreview'; import { RadialMenu } from './nodes/RadialMenu'; @@ -66,6 +62,10 @@ import { PreviewCursor } from './PreviewCursor'; import { PropertiesView } from './PropertiesView'; import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider'; import { TopBar } from './topbar/TopBar'; +import { RichTextMenu } from './nodes/formattedText/RichTextMenu'; +import { ScriptField } from '../../fields/ScriptField'; +import { ButtonType } from './nodes/button/FontIconBox'; +import { ComponentDecorations } from './ComponentDecorations'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -247,7 +247,10 @@ export class MainView extends React.Component { if (!await this.userDoc.myFilesystem) { this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true }); const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!; - const newFolderButton: Doc = Docs.Create.FontIconDocument({ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true }); + const newFolderButton: Doc = Docs.Create.FontIconDocument({ + onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", + btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true + }); this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], { title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", @@ -450,7 +453,7 @@ export class MainView extends React.Component { r && new _global.ResizeObserver(action(() => { this._panelWidth = r.getBoundingClientRect().width; this._panelHeight = r.getBoundingClientRect().height; })).observe(r); }} style={{ color: this.darkScheme ? "rgb(205,205,205)" : "black", - height: `calc(100% - ${this.topOffset}px)`, + height: `calc(100% - ${this.topOffset - 35}px)`, width: "100%", }} > {this.mainInnerContent} @@ -495,8 +498,8 @@ export class MainView extends React.Component { rootSelected={returnTrue} bringToFront={emptyFunction} select={emptyFunction} - isContentActive={returnFalse} isAnyChildContentActive={returnFalse} + isContentActive={returnFalse} isSelected={returnFalse} docViewPath={returnEmptyDoclist} moveDocument={this.moveButtonDoc} @@ -604,7 +607,7 @@ export class MainView extends React.Component { - + {/* 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js */} {this.topbar} {LinkDescriptionPopup.descriptionPopup ? : null} {DocumentLinksButton.LinkEditorDocView ? : (null)} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx index fd99abce5..ed196349e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx @@ -293,12 +293,12 @@ export class CollectionSchemaCell extends React.Component { } } const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length; + const changeMade = value.length - 2 !== value.length; script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); // handle booleans } else if (inputIsBool) { const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length; + const changeMade = value.length - 2 !== value.length; script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); } } -- cgit v1.2.3-70-g09d2 From eb50e46332c2f0b48c7cb165d55245aab317ef08 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 21 Sep 2021 19:43:32 -0400 Subject: fixed up some darkScheme css, enabled comic mode for developers, enabled opening up fields on dashboards in myDocuments --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 30 ++++++++++------ src/client/util/SelectionManager.ts | 14 ++------ src/client/util/SettingsManager.tsx | 19 +++++----- src/client/views/ContextMenu.scss | 1 - src/client/views/DocumentDecorations.scss | 28 +++++++++++---- src/client/views/DocumentDecorations.tsx | 42 +++++++++++++--------- src/client/views/MainView.scss | 12 +++---- src/client/views/MainView.tsx | 14 ++++---- src/client/views/StyleProvider.tsx | 5 +-- .../views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 9 +++-- .../CollectionFreeFormLayoutEngines.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 ++- .../collectionSchema/CollectionSchemaView.tsx | 7 ++-- src/client/views/nodes/DocumentView.tsx | 6 ++-- src/client/views/nodes/button/FontIconBox.tsx | 2 -- .../views/nodes/formattedText/DashDocView.tsx | 3 +- src/mobile/MobileInterface.tsx | 4 +-- 19 files changed, 118 insertions(+), 89 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fafbc4a7d..206f65bfd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -862,7 +862,7 @@ export namespace Docs { export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true, isFolder: true }); const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true, isFolder: true }); - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } export function DirectoryImportDocument(options: DocumentOptions = {}) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index d5dc9e2be..568a9ddbd 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -20,6 +20,7 @@ import { Networking } from "../Network"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; +import { TreeView } from "../views/collections/TreeView"; import { Colors } from "../views/global/globalEnums"; import { MainView } from "../views/MainView"; import { ButtonType, NumButtonType } from "../views/nodes/button/FontIconBox"; @@ -38,7 +39,6 @@ import { ColorScheme } from "./SettingsManager"; import { SharingManager } from "./SharingManager"; import { SnappingManager } from "./SnappingManager"; import { UndoManager } from "./UndoManager"; -import { TreeView } from "../views/collections/TreeView"; interface Button { title?: string; @@ -816,16 +816,19 @@ export class CurrentUserUtils { _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true, explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files." })); - // const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`); - // const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); - // const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`); + const toggleDarkTheme = ScriptField.MakeScript(`this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`); + const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); + const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`); const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`); const removeDashboard = ScriptField.MakeScript('removeDashboard(self)'); - (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, shareDashboard!, removeDashboard!]); - (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]); - (doc.myDashboards as any as Doc).childContextMenuIcons = new List(["plus", "user-friends", "times"]); - // (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]); - // (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]); + const developerFilter = ScriptField.MakeFunction('!IsNoviceMode()'); + // (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, shareDashboard!, removeDashboard!]); + // (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]); + // (doc.myDashboards as any as Doc).childContextMenuIcons = new List(["plus", "user-friends", "times"]); + (doc.myDashboards as any as Doc).childContextMenuScripts = new List([newDashboard!, toggleDarkTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]); + (doc.myDashboards as any as Doc).childContextMenuLabels = new List(["Create New Dashboard", "Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]); + (doc.myDashboards as any as Doc).childContextMenuIcons = new List(["plus", "chalkboard", "tv", "camera", "users", "times"]); + (doc.myDashboards as any as Doc).childContextMenuFilters = new List([undefined as any, developerFilter, developerFilter, developerFilter, undefined as any, undefined as any]); } return doc.myDashboards as any as Doc; } @@ -1302,7 +1305,6 @@ export class CurrentUserUtils { }, { fireImmediately: true }); // Document properties on load doc.system = true; - doc.darkScheme = ColorScheme.Dark; doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode; doc.title = Doc.CurrentUserEmail; doc._raiseWhenDragged = true; @@ -1321,7 +1323,6 @@ export class CurrentUserUtils { doc.fontColor = StrCast(doc.fontColor, "black"); doc.fontHighlight = StrCast(doc.fontHighlight, ""); doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, false); - doc.activeCollectionBackground = StrCast(doc.activeCollectionBackground, "white"); doc.activeCollectionNestedBackground = Cast(doc.activeCollectionNestedBackground, "string", null); doc.noviceMode = BoolCast(doc.noviceMode, true); doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); // @@ -1358,6 +1359,10 @@ export class CurrentUserUtils { // }); setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500); doc.fieldInfos = await Docs.setupFieldInfos(); + if (doc.activeDashboard instanceof Doc) { + // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) + doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme; + } return doc; } @@ -1637,4 +1642,7 @@ Scripting.addGlobal(function makeTopLevelFolder() { const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true }); TreeView._editTitleOnLoad = { id: folder[Id], parent: undefined }; return Doc.AddDocToList(Doc.UserDoc().myFilesystem as Doc, "data", folder); +}); +Scripting.addGlobal(function toggleComicMode() { + Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }); \ No newline at end of file diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index bac13373c..e507ec3bf 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -2,7 +2,6 @@ import { action, observable, ObservableMap } from "mobx"; import { computedFn } from "mobx-utils"; import { Doc, Opt } from "../../fields/Doc"; import { DocumentType } from "../documents/DocumentTypes"; -import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView"; import { CollectionViewType } from "../views/collections/CollectionView"; import { DocumentView } from "../views/nodes/DocumentView"; @@ -13,12 +12,10 @@ export namespace SelectionManager { @observable IsDragging: boolean = false; SelectedViews: ObservableMap = new ObservableMap(); @observable SelectedSchemaDocument: Doc | undefined; - @observable SelectedSchemaCollection: CollectionSchemaView | undefined; @action - SelectSchemaView(collectionView: Opt, doc: Opt) { + SelectSchemaViewDoc(doc: Opt) { manager.SelectedSchemaDocument = doc; - manager.SelectedSchemaCollection = collectionView; } @action SelectView(docView: DocumentView, ctrlPressed: boolean): void { @@ -33,7 +30,6 @@ export namespace SelectionManager { } else if (!ctrlPressed && Array.from(manager.SelectedViews.entries()).length > 1) { Array.from(manager.SelectedViews.keys()).map(dv => dv !== docView && dv.props.whenChildContentsActiveChanged(false)); manager.SelectedSchemaDocument = undefined; - manager.SelectedSchemaCollection = undefined; manager.SelectedViews.clear(); manager.SelectedViews.set(docView, docView.rootDoc); } @@ -47,7 +43,6 @@ export namespace SelectionManager { } @action DeselectAll(): void { - manager.SelectedSchemaCollection = undefined; manager.SelectedSchemaDocument = undefined; Array.from(manager.SelectedViews.keys()).map(dv => dv.props.whenChildContentsActiveChanged(false)); manager.SelectedViews.clear(); @@ -62,8 +57,8 @@ export namespace SelectionManager { export function SelectView(docView: DocumentView, ctrlPressed: boolean): void { manager.SelectView(docView, ctrlPressed); } - export function SelectSchemaView(colSchema: Opt, document: Opt): void { - manager.SelectSchemaView(colSchema, document); + export function SelectSchemaViewDoc(document: Opt): void { + manager.SelectSchemaViewDoc(document); } const IsSelectedCache = computedFn(function isSelected(doc: DocumentView) { // wrapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed @@ -96,9 +91,6 @@ export namespace SelectionManager { export function SelectedSchemaDoc(): Doc | undefined { return manager.SelectedSchemaDocument; } - export function SelectedSchemaCollection(): CollectionSchemaView | undefined { - return manager.SelectedSchemaCollection; - } export function Docs(): Doc[] { return Array.from(manager.SelectedViews.values()).filter(doc => doc?._viewType !== CollectionViewType.Docking); } diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index bd91db779..6a26dfdc7 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -19,9 +19,9 @@ export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; export enum ColorScheme { - Dark = "Dark", - Light = "Light", - System = "Match System" + Dark = "-Dark", + Light = "-Light", + System = "-MatchSystem" } @observer @@ -38,7 +38,7 @@ export class SettingsManager extends React.Component<{}> { @observable activeTab = "Accounts"; @computed get backgroundColor() { return Doc.UserDoc().activeCollectionBackground; } - @computed get colorScheme() { return Doc.UserDoc().colorScheme; } + @computed get colorScheme() { return CurrentUserUtils.ActiveDashboard.colorScheme; } constructor(props: {}) { super(props); @@ -81,16 +81,16 @@ export class SettingsManager extends React.Component<{}> { const scheme: ColorScheme = (e.currentTarget as any).value; switch (scheme) { case ColorScheme.Light: - Doc.UserDoc().colorScheme = ColorScheme.Light; + CurrentUserUtils.ActiveDashboard.colorScheme = undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "#d3d3d3 !important" }); break; case ColorScheme.Dark: - Doc.UserDoc().colorScheme = ColorScheme.Dark; + CurrentUserUtils.ActiveDashboard.colorScheme = ColorScheme.Dark; addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "black !important" }); break; case ColorScheme.System: default: window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - Doc.UserDoc().colorScheme = e.matches ? ColorScheme.Dark : ColorScheme.Light; + CurrentUserUtils.ActiveDashboard.colorScheme = e.matches ? ColorScheme.Dark : undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) }); break; } @@ -119,6 +119,7 @@ export class SettingsManager extends React.Component<{}> {
; const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.System]; + const schemeMap = ["Light", "Dark", "Match system"]; return
@@ -132,8 +133,8 @@ export class SettingsManager extends React.Component<{}> {
Color Scheme
- + {colorSchemes.map((scheme, i) => )}
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index 47ae0424b..ea24dbf6d 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -8,7 +8,6 @@ flex-direction: column; background: whitesmoke; border-radius: 3px; - border: solid $light-gray 1px; } // .contextMenu-item:first-child { diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index a9f50f81b..d8ad47ecb 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -2,10 +2,14 @@ $linkGap: 3px; +.documentDecorations-Dark, .documentDecorations { position: absolute; z-index: 2000; } +.documentDecorations-Dark { + background: dimgray; +} .documentDecorations-container { z-index: $docDecorations-zindex; position: absolute; @@ -50,12 +54,17 @@ $linkGap: 3px; pointer-events: auto; background: $medium-gray; opacity: 0.1; - &:hover { opacity: 1; } } + .documentDecorations-resizer-Dark + { + background: $light-gray; + opacity: 0.2; + } + .documentDecorations-topLeftResizer, .documentDecorations-leftResizer, .documentDecorations-bottomLeftResizer { @@ -221,6 +230,7 @@ $linkGap: 3px; cursor: ns-resize; } + .documentDecorations-title-Dark, .documentDecorations-title { opacity: 1; grid-column-start: 2; @@ -233,14 +243,22 @@ $linkGap: 3px; height: 22px; position: absolute; - .documentDecorations-titleSpan { + .documentDecorations-titleSpan, + .documentDecorations-titleSpan-Dark { width: 100%; border-radius: 8px; - background: #ffffffcf; + background: #ffffffa0; position: absolute; display: inline-block; cursor: move; } + .documentDecorations-titleSpan-Dark { + background: hsla(0, 0%, 0%, 0.412); + } + } + .documentDecorations-title-Dark { + color: white; + background: black; } .documentDecorations-contextMenu { @@ -439,10 +457,6 @@ $linkGap: 3px; } } -.documentDecorations-darkScheme { - background: dimgray; -} - #template-list { position: absolute; top: 25px; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d785d5419..e9a54d6a5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -8,7 +8,7 @@ import { AclAdmin, AclEdit, DataSym, Doc, DocListCast, Field, HeightSym, WidthSy import { Document } from '../../fields/documentSchemas'; import { InkField } from "../../fields/InkField"; import { ScriptField } from '../../fields/ScriptField'; -import { Cast, NumCast } from "../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../fields/Types"; import { GetEffectiveAcl } from '../../fields/util'; import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils"; import { Docs } from "../documents/Documents"; @@ -27,6 +27,8 @@ import { LightboxView } from './LightboxView'; import { DocumentView } from "./nodes/DocumentView"; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import React = require("react"); +import { dark } from '@material-ui/core/styles/createPalette'; +import { color } from 'd3-color'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number, PanelHeight: number, boundsLeft: number, boundsTop: number }, { value: string }> { @@ -241,7 +243,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P InkStrokeProperties.Instance?._lock && SelectionManager.Views().filter(dv => dv.rootDoc.type === DocumentType.INK) .forEach(dv => fixedAspect = Doc.NativeAspect(dv.rootDoc)); - if (fixedAspect && (this._resizeHdlId === "documentDecorations-bottomRightResizer" || this._resizeHdlId === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles + const resizeHdl = this._resizeHdlId.split(" ")[0]; + if (fixedAspect && (resizeHdl === "documentDecorations-bottomRightResizer" || resizeHdl === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles const project = (p: number[], a: number[], b: number[]) => { const atob = [b[0] - a[0], b[1] - a[1]]; const atop = [p[0] - a[0], p[1] - a[1]]; @@ -264,7 +267,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P this._snapY = thisPt.y; let dragBottom = false, dragRight = false, dragBotRight = false; let dX = 0, dY = 0, dW = 0, dH = 0; - switch (this._resizeHdlId) { + switch (this._resizeHdlId.split(" ")[0]) { case "": break; case "documentDecorations-topLeftResizer": dX = -1; @@ -437,11 +440,17 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
); + const colorScheme = StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); const titleArea = this._edtingTitle ? - this.titleBlur()} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> : + this.titleBlur()} + onChange={action(e => this._accumulatedTitle = e.target.value)} + onKeyPress={this.titleEntered} /> :
- {`${this.selectionTitle}`} + {`${this.selectionTitle}`}
; let inMainMenuPanel = false; @@ -457,8 +466,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); const useRotation = seldoc.rootDoc.type === DocumentType.INK; + const resizerScheme = colorScheme ? "documentDecorations-resizer" + colorScheme : ""; - return (
+ return (
{SelectionManager.Views().length !== 1 || hideTitle ? (null) : topBtn("iconify", `window-${seldoc.finalLayoutKey.includes("icon") ? "restore" : "minimize"}`, undefined, this.onIconifyClick, `${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`)} -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
-
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> +
e.preventDefault()} /> +
e.preventDefault()} /> +
e.preventDefault()} /> +
e.preventDefault()} /> +
+
e.preventDefault()} /> +
e.preventDefault()} /> +
e.preventDefault()} /> +
e.preventDefault()} /> {seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) : topBtn("selector", "arrow-alt-circle-up", undefined, this.onSelectorClick, "tap to select containing document")} diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 4f871f5ec..7fa841002 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -41,7 +41,7 @@ } .mainView-container, -.mainView-container-dark { +.mainView-container-Dark { width: 100%; height: 100%; position: absolute; @@ -65,7 +65,7 @@ } } -.mainView-container-dark { +.mainView-container-Dark { color: $light-gray; .lm_goldenlayout { @@ -91,7 +91,7 @@ .contextMenu-cont, .contextMenu-item { - background: $medium-gray; + background: $dark-gray; } .contextMenu-item:hover { @@ -144,7 +144,7 @@ } } -.mainView-innerContent, .mainView-innerContent-dark { +.mainView-innerContent, .mainView-innerContent-Dark { display: contents; flex-direction: row; position: relative; @@ -175,7 +175,7 @@ .mainView-libraryHandle { background-color: $light-gray; } -.mainView-innerContent-dark +.mainView-innerContent-Dark { .propertiesView { background-color: #252525; @@ -198,7 +198,7 @@ background: #353535; } } -.mainView-container-dark { +.mainView-container-Dark { .contextMenu-cont { background: $medium-gray; color: $white; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index d854f118f..c99ba447c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -26,7 +26,7 @@ import { HistoryUtil } from '../util/History'; import { Hypothesis } from '../util/HypothesisUtils'; import { Scripting } from '../util/Scripting'; import { SelectionManager } from '../util/SelectionManager'; -import { SettingsManager } from '../util/SettingsManager'; +import { SettingsManager, ColorScheme } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; import { SnappingManager } from '../util/SnappingManager'; import { Transform } from '../util/Transform'; @@ -88,7 +88,7 @@ export class MainView extends React.Component { @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; } @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; } @computed private get userDoc() { return Doc.UserDoc(); } - @computed private get darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } + @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); } @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; } @computed public get mainFreeform(): Opt { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); } @@ -430,10 +430,10 @@ export class MainView extends React.Component { const transform = this._leftMenuFlyoutWidth ? 'translate(-28px, 0px)' : undefined; return <> {this.leftMenuPanel} -
+
{this.flyout}
- +
@@ -441,7 +441,7 @@ export class MainView extends React.Component { {this.dockingContent}
- +
{this.propertiesWidth() < 10 ? (null) : } @@ -459,7 +459,7 @@ export class MainView extends React.Component { this._dashUIHeight = r.getBoundingClientRect().height; })).observe(r); }} style={{ - color: this.darkScheme ? "rgb(205,205,205)" : "black", + color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black", height: `calc(100% - ${this.topOfDashUI}px)`, width: "100%", }} > @@ -601,7 +601,7 @@ export class MainView extends React.Component { } render() { - return (
((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)} ref={r => { r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 3c88a4830..1eb7a222e 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -22,6 +22,7 @@ import "./StyleProvider.scss"; import React = require("react"); import Color = require('color'); import { lightOrDark } from '../../Utils'; +import { ColorScheme } from '../util/SettingsManager'; export enum StyleLayers { Background = "background" @@ -49,7 +50,7 @@ export enum StyleProp { FontSize = "fontSize", // size of text font } -function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } +function darkScheme() { return CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark; } function toggleBackground(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { @@ -143,7 +144,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 0 ? Doc.UserDoc().activeCollectionNestedBackground : - Doc.UserDoc().activeCollectionBackground))); + Doc.UserDoc().activeCollectionBackground ?? (darkScheme() ? Colors.BLACK : Colors.WHITE)))); break; //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); break; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 6a22acae8..3ea190a98 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -353,7 +353,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setFocused = (doc: Doc) => this._focusedTable = doc; @action setPreviewDoc = (doc: Opt) => { - SelectionManager.SelectSchemaView(this, doc); + SelectionManager.SelectSchemaViewDoc(doc); this._previewDoc = doc; } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 97de097e0..a3da0e0e4 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -481,13 +481,16 @@ export class TreeView extends React.Component { } @computed get validExpandViewTypes() { - if (this.doc.viewType === CollectionViewType.Docking) return [this.fieldKey]; + if (this.props.treeView.dashboardMode && Doc.UserDoc().noviceMode) { + return [this.doc.viewType === CollectionViewType.Docking ? this.fieldKey : "layout"]; + } const annos = () => DocListCast(this.doc[this.fieldKey + "-annotations"]).length ? "annotations" : ""; const links = () => DocListCast(this.doc.links).length ? "links" : ""; - const data = () => this.childDocs && !this.props.treeView.dashboardMode ? this.fieldKey : ""; + const data = () => this.childDocs ? this.fieldKey : ""; const aliases = () => this.props.treeView.dashboardMode ? "" : "aliases"; const fields = () => Doc.UserDoc().noviceMode ? "" : "fields"; - return [data(), "layout", ...(this.props.treeView.fileSysMode ? [aliases(), links(), annos()] : []), fields()].filter(m => m); + const layout = this.doc.viewType === CollectionViewType.Docking ? [] : ["layout"]; + return [data(), ...layout, ...(this.props.treeView.fileSysMode ? [aliases(), links(), annos()] : []), fields()].filter(m => m); } @action expandNextviewType = () => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 37444a9dc..b3c57d33a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -7,6 +7,7 @@ import { Cast, NumCast, StrCast } from "../../../../fields/Types"; import { aggregateBounds } from "../../../../Utils"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; import React = require("react"); +import { ColorScheme } from "../../../util/SettingsManager"; export interface ViewDefBounds { type: string; @@ -361,7 +362,7 @@ export function computeTimelineLayout( groupNames.push({ type: "text", text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined }); } - const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; + const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]); function layoutDocsAtTime(keyDocs: Doc[], key: number) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 94cf1c5a6..0b12f6c21 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -51,6 +51,7 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import Color = require("color"); +import { ColorScheme } from "../../../util/SettingsManager"; export const panZoomSchema = createSchema({ _panX: "number", @@ -1419,6 +1420,7 @@ export class CollectionFreeFormView extends CollectionSubView { const ctx = el?.getContext('2d'); @@ -1429,7 +1431,7 @@ export class CollectionFreeFormView extends CollectionSubView 50 ? [3, 3] : [1, 5]); ctx.clearRect(0, 0, w, h); if (ctx) { - ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; + ctx.strokeStyle = strokeStyle; ctx.beginPath(); for (let x = Cx - renderGridSpace; x <= w - Cx; x += renderGridSpace) { ctx.moveTo(x, Cy - h); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index dfe99ffc8..12493ecc1 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -337,8 +337,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { {this.renderTypes(this._col)} {this.renderColors(this._col)}
- +
; } @@ -353,7 +354,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setFocused = (doc: Doc) => this._focusedTable = doc; @action setPreviewDoc = (doc: Opt) => { - SelectionManager.SelectSchemaView(this, doc); + SelectionManager.SelectSchemaViewDoc(doc); this._previewDoc = doc; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3e15ed661..5d0b91b91 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -25,7 +25,6 @@ import { InteractionUtils } from '../../util/InteractionUtils'; import { LinkManager } from '../../util/LinkManager'; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from "../../util/SelectionManager"; -import { ColorScheme } from "../../util/SettingsManager"; import { SharingManager } from '../../util/SharingManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from "../../util/Transform"; @@ -50,6 +49,7 @@ import { ScriptingBox } from "./ScriptingBox"; import { PresBox } from './trails/PresBox'; import React = require("react"); import { IconProp } from "@fortawesome/fontawesome-svg-core"; +import { ColorScheme } from "../../util/SettingsManager"; const { Howl } = require('howler'); interface Window { @@ -1061,9 +1061,7 @@ export class DocumentViewInternal extends DocComponent(Fon render() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); - const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark; const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index e519de1c5..149836e93 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -12,6 +12,7 @@ import { FormattedTextBox } from "./FormattedTextBox"; import React = require("react"); import * as ReactDOM from 'react-dom'; import { observer } from "mobx-react"; +import { ColorScheme } from "../../../util/SettingsManager"; export class DashDocView { _fieldWrapper: HTMLSpanElement; // container for label and value @@ -20,7 +21,7 @@ export class DashDocView { this._fieldWrapper = document.createElement("span"); this._fieldWrapper.style.position = "relative"; this._fieldWrapper.style.textIndent = "0"; - this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard.darkScheme ? "dimGray" : "lightGray")); + this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "lightGray")); this._fieldWrapper.style.width = node.attrs.width; this._fieldWrapper.style.height = node.attrs.height; this._fieldWrapper.style.display = node.attrs.hidden ? "none" : "inline-block"; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 404e828ea..652804126 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -17,7 +17,7 @@ import { Docs, DocumentOptions, DocUtils } from '../client/documents/Documents'; import { DocumentType } from "../client/documents/DocumentTypes"; import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; import { Scripting } from '../client/util/Scripting'; -import { SettingsManager } from '../client/util/SettingsManager'; +import { SettingsManager, ColorScheme } from '../client/util/SettingsManager'; import { Transform } from '../client/util/Transform'; import { UndoManager } from "../client/util/UndoManager"; import { TabDocView } from '../client/views/collections/TabDocView'; @@ -403,7 +403,7 @@ export class MobileInterface extends React.Component { const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); - const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); + const toggleTheme = ScriptField.MakeScript(`self.colorScheme = self.colorScheme ? undefined: ${ColorScheme.Dark}}`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`); dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, cloneDashboard!]); -- cgit v1.2.3-70-g09d2 From d5f9533d153e11e24d2ab7c03b4561170f0768fe Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Thu, 23 Sep 2021 11:18:30 -0400 Subject: small schema UI tweak --- src/client/util/CurrentUserUtils.ts | 2 -- .../collections/collectionSchema/CollectionSchemaView.scss | 3 ++- src/client/views/nodes/button/FontIconBox.tsx | 13 +++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 297d4b241..4ec83f2d7 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1019,8 +1019,6 @@ export class CurrentUserUtils { title: "Show preview", toolTip: "Show preview of selected document", btnType: ButtonType.ToggleButton, - switchToggle: true, - width: 100, buttonText: "Show Preview", icon: "eye", click: 'toggleSchemaPreview()', diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 3074ce66e..9ebe14d6c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -444,11 +444,12 @@ button.add-column { border: none; background-color: $white; width: 100%; - height: 100%; + height: fit-content; min-height: 26px; } } &.focused { + overflow: hidden; &.inactive { border: none; } diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index 511df8786..af4a581f1 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -861,4 +861,17 @@ Scripting.addGlobal(function toggleSchemaPreview(checkResult?: boolean) { selected.schemaPreviewWidth = 0; } } +}); + +/** STACK + * groupBy + */ +Scripting.addGlobal(function setGroupBy(key: string, checkResult?: boolean) { + SelectionManager.Docs().map(doc => doc._fontFamily = key); + const editorView = RichTextMenu.Instance.TextView?.EditorView; + if (checkResult) { + return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); + } + if (editorView) RichTextMenu.Instance.setFontFamily(key); + else Doc.UserDoc().fontFamily = key; }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 780346cb03a2dcc10c1edcf4ecc4f57a091d36bc Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 23 Sep 2021 15:26:30 -0400 Subject: fixed one crash when color string has capital letters. --- src/client/util/CurrentUserUtils.ts | 10 +++++----- .../collectionFreeForm/CollectionFreeFormLayoutEngines.tsx | 2 +- src/client/views/collections/collectionSchema/SchemaTable.tsx | 2 +- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 7 +++---- src/client/views/nodes/LabelBox.scss | 2 +- src/client/views/nodes/LinkAnchorBox.tsx | 2 +- src/client/views/nodes/formattedText/DashDocView.tsx | 2 +- src/client/views/nodes/formattedText/DashFieldView.scss | 2 +- 9 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 4ec83f2d7..3c32c2359 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -226,9 +226,9 @@ export class CurrentUserUtils { const descriptionWrapper = MasonryDocument([details, short, long], { ...shared, ...descriptionWrapperOpts }); descriptionWrapper._columnHeaders = new List([ - new SchemaHeaderField("[A Short Description]", "dimGray", undefined, undefined, undefined, false), - new SchemaHeaderField("[Long Description]", "dimGray", undefined, undefined, undefined, true), - new SchemaHeaderField("[Details]", "dimGray", undefined, undefined, undefined, true), + new SchemaHeaderField("[A Short Description]", "dimgray", undefined, undefined, undefined, false), + new SchemaHeaderField("[Long Description]", "dimgray", undefined, undefined, undefined, true), + new SchemaHeaderField("[Details]", "dimgray", undefined, undefined, undefined, true), ]); const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, _chromeHidden: true, system: true }); detailView.isTemplateDoc = makeTemplate(detailView); @@ -349,7 +349,7 @@ export class CurrentUserUtils { static setupDefaultIconTemplates(doc: Doc) { if (doc["template-icon-view"] === undefined) { const iconView = Docs.Create.LabelDocument({ - title: "icon", textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("title"), _backgroundColor: "dimGray", + title: "icon", textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("title"), _backgroundColor: "dimgray", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)"), system: true }); // Docs.Create.TextDocument("", { @@ -1238,7 +1238,7 @@ export class CurrentUserUtils { static setupSearchSidebar(doc: Doc) { if (doc.mySearchPanel === undefined) { doc.mySearchPanel = new PrefetchProxy(Docs.Create.SearchDocument({ - backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true, + backgroundColor: "dimgray", ignoreClick: true, _searchDoc: true, childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "Search Panel", system: true })) as any as Doc; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index b3c57d33a..9fed82dae 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -362,7 +362,7 @@ export function computeTimelineLayout( groupNames.push({ type: "text", text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined }); } - const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; + const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimgray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]); function layoutDocsAtTime(keyDocs: Doc[], key: number) { diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index 3833f968b..d157832d9 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -567,7 +567,7 @@ export class SchemaTable extends React.Component {
{ this._timeout = undefined; clickFunc(); }, 350); } else clickFunc(); - } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself - this.props.addDocTab(DocUtils.makeCustomViewClicked(Doc.MakeAlias(this.props.Document), undefined, "onClick"), "add:right"); } else if (this.allLinks && this.Document.type !== DocumentType.LINK && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) { this.allLinks.length && LinkManager.FollowLink(undefined, this.props.Document, this.props, e.altKey); } else { @@ -582,8 +580,9 @@ export class DocumentViewInternal extends DocComponent Doc.UnBrushDoc(this.rootDoc)}> { })} /> {!this._forceOpen ? (null) :
this._isOpen = this._editing = this._forceOpen = false)}> - +
}
); diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 149836e93..364be461f 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -21,7 +21,7 @@ export class DashDocView { this._fieldWrapper = document.createElement("span"); this._fieldWrapper.style.position = "relative"; this._fieldWrapper.style.textIndent = "0"; - this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "lightGray")); + this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimgray" : "lightGray")); this._fieldWrapper.style.width = node.attrs.width; this._fieldWrapper.style.height = node.attrs.height; this._fieldWrapper.style.display = node.attrs.hidden ? "none" : "inline-block"; diff --git a/src/client/views/nodes/formattedText/DashFieldView.scss b/src/client/views/nodes/formattedText/DashFieldView.scss index e7dd286a5..c36e6804b 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.scss +++ b/src/client/views/nodes/formattedText/DashFieldView.scss @@ -8,7 +8,7 @@ height: 10px; position: relative; display: inline-block; - background: dimGray; + background: dimgray; } .dashFieldView-fieldCheck { min-width: 12px; -- cgit v1.2.3-70-g09d2 From fc679d849ae8afa3ef66e4e0b2b2b816e1fb41d4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 4 Oct 2021 21:21:55 -0400 Subject: fixed how filters work in Schema View. made filtering the default for clicking in title area. --- .../views/collections/CollectionSchemaView.tsx | 575 --------------------- .../collectionSchema/CollectionSchemaHeaders.tsx | 72 ++- .../collectionSchema/CollectionSchemaView.tsx | 2 +- .../collections/collectionSchema/SchemaTable.tsx | 14 +- src/fields/Doc.ts | 2 +- 5 files changed, 40 insertions(+), 625 deletions(-) delete mode 100644 src/client/views/collections/CollectionSchemaView.tsx (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx deleted file mode 100644 index 3ea190a98..000000000 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ /dev/null @@ -1,575 +0,0 @@ -import React = require("react"); -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, untracked } from "mobx"; -import { observer } from "mobx-react"; -import Measure from "react-measure"; -import { Resize } from "react-table"; -import "react-table/react-table.css"; -import { Doc, Opt } from "../../../fields/Doc"; -import { List } from "../../../fields/List"; -import { listSpec } from "../../../fields/Schema"; -import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; -import { Cast, NumCast } from "../../../fields/Types"; -import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../Utils"; -import { DocUtils } from "../../documents/Documents"; -import { SelectionManager } from "../../util/SelectionManager"; -import { SnappingManager } from "../../util/SnappingManager"; -import { Transform } from "../../util/Transform"; -import { undoBatch } from "../../util/UndoManager"; -import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss'; -import { SchemaTable } from "../collections/collectionSchema/SchemaTable"; -import { ContextMenu } from "../ContextMenu"; -import { ContextMenuProps } from "../ContextMenuItem"; -import '../DocumentDecorations.scss'; -import { DocumentView } from "../nodes/DocumentView"; -import { DefaultStyleProvider } from "../StyleProvider"; -import "./CollectionSchemaView.scss"; -import { CollectionSubView } from "./CollectionSubView"; -// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 - -export enum ColumnType { - Any, - Number, - String, - Boolean, - Doc, - Image, - List, - Date -} -// this map should be used for keys that should have a const type of value -const columnTypes: Map = new Map([ - ["title", ColumnType.String], - ["x", ColumnType.Number], ["y", ColumnType.Number], ["_width", ColumnType.Number], ["_height", ColumnType.Number], - ["_nativeWidth", ColumnType.Number], ["_nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean], - ["_curPage", ColumnType.Number], ["_currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number] -]); - -@observer -export class CollectionSchemaView extends CollectionSubView(doc => doc) { - private _previewCont?: HTMLDivElement; - - @observable _previewDoc: Doc | undefined = undefined; - @observable _focusedTable: Doc = this.props.Document; - @observable _col: any = ""; - @observable _menuWidth = 0; - @observable _headerOpen = false; - @observable _headerIsEditing = false; - @observable _menuHeight = 0; - @observable _pointerX = 0; - @observable _pointerY = 0; - @observable _openTypes: boolean = false; - - @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } - @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } - @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - Number(SCHEMA_DIVIDER_WIDTH) - this.previewWidth(); } - @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } - @computed get scale() { return this.props.ScreenToLocalTransform().Scale; } - @computed get columns() { return Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []); } - set columns(columns: SchemaHeaderField[]) { this.props.Document._schemaHeaders = new List(columns); } - - @computed get menuCoordinates() { - let searchx = 0; - let searchy = 0; - if (this.props.Document._searchDoc) { - const el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0]; - if (el !== undefined) { - const rect = el.getBoundingClientRect(); - searchx = rect.x; - searchy = rect.y; - } - } - const x = Math.max(0, Math.min(document.body.clientWidth - this._menuWidth, this._pointerX)) - searchx; - const y = Math.max(0, Math.min(document.body.clientHeight - this._menuHeight, this._pointerY)) - searchy; - return this.props.ScreenToLocalTransform().transformPoint(x, y); - } - - get documentKeys() { - const docs = this.childDocs; - const keys: { [key: string]: boolean } = {}; - // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. - // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be - // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked. - // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu - // is displayed (unlikely) it won't show up until something else changes. - //TODO Types - untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false)))); - - this.columns.forEach(key => keys[key.heading] = true); - return Array.from(Object.keys(keys)); - } - - @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing; - - @undoBatch - setColumnType = action((columnField: SchemaHeaderField, type: ColumnType): void => { - this._openTypes = false; - if (columnTypes.get(columnField.heading)) return; - - const columns = this.columns; - const index = columns.indexOf(columnField); - if (index > -1) { - columnField.setType(NumCast(type)); - columns[index] = columnField; - this.columns = columns; - } - }); - - @undoBatch - setColumnColor = (columnField: SchemaHeaderField, color: string): void => { - const columns = this.columns; - const index = columns.indexOf(columnField); - if (index > -1) { - columnField.setColor(color); - columns[index] = columnField; - this.columns = columns; // need to set the columns to trigger rerender - } - } - - @undoBatch - @action - setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => { - const columns = this.columns; - columns.forEach(col => col.setDesc(undefined)); - - const index = columns.findIndex(c => c.heading === columnField.heading); - const column = columns[index]; - column.setDesc(descending); - columns[index] = column; - this.columns = columns; - } - - renderTypes = (col: any) => { - if (columnTypes.get(col.heading)) return (null); - - const type = col.type; - - const anyType =
this.setColumnType(col, ColumnType.Any)}> - - Any -
; - - const numType =
this.setColumnType(col, ColumnType.Number)}> - - Number -
; - - const textType =
this.setColumnType(col, ColumnType.String)}> - - Text -
; - - const boolType =
this.setColumnType(col, ColumnType.Boolean)}> - - Checkbox -
; - - const listType =
this.setColumnType(col, ColumnType.List)}> - - List -
; - - const docType =
this.setColumnType(col, ColumnType.Doc)}> - - Document -
; - - const imageType =
this.setColumnType(col, ColumnType.Image)}> - - Image -
; - - const dateType =
this.setColumnType(col, ColumnType.Date)}> - - Date -
; - - - const allColumnTypes =
- {anyType} - {numType} - {textType} - {boolType} - {listType} - {docType} - {imageType} - {dateType} -
; - - const justColType = type === ColumnType.Any ? anyType : type === ColumnType.Number ? numType : - type === ColumnType.String ? textType : type === ColumnType.Boolean ? boolType : - type === ColumnType.List ? listType : type === ColumnType.Doc ? docType : - type === ColumnType.Date ? dateType : imageType; - - return ( -
this._openTypes = !this._openTypes)}> -
- - -
- {this._openTypes ? allColumnTypes : justColType} -
- ); - } - - renderSorting = (col: any) => { - const sort = col.desc; - return ( -
- -
-
this.setColumnSort(col, true)}> - - Sort descending -
-
this.setColumnSort(col, false)}> - - Sort ascending -
-
this.setColumnSort(col, undefined)}> - - Clear sorting -
-
-
- ); - } - - renderColors = (col: any) => { - const selected = col.color; - - const pink = PastelSchemaPalette.get("pink2"); - const purple = PastelSchemaPalette.get("purple2"); - const blue = PastelSchemaPalette.get("bluegreen1"); - const yellow = PastelSchemaPalette.get("yellow4"); - const red = PastelSchemaPalette.get("red2"); - const gray = "#f1efeb"; - - return ( -
- -
-
this.setColumnColor(col, pink!)}>
-
this.setColumnColor(col, purple!)}>
-
this.setColumnColor(col, blue!)}>
-
this.setColumnColor(col, yellow!)}>
-
this.setColumnColor(col, red!)}>
-
this.setColumnColor(col, gray)}>
-
-
- ); - } - - @undoBatch - @action - changeColumns = (oldKey: string, newKey: string, addNew: boolean, filter?: string) => { - const columns = this.columns; - if (columns === undefined) { - this.columns = new List([new SchemaHeaderField(newKey, "f1efeb")]); - } else { - if (addNew) { - columns.push(new SchemaHeaderField(newKey, "f1efeb")); - this.columns = columns; - } else { - const index = columns.map(c => c.heading).indexOf(oldKey); - if (index > -1) { - const column = columns[index]; - column.setHeading(newKey); - columns[index] = column; - this.columns = columns; - if (filter) { - Doc.setDocFilter(this.props.Document, newKey, filter, "match"); - } - else { - this.props.Document._docFilters = undefined; - } - } - } - } - } - - @action - openHeader = (col: any, screenx: number, screeny: number) => { - this._col = col; - this._headerOpen = true; - this._pointerX = screenx; - this._pointerY = screeny; - } - - @action - closeHeader = () => { this._headerOpen = false; } - - @undoBatch - @action - deleteColumn = (key: string) => { - const columns = this.columns; - if (columns === undefined) { - this.columns = new List([]); - } else { - const index = columns.map(c => c.heading).indexOf(key); - if (index > -1) { - columns.splice(index, 1); - this.columns = columns; - } - } - this.closeHeader(); - } - - getPreviewTransform = (): Transform => { - return this.props.ScreenToLocalTransform().translate(- this.borderWidth - NumCast(COLLECTION_BORDER_WIDTH) - this.tableWidth, - this.borderWidth); - } - - @action - onHeaderClick = (e: React.PointerEvent) => { - e.stopPropagation(); - } - - @action - onWheel(e: React.WheelEvent) { - const scale = this.props.ScreenToLocalTransform().Scale; - this.props.isContentActive(true) && e.stopPropagation(); - } - - @computed get renderMenuContent() { - TraceMobx(); - return
- {this.renderTypes(this._col)} - {this.renderColors(this._col)} -
- -
-
; - } - - private createTarget = (ele: HTMLDivElement) => { - this._previewCont = ele; - super.CreateDropTarget(ele); - } - - isFocused = (doc: Doc, outsideReaction: boolean): boolean => this.props.isSelected(outsideReaction) && doc === this._focusedTable; - - @action setFocused = (doc: Doc) => this._focusedTable = doc; - - @action setPreviewDoc = (doc: Opt) => { - SelectionManager.SelectSchemaViewDoc(doc); - this._previewDoc = doc; - } - - //toggles preview side-panel of schema - @action - toggleExpander = () => { - this.props.Document.schemaPreviewWidth = this.previewWidth() === 0 ? Math.min(this.tableWidth / 3, 200) : 0; - } - - onDividerDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.onDividerMove, emptyFunction, this.toggleExpander); - } - @action - onDividerMove = (e: PointerEvent, down: number[], delta: number[]) => { - const nativeWidth = this._previewCont!.getBoundingClientRect(); - const minWidth = 40; - const maxWidth = 1000; - const movedWidth = this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]; - const width = movedWidth < minWidth ? minWidth : movedWidth > maxWidth ? maxWidth : movedWidth; - this.props.Document.schemaPreviewWidth = width; - return false; - } - - onPointerDown = (e: React.PointerEvent): void => { - if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { - if (this.props.isSelected(true)) e.stopPropagation(); - else this.props.select(false); - } - } - - @computed - get previewDocument(): Doc | undefined { return this._previewDoc; } - - @computed - get dividerDragger() { - return this.previewWidth() === 0 ? (null) : -
-
-
; - } - - @computed - get previewPanel() { - return
- {!this.previewDocument ? (null) : - } -
; - } - - @computed - get schemaTable() { - return ; - } - - @computed - public get schemaToolbar() { - return
-
-
- - Show Preview -
-
-
; - } - - onSpecificMenu = (e: React.MouseEvent) => { - if ((e.target as any)?.className?.includes?.("collectionSchemaView-cell") || (e.target instanceof HTMLSpanElement)) { - const cm = ContextMenu.Instance; - const options = cm.findByDescription("Options..."); - const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; - optionItems.push({ description: "remove", event: () => this._previewDoc && this.props.removeDocument?.(this._previewDoc), icon: "trash" }); - !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); - cm.displayMenu(e.clientX, e.clientY); - (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this. - e.stopPropagation(); - } - } - - @action - onTableClick = (e: React.MouseEvent): void => { - if (!(e.target as any)?.className?.includes?.("collectionSchemaView-cell") && !(e.target instanceof HTMLSpanElement)) { - this.setPreviewDoc(undefined); - } else { - e.stopPropagation(); - } - this.setFocused(this.props.Document); - this.closeHeader(); - } - - onResizedChange = (newResized: Resize[], event: any) => { - const columns = this.columns; - newResized.forEach(resized => { - const index = columns.findIndex(c => c.heading === resized.id); - const column = columns[index]; - column.setWidth(resized.value); - columns[index] = column; - }); - this.columns = columns; - } - - @action - setColumns = (columns: SchemaHeaderField[]) => this.columns = columns - - @undoBatch - reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => { - const columns = [...columnsValues]; - const oldIndex = columns.indexOf(toMove); - const relIndex = columns.indexOf(relativeTo); - const newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - - if (oldIndex === newIndex) return; - - columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); - this.columns = columns; - } - - onZoomMenu = (e: React.WheelEvent) => this.props.isContentActive(true) && e.stopPropagation(); - - render() { - TraceMobx(); - if (!this.props.isContentActive()) setTimeout(() => this.closeHeader(), 0); - const menuContent = this.renderMenuContent; - const menu =
this.onZoomMenu(e)} - onPointerDown={e => this.onHeaderClick(e)} - style={{ transform: `translate(${(this.menuCoordinates[0])}px, ${(this.menuCoordinates[1])}px)` }}> - { - const dim = this.props.ScreenToLocalTransform().inverse().transformDirection(r.offset.width, r.offset.height); - this._menuWidth = dim[0]; this._menuHeight = dim[1]; - })}> - {({ measureRef }) =>
{menuContent}
} -
-
; - return
-
this.props.isContentActive(true) && e.stopPropagation()} - onDrop={e => this.onExternalDrop(e, {})} - ref={this.createTarget}> - {this.schemaTable} -
- {this.dividerDragger} - {!this.previewWidth() ? (null) : this.previewPanel} - {this._headerOpen && this.props.isContentActive() ? menu : null} -
; - } -} \ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx index a25f962df..c659f749e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx @@ -1,18 +1,17 @@ import React = require("react"); -import { IconProp, library } from "@fortawesome/fontawesome-svg-core"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, runInAction } from "mobx"; +import { action, computed, observable, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, Opt } from "../../../../fields/Doc"; +import { Doc, DocListCast, Opt, StrListCast } from "../../../../fields/Doc"; import { listSpec } from "../../../../fields/Schema"; import { PastelSchemaPalette, SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; import { ScriptField } from "../../../../fields/ScriptField"; import { Cast, StrCast } from "../../../../fields/Types"; import { undoBatch } from "../../../util/UndoManager"; -import { SearchBox } from "../../search/SearchBox"; +import { CollectionView } from "../CollectionView"; import { ColumnType } from "./CollectionSchemaView"; import "./CollectionSchemaView.scss"; -import { CollectionView } from "../CollectionView"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -26,9 +25,9 @@ export interface AddColumnHeaderProps { @observer export class CollectionSchemaAddColumnHeader extends React.Component { render() { - return ( - - ); + return ; } } @@ -234,7 +233,7 @@ export interface KeysDropdownProps { @observer export class KeysDropdown extends React.Component { @observable private _key: string = this.props.keyValue; - @observable private _searchTerm: string = this.props.keyValue; + @observable private _searchTerm: string = this.props.keyValue + ":"; @observable private _isOpen: boolean = false; @observable private _node: HTMLDivElement | null = null; @observable private _inputRef: React.RefObject = React.createRef(); @@ -326,11 +325,11 @@ export class KeysDropdown extends React.Component { || ((!key.startsWith("_") && key[0] === key[0].toUpperCase()) || key[0] === "#")) ? showKeys.add(key) : null); return Array.from(showKeys.keys()).filter(key => !this._searchTerm || key.includes(this._searchTerm)); } - @action - renderOptions = (): JSX.Element[] | JSX.Element => { + + @computed get renderOptions() { if (!this._isOpen) { this.defaultMenuHeight = 0; - return <>; + return (null); } const options = this.showKeys.map(key => { return
{ return options; } - docSafe: Doc[] = []; + @computed get docSafe() { return DocListCast(this.props.dataDoc?.[this.props.fieldKey]); } - @action - renderFilterOptions = (): JSX.Element[] | JSX.Element => { + @computed get renderFilterOptions() { if (!this._isOpen || !this.props.dataDoc) { this.defaultMenuHeight = 0; - return <>; + return (null); } const keyOptions: string[] = []; const colpos = this._searchTerm.indexOf(":"); const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length); - if (this.docSafe.length === 0) { - this.docSafe = DocListCast(this.props.dataDoc[this.props.fieldKey]); - } - const docs = this.docSafe; - docs.forEach((doc) => { + this.docSafe.forEach(doc => { const key = StrCast(doc[this._key]); if (keyOptions.includes(key) === false && key.includes(temp) && key !== "") { keyOptions.push(key); } }); - const filters = Cast(this.props.Document._docFilters, listSpec("string")); - if (filters === undefined || filters.length === 0 || filters.some(filter => filter.split(":")[0] === this._key) === false) { + const filters = StrListCast(this.props.Document._docFilters); + if (filters.some(filter => filter.split(":")[0] === this._key) === false) { this.props.col.setColor("rgb(241, 239, 235)"); this.closeResultsVisibility = "none"; } @@ -408,9 +402,9 @@ export class KeysDropdown extends React.Component { const options = keyOptions.map(key => { let bool = false; if (filters !== undefined) { - const ind = filters.findIndex(filter => filter.split(":")[0] === key); + const ind = filters.findIndex(filter => filter.split(":")[1] === key); const fields = ind === -1 ? undefined : filters[ind].split(":"); - bool = fields ? fields[1] === "check" : false; + bool = fields ? fields[2] === "check" : false; } return
{ e.stopPropagation()} onClick={e => e.stopPropagation()} - onChange={(e) => { - e.target.checked === true ? Doc.setDocFilter(this.props.Document, this._key, key, "check") : Doc.setDocFilter(this.props.Document, this._key, key, "remove"); - e.target.checked === true ? this.closeResultsVisibility = "contents" : console.log(""); - e.target.checked === true ? this.props.col.setColor("green") : this.updateFilter(); - e.target.checked === true ? Doc.setDocFilter(docs[0], this._key, key, "check") : Doc.setDocFilter(docs[0], this._key, key, "remove"); - }} + onChange={action(e => { + if (e.target.checked) { + Doc.setDocFilter(this.props.Document, this._key, key, "check"); + this.closeResultsVisibility = "contents"; + this.props.col.setColor("green"); + } else { + Doc.setDocFilter(this.props.Document, this._key, key, "remove"); + this.updateFilter(); + } + })} checked={bool} /> @@ -472,11 +470,7 @@ export class KeysDropdown extends React.Component { removeFilters = (e: React.PointerEvent): void => { const keyOptions: string[] = []; - if (this.docSafe.length === 0 && this.props.dataDoc) { - this.docSafe = DocListCast(this.props.dataDoc[this.props.fieldKey]); - } - const docs = this.docSafe; - docs.forEach((doc) => { + this.docSafe.forEach(doc => { const key = StrCast(doc[this._key]); if (keyOptions.includes(key) === false) { keyOptions.push(key); @@ -494,10 +488,6 @@ export class KeysDropdown extends React.Component {
- {/* { - runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) - }} /> */} -
{ {!this._isOpen ? (null) :
- {this._searchTerm.includes(":") ? this.renderFilterOptions() : this.renderOptions()} + {this._searchTerm.includes(":") ? this.renderFilterOptions : this.renderOptions}
}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 12493ecc1..b89246489 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, untracked } from "mobx"; +import { action, computed, observable, untracked, trace } from "mobx"; import { observer } from "mobx-react"; import Measure from "react-measure"; import { Resize } from "react-table"; diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index d157832d9..bc5a9559f 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -1,7 +1,7 @@ import React = require("react"); import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable } from "mobx"; +import { action, computed, observable, trace } from "mobx"; import { observer } from "mobx-react"; import ReactTable, { CellInfo, Column, ComponentPropsGetterR, Resize, SortingRule } from "react-table"; import "react-table/react-table.css"; @@ -386,13 +386,13 @@ export class SchemaTable extends React.Component { @undoBatch @action createColumn = () => { - let index = 0; - let found = this.props.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1; - while (found) { - index++; - found = this.props.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1; + const newFieldName = (index: number) => `New field${index ? ` (${index})` : ""}`; + for (let index = 0; index < 100; index++) { + if (this.props.columns.findIndex(col => col.heading === newFieldName(index)) === -1) { + this.props.columns.push(new SchemaHeaderField(newFieldName(index), "#f1efeb")); + break; + } } - this.props.columns.push(new SchemaHeaderField(`New field ${index ? "(" + index + ")" : ""}`, "#f1efeb")); } @action diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index d8690831f..9490edc2c 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1142,7 +1142,7 @@ export namespace Doc { runInAction(() => { for (let i = 0; i < docFilters.length; i++) { const fields = docFilters[i].split(":"); // split key:value:modifier - if (fields[0] === key && (fields[1] === value || modifiers === "match" || modifiers === "remove")) { + if (fields[0] === key && (fields[1] === value || modifiers === "match")) { if (fields[2] === modifiers && modifiers && fields[1] === value) { if (toggle) modifiers = "remove"; else return; -- cgit v1.2.3-70-g09d2 From a46d659229120cdb139f716b1a48ec6b887807bb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Oct 2021 19:40:40 -0400 Subject: fixed lightbox view to shrinkwrap collections when opened, but not force fit contents to allow users to navigate. fixed comparison box to show context of maker'/annotation documents. fixed ink pointer events to honor pointerEvents prop (eg when embedded in a comparisonBox that turns them off). --- src/client/views/InkingStroke.tsx | 2 +- src/client/views/LightboxView.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionSchema/CollectionSchemaCells.tsx | 1 - src/client/views/nodes/ComparisonBox.tsx | 12 +++++++++--- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/collectionSchema') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index d05a4a6e4..752db1413 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -209,7 +209,7 @@ export class InkingStroke extends ViewBoxBaseComponent { LightboxView.SetLightboxDoc(undefined); } }} > - +
{ DataDoc={undefined} LayoutTemplate={LightboxView.LightboxDocTemplate} addDocument={undefined} - fitContentsToDoc={this.fitToBox} + // fitContentsToDoc={this.fitToBox} // bcz: why do we want this? when we initially open a colletion, we shrinkwrap it which allows for user navigation. if we later encounter a collection, it's not clear to me that we want to make it either shrinkwrap or fitContents... isDocumentActive={returnFalse} isContentActive={returnTrue} addDocTab={this.addDocTab} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b2db1168d..7dcd63b80 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1036,7 +1036,7 @@ export class CollectionFreeFormView extends CollectionSubView; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx index ed196349e..0274cc49c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx @@ -103,7 +103,6 @@ export class CollectionSchemaCell extends React.Component { this.props.changeFocusedCellByIndex(this.props.row, this.props.col); this.props.setPreviewDoc(this.props.rowProps.original); - console.log("click cell"); let url: string; if (url = StrCast(this.props.rowProps.row.href)) { try { diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index f23c68409..b1aada158 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -89,14 +89,20 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { var whichDoc = Cast(this.dataDoc[which], Doc, null); - if (whichDoc?.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null); + //if (whichDoc?.type === DocumentType.MARKER) + const targetDoc = Cast(whichDoc.annotationOn, Doc, null) ?? whichDoc; return whichDoc ? <> - { + whichDoc !== targetDoc && r?.focus(targetDoc); + }} + {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} isContentActive={returnFalse} isDocumentActive={returnFalse} styleProvider={this.docStyleProvider} - Document={whichDoc} + Document={targetDoc} DataDoc={undefined} + hideLinkButton={true} pointerEvents={"none"} /> {clearButton(which)} : // placeholder image if doc is missing -- cgit v1.2.3-70-g09d2