diff options
Diffstat (limited to 'src/client/views/collections/CollectionMenu.tsx')
-rw-r--r-- | src/client/views/collections/CollectionMenu.tsx | 174 |
1 files changed, 99 insertions, 75 deletions
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 4f25f69ef..e53071584 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -1,10 +1,17 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable jsx-a11y/control-has-associated-label */ +/* eslint-disable react/no-unused-class-component-methods */ +/* eslint-disable react/sort-comp */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Toggle, ToggleType, Type } from 'browndash-components'; import { Lambda, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils'; +import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils'; +import { emptyFunction } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; @@ -12,14 +19,13 @@ import { ObjectField } from '../../../fields/ObjectField'; import { RichTextField } from '../../../fields/RichTextField'; import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; -import { DragManager, dropActionType } from '../../util/DragManager'; -import { SelectionManager } from '../../util/SelectionManager'; -import { SettingsManager } from '../../util/SettingsManager'; +import { DragManager } from '../../util/DragManager'; +import { dropActionType } from '../../util/DropActionTypes'; +import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; import { AntimodeMenu } from '../AntimodeMenu'; import { EditableView } from '../EditableView'; -import { MainView } from '../MainView'; import { DefaultStyleProvider } from '../StyleProvider'; import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView'; import './CollectionMenu.scss'; @@ -30,10 +36,12 @@ interface CollectionMenuProps { panelWidth: () => number; toggleTopBar: () => void; topBarHeight: () => number; + togglePropertiesFlyout: () => void; } @observer export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { + // eslint-disable-next-line no-use-before-define @observable static Instance: CollectionMenu; @observable SelectedCollection: DocumentView | undefined = undefined; @@ -44,13 +52,13 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { makeObservable(this); CollectionMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away - this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true); + this.Pinned = Cast(Doc.UserDoc().menuCollections_pinned, 'boolean', true); this.jumpTo(300, 300); } componentDidMount() { reaction( - () => SelectionManager.Views.lastElement(), + () => DocumentView.Selected().lastElement(), view => view && this.SetSelection(view) ); } @@ -61,25 +69,16 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { } @action - toggleMenuPin = (e: React.MouseEvent) => { - Doc.UserDoc()['menuCollections-pinned'] = this.Pinned = !this.Pinned; + toggleMenuPin = () => { + Doc.UserDoc().menuCollections_pinned = this.Pinned = !this.Pinned; if (!this.Pinned && this._left < 0) { this.jumpTo(300, 300); } }; - @action - toggleProperties = () => { - if (MainView.Instance.propertiesWidth() > 0) { - SettingsManager.Instance.propertiesWidth = 0; - } else { - SettingsManager.Instance.propertiesWidth = 300; - } - }; - buttonBarXf = () => { if (!this._docBtnRef.current) return Transform.Identity(); - const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current); + const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._docBtnRef.current); return new Transform(-translateX, -translateY, 1 / scale); }; @@ -119,15 +118,15 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { render() { const headerIcon = this.props.topBarHeight() > 0 ? 'angle-double-up' : 'angle-double-down'; const headerTitle = this.props.topBarHeight() > 0 ? 'Close Header Bar' : 'Open Header Bar'; - const propIcon = SettingsManager.Instance.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left'; - const propTitle = SettingsManager.Instance.propertiesWidth > 0 ? 'Close Properties' : 'Open Properties'; + const propIcon = SnappingManager.PropertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left'; + const propTitle = SnappingManager.PropertiesWidth > 0 ? 'Close Properties' : 'Open Properties'; const hardCodedButtons = ( - <div className={`hardCodedButtons`}> + <div className="hardCodedButtons"> <Toggle toggleType={ToggleType.BUTTON} type={Type.PRIM} - color={SettingsManager.userColor} + color={SnappingManager.userColor} onClick={this.props.toggleTopBar} toggleStatus={this.props.topBarHeight() > 0} icon={<FontAwesomeIcon icon={headerIcon} size="lg" />} @@ -136,21 +135,21 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { <Toggle toggleType={ToggleType.BUTTON} type={Type.PRIM} - color={SettingsManager.userColor} - onClick={this.toggleProperties} - toggleStatus={SettingsManager.Instance.propertiesWidth > 0} + color={SnappingManager.userColor} + onClick={this._props.togglePropertiesFlyout} + toggleStatus={SnappingManager.PropertiesWidth > 0} icon={<FontAwesomeIcon icon={propIcon} size="lg" />} tooltip={propTitle} /> </div> ); - //dash col linear view buttons + // dash col linear view buttons const contMenuButtons = ( <div className="collectionMenu-container" style={{ - background: SettingsManager.userBackgroundColor, + background: SnappingManager.userBackgroundColor, // borderColor: SettingsManager.userColor }}> {this.contMenuButtons} @@ -163,7 +162,9 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { } interface CollectionViewMenuProps { + // eslint-disable-next-line react/no-unused-prop-types type: CollectionViewType; + // eslint-disable-next-line react/no-unused-prop-types fieldKey: string; docView: DocumentView; } @@ -172,7 +173,7 @@ const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @observer export class CollectionViewBaseChrome extends React.Component<CollectionViewMenuProps> { - //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) + // (!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) get document() { return this.props.docView?.Document; @@ -206,14 +207,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu 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]))), + immediate: undoBatch((source: Doc[]) => { + source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0])); + }), initialize: emptyFunction, }; _contentCommand = { params: ['target', 'source'], title: 'set content', script: 'getProto(this.target).data = copyField(this.source);', - immediate: undoBatch((source: Doc[]) => (this.target[DocData].data = new List<Doc>(source))), + immediate: undoBatch((source: Doc[]) => { + this.target[DocData].data = new List<Doc>(source); + }), initialize: emptyFunction, }; _onClickCommand = { @@ -224,14 +229,14 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu getProto(this.proxy[0]).target = this.target.target; getProto(this.proxy[0]).source = copyField(this.target.source); }}`, - immediate: undoBatch((source: Doc[]) => {}), + immediate: undoBatch(() => {}), initialize: emptyFunction, }; _viewCommand = { params: ['target'], title: 'bookmark view', - script: "this.target._freeform_panX = self['target-freeform_panX']; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);", - immediate: undoBatch((source: Doc[]) => { + script: "this.target._freeform_panX = this.target_freeform_panX; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);", + immediate: undoBatch(() => { this.target._freeform_panX = 0; this.target._freeform_panY = 0; this.target._freeform_scale = 1; @@ -248,30 +253,34 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu params: ['target'], title: 'fit content', script: 'this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;', - immediate: undoBatch((source: Doc[]) => (this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox)), + immediate: undoBatch(() => { + this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox; + }), initialize: emptyFunction, }; _fitContentCommand = { params: ['target'], title: 'toggle clusters', script: 'this.target._freeform_useClusters = !this.target._freeform_useClusters;', - immediate: undoBatch((source: Doc[]) => (this.target._freeform_useClusters = !this.target._freeform_useClusters)), + immediate: undoBatch(() => { + this.target._freeform_useClusters = !this.target._freeform_useClusters; + }), initialize: emptyFunction, }; _saveFilterCommand = { params: ['target'], title: 'save filter', - script: `this.target._childFilters = compareLists(this['target-childFilters'],this.target._childFilters) ? undefined : copyField(this['target-childFilters']); - this.target._searchFilterDocs = compareLists(this['target-searchFilterDocs'],this.target._searchFilterDocs) ? undefined: copyField(this['target-searchFilterDocs']);`, - immediate: undoBatch((source: Doc[]) => { + script: `this.target._childFilters = compareLists(this.target_childFilters,this.target._childFilters) ? undefined : copyField(this.target_childFilters); + this.target._searchFilterDocs = compareLists(this.target_searchFilterDocs,this.target._searchFilterDocs) ? undefined: copyField(this.target_searchFilterDocs);`, + immediate: undoBatch(() => { this.target._childFilters = undefined; this.target._searchFilterDocs = undefined; }), initialize: (button: Doc) => { const activeDash = Doc.ActiveDashboard; if (activeDash) { - button['target-childFilters'] = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined; - button['target-searchFilterDocs'] = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined; + button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined; + button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined; } }, }; @@ -299,8 +308,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu } private get _buttonizableCommands() { switch (this.props.type) { - default: - return this._doc_commands; case CollectionViewType.Freeform: return this._freeform_commands; case CollectionViewType.Tree: @@ -319,6 +326,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu return this._freeform_commands; case CollectionViewType.Carousel3D: return this._freeform_commands; + default: + return this._doc_commands; } } private _commandRef = React.createRef<HTMLInputElement>(); @@ -332,13 +341,13 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu @undoBatch viewChanged = (e: React.ChangeEvent) => { const target = this.document !== Doc.MyLeftSidebarPanel ? this.document : DocCast(this.document.proto); - //@ts-ignore - target._type_collection = e.target.selectedOptions[0].value; + target._type_collection = (e.target as any).selectedOptions[0].value; }; commandChanged = (e: React.ChangeEvent) => { - //@ts-ignore - runInAction(() => (this._currentKey = e.target.selectedOptions[0].value)); + runInAction(() => { + this._currentKey = (e.target as any).selectedOptions[0].value; + }); }; @action closeViewSpecs = () => { @@ -356,7 +365,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu @undoBatch @action protected drop(e: Event, de: DragManager.DropEvent): boolean { - const docDragData = de.complete.docDragData; + const { docDragData } = de.complete; if (docDragData?.draggedDocuments.length) { this._buttonizableCommands?.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); e.stopPropagation(); @@ -369,16 +378,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu setupMoveUpEvents( this, e, - (e, down, delta) => { + moveEv => { const vtype = this.props.type; const c = { params: ['target'], title: vtype, script: `this.target._type_collection = '${StrCast(this.props.type)}'`, - immediate: (source: Doc[]) => (this.document._type_collection = Doc.getDocTemplate(source?.[0])), + immediate: (source: Doc[]) => { + this.document._type_collection = Doc.getDocTemplate(source?.[0]); + }, initialize: emptyFunction, }; - DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), { target: this.document }, c.params, c.initialize, e.clientX, e.clientY); + DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), { target: this.document }, c.params, c.initialize, moveEv.clientX, moveEv.clientY); return true; }, emptyFunction, @@ -389,8 +400,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu 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.document }, c.params, c.initialize, e.clientX, e.clientY)); + moveEv => { + this._buttonizableCommands + ?.filter(c => c.title === this._currentKey) + .map(c => DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, { target: this.document }, c.params, c.initialize, moveEv.clientX, moveEv.clientY)); return true; }, emptyFunction, @@ -405,11 +418,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu <div className="collectionViewBaseChrome-template" ref={this.createDropTarget}> <Tooltip title={<div className="dash-tooltip">drop document to apply or drag to create button</div>} placement="bottom"> <div className="commandEntry-outerDiv" ref={this._commandRef} onPointerDown={this.dragCommandDown}> - <button className={'antimodeMenu-button'}> + <button type="button" className="antimodeMenu-button"> <FontAwesomeIcon icon="bullseye" size="lg" /> </button> <select className="collectionViewBaseChrome-cmdPicker" onPointerDown={stopPropagation} onChange={this.commandChanged} value={this._currentKey}> - <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={'empty'} value={''} /> + <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key="empty" value="" /> {this._buttonizableCommands?.map(cmd => ( <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}> {cmd.title} @@ -456,23 +469,19 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi if (docs instanceof Doc) { const keys = Object.keys(docs).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0].toUpperCase() === key[0] && key[0] !== '_')); return keys.filter(key => key.toLowerCase().indexOf(val) > -1); - } else { - const keys = new Set<string>(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - const noviceKeys = Array.from(keys).filter( - key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_') - ); - return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1); } + const keys = new Set<string>(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + const noviceKeys = Array.from(keys).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_')); + return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1); } if (docs instanceof Doc) { return Object.keys(docs).filter(key => key.toLowerCase().indexOf(val) > -1); - } else { - const keys = new Set<string>(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1); } + const keys = new Set<string>(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1); }; @action @@ -482,9 +491,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi getSuggestionValue = (suggestion: string) => suggestion; - renderSuggestion = (suggestion: string) => { - return <p>{suggestion}</p>; - }; + renderSuggestion = (suggestion: string) => <p>{suggestion}</p>; onSuggestionFetch = async ({ value }: { value: string }) => { const sugg = await this.getKeySuggestions(value); @@ -572,12 +579,16 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu } componentDidMount() { - runInAction(() => (this.resize = this.props.docView.props.PanelWidth() < 700)); + runInAction(() => { + this.resize = this.props.docView.props.PanelWidth() < 700; + }); // listener to reduce text on chrome resize (panel resize) this.resizeListenerDisposer = reaction( () => this.panelWidth, - newValue => (this.resize = newValue < 700) + newValue => { + this.resize = newValue < 700; + } ); } @@ -593,7 +604,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu * Sets the value of `numCols` on the grid's Document to the value entered. */ onNumColsChange = (e: React.ChangeEvent<HTMLInputElement>) => { - if (e.currentTarget.valueAsNumber > 0) undoBatch(() => (this.document.gridNumCols = e.currentTarget.valueAsNumber))(); + if (e.currentTarget.valueAsNumber > 0) + undoBatch(() => { + this.document.gridNumCols = e.currentTarget.valueAsNumber; + })(); }; /** @@ -622,7 +636,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu onIncrementButtonClick = () => { this.clicked = true; this.entered && (this.document.gridNumCols as number)--; - undoBatch(() => (this.document.gridNumCols = this.numCols + 1))(); + undoBatch(() => { + this.document.gridNumCols = this.numCols + 1; + })(); this.entered = false; }; @@ -633,7 +649,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu this.clicked = true; if (this.numCols > 1 && !this.decrementLimitReached) { this.entered && (this.document.gridNumCols as number)++; - undoBatch(() => (this.document.gridNumCols = this.numCols - 1))(); + undoBatch(() => { + this.document.gridNumCols = this.numCols - 1; + })(); if (this.numCols === 1) this.decrementLimitReached = true; } this.entered = false; @@ -726,7 +744,13 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu <label className="flexLabel">{this.resize ? 'Flex' : 'Flexible'}</label> </span> - <button onClick={() => (this.document.gridResetLayout = true)}>{!this.resize ? 'Reset' : <FontAwesomeIcon icon="redo-alt" size="1x" />}</button> + <button + type="button" + onClick={() => { + this.document.gridResetLayout = true; + }}> + {!this.resize ? 'Reset' : <FontAwesomeIcon icon="redo-alt" size="1x" />} + </button> </div> ); } |