From 6c96bd6c8ef06e1ecb75ca39a575155dafcc26f1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 21:56:48 -0400 Subject: moving collectionViewChrome to CollectionMenu --- src/client/views/collections/CollectionMenu.tsx | 331 ++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 src/client/views/collections/CollectionMenu.tsx (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx new file mode 100644 index 000000000..d79ffffa1 --- /dev/null +++ b/src/client/views/collections/CollectionMenu.tsx @@ -0,0 +1,331 @@ +import React = require("react"); +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable, reaction, runInAction } from "mobx"; +import { observer } from "mobx-react"; +import { Doc, DocListCast } from "../../../fields/Doc"; +import { BoolCast, Cast, StrCast, NumCast } from "../../../fields/Types"; +import AntimodeMenu from "../AntimodeMenu"; +import "./CollectionMenu.scss"; +import { undoBatch } from "../../util/UndoManager"; +import { CollectionViewType, CollectionView } from "./CollectionView"; +import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { CollectionGridViewChrome } from "./CollectionViewChromes"; +import { DragManager } from "../../util/DragManager"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { List } from "../../../fields/List"; +import { SelectionManager } from "../../util/SelectionManager"; + +@observer +export default class CollectionMenu extends AntimodeMenu { + static Instance: CollectionMenu; + + @observable SelectedCollection: CollectionView | undefined; + + constructor(props: Readonly<{}>) { + super(props); + CollectionMenu.Instance = this; + this._canFade = false; // don't let the inking menu fade away + this.Pinned = Cast(Doc.UserDoc()["menuCollections-pinned"], "boolean", true); + } + + @action + toggleMenuPin = (e: React.MouseEvent) => { + Doc.UserDoc()["menuCollections-pinned"] = this.Pinned = !this.Pinned; + } + + @computed get aButton() { + return
+ +
; + } + + render() { + return this.getElement([ + this.aButton, + !this.SelectedCollection ? <> : , + + ]); + } +} + +interface CollectionViewChromeProps { + CollectionView: CollectionView; + type: CollectionViewType; + collapse?: (value: boolean) => any; +} + +const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); + +@observer +export class CollectionViewBaseChrome extends React.Component { + //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) + + get target() { return this.props.CollectionView.props.Document; } + _templateCommand = { + params: ["target", "source"], title: "=> item view", + script: "this.target.childLayout = getDocTemplate(this.source?.[0])", + immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))), + initialize: emptyFunction, + }; + _narrativeCommand = { + params: ["target", "source"], title: "=> child click view", + script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])", + immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))), + initialize: emptyFunction, + }; + _contentCommand = { + params: ["target", "source"], title: "=> clear content", + script: "getProto(this.target).data = copyField(this.source);", + immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), + initialize: emptyFunction, + }; + _viewCommand = { + params: ["target"], title: "=> reset view", + script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }), + initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; }, + }; + _clusterCommand = { + params: ["target"], title: "=> fit content", + script: "this.target._fitToBox = !this.target._fitToBox;", + immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox), + initialize: emptyFunction + }; + _fitContentCommand = { + params: ["target"], title: "=> toggle clusters", + script: "this.target.useClusters = !this.target.useClusters;", + immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters), + initialize: emptyFunction + }; + + _freeform_commands = [this._viewCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; + _stacking_commands = [this._contentCommand, this._templateCommand]; + _masonry_commands = [this._contentCommand, this._templateCommand]; + _schema_commands = [this._templateCommand, this._narrativeCommand]; + _tree_commands = []; + private get _buttonizableCommands() { + switch (this.props.type) { + case CollectionViewType.Tree: return this._tree_commands; + case CollectionViewType.Schema: return this._schema_commands; + case CollectionViewType.Stacking: return this._stacking_commands; + case CollectionViewType.Masonry: return this._stacking_commands; + case CollectionViewType.Freeform: return this._freeform_commands; + case CollectionViewType.Time: return this._freeform_commands; + case CollectionViewType.Carousel: return this._freeform_commands; + case CollectionViewType.Carousel3D: return this._freeform_commands; + } + return []; + } + private _picker: any; + private _commandRef = React.createRef(); + private _viewRef = React.createRef(); + @observable private _currentKey: string = ""; + + componentDidMount = action(() => { + this._currentKey = this._currentKey || (this._buttonizableCommands.length ? this._buttonizableCommands[0]?.title : ""); + }); + + @undoBatch + viewChanged = (e: React.ChangeEvent) => { + //@ts-ignore + this.document._viewType = e.target.selectedOptions[0].value; + } + + commandChanged = (e: React.ChangeEvent) => { + //@ts-ignore + runInAction(() => this._currentKey = e.target.selectedOptions[0].value); + } + + @action + toggleViewSpecs = (e: React.SyntheticEvent) => { + this.document._facetWidth = this.document._facetWidth ? 0 : 200; + e.stopPropagation(); + } + + @action closeViewSpecs = () => { + this.document._facetWidth = 0; + } + + + @computed get subChrome() { + switch (this.props.type) { + case CollectionViewType.Freeform: return (); + // case CollectionViewType.Stacking: return (); + // case CollectionViewType.Schema: return (); + // case CollectionViewType.Tree: return (); + // case CollectionViewType.Masonry: return (); + // case CollectionViewType.Carousel3D: return (); + // case CollectionViewType.Grid: return (); + default: return null; + } + } + + private get document() { + return this.props.CollectionView.props.Document; + } + + private dropDisposer?: DragManager.DragDropDisposer; + protected createDropTarget = (ele: HTMLDivElement) => { + this.dropDisposer?.(); + if (ele) { + this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.document); + } + } + + @undoBatch + @action + protected drop(e: Event, de: DragManager.DropEvent): boolean { + const docDragData = de.complete.docDragData; + if (docDragData?.draggedDocuments.length) { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); + e.stopPropagation(); + } + return true; + } + + dragViewDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, (e, down, delta) => { + const vtype = this.props.CollectionView.collectionViewType; + const c = { + params: ["target"], title: vtype, + script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`, + immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]), + initialize: emptyFunction, + }; + DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), + { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY); + return true; + }, emptyFunction, emptyFunction); + } + dragCommandDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, (e, down, delta) => { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => + DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, + { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY)); + return true; + }, emptyFunction, () => { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate([])); + }); + } + + @computed get templateChrome() { + return
+
+
+ +
+ +
+
; + } + + @computed get viewModes() { + const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; + return
+
+
+ +
+ +
+
; + } + + render() { + const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform()?.Scale); + return ( +
+
+
+ {this.viewModes} +
+
+ +
+
+ {this.templateChrome} +
+ {this.subChrome} +
+
+ ); + } +} + +@observer +export class CollectionFreeFormViewChrome extends React.Component { + + get Document() { return this.props.CollectionView.props.Document; } + @computed get dataField() { + return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)]; + } + @computed get childDocs() { + return DocListCast(this.dataField); + } + @undoBatch + @action + nextKeyframe = (): void => { + const currentFrame = NumCast(this.Document.currentFrame); + if (currentFrame === undefined) { + this.Document.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); + } + CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1); + this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame)); + } + @undoBatch + @action + prevKeyframe = (): void => { + const currentFrame = NumCast(this.Document.currentFrame); + if (currentFrame === undefined) { + this.Document.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); + } + CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1); + } + render() { + return this.Document.isAnnotationOverlay ? (null) : +
+
+ +
+
this.Document.editing = !this.Document.editing)} > + {NumCast(this.Document.currentFrame)} +
+
+ +
+
; + } +} -- cgit v1.2.3-70-g09d2 From 95429adb77402ce2a218c5585ceef4db0c8494db Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 23:55:59 -0400 Subject: converted collectionChrome into a menu bar --- src/client/views/MainView.tsx | 6 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionMenu.scss | 475 ++++++++++++++++++++- src/client/views/collections/CollectionMenu.tsx | 443 +++++++++++++++++-- src/client/views/collections/CollectionView.tsx | 11 +- 5 files changed, 888 insertions(+), 49 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 428fb835b..95b2dfcdb 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -392,7 +392,7 @@ export class MainView extends React.Component { doc.dockingConfig ? this.openWorkspace(doc) : CollectionDockingView.AddRightSplit(doc, libraryPath); } - sidebarScreenToLocal = () => new Transform(0, RichTextMenu.Instance.Pinned ? -35 : 0, 1); + sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (InkOptionsMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1); mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight); @computed get flyout() { @@ -469,11 +469,13 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc?.["tabs-panelContainer"]; + const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (InkOptionsMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0); + const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index f408e24a8..657296566 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -436,7 +436,7 @@ export class CollectionDockingView extends React.Component - -
; - } - render() { return this.getElement([ - this.aButton, !this.SelectedCollection ? <> : , - ]); @@ -55,7 +47,6 @@ export default class CollectionMenu extends AntimodeMenu { interface CollectionViewChromeProps { CollectionView: CollectionView; type: CollectionViewType; - collapse?: (value: boolean) => any; } const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @@ -154,12 +145,12 @@ export class CollectionViewBaseChrome extends React.Component); - // case CollectionViewType.Stacking: return (); - // case CollectionViewType.Schema: return (); - // case CollectionViewType.Tree: return (); - // case CollectionViewType.Masonry: return (); - // case CollectionViewType.Carousel3D: return (); - // case CollectionViewType.Grid: return (); + case CollectionViewType.Stacking: return (); + case CollectionViewType.Schema: return (); + case CollectionViewType.Tree: return (); + case CollectionViewType.Masonry: return (); + case CollectionViewType.Carousel3D: return (); + case CollectionViewType.Grid: return (); default: return null; } } @@ -230,8 +221,7 @@ export class CollectionViewBaseChrome extends React.Component + return
@@ -258,7 +248,7 @@ export class CollectionViewBaseChrome extends React.Component { - const currentFrame = NumCast(this.Document.currentFrame); + const currentFrame = Cast(this.Document.currentFrame, "number", null); if (currentFrame === undefined) { this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); @@ -305,7 +295,7 @@ export class CollectionFreeFormViewChrome extends React.Component { - const currentFrame = NumCast(this.Document.currentFrame); + const currentFrame = Cast(this.Document.currentFrame, "number", null); if (currentFrame === undefined) { this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); @@ -315,7 +305,7 @@ export class CollectionFreeFormViewChrome extends React.Component +
@@ -329,3 +319,400 @@ export class CollectionFreeFormViewChrome extends React.Component; } } +@observer +export class CollectionStackingViewChrome extends React.Component { + @observable private _currentKey: string = ""; + @observable private suggestions: string[] = []; + + @computed private get descending() { return StrCast(this.props.CollectionView.props.Document._columnsSort) === "descending"; } + @computed get pivotField() { return StrCast(this.props.CollectionView.props.Document._pivotField); } + + getKeySuggestions = async (value: string): Promise => { + value = value.toLowerCase(); + const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); + if (docs instanceof Doc) { + return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); + } else { + const keys = new Set(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); + } + } + + @action + onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { + this._currentKey = newValue; + } + + getSuggestionValue = (suggestion: string) => suggestion; + + renderSuggestion = (suggestion: string) => { + return

{suggestion}

; + } + + onSuggestionFetch = async ({ value }: { value: string }) => { + const sugg = await this.getKeySuggestions(value); + runInAction(() => { + this.suggestions = sugg; + }); + } + + @action + onSuggestionClear = () => { + this.suggestions = []; + } + + @action + setValue = (value: string) => { + this.props.CollectionView.props.Document._pivotField = value; + return true; + } + + @action toggleSort = () => { + this.props.CollectionView.props.Document._columnsSort = + this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" : + this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending"; + } + @action resetValue = () => { this._currentKey = this.pivotField; }; + + render() { + return ( +
+
+
+ GROUP BY: +
+
+ +
+
+ this.pivotField} + autosuggestProps={ + { + resetValue: this.resetValue, + value: this._currentKey, + onChange: this.onKeyChange, + autosuggestProps: { + inputProps: + { + value: this._currentKey, + onChange: this.onKeyChange + }, + getSuggestionValue: this.getSuggestionValue, + suggestions: this.suggestions, + alwaysRenderSuggestions: true, + renderSuggestion: this.renderSuggestion, + onSuggestionsFetchRequested: this.onSuggestionFetch, + onSuggestionsClearRequested: this.onSuggestionClear + } + }} + oneLine + SetValue={this.setValue} + contents={this.pivotField ? this.pivotField : "N/A"} + /> +
+
+
+ ); + } +} + + +@observer +export class CollectionSchemaViewChrome extends React.Component { + // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; + + @undoBatch + togglePreview = () => { + const dividerWidth = 4; + const borderWidth = Number(COLLECTION_BORDER_WIDTH); + const panelWidth = this.props.CollectionView.props.PanelWidth(); + const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); + const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth; + this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0; + } + + @undoBatch + @action + toggleTextwrap = async () => { + const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []); + if (textwrappedRows.length) { + this.props.CollectionView.props.Document.textwrappedSchemaRows = new List([]); + } else { + const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); + const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]); + this.props.CollectionView.props.Document.textwrappedSchemaRows = new List(allRows); + } + } + + + render() { + const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); + const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; + + return ( +
+
+
Show Preview:
+
+
+ {previewWidth !== 0 ? "on" : "off"} +
+
+
+
+ ); + } +} + +@observer +export class CollectionTreeViewChrome extends React.Component { + + get sortAscending() { + return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; + } + set sortAscending(value) { + this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value; + } + @computed private get ascending() { + return Cast(this.sortAscending, "boolean", null); + } + + @action toggleSort = () => { + if (this.sortAscending) this.sortAscending = undefined; + else if (this.sortAscending === undefined) this.sortAscending = false; + else this.sortAscending = true; + } + + render() { + return ( +
+ +
+ ); + } +} + +// Enter scroll speed for 3D Carousel +@observer +export class Collection3DCarouselViewChrome extends React.Component { + @computed get scrollSpeed() { + return this.props.CollectionView.props.Document._autoScrollSpeed; + } + + @action + setValue = (value: string) => { + const numValue = Number(StrCast(value)); + if (numValue > 0) { + this.props.CollectionView.props.Document._autoScrollSpeed = numValue; + return true; + } + return false; + } + + render() { + return ( +
+
+
+ AUTOSCROLL SPEED: +
+
+ StrCast(this.scrollSpeed)} + oneLine + SetValue={this.setValue} + contents={this.scrollSpeed ? this.scrollSpeed : 1000} /> +
+
+
+ ); + } +} + +/** + * Chrome for grid view. + */ +@observer +export class CollectionGridViewChrome extends React.Component { + + private clicked: boolean = false; + private entered: boolean = false; + private decrementLimitReached: boolean = false; + @observable private resize = false; + private resizeListenerDisposer: Opt; + + componentDidMount() { + + runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700); + + // listener to reduce text on chrome resize (panel resize) + this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => { + runInAction(() => this.resize = newValue < 700); + }); + } + + componentWillUnmount() { + this.resizeListenerDisposer?.(); + } + + get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); } + + /** + * Sets the value of `numCols` on the grid's Document to the value entered. + */ + @undoBatch + onNumColsEnter = (e: React.KeyboardEvent) => { + if (e.key === "Enter" || e.key === "Tab") { + if (e.currentTarget.valueAsNumber > 0) { + this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber; + } + + } + } + + /** + * Sets the value of `rowHeight` on the grid's Document to the value entered. + */ + // @undoBatch + // onRowHeightEnter = (e: React.KeyboardEvent) => { + // if (e.key === "Enter" || e.key === "Tab") { + // if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) { + // this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber; + // } + // } + // } + + /** + * Sets whether the grid is flexible or not on the grid's Document. + */ + @undoBatch + toggleFlex = () => { + this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true); + } + + /** + * Increments the value of numCols on button click + */ + onIncrementButtonClick = () => { + this.clicked = true; + this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--; + undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)(); + this.entered = false; + } + + /** + * Decrements the value of numCols on button click + */ + onDecrementButtonClick = () => { + this.clicked = true; + if (!this.decrementLimitReached) { + this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++; + undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)(); + } + this.entered = false; + } + + /** + * Increments the value of numCols on button hover + */ + incrementValue = () => { + this.entered = true; + if (!this.clicked && !this.decrementLimitReached) { + this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1; + } + this.decrementLimitReached = false; + this.clicked = false; + } + + /** + * Decrements the value of numCols on button hover + */ + decrementValue = () => { + this.entered = true; + if (!this.clicked) { + if (this.numCols !== 1) { + this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1; + } + else { + this.decrementLimitReached = true; + } + } + + this.clicked = false; + } + + /** + * Toggles the value of preventCollision + */ + toggleCollisions = () => { + this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision; + } + + /** + * Changes the value of the compactType + */ + changeCompactType = (e: React.ChangeEvent) => { + // need to change startCompaction so that this operation will be undoable. + this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value; + } + + render() { + return ( +
+ + + + + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> + + + + {/* + + + + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> + */} + + + + + + + + + + + + + + +
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e18fe319e..6cd6a827f 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -47,7 +47,6 @@ import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; -import { CollectionViewBaseChrome } from './CollectionViewChromes'; import CollectionMenu from './CollectionMenu'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -235,16 +234,8 @@ export class CollectionView extends Touchable { - this.props.Document._chromeStatus = value ? "collapsed" : "enabled"; - } - private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => { - // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip - const chrome = this.props.Document._chromeStatus === "disabled" || this.props.Document._chromeStatus === "replaced" || type === CollectionViewType.Docking ? (null) : - ; - return <>{chrome} {this.SubViewHelper(type, renderProps)}; + return this.SubViewHelper(type, renderProps); } -- cgit v1.2.3-70-g09d2 From 162aea736a27a3058b49d5bc3218f75d41a38b68 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 11:27:28 -0400 Subject: make collectionMenu unpinnable --- src/client/views/collections/CollectionMenu.tsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 1644bc726..d7e2baca8 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -32,6 +32,9 @@ export default class CollectionMenu extends AntimodeMenu { @action toggleMenuPin = (e: React.MouseEvent) => { Doc.UserDoc()["menuCollections-pinned"] = this.Pinned = !this.Pinned; + if (!this.Pinned && this._left < 0) { + this.jumpTo(300, 300); + } } render() { -- cgit v1.2.3-70-g09d2 From ba86637704663e4791b0bccd2762f15a55fc188d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 11:32:25 -0400 Subject: moved all of collectionViewChrome permanently into CollectionMenu --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/collections/CollectionMenu.scss | 5 +- src/client/views/collections/CollectionMenu.tsx | 25 +- .../views/collections/CollectionViewChromes.scss | 466 ------------ .../views/collections/CollectionViewChromes.tsx | 800 --------------------- 5 files changed, 15 insertions(+), 1283 deletions(-) delete mode 100644 src/client/views/collections/CollectionViewChromes.scss delete mode 100644 src/client/views/collections/CollectionViewChromes.tsx (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 444d2fe50..bf3037e91 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -150,7 +150,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (e.button === 0 && !e.altKey && !e.ctrlKey) { let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0]; while (child.children.length) { - const next = Array.from(child.children).find(c => typeof (c.className) !== "string" || !c.className.includes("collectionViewChrome")); + const next = Array.from(child.children).find(c => typeof (c.className) !== "string"); if (typeof (next?.className) === "string" && next?.className.includes("documentView-node")) break; if (next) child = next; else break; diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index c1a3f9c09..348b9e6ea 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -11,6 +11,8 @@ background: #121721; color: white; transform-origin: top left; + top: 0; + width:100%; .antimodeMenu-button { padding:0; @@ -21,13 +23,14 @@ } } - .collectionViewChrome { + .collectionMenu { display: flex; padding-bottom: 1px; height: 32px; border-bottom: .5px solid rgb(180, 180, 180); overflow: visible; z-index: 9001; + border: unset; .collectionViewBaseChrome { display: flex; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index d7e2baca8..827c3e299 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -47,7 +47,7 @@ export default class CollectionMenu extends AntimodeMenu { } } -interface CollectionViewChromeProps { +interface CollectionMenuProps { CollectionView: CollectionView; type: CollectionViewType; } @@ -55,7 +55,7 @@ interface CollectionViewChromeProps { const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @observer -export class CollectionViewBaseChrome extends React.Component { +export class CollectionViewBaseChrome extends React.Component { //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) get target() { return this.props.CollectionView.props.Document; } @@ -249,14 +249,9 @@ export class CollectionViewBaseChrome extends React.Component -
+
+
{this.viewModes}
@@ -274,7 +269,7 @@ export class CollectionViewBaseChrome extends React.Component { +export class CollectionFreeFormViewChrome extends React.Component { get Document() { return this.props.CollectionView.props.Document; } @computed get dataField() { @@ -323,7 +318,7 @@ export class CollectionFreeFormViewChrome extends React.Component { +export class CollectionStackingViewChrome extends React.Component { @observable private _currentKey: string = ""; @observable private suggestions: string[] = []; @@ -423,7 +418,7 @@ export class CollectionStackingViewChrome extends React.Component { +export class CollectionSchemaViewChrome extends React.Component { // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; @undoBatch @@ -470,7 +465,7 @@ export class CollectionSchemaViewChrome extends React.Component { +export class CollectionTreeViewChrome extends React.Component { get sortAscending() { return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; @@ -506,7 +501,7 @@ export class CollectionTreeViewChrome extends React.Component { +export class Collection3DCarouselViewChrome extends React.Component { @computed get scrollSpeed() { return this.props.CollectionView.props.Document._autoScrollSpeed; } @@ -545,7 +540,7 @@ export class Collection3DCarouselViewChrome extends React.Component { +export class CollectionGridViewChrome extends React.Component { private clicked: boolean = false; private entered: boolean = false; diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss deleted file mode 100644 index b1e8d20ad..000000000 --- a/src/client/views/collections/CollectionViewChromes.scss +++ /dev/null @@ -1,466 +0,0 @@ -@import "../globalCssVariables"; -@import '~js-datepicker/dist/datepicker.min.css'; - -.collectionViewChrome-cont { - position: absolute; - width: 100%; - opacity: 0.9; - z-index: 9001; - transition: top .5s; - background: lightgrey; - transform-origin: top left; - - .collectionViewChrome { - display: flex; - padding-bottom: 1px; - height: 32px; - border-bottom: .5px solid rgb(180, 180, 180); - overflow: visible; - z-index: 9001; - - .collectionViewBaseChrome { - display: flex; - - .collectionViewBaseChrome-viewPicker { - font-size: 75%; - //text-transform: uppercase; - //letter-spacing: 2px; - background: rgb(238, 238, 238); - color: grey; - outline-color: black; - border: none; - //padding: 12px 10px 11px 10px; - } - - .collectionViewBaseChrome-viewPicker:active { - outline-color: black; - } - - .collectionViewBaseChrome-button { - font-size: 75%; - text-transform: uppercase; - letter-spacing: 2px; - background: rgb(238, 238, 238); - color: purple; - outline-color: black; - border: none; - padding: 12px 10px 11px 10px; - margin-left: 10px; - } - - .collectionViewBaseChrome-cmdPicker { - margin-left: 3px; - margin-right: 0px; - font-size: 75%; - background: rgb(238, 238, 238); - border: none; - color: grey; - } - - .commandEntry-outerDiv { - pointer-events: all; - background-color: gray; - display: flex; - flex-direction: row; - height: 30px; - - .commandEntry-drop { - color: white; - width: 25px; - margin-top: auto; - margin-bottom: auto; - } - } - - .collectionViewBaseChrome-collapse { - transition: all .5s, opacity 0.3s; - position: absolute; - width: 40px; - transform-origin: top left; - pointer-events: all; - // margin-top: 10px; - } - - @media only screen and (max-device-width: 480px) { - .collectionViewBaseChrome-collapse { - display: none; - } - } - - .collectionViewBaseChrome-template, - .collectionViewBaseChrome-viewModes { - display: grid; - background: rgb(238, 238, 238); - color: grey; - margin-top: auto; - margin-bottom: auto; - margin-left: 5px; - } - - .collectionViewBaseChrome-viewModes { - margin-left: 25px; - } - - .collectionViewBaseChrome-viewSpecs { - margin-left: 5px; - display: grid; - - .collectionViewBaseChrome-filterIcon { - position: relative; - display: flex; - margin: auto; - background: gray; - color: white; - width: 30px; - height: 30px; - align-items: center; - justify-content: center; - } - - .collectionViewBaseChrome-viewSpecsInput { - padding: 12px 10px 11px 10px; - border: 0px; - color: grey; - text-align: center; - letter-spacing: 2px; - outline-color: black; - font-size: 75%; - background: rgb(238, 238, 238); - height: 100%; - width: 75px; - } - - .collectionViewBaseChrome-viewSpecsMenu { - overflow: hidden; - transition: height .5s, display .5s; - position: absolute; - top: 60px; - z-index: 100; - display: flex; - flex-direction: column; - background: rgb(238, 238, 238); - box-shadow: grey 2px 2px 4px; - - .qs-datepicker { - left: unset; - right: 0; - } - - .collectionViewBaseChrome-viewSpecsMenu-row { - display: grid; - grid-template-columns: 150px 200px 150px; - margin-top: 10px; - margin-right: 10px; - - .collectionViewBaseChrome-viewSpecsMenu-rowLeft, - .collectionViewBaseChrome-viewSpecsMenu-rowMiddle, - .collectionViewBaseChrome-viewSpecsMenu-rowRight { - font-size: 75%; - letter-spacing: 2px; - color: grey; - margin-left: 10px; - padding: 5px; - border: none; - outline-color: black; - } - } - - .collectionViewBaseChrome-viewSpecsMenu-lastRow { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-gap: 10px; - margin: 10px; - } - } - } - } - - .collectionStackingViewChrome-cont, - .collectionTreeViewChrome-cont, - .collection3DCarouselViewChrome-cont { - display: flex; - justify-content: space-between; - } - - .collectionGridViewChrome-cont { - display: flex; - margin-left: 10; - - .collectionGridViewChrome-viewPicker { - font-size: 75%; - //text-transform: uppercase; - //letter-spacing: 2px; - background: rgb(238, 238, 238); - color: grey; - outline-color: black; - border: none; - //padding: 12px 10px 11px 10px; - } - - .collectionGridViewChrome-viewPicker:active { - outline-color: black; - } - - .grid-control { - align-self: center; - display: flex; - flex-direction: row; - margin-right: 5px; - - .grid-icon { - margin-right: 5px; - align-self: center; - } - - .flexLabel { - margin-bottom: 0; - } - } - - .collectionGridViewChrome-entryBox { - width: 50%; - } - } - - - .collectionStackingViewChrome-sort, - .collectionTreeViewChrome-sort { - display: flex; - align-items: center; - justify-content: space-between; - - .collectionStackingViewChrome-sortIcon, - .collectionTreeViewChrome-sortIcon { - transition: transform .5s; - margin-left: 10px; - } - } - - button:hover { - transform: scale(1); - } - - - .collectionStackingViewChrome-pivotField-cont, - .collectionTreeViewChrome-pivotField-cont, - .collection3DCarouselViewChrome-scrollSpeed-cont { - justify-self: right; - display: flex; - font-size: 75%; - letter-spacing: 2px; - - .collectionStackingViewChrome-pivotField-label, - .collectionTreeViewChrome-pivotField-label, - .collection3DCarouselViewChrome-scrollSpeed-label { - vertical-align: center; - padding-left: 10px; - margin: auto; - } - - .collectionStackingViewChrome-pivotField, - .collectionTreeViewChrome-pivotField, - .collection3DCarouselViewChrome-scrollSpeed { - color: white; - width: 100%; - min-width: 100px; - display: flex; - align-items: center; - background: rgb(238, 238, 238); - - .editable-view-input, - input, - .editableView-container-editing-oneLine, - .editableView-container-editing { - margin: auto; - border: 0px; - color: grey !important; - text-align: center; - letter-spacing: 2px; - outline-color: black; - height: 100%; - } - - .react-autosuggest__container { - margin: 0; - color: grey; - padding: 0px; - } - } - } - - .collectionStackingViewChrome-pivotField:hover, - .collectionTreeViewChrome-pivotField:hover, - .collection3DCarouselViewChrome-scrollSpeed:hover { - cursor: text; - } - - } -} - -.collectionFreeFormViewChrome-cont { - width: 60px; - display: flex; - position: relative; - align-items: center; - - .fwdKeyframe, - .numKeyframe, - .backKeyframe { - cursor: pointer; - position: absolute; - width: 20; - height: 30; - bottom: 0; - background: gray; - display: flex; - align-items: center; - color: white; - } - - .backKeyframe { - left: 0; - - svg { - display: block; - margin: auto; - } - } - - .numKeyframe { - left: 20; - display: flex; - flex-direction: column; - padding: 5px; - } - - .fwdKeyframe { - left: 40; - - svg { - display: block; - margin: auto; - } - } -} - -.collectionSchemaViewChrome-cont { - display: flex; - font-size: 10.5px; - - .collectionSchemaViewChrome-toggle { - display: flex; - margin-left: 10px; - } - - .collectionSchemaViewChrome-label { - text-transform: uppercase; - letter-spacing: 2px; - margin-right: 5px; - display: flex; - flex-direction: column; - justify-content: center; - } - - .collectionSchemaViewChrome-toggler { - width: 100px; - height: 41px; - background-color: black; - position: relative; - } - - .collectionSchemaViewChrome-togglerButton { - width: 47px; - height: 35px; - background-color: $light-color-secondary; - // position: absolute; - transition: all 0.5s ease; - // top: 3px; - margin-top: 3px; - color: gray; - letter-spacing: 2px; - text-transform: uppercase; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; - - &.on { - margin-left: 3px; - } - - &.off { - margin-left: 50px; - } - } -} - - -.commandEntry-outerDiv { - display: flex; - flex-direction: column; - height: 40px; -} - -.commandEntry-inputArea { - display: flex; - flex-direction: row; - width: 150px; - margin: auto auto auto auto; -} - -.react-autosuggest__container { - position: relative; - width: 100%; - margin-left: 5px; - margin-right: 5px; -} - -.react-autosuggest__input { - border: 1px solid #aaa; - border-radius: 4px; - width: 100%; -} - -.react-autosuggest__input--focused { - outline: none; -} - -.react-autosuggest__input--open { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.react-autosuggest__suggestions-container { - display: none; -} - -.react-autosuggest__suggestions-container--open { - display: block; - position: fixed; - overflow-y: auto; - max-height: 400px; - width: 180px; - border: 1px solid #aaa; - background-color: #fff; - font-family: Helvetica, sans-serif; - font-weight: 300; - font-size: 16px; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - z-index: 2; -} - -.react-autosuggest__suggestions-list { - margin: 0; - padding: 0; - list-style-type: none; -} - -.react-autosuggest__suggestion { - cursor: pointer; - padding: 10px 20px; -} - -.react-autosuggest__suggestion--highlighted { - background-color: #ddd; -} \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx deleted file mode 100644 index 7f1fe7649..000000000 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ /dev/null @@ -1,800 +0,0 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, runInAction, Lambda } from "mobx"; -import { observer } from "mobx-react"; -import * as React from "react"; -import { Doc, DocListCast, Opt } from "../../../fields/Doc"; -import { Id } from "../../../fields/FieldSymbols"; -import { List } from "../../../fields/List"; -import { listSpec } from "../../../fields/Schema"; -import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { Utils, emptyFunction, setupMoveUpEvents } from "../../../Utils"; -import { DragManager } from "../../util/DragManager"; -import { undoBatch } from "../../util/UndoManager"; -import { EditableView } from "../EditableView"; -import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss"; -import { CollectionViewType } from "./CollectionView"; -import { CollectionView } from "./CollectionView"; -import "./CollectionViewChromes.scss"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; - -interface CollectionViewChromeProps { - CollectionView: CollectionView; - type: CollectionViewType; - collapse?: (value: boolean) => any; - PanelWidth: () => number; -} - -interface Filter { - key: string; - value: string; - contains: boolean; -} - -const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); - -@observer -export class CollectionViewBaseChrome extends React.Component { - //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) - - get target() { return this.props.CollectionView.props.Document; } - _templateCommand = { - params: ["target", "source"], title: "=> item view", - script: "this.target.childLayout = getDocTemplate(this.source?.[0])", - immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))), - initialize: emptyFunction, - }; - _narrativeCommand = { - params: ["target", "source"], title: "=> child click view", - script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])", - immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))), - initialize: emptyFunction, - }; - _contentCommand = { - params: ["target", "source"], title: "=> clear content", - script: "getProto(this.target).data = copyField(this.source);", - immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), - initialize: emptyFunction, - }; - _viewCommand = { - params: ["target"], title: "=> reset view", - script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", - immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }), - initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; }, - }; - _clusterCommand = { - params: ["target"], title: "=> fit content", - script: "this.target._fitToBox = !this.target._fitToBox;", - immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox), - initialize: emptyFunction - }; - _fitContentCommand = { - params: ["target"], title: "=> toggle clusters", - script: "this.target.useClusters = !this.target.useClusters;", - immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters), - initialize: emptyFunction - }; - - _freeform_commands = [this._viewCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; - _stacking_commands = [this._contentCommand, this._templateCommand]; - _masonry_commands = [this._contentCommand, this._templateCommand]; - _schema_commands = [this._templateCommand, this._narrativeCommand]; - _tree_commands = []; - private get _buttonizableCommands() { - switch (this.props.type) { - case CollectionViewType.Tree: return this._tree_commands; - case CollectionViewType.Schema: return this._schema_commands; - case CollectionViewType.Stacking: return this._stacking_commands; - case CollectionViewType.Masonry: return this._stacking_commands; - case CollectionViewType.Freeform: return this._freeform_commands; - case CollectionViewType.Time: return this._freeform_commands; - case CollectionViewType.Carousel: return this._freeform_commands; - case CollectionViewType.Carousel3D: return this._freeform_commands; - } - return []; - } - private _picker: any; - private _commandRef = React.createRef(); - private _viewRef = React.createRef(); - @observable private _currentKey: string = ""; - - componentDidMount = action(() => { - this._currentKey = this._currentKey || (this._buttonizableCommands.length ? this._buttonizableCommands[0]?.title : ""); - // chrome status is one of disabled, collapsed, or visible. this determines initial state from document - switch (this.props.CollectionView.props.Document._chromeStatus) { - case "disabled": - throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!"); - case "collapsed": - this.props.collapse?.(true); - break; - } - }); - - @undoBatch - viewChanged = (e: React.ChangeEvent) => { - //@ts-ignore - this.document._viewType = e.target.selectedOptions[0].value; - } - - commandChanged = (e: React.ChangeEvent) => { - //@ts-ignore - runInAction(() => this._currentKey = e.target.selectedOptions[0].value); - } - - @action - toggleViewSpecs = (e: React.SyntheticEvent) => { - this.document._facetWidth = this.document._facetWidth ? 0 : 200; - e.stopPropagation(); - } - - @action closeViewSpecs = () => { - this.document._facetWidth = 0; - } - - // @action - // openDatePicker = (e: React.PointerEvent) => { - // if (this._picker) { - // this._picker.alwaysShow = true; - // this._picker.show(); - // // TODO: calendar is offset when zoomed in/out - // // this._picker.calendar.style.position = "absolute"; - // // let transform = this.props.CollectionView.props.ScreenToLocalTransform(); - // // let x = parseInt(this._picker.calendar.style.left) / transform.Scale; - // // let y = parseInt(this._picker.calendar.style.top) / transform.Scale; - // // this._picker.calendar.style.left = x; - // // this._picker.calendar.style.top = y; - - // e.stopPropagation(); - // } - // } - - // runInAction(() => this._dateValue = e.target.value)} - // onPointerDown={this.openDatePicker} - // placeholder="Value" /> - // @action.bound - // applyFilter = (e: React.MouseEvent) => { - // const keyRestrictionScript = "(" + this._keyRestrictions.map(i => i[1]).filter(i => i.length > 0).join(" && ") + ")"; - // const yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0; - // const monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0; - // const weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0; - // const dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7; - // let dateRestrictionScript = ""; - // if (this._dateValue instanceof Date) { - // const lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset); - // const upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1); - // dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; - // } - // else { - // const createdDate = new Date(this._dateValue); - // if (!isNaN(createdDate.getTime())) { - // const lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset); - // const upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1); - // dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; - // } - // } - // const fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ? - // `${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` : - // `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` : - // "true"; - - // this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(fullScript, { doc: Doc.name }); - // } - - // datePickerRef = (node: HTMLInputElement) => { - // if (node) { - // try { - // this._picker = datepicker("#" + node.id, { - // disabler: (date: Date) => date > new Date(), - // onSelect: (instance: any, date: Date) => runInAction(() => {}), // this._dateValue = date), - // dateSelected: new Date() - // }); - // } catch (e) { - // console.log("date picker exception:" + e); - // } - // } - // } - - - @action - toggleCollapse = () => { - this.document._chromeStatus = this.document._chromeStatus === "enabled" ? "collapsed" : "enabled"; - if (this.props.collapse) { - this.props.collapse(this.props.CollectionView.props.Document._chromeStatus !== "enabled"); - } - } - - @computed get subChrome() { - const collapsed = this.document._chromeStatus !== "enabled"; - if (collapsed) return null; - switch (this.props.type) { - case CollectionViewType.Freeform: return (); - case CollectionViewType.Stacking: return (); - case CollectionViewType.Schema: return (); - case CollectionViewType.Tree: return (); - case CollectionViewType.Masonry: return (); - case CollectionViewType.Carousel3D: return (); - case CollectionViewType.Grid: return (); - default: return null; - } - } - - private get document() { - return this.props.CollectionView.props.Document; - } - - private dropDisposer?: DragManager.DragDropDisposer; - protected createDropTarget = (ele: HTMLDivElement) => { - this.dropDisposer?.(); - if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.document); - } - } - - @undoBatch - @action - protected drop(e: Event, de: DragManager.DropEvent): boolean { - const docDragData = de.complete.docDragData; - if (docDragData?.draggedDocuments.length) { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); - e.stopPropagation(); - } - return true; - } - - dragViewDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, (e, down, delta) => { - const vtype = this.props.CollectionView.collectionViewType; - const c = { - params: ["target"], title: vtype, - script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`, - immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]), - initialize: emptyFunction, - }; - DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), - { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY); - return true; - }, emptyFunction, emptyFunction); - } - dragCommandDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, (e, down, delta) => { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => - DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, - { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY)); - return true; - }, emptyFunction, () => { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate([])); - }); - } - - @computed get templateChrome() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - return
-
-
- -
- -
-
; - } - - @computed get viewModes() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - return
-
-
- -
- -
-
; - } - - render() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform()?.Scale); - return ( -
-
-
- - {this.viewModes} -
-
- -
-
- {this.templateChrome} -
- {this.subChrome} -
-
- ); - } -} - -@observer -export class CollectionFreeFormViewChrome extends React.Component { - - get Document() { return this.props.CollectionView.props.Document; } - @computed get dataField() { - return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)]; - } - @computed get childDocs() { - return DocListCast(this.dataField); - } - @undoBatch - @action - nextKeyframe = (): void => { - const currentFrame = NumCast(this.Document.currentFrame); - if (currentFrame === undefined) { - this.Document.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); - } - CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); - this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1); - this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame)); - } - @undoBatch - @action - prevKeyframe = (): void => { - const currentFrame = NumCast(this.Document.currentFrame); - if (currentFrame === undefined) { - this.Document.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); - } - CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); - this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1); - } - render() { - return this.Document.isAnnotationOverlay ? (null) : -
-
- -
-
this.Document.editing = !this.Document.editing)} > - {NumCast(this.Document.currentFrame)} -
-
- -
-
; - } -} - -@observer -export class CollectionStackingViewChrome extends React.Component { - @observable private _currentKey: string = ""; - @observable private suggestions: string[] = []; - - @computed private get descending() { return StrCast(this.props.CollectionView.props.Document._columnsSort) === "descending"; } - @computed get pivotField() { return StrCast(this.props.CollectionView.props.Document._pivotField); } - - getKeySuggestions = async (value: string): Promise => { - value = value.toLowerCase(); - const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); - if (docs instanceof Doc) { - return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); - } else { - const keys = new Set(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); - } - } - - @action - onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { - this._currentKey = newValue; - } - - getSuggestionValue = (suggestion: string) => suggestion; - - renderSuggestion = (suggestion: string) => { - return

{suggestion}

; - } - - onSuggestionFetch = async ({ value }: { value: string }) => { - const sugg = await this.getKeySuggestions(value); - runInAction(() => { - this.suggestions = sugg; - }); - } - - @action - onSuggestionClear = () => { - this.suggestions = []; - } - - @action - setValue = (value: string) => { - this.props.CollectionView.props.Document._pivotField = value; - return true; - } - - @action toggleSort = () => { - this.props.CollectionView.props.Document._columnsSort = - this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" : - this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending"; - } - @action resetValue = () => { this._currentKey = this.pivotField; }; - - render() { - return ( -
-
-
- GROUP BY: -
-
- -
-
- this.pivotField} - autosuggestProps={ - { - resetValue: this.resetValue, - value: this._currentKey, - onChange: this.onKeyChange, - autosuggestProps: { - inputProps: - { - value: this._currentKey, - onChange: this.onKeyChange - }, - getSuggestionValue: this.getSuggestionValue, - suggestions: this.suggestions, - alwaysRenderSuggestions: true, - renderSuggestion: this.renderSuggestion, - onSuggestionsFetchRequested: this.onSuggestionFetch, - onSuggestionsClearRequested: this.onSuggestionClear - } - }} - oneLine - SetValue={this.setValue} - contents={this.pivotField ? this.pivotField : "N/A"} - /> -
-
-
- ); - } -} - - -@observer -export class CollectionSchemaViewChrome extends React.Component { - // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; - - @undoBatch - togglePreview = () => { - const dividerWidth = 4; - const borderWidth = Number(COLLECTION_BORDER_WIDTH); - const panelWidth = this.props.CollectionView.props.PanelWidth(); - const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); - const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth; - this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0; - } - - @undoBatch - @action - toggleTextwrap = async () => { - const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []); - if (textwrappedRows.length) { - this.props.CollectionView.props.Document.textwrappedSchemaRows = new List([]); - } else { - const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); - const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]); - this.props.CollectionView.props.Document.textwrappedSchemaRows = new List(allRows); - } - } - - - render() { - const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); - const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; - - return ( -
-
-
Show Preview:
-
-
- {previewWidth !== 0 ? "on" : "off"} -
-
-
-
- ); - } -} - -@observer -export class CollectionTreeViewChrome extends React.Component { - - get sortAscending() { - return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; - } - set sortAscending(value) { - this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value; - } - @computed private get ascending() { - return Cast(this.sortAscending, "boolean", null); - } - - @action toggleSort = () => { - if (this.sortAscending) this.sortAscending = undefined; - else if (this.sortAscending === undefined) this.sortAscending = false; - else this.sortAscending = true; - } - - render() { - return ( -
- -
- ); - } -} - -// Enter scroll speed for 3D Carousel -@observer -export class Collection3DCarouselViewChrome extends React.Component { - @computed get scrollSpeed() { - return this.props.CollectionView.props.Document._autoScrollSpeed; - } - - @action - setValue = (value: string) => { - const numValue = Number(StrCast(value)); - if (numValue > 0) { - this.props.CollectionView.props.Document._autoScrollSpeed = numValue; - return true; - } - return false; - } - - render() { - return ( -
-
-
- AUTOSCROLL SPEED: -
-
- StrCast(this.scrollSpeed)} - oneLine - SetValue={this.setValue} - contents={this.scrollSpeed ? this.scrollSpeed : 1000} /> -
-
-
- ); - } -} - -/** - * Chrome for grid view. - */ -@observer -export class CollectionGridViewChrome extends React.Component { - - private clicked: boolean = false; - private entered: boolean = false; - private decrementLimitReached: boolean = false; - @observable private resize = false; - private resizeListenerDisposer: Opt; - - componentDidMount() { - - runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700); - - // listener to reduce text on chrome resize (panel resize) - this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => { - runInAction(() => this.resize = newValue < 700); - }); - } - - componentWillUnmount() { - this.resizeListenerDisposer?.(); - } - - get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); } - - /** - * Sets the value of `numCols` on the grid's Document to the value entered. - */ - @undoBatch - onNumColsEnter = (e: React.KeyboardEvent) => { - if (e.key === "Enter" || e.key === "Tab") { - if (e.currentTarget.valueAsNumber > 0) { - this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber; - } - - } - } - - /** - * Sets the value of `rowHeight` on the grid's Document to the value entered. - */ - // @undoBatch - // onRowHeightEnter = (e: React.KeyboardEvent) => { - // if (e.key === "Enter" || e.key === "Tab") { - // if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) { - // this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber; - // } - // } - // } - - /** - * Sets whether the grid is flexible or not on the grid's Document. - */ - @undoBatch - toggleFlex = () => { - this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true); - } - - /** - * Increments the value of numCols on button click - */ - onIncrementButtonClick = () => { - this.clicked = true; - this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--; - undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)(); - this.entered = false; - } - - /** - * Decrements the value of numCols on button click - */ - onDecrementButtonClick = () => { - this.clicked = true; - if (!this.decrementLimitReached) { - this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++; - undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)(); - } - this.entered = false; - } - - /** - * Increments the value of numCols on button hover - */ - incrementValue = () => { - this.entered = true; - if (!this.clicked && !this.decrementLimitReached) { - this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1; - } - this.decrementLimitReached = false; - this.clicked = false; - } - - /** - * Decrements the value of numCols on button hover - */ - decrementValue = () => { - this.entered = true; - if (!this.clicked) { - if (this.numCols !== 1) { - this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1; - } - else { - this.decrementLimitReached = true; - } - } - - this.clicked = false; - } - - /** - * Toggles the value of preventCollision - */ - toggleCollisions = () => { - this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision; - } - - /** - * Changes the value of the compactType - */ - changeCompactType = (e: React.ChangeEvent) => { - // need to change startCompaction so that this operation will be undoable. - this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value; - } - - render() { - return ( -
- - - - - ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> - - - - {/* - - - - ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> - */} - - - - - - - - - - - - - - -
- ); - } -} -- cgit v1.2.3-70-g09d2 From 3fdee81100954e66f54c73661cb11967993ff467 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 15:24:53 -0400 Subject: fixed tooltips to share a csss style. added tooltips for richtext. --- src/client/documents/Documents.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 10 ++--- src/client/views/DocumentDecorations.tsx | 15 +++---- src/client/views/MainView.scss | 4 ++ .../views/collections/CollectionLinearView.tsx | 20 +++++---- src/client/views/collections/CollectionMenu.tsx | 13 +++--- src/client/views/collections/CollectionView.tsx | 3 +- .../CollectionFreeFormLinkView.tsx | 12 +++--- src/client/views/linking/LinkEditor.tsx | 14 +++---- src/client/views/linking/LinkMenuItem.tsx | 19 +++------ src/client/views/nodes/DocumentLinksButton.tsx | 5 +-- src/client/views/nodes/DocumentView.tsx | 25 +++-------- .../formattedText/FormattedTextBoxComment.tsx | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 49 +++++++++++++--------- src/client/views/pdf/PDFViewer.tsx | 2 +- 15 files changed, 94 insertions(+), 103 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1fd533b62..b57f4c6c7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -915,7 +915,7 @@ export namespace DocUtils { const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); linkDoc.linkDisplay = true; - linkDoc.hideAnhors = true; + linkDoc.hidden = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 05538a28e..45f4c7393 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -118,7 +118,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const targetDoc = this.view0?.props.Document; const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined; const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none"; - return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}> + return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}>
(DocumentV })(); return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) :
{title}
}> + title={<>
{title}
}>
{ @@ -197,7 +197,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get pinButton() { const targetDoc = this.view0?.props.Document; const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}> + return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}>
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> @@ -209,7 +209,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get metadataButton() { const view0 = this.view0; - return !view0 ? (null) :
Show metadata panel
}> + return !view0 ? (null) :
Show metadata panel
}>
dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}> @@ -258,7 +258,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV Array.from(Object.values(Templates.TemplateList)).map(template => templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); return !view0 ? (null) : -
Tap: Customize layout. Drag: Create alias
}> +
Tap: Customize layout. Drag: Create alias
}>
this._aliasDown = true)} onClose={action(() => this._aliasDown = false)} content={!this._aliasDown ? (null) : v).map(v => v as DocumentView)} templates={templates} />}> diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2fd017f7b..376b1d46b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -81,6 +81,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || documentView.props.treeViewDoc || + !documentView.ContentDiv || Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) { return bounds; } @@ -88,7 +89,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); if (documentView.props.Document.type === DocumentType.LINK) { - const docuBox = documentView.ContentDiv!.getElementsByClassName("linkAnchorBox-cont"); + const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); if (docuBox.length) { const rect = docuBox[0].getBoundingClientRect(); sptX = rect.left; @@ -544,11 +545,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } const minimal = bounds.r - bounds.x < 100 ? true : false; const maximizeIcon = minimal ? ( -
Show context menu
} placement="top"> +
Show context menu
} placement="top">
) : ( -
Iconify
} placement="top"> +
Iconify
} placement="top">
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} @@ -572,7 +573,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
} : <> - {minimal ? (null) :
Show context menu
} placement="top">
+ {minimal ? (null) :
Show context menu
} placement="top">
}
@@ -611,11 +612,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> {maximizeIcon} {titleArea} {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : -
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top"> +
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top">
{"_"}
} -
Open Document In Tab
} placement="top">
+
Open Document In Tab
} placement="top">
{SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
e.preventDefault()}>
{seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) : -
tap to select containing document
} placement="top"> +
tap to select containing document
} placement="top">
e.preventDefault()}> diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 5b142ffda..e1ddbc533 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -1,6 +1,10 @@ @import "globalCssVariables"; @import "nodeModuleOverrides"; +.dash-tooltip { + font-size: 11px; + padding: 2px; +} .mainView-tabButtons { position: relative; diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 319cca70f..407524353 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -124,7 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { return
-
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> +
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> {menuOpener}
e.stopPropagation()} > - Creating link from: {DocumentLinksButton.StartLink.title} + Creating link from: {DocumentLinksButton.StartLink.title} + -
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : - "Turn on description pop-up"}
} placement="top"> - Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"} +
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : + "Turn on description pop-up"}
} placement="top"> + + Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
-
Exit link clicking mode
} placement="top"> - Clear +
Exit link clicking mode
} placement="top"> + + Clear +
{/* : , - - ]); + const button = ; + + return this.getElement(!this.SelectedCollection ? [button] : + [, + button]); } } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c1a6b5b0d..c1da23470 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -142,6 +142,7 @@ export class CollectionView extends Touchable d instanceof Doc); - first && (first.hidden = true); doc.displayTimecode = undefined; } doc.context = this.props.Document; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index dea936113..0933d525a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -29,13 +29,13 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { - if (SnappingManager.GetIsDragging()) return; + if (SnappingManager.GetIsDragging() || !this.props.A.ContentDiv || !this.props.B.ContentDiv) return; setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!this.props.LinkDocs.length || !this.props.LinkDocs[0].linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. - const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!); - const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!); + const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv); + const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv); const a = adiv.getBoundingClientRect(); const b = bdiv.getBoundingClientRect(); const abounds = adiv.parentElement!.getBoundingClientRect(); @@ -103,7 +103,7 @@ export class CollectionFreeFormLinkView extends React.Component { @observable description = StrCast(LinkManager.currentLink?.description); @observable openDropdown: boolean = false; - @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default"; @observable showInfo: boolean = false; @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; } @observable private buttonColor: string = "black"; @@ -364,8 +363,7 @@ export class LinkEditor extends React.Component { @action changeFollowBehavior = (follow: string) => { this.openDropdown = false; - this.followBehavior = follow; - this.props.linkDoc.follow = follow; + Doc.GetProto(this.props.linkDoc).followLinkLocation = follow; } @computed @@ -376,7 +374,7 @@ export class LinkEditor extends React.Component {
- {this.followBehavior} + {StrCast(this.props.linkDoc.followLinkLocation, "Default")} @@ -388,11 +386,11 @@ export class LinkEditor extends React.Component { Default
this.changeFollowBehavior("Always open in right tab")}> + onPointerDown={() => this.changeFollowBehavior("onRight")}> Always open in right tab
this.changeFollowBehavior("Always open in new tab")}> + onPointerDown={() => this.changeFollowBehavior("inTab")}> Always open in new tab
@@ -416,7 +414,7 @@ export class LinkEditor extends React.Component { return !destination ? (null) : (
-
Return to link menu
} placement="top"> +
Return to link menu
} placement="top"> */} -
Show more link information
} placement="top"> +
Show more link information
} placement="top">
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 6782f625b..0e847632b 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -16,7 +16,6 @@ import { DocumentView } from '../nodes/DocumentView'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import { Tooltip } from '@material-ui/core'; -import { RichTextField } from '../../../fields/RichTextField'; import { DocumentType } from '../../documents/DocumentTypes'; library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash); @@ -157,14 +156,8 @@ export class LinkMenuItem extends React.Component { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; - if (this.props.linkDoc.follow) { - if (this.props.linkDoc.follow === "Default") { - DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); - } else if (this.props.linkDoc.follow === "Always open in right tab") { - this.props.addDocTab(this.props.destinationDoc, "onRight"); - } else if (this.props.linkDoc.follow === "Always open in new tab") { - this.props.addDocTab(this.props.destinationDoc, "inTab"); - } + if (this.props.linkDoc.followLinkLocation && this.props.linkDoc.followLinkLocation !== "Default") { + this.props.addDocTab(this.props.destinationDoc, StrCast(this.props.linkDoc.followLinkLocation)); } else { DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } @@ -221,8 +214,6 @@ export class LinkMenuItem extends React.Component { StrCast(this.props.linkDoc.storedText).substr(0, 18) : this.props.linkDoc.storedText : undefined : undefined; - const showTitle = this.props.linkDoc.hidden ? "Show link" : "Hide link"; - return (
@@ -255,16 +246,16 @@ export class LinkMenuItem extends React.Component { {canExpand ?
this.toggleShowMore(e)}>
: <>} -
{showTitle}
}> +
{this.props.linkDoc.hidden ? "Show link" : "Hide link"}
}>
-
Edit Link
}> +
Edit Link
}>
-
Delete Link
}> +
Delete Link
}>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 01c068966..bbef48e44 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -134,7 +134,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { @@ -213,10 +212,10 @@ export class DocumentLinksButton extends React.Component
{title}
}> +
{title}
}> {linkButton}
: !!!DocumentLinksButton.EditLink ? -
{title}
}> +
{title}
}> {linkButton}
: linkButton; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a6771443a..c0a8b3a59 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -589,16 +589,12 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleLinkButtonBehavior = (): void => { + this.Document.ignoreClick = false; if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) { this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - this.Document.ignoreClick = false; this.Document.onClick = this.layoutDoc.onClick = undefined; } else { this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = false; this.Document.followLinkLocation = undefined; } @@ -606,14 +602,9 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowInPlace = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = true; this.Document.followLinkLocation = "inPlace"; } @@ -621,15 +612,10 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowOnRight = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; this.Document.followLinkZoom = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkLocation = "onRight"; } } @@ -643,7 +629,6 @@ export class DocumentView extends DocComponent(Docu } const makeLink = action((linkDoc: Doc) => { LinkManager.currentLink = linkDoc; - linkDoc.hidden = true; LinkCreatedBox.popupX = de.x; LinkCreatedBox.popupY = de.y - 33; diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index c98b5eac1..3687d5513 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -270,14 +270,14 @@ export class FormattedTextBoxComment {
-
Delete Link
} placement="top"> +
Delete Link
} placement="top">
this._deleteRef = r}>
-
Follow Link
} placement="top"> +
Follow Link
} placement="top">
this._followRef = r}> - - + {title}
} key={title} placement="bottom"> + +
); } @@ -388,7 +391,9 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + return {key}
} placement="bottom"> + + ; } createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element { @@ -412,7 +417,10 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + + return {key}
} placement="bottom"> + + ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -595,10 +603,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -667,11 +676,12 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -720,11 +730,12 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -763,7 +774,9 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; - const button = ; + const button = set hyperlink
} placement="bottom"> +
+ ; const dropdownContent =
@@ -774,9 +787,7 @@ export default class RichTextMenu extends AntimodeMenu {
; - return ( - - ); + return ; } async getTextLinkTargetTitle() { @@ -935,7 +946,7 @@ export default class RichTextMenu extends AntimodeMenu { {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
, - this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes", action((val: string) => this.activeListType = val)), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)), this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule), diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 4e5fdbfbb..56212a773 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -637,7 +637,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - if (this.active()) { + if (this.active(true)) { e.stopPropagation(); if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); -- cgit v1.2.3-70-g09d2 From 21284a84b6d9930b5ddfddaa600b6916613748c4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 16:13:50 -0400 Subject: adjusted startup location of unpinned CollectionMenu --- src/client/views/collections/CollectionMenu.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 0696b93db..cdd653823 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -27,6 +27,7 @@ export default class CollectionMenu extends AntimodeMenu { CollectionMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away this.Pinned = Cast(Doc.UserDoc()["menuCollections-pinned"], "boolean", true); + this.jumpTo(300, 300); } @action @@ -44,7 +45,7 @@ export default class CollectionMenu extends AntimodeMenu { return this.getElement(!this.SelectedCollection ? [button] : [, - button]); + button]); } } -- cgit v1.2.3-70-g09d2