diff options
Diffstat (limited to 'src/client/views/collections')
24 files changed, 269 insertions, 232 deletions
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx index 578ce77a5..43e5a68eb 100644 --- a/src/client/views/collections/CollectionCalendarView.tsx +++ b/src/client/views/collections/CollectionCalendarView.tsx @@ -25,16 +25,13 @@ export class CollectionCalendarView extends CollectionSubView() { removeCalendar = () => {}; - addCalendar = (doc: Doc | Doc[], annotationKey?: string | undefined): boolean => { + addCalendar = (/* doc: Doc | Doc[], annotationKey?: string | undefined */): boolean => // bring up calendar modal with option to create a calendar - return true; - }; + true; _stackRef = React.createRef<CollectionStackingView>(); - panelHeight = () => { - return this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title - }; + panelHeight = () => this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title // most recent calendar should come first sortByMostRecentDate = (calendarA: Doc, calendarB: Doc) => { @@ -46,18 +43,18 @@ export class CollectionCalendarView extends CollectionSubView() { if (aFromDate > bFromDate) { return -1; // a comes first - } else if (aFromDate < bFromDate) { + } + if (aFromDate < bFromDate) { + return 1; // b comes first + } + // start dates are the same + if (aToDate > bToDate) { + return -1; // a comes first + } + if (aToDate < bToDate) { return 1; // b comes first - } else { - // start dates are the same - if (aToDate > bToDate) { - return -1; // a comes first - } else if (aToDate < bToDate) { - return 1; // b comes first - } else { - return 0; // same start and end dates - } } + return 0; // same start and end dates }; screenToLocalTransform = () => @@ -74,6 +71,7 @@ export class CollectionCalendarView extends CollectionSubView() { return ( <div className="collectionCalendarView"> <CollectionStackingView + // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} setContentViewBox={emptyFunction} ref={this._stackRef} diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 6dda6e545..51352d3e2 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -1,3 +1,6 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable react/jsx-props-no-spreading */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; @@ -107,10 +110,10 @@ export class CollectionCarouselView extends CollectionSubView() { return ( <> <div key="back" className="carouselView-back" onClick={this.goback}> - <FontAwesomeIcon icon={'chevron-left'} size={'2x'} /> + <FontAwesomeIcon icon="chevron-left" size="2x" /> </div> <div key="fwd" className="carouselView-fwd" onClick={this.advance}> - <FontAwesomeIcon icon={'chevron-right'} size={'2x'} /> + <FontAwesomeIcon icon="chevron-right" size="2x" /> </div> </> ); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9a1781b93..fefaf6591 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -120,7 +120,7 @@ export class CollectionDockingView extends CollectionSubView() { @undoBatch public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean { if (CollectionDockingView.Instance) { - const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document)); + const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tabView => (panelName ? tabView.contentItem.config.props.panelName === panelName : tabView.DashDoc === document)); if (tab) { const j = tab.header.parent.contentItems.indexOf(tab.contentItem); if (j !== -1) { @@ -147,7 +147,7 @@ export class CollectionDockingView extends CollectionSubView() { stack.contentItems[activeContentItemIndex].remove(); return instance.layoutChanged(); } - const tab = Array.from(instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName); + const tab = Array.from(instance.tabMap.keys()).find(tabView => tabView.contentItem.config.props.panelName === panelName); if (tab) { const j = tab.header.parent.contentItems.indexOf(tab.contentItem); if (newConfig.props.documentId !== tab.header.parent.contentItems[j].config.props.documentId) { @@ -172,7 +172,7 @@ export class CollectionDockingView extends CollectionSubView() { public static AddSplit(document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) { if (document?._type_collection === CollectionViewType.Docking && !keyValue) return DashboardView.openDashboard(document); if (!CollectionDockingView.Instance) return false; - const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === document && !tab.contentItem.config.props.keyValue && !keyValue); + const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tabView => tabView.DashDoc === document && !tabView.contentItem.config.props.keyValue && !keyValue); if (tab) { tab.header.parent.setActiveContentItem(tab.contentItem); return true; diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index e00fdb50c..95aecc7d0 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -14,7 +15,7 @@ import { DocUtils, Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { undoBatch } from '../../util/UndoManager'; +import { undoBatch, undoable } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; @@ -113,13 +114,15 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV }; @action - headingChanged = (value: string, shiftDown?: boolean) => { + headingChanged = (value: string /* , shiftDown?: boolean */) => { const castedValue = this.getValue(value); if (castedValue) { if (this._props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) { return false; } - this._props.docList.forEach(d => (d[this._props.pivotField] = castedValue)); + this._props.docList.forEach(d => { + d[this._props.pivotField] = castedValue; + }); if (this._props.headingObject) { this._props.headingObject.setHeading(castedValue.toString()); this._heading = this._props.headingObject.heading; @@ -129,10 +132,14 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV return false; }; - @action pointerEntered = () => (this._hover = true); - @action pointerLeave = () => (this._hover = false); - @undoBatch - addTextNote = (char: string) => this.addNewTextDoc('-typed text-', false, true); + @action pointerEntered = () => { + this._hover = true; + }; + @action pointerLeave = () => { + this._hover = false; + }; + + addTextNote = undoable(() => this.addNewTextDoc('-typed text-', false, true), 'add text note'); // addNewTextDoc is called when a user starts typing in a column to create a new node @action @@ -195,6 +202,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV } return this._props.addDocument?.(created); } + return undefined; }, icon: 'compress-arrows-alt', }) @@ -214,6 +222,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV } return this._props.addDocument?.(created) || false; } + return undefined; }, icon: 'compress-arrows-alt', }) @@ -238,7 +247,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV const key = this._props.pivotField; const heading = this._heading; const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin; - const evContents = heading ? heading : '25'; + const evContents = heading || '25'; const headingView = this._props.headingObject ? ( <div key={heading} @@ -252,17 +261,16 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV className="collectionNoteTakingView-sectionHeader-subCont" title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''} style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}> - <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} /> + <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine /> </div> {(this._props.colHeaderData?.length ?? 0) > 1 && ( - <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}> + <button type="button" className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}> <FontAwesomeIcon icon="trash" size="lg" /> </button> )} </div> ) : null; const templatecols = this.columnWidth; - const type = this._props.Document.type; return ( <> {headingView} @@ -270,7 +278,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV <div className="collectionNoteTakingView-columnStack"> <div key={`${heading}-stack`} - className={`collectionNoteTakingView-Nodes`} + className="collectionNoteTakingView-Nodes" style={{ padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`, gridGap: this._props.gridGap, @@ -282,10 +290,13 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV {!this._props.chromeHidden ? ( <div className="collectionNoteTakingView-DocumentButtons" style={{ display: this._props.isContentActive() ? 'flex' : 'none', marginBottom: 10 }}> <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}> - <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents={'+ Node'} menuCallback={this.menuCallback} /> + <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents="+ Node" menuCallback={this.menuCallback} /> </div> <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}> - <EditableView {...this._props.editableViewProps()} /> + { + // eslint-disable-next-line react/jsx-props-no-spreading + <EditableView {...this._props.editableViewProps()} /> + } </div> </div> ) : null} diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx index 67070b24d..ddd4b8137 100644 --- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx @@ -28,7 +28,7 @@ export class CollectionNoteTakingViewDivider extends ObservableReactComponent<Di setupMoveUpEvents( this, e, - (e, down, delta) => { + (moveEv, down, delta) => { if (!batch) batch = UndoManager.StartBatch('resizing'); this._props.setColumnStartXCoords(delta[0], this._props.index); return false; diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 35f330b44..cb463077c 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -157,7 +157,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< const key = this._props.pivotField; const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true }); key && (newDoc[key] = this.getValue(this._props.heading)); - const maxHeading = this._props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0); + const maxHeading = this._props.docList.reduce((prevHeading, doc) => (NumCast(doc.heading) > prevHeading ? NumCast(doc.heading) : prevHeading), 0); const heading = maxHeading === 0 || this._props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3; newDoc.heading = heading; FormattedTextBox.SetSelectOnLoad(newDoc); @@ -220,9 +220,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< renderMenu = () => ( <div className="collectionStackingView-optionPicker"> <div className="optionOptions"> - <div className={'optionPicker' + (true ? ' active' : '')} onClick={action(() => {})}> - Add options here - </div> + <div className="optionPicker active">Add options here</div> </div> </div> ); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 538a6fd5e..bf81bdc7f 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -177,24 +177,24 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, -this._headerHeight); @action - remove = (doc: Doc | Doc[]): boolean => { - const docs = doc instanceof Doc ? [doc] : doc; + remove = (docIn: Doc | Doc[]): boolean => { + const docs = docIn instanceof Doc ? [docIn] : docIn; const targetDataDoc = this.Document[DocData]; const value = DocListCast(targetDataDoc[this._props.fieldKey]); const result = value.filter(v => !docs.includes(v)); - if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views.some(dv => Doc.AreProtosEqual(dv.Document, doc)))) SelectionManager.DeselectAll(); + if (docs.some(doc => SelectionManager.Views.some(dv => Doc.AreProtosEqual(dv.Document, doc)))) SelectionManager.DeselectAll(); if (result.length !== value.length) { - if (doc instanceof Doc) { - const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(doc); + if (docIn instanceof Doc) { + const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(docIn); const prev = ind && DocListCast(targetDataDoc[this._props.fieldKey])[ind - 1]; - this._props.removeDocument?.(doc); + this._props.removeDocument?.(docIn); if (ind > 0 && prev) { FormattedTextBox.SetSelectOnLoad(prev); DocumentManager.Instance.getDocumentView(prev, this.DocumentView?.())?.select(false); } return true; } - return this._props.removeDocument?.(doc) ?? false; + return this._props.removeDocument?.(docIn) ?? false; } return false; }; @@ -299,7 +299,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree @computed get treeViewElements() { TraceMobx(); const dragAction = StrCast(this.Document.childDragAction) as any as dropActionType; - const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); + const treeAddDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this._props.moveDocument?.(d, target, addDoc) || false; if (this._renderCount < this.treeChildren.length) setTimeout( @@ -315,7 +315,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree this._props.TemplateDataDocument, undefined, undefined, - addDoc, + treeAddDoc, this.remove, moveDoc, dragAction, @@ -419,8 +419,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree addAnnotationDocument = (doc: Doc | Doc[]) => this.addDocument(doc, `${this._props.fieldKey}_annotations`) || false; remAnnotationDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, `${this._props.fieldKey}_annotations`) || false; - moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => - this.moveDocument(doc, targetCollection, addDocument, `${this._props.fieldKey}_annotations`) || false; + moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => this.moveDocument(doc, targetCollection, addDocument) || false; @observable _headerHeight = 0; @computed get content() { diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx index 4523a4f1e..7dc08389b 100644 --- a/src/client/views/collections/KeyRestrictionRow.tsx +++ b/src/client/views/collections/KeyRestrictionRow.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/button-has-type */ import { observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -35,11 +36,36 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr return ( <div className="collectionViewBaseChrome-viewSpecsMenu-row"> - <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft" value={this._key} onChange={e => runInAction(() => (this._key = e.target.value))} placeholder="KEY" /> - <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle" style={{ background: this._contains ? '#77dd77' : '#ff6961' }} onClick={() => runInAction(() => (this._contains = !this._contains))}> + <input + className="collectionViewBaseChrome-viewSpecsMenu-rowLeft" + value={this._key} + onChange={e => + runInAction(() => { + this._key = e.target.value; + }) + } + placeholder="KEY" + /> + <button + className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle" + style={{ background: this._contains ? '#77dd77' : '#ff6961' }} + onClick={() => + runInAction(() => { + this._contains = !this._contains; + }) + }> {this._contains ? 'CONTAINS' : 'DOES NOT CONTAIN'} </button> - <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight" value={this._value} onChange={e => runInAction(() => (this._value = e.target.value))} placeholder="VALUE" /> + <input + className="collectionViewBaseChrome-viewSpecsMenu-rowRight" + value={this._value} + onChange={e => + runInAction(() => { + this._value = e.target.value; + }) + } + placeholder="VALUE" + /> </div> ); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx index 0acc99360..d2ce17f99 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx @@ -10,6 +10,7 @@ export interface CollectionFreeFormViewBackgroundGridProps { PanelWidth: () => number; PanelHeight: () => number; color: () => string; + // eslint-disable-next-line react/require-default-props isAnnotationOverlay?: boolean; nativeDimScaling: () => number; zoomScaling: () => number; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx index 73dd7fea3..fc39cafaa 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx @@ -5,13 +5,13 @@ import * as React from 'react'; import { SettingsManager } from '../../../util/SettingsManager'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormView.scss'; -import { Doc } from '../../../../fields/Doc'; /** * An Fsa Arc. The first array element is a test condition function that will be observed. * The second array element is a function that will be invoked when the first test function * returns a truthy value */ +// eslint-disable-next-line no-use-before-define export type infoArc = [() => any, (res?: any) => infoState]; export const StateMessage = Symbol('StateMessage'); @@ -46,6 +46,7 @@ export function InfoState( gif?: string, entryFunc?: () => any ) { + // eslint-disable-next-line new-cap return new infoState(msg, arcs, gif, entryFunc); } @@ -73,14 +74,15 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec } clearState = () => this._disposers.map(disposer => disposer()); - initState = () => (this._disposers = - this.Arcs.map(arc => ({ test: arc[0], act: arc[1] })).map( - arc => reaction( - arc.test, - res => res && this._props.next(arc.act(res)), - { fireImmediately: true } - ) - )); // prettier-ignore + initState = () => { + this._disposers = this.Arcs + .map(arc => ({ test: arc[0], act: arc[1] })) + .map(arc => reaction( + arc.test, + res => res && this._props.next(arc.act(res)), + { fireImmediately: true } + ) + )}; // prettier-ignore componentDidMount() { this.initState(); @@ -97,10 +99,15 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec render() { const gif = this.State?.[StateMessageGIF]; return ( - <div className={'collectionFreeform-infoUI'}> + <div className="collectionFreeform-infoUI"> <p className="collectionFreeform-infoUI-msg"> {this.State?.[StateMessage]} - <button className={'collectionFreeform-' + (!gif ? 'hidden' : 'infoUI-button')} onClick={action(() => (this._expanded = !this._expanded))}> + <button + type="button" + className={'collectionFreeform-' + (!gif ? 'hidden' : 'infoUI-button')} + onClick={action(() => { + this._expanded = !this._expanded; + })}> {this._expanded ? 'Less...' : 'More...'} </button> </p> @@ -108,7 +115,7 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec <img src={`/assets/${gif}`} alt="state message gif" /> </div> <div className="collectionFreeform-infoUI-close"> - <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(e => this.props.close())} /> + <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(() => this.props.close())} /> </div> </div> ); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 3970c6807..a4496a417 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -147,10 +147,10 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do } const val = Field.toString(pair.layout[pivotFieldKey] as FieldType); if (listValue) { - listValue.forEach((val, i) => { - !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] }); - pivotColumnGroups.get(val)!.docs.push(pair.layout); - pivotColumnGroups.get(val)!.replicas.push(i.toString()); + listValue.forEach((lval, i) => { + !pivotColumnGroups.get(lval) && pivotColumnGroups.set(lval, { docs: [], filters: [lval], replicas: [] }); + pivotColumnGroups.get(lval)!.docs.push(pair.layout); + pivotColumnGroups.get(lval)!.replicas.push(i.toString()); }); } else if (val) { !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index 35394016d..f64c6715b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -4,9 +4,7 @@ import * as mobxUtils from 'mobx-utils'; import * as React from 'react'; import * as uuid from 'uuid'; import CursorField from '../../../../fields/CursorField'; -import { Doc, FieldResult } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; -import { List } from '../../../../fields/List'; import { listSpec } from '../../../../fields/Schema'; import { Cast } from '../../../../fields/Types'; import { CollectionViewProps } from '../CollectionSubView'; @@ -16,14 +14,12 @@ import './CollectionFreeFormView.scss'; export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> { @computed protected get cursors(): CursorField[] { const { Document } = this.props; - - let cursors: FieldResult<List<CursorField>>; - const id = Doc.UserDoc()[Id]; - if (!id || !(cursors = Cast(Document.cursors, listSpec(CursorField)))) { + const cursors = Cast(Document.cursors, listSpec(CursorField)); + if (!cursors) { return []; } const now = mobxUtils.now(); - return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== id && now - metadata.timestamp < 1000); + return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== Document[Id] && now - metadata.timestamp < 1000); } @computed get renderedCursors() { @@ -33,46 +29,44 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV metadata, position: { x, y }, }, - }) => { - return ( - <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}> - <canvas - className="collectionFreeFormRemoteCursors-canvas" - ref={el => { - if (el) { - const ctx = el.getContext('2d'); - if (ctx) { - ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22'; - ctx.fillRect(0, 0, 20, 20); + }) => ( + <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}> + <canvas + className="collectionFreeFormRemoteCursors-canvas" + ref={el => { + if (el) { + const ctx = el.getContext('2d'); + if (ctx) { + ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22'; + ctx.fillRect(0, 0, 20, 20); - ctx.fillStyle = 'black'; - ctx.lineWidth = 0.5; + ctx.fillStyle = 'black'; + ctx.lineWidth = 0.5; - ctx.beginPath(); + ctx.beginPath(); - ctx.moveTo(10, 0); - ctx.lineTo(10, 8); + ctx.moveTo(10, 0); + ctx.lineTo(10, 8); - ctx.moveTo(10, 20); - ctx.lineTo(10, 12); + ctx.moveTo(10, 20); + ctx.lineTo(10, 12); - ctx.moveTo(0, 10); - ctx.lineTo(8, 10); + ctx.moveTo(0, 10); + ctx.lineTo(8, 10); - ctx.moveTo(20, 10); - ctx.lineTo(12, 10); + ctx.moveTo(20, 10); + ctx.lineTo(12, 10); - ctx.stroke(); - } + ctx.stroke(); } - }} - width={20} - height={20} - /> - <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p> - </div> - ); - } + } + }} + width={20} + height={20} + /> + <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p> + </div> + ) ); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index 79cc534dc..adac5a102 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -9,6 +9,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; @observer export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> { + // eslint-disable-next-line no-use-before-define static Instance: MarqueeOptionsMenu; public createCollection: (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => void = unimplementedFunction; @@ -29,14 +30,13 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> { } render() { - const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ width: 19 }} />; const buttons = ( <> - <IconButton tooltip={'Create a Collection'} onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} /> - <IconButton tooltip={'Create a Grouping'} onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} /> - <IconButton tooltip={'Summarize Documents'} onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} /> - <IconButton tooltip={'Delete Documents'} onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} /> - <IconButton tooltip={'Pin selected region'} onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} /> + <IconButton tooltip="Create a Collection" onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} /> + <IconButton tooltip="Create a Grouping" onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} /> + <IconButton tooltip="Summarize Documents" onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} /> + <IconButton tooltip="Delete Documents" onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} /> + <IconButton tooltip="Pin selected region" onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} /> </> ); return this.getElement(buttons); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index ab6788e6f..1634daaf7 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -17,6 +17,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionGridView.scss'; import Grid, { Layout } from './Grid'; + @observer export class CollectionGridView extends CollectionSubView() { private _containerRef: React.RefObject<HTMLDivElement> = React.createRef(); @@ -77,15 +78,13 @@ export class CollectionGridView extends CollectionSubView() { pairs.forEach((pair, i) => { const existing = oldLayouts.find(l => l.i === pair.layout[Id]); if (existing) newLayouts.push(existing); - else { - if (Object.keys(this.dropLocation).length) { - // external drop - this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid)); - this.dropLocation = {}; - } else { - // internal drop - this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid)); - } + else if (Object.keys(this.dropLocation).length) { + // external drop + this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid)); + this.dropLocation = {}; + } else { + // internal drop + this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid)); } }); pairs?.length && this.setLayoutList(newLayouts); @@ -140,9 +139,7 @@ export class CollectionGridView extends CollectionSubView() { /** * Creates a layout object for a grid item */ - makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => { - return { i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static }; - }; + makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => ({ i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static }); /** * Adds a layout to the list of layouts. @@ -190,6 +187,7 @@ export class CollectionGridView extends CollectionSubView() { getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { return ( <DocumentView + // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} NativeWidth={returnZero} NativeHeight={returnZero} @@ -219,7 +217,7 @@ export class CollectionGridView extends CollectionSubView() { if (this.flexGrid) { const savedLayouts = this.savedLayoutList; this.childLayoutPairs.forEach(({ layout: doc }) => { - const gridLayout = savedLayouts.find(gridLayout => gridLayout.i === doc[Id]); + const gridLayout = savedLayouts.find(layout => layout.i === doc[Id]); if (gridLayout) Object.assign(gridLayout, layoutArray.find(layout => layout.i === doc[Id]) || gridLayout); }); @@ -318,7 +316,9 @@ export class CollectionGridView extends CollectionSubView() { e, returnFalse, action(() => { - undoBatch(() => (this.Document.gridRowHeight = this._rowHeight))(); + undoBatch(() => { + this.Document.gridRowHeight = this._rowHeight; + })(); this._rowHeight = undefined; }), emptyFunction, @@ -332,8 +332,20 @@ export class CollectionGridView extends CollectionSubView() { */ onContextMenu = () => { const displayOptionsMenu: ContextMenuProps[] = []; - displayOptionsMenu.push({ description: 'Toggle Content Display Style', event: () => (this.Document.display = this.Document.display ? undefined : 'contents'), icon: 'copy' }); - displayOptionsMenu.push({ description: 'Toggle Vertical Centering', event: () => (this.Document.centerY = !this.Document.centerY), icon: 'copy' }); + displayOptionsMenu.push({ + description: 'Toggle Content Display Style', + event: () => { + this.Document.display = this.Document.display ? undefined : 'contents'; + }, + icon: 'copy', + }); + displayOptionsMenu.push({ + description: 'Toggle Vertical Centering', + event: () => { + this.Document.centerY = !this.Document.centerY; + }, + icon: 'copy', + }); ContextMenu.Instance.addItem({ description: 'Display', subitems: displayOptionsMenu, icon: 'tv' }); }; @@ -347,14 +359,14 @@ export class CollectionGridView extends CollectionSubView() { e, returnFalse, returnFalse, - (e: PointerEvent, doubleTap?: boolean) => { - if (doubleTap && !e.button) { + (clickEv: PointerEvent, doubleTap?: boolean) => { + if (doubleTap && !clickEv.button) { undoBatch( action(() => { const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 }); FormattedTextBox.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed Doc.AddDocToList(this.Document, this._props.fieldKey, text); - this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY)))); + this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(clickEv.clientX, clickEv.clientY)))); }) )(); } @@ -387,7 +399,7 @@ export class CollectionGridView extends CollectionSubView() { width={this._props.PanelWidth()} nodeList={this.contents.length ? this.contents : null} layout={this.contents.length ? this.renderedLayoutList : undefined} - childrenDraggable={this._props.isSelected() ? true : false} + childrenDraggable={!!this._props.isSelected()} numCols={this.numCols} rowHeight={this.rowHeight} setLayout={this.setLayout} diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 6635ab222..e68ed0e17 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -15,7 +15,8 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../ import { CollectionViewType } from '../../../documents/DocumentTypes'; import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; import { DocumentManager } from '../../../util/DocumentManager'; -import { DragManager, dropActionType } from '../../../util/DragManager'; +import { DragManager } from '../../../util/DragManager'; +import { dropActionType } from '../../../util/DropActionTypes'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { UndoStack } from '../../UndoStack'; diff --git a/src/client/views/collections/collectionLinear/index.ts b/src/client/views/collections/collectionLinear/index.ts index ff73e14ae..ab3b4b0b5 100644 --- a/src/client/views/collections/collectionLinear/index.ts +++ b/src/client/views/collections/collectionLinear/index.ts @@ -1 +1 @@ -export * from "./CollectionLinearView";
\ No newline at end of file +export * from './CollectionLinearView'; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 125dd2781..b8509a005 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -1,3 +1,5 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Button, IconButton } from 'browndash-components'; @@ -7,7 +9,7 @@ import * as React from 'react'; import { FaChevronRight } from 'react-icons/fa'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { DragManager, dropActionType } from '../../../util/DragManager'; +import { DragManager } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { undoBatch, undoable } from '../../../util/UndoManager'; @@ -16,6 +18,7 @@ import { CollectionSubView } from '../CollectionSubView'; import './CollectionMulticolumnView.scss'; import ResizeBar from './MulticolumnResizer'; import WidthLabel from './MulticolumnWidthLabel'; +import { dropActionType } from '../../../util/DropActionTypes'; interface WidthSpecifier { magnitude: number; @@ -80,7 +83,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { private get resolvedLayoutInformation(): LayoutData { let starSum = 0; const widthSpecifiers: WidthSpecifier[] = []; - this.childLayouts.map(layout => { + this.childLayouts.forEach(layout => { const unit = StrCast(layout._dimUnit, '*'); const magnitude = NumCast(layout._dimMagnitude, this.minimumDim); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { @@ -140,6 +143,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { return this._props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._xMargin); } + return undefined; } /** @@ -159,6 +163,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) { return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum; } + return undefined; } /** @@ -175,7 +180,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { * or the ratio width evaluated to a pixel value */ private lookupPixels = (layout: Doc): number => { - const columnUnitLength = this.columnUnitLength; + const { columnUnitLength } = this; if (columnUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } @@ -193,19 +198,19 @@ export class CollectionMulticolumnView extends CollectionSubView() { * documents before the target. */ private lookupIndividualTransform = (layout: Doc) => { - const columnUnitLength = this.columnUnitLength; + const { columnUnitLength } = this; if (columnUnitLength === undefined) { return Transform.Identity(); // we're still waiting on promises to resolve } let offset = 0; - var xf = Transform.Identity(); - this.childLayouts.map(candidate => { + // eslint-disable-next-line no-restricted-syntax + for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return (xf = this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0)); + return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); } offset += this.lookupPixels(candidate) + resizerWidth; - }); - return xf; + } + return Transform.Identity(); }; @undoBatch @@ -213,7 +218,9 @@ export class CollectionMulticolumnView extends CollectionSubView() { let dropInd = -1; if (de.complete.docDragData && this._mainCont) { let curInd = -1; - de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d))); + de.complete.docDragData?.droppedDocuments.forEach(d => { + curInd = this.childDocs.indexOf(d); + }); Array.from(this._mainCont.children).forEach((child, index) => { const brect = child.getBoundingClientRect(); if (brect.x < de.x && brect.x + brect.width > de.x) { @@ -265,7 +272,6 @@ export class CollectionMulticolumnView extends CollectionSubView() { this.lookupIndividualTransform(childLayout) .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin)) .scale(this._props.NativeDimScaling?.() || 1); - const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(childLayout.freeform_fitContentsToBox); return ( <DocumentView Document={childLayout} @@ -281,11 +287,11 @@ export class CollectionMulticolumnView extends CollectionSubView() { dragAction={StrCast(this.Document.childDragAction, this._props.childDragAction) as dropActionType} onClickScript={this.onChildClickHandler} onDoubleClickScript={this.onChildDoubleClickHandler} - suppressSetHeight={true} + suppressSetHeight ScreenToLocalTransform={dxf} isContentActive={this.isChildContentActive} isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} - hideResizeHandles={childLayout.layout_fitWidth || this._props.childHideResizeHandles ? true : false} + hideResizeHandles={!!(childLayout.layout_fitWidth || this._props.childHideResizeHandles)} hideDecorationTitle={this._props.childHideDecorationTitle} fitContentsToBox={this._props.fitContentsToBox} focus={this._props.focus} @@ -312,17 +318,19 @@ export class CollectionMulticolumnView extends CollectionSubView() { const collector: JSX.Element[] = []; this.childLayouts.forEach((layout, i) => { collector.push( + // eslint-disable-next-line react/no-array-index-key <Tooltip title={'Tab: ' + StrCast(layout.title)} key={'wrapper' + i}> <div className="document-wrapper" style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}> {this.getDisplayDoc(layout)} {this.layoutDoc._chromeHidden ? null : ( - <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(e => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} /> + <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} /> )} <WidthLabel layout={layout} collectionDoc={this.Document} /> </div> </Tooltip>, <ResizeBar width={resizerWidth} + // eslint-disable-next-line react/no-array-index-key key={'resizer' + i} styleProvider={this._props.styleProvider} isContentActive={this._props.isContentActive} @@ -353,14 +361,29 @@ export class CollectionMulticolumnView extends CollectionSubView() { {this.contents} {!this._startIndex ? null : ( <Tooltip title="scroll back"> - <div style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}> - <Button tooltip="Scroll back" icon={<FontAwesomeIcon icon="chevron-left" size="lg" />} onClick={action(e => (this._startIndex = Math.max(0, this._startIndex - this.maxShown)))} color={SettingsManager.userColor} /> + <div + style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }} + onClick={action(() => { + this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown); + })}> + <Button + tooltip="Scroll back" + icon={<FontAwesomeIcon icon="chevron-left" size="lg" />} + onClick={action(() => { + this._startIndex = Math.max(0, this._startIndex - this.maxShown); + })} + color={SettingsManager.userColor} + /> </div> </Tooltip> )} {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : ( <Tooltip title="scroll forward"> - <div style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}> + <div + style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }} + onClick={action(() => { + this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown); + })}> <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} /> </div> </Tooltip> diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 17bf3e50c..3fe3d5343 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -3,7 +3,8 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { DragManager, dropActionType } from '../../../util/DragManager'; +import { DragManager } from '../../../util/DragManager'; +import { dropActionType } from '../../../util/DropActionTypes'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; @@ -11,6 +12,7 @@ import { CollectionSubView } from '../CollectionSubView'; import './CollectionMultirowView.scss'; import HeightLabel from './MultirowHeightLabel'; import ResizeBar from './MultirowResizer'; + interface HeightSpecifier { magnitude: number; unit: string; @@ -63,7 +65,7 @@ export class CollectionMultirowView extends CollectionSubView() { private get resolvedLayoutInformation(): LayoutData { let starSum = 0; const heightSpecifiers: HeightSpecifier[] = []; - this.childLayoutPairs.map(pair => { + this.childLayoutPairs.forEach(pair => { const unit = StrCast(pair.layout._dimUnit, '*'); const magnitude = NumCast(pair.layout._dimMagnitude, this.minimumDim); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { @@ -123,6 +125,7 @@ export class CollectionMultirowView extends CollectionSubView() { if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { return this._props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._yMargin); } + return undefined; } /** @@ -142,6 +145,7 @@ export class CollectionMultirowView extends CollectionSubView() { if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) { return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum; } + return undefined; } /** @@ -158,13 +162,12 @@ export class CollectionMultirowView extends CollectionSubView() { * or the ratio width evaluated to a pixel value */ private lookupPixels = (layout: Doc): number => { - const rowUnitLength = this.rowUnitLength; - if (rowUnitLength === undefined) { + if (this.rowUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } let height = NumCast(layout._dimMagnitude, this.minimumDim); if (StrCast(layout._dimUnit, '*') === DimUnit.Ratio) { - height *= rowUnitLength; + height *= this.rowUnitLength; } return height; }; @@ -176,11 +179,11 @@ export class CollectionMultirowView extends CollectionSubView() { * documents before the target. */ private lookupIndividualTransform = (layout: Doc) => { - const rowUnitLength = this.rowUnitLength; - if (rowUnitLength === undefined) { + if (this.rowUnitLength === undefined) { return Transform.Identity(); // we're still waiting on promises to resolve } let offset = 0; + // eslint-disable-next-line no-restricted-syntax for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); @@ -195,7 +198,9 @@ export class CollectionMultirowView extends CollectionSubView() { let dropInd = -1; if (de.complete.docDragData && this._mainCont) { let curInd = -1; - de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d))); + de.complete.docDragData?.droppedDocuments.forEach(d => { + curInd = this.childDocs.indexOf(d); + }); Array.from(this._mainCont.children).forEach((child, index) => { const brect = child.getBoundingClientRect(); if (brect.y < de.y && brect.y + brect.height > de.y) { @@ -247,7 +252,6 @@ export class CollectionMultirowView extends CollectionSubView() { this.lookupIndividualTransform(layout) .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin)) .scale(this._props.NativeDimScaling?.() || 1); - const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox); return ( <DocumentView Document={layout} @@ -266,7 +270,7 @@ export class CollectionMultirowView extends CollectionSubView() { ScreenToLocalTransform={dxf} isContentActive={this.isChildContentActive} isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} - hideResizeHandles={layout.layout_fitWidth || this._props.childHideResizeHandles ? true : false} + hideResizeHandles={!!(layout.layout_fitWidth || this._props.childHideResizeHandles)} hideDecorationTitle={this._props.childHideDecorationTitle} fitContentsToBox={this._props.fitContentsToBox} focus={this._props.focus} diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index d580d9c52..49ba85524 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/require-default-props */ import { action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -52,27 +53,6 @@ export default class ResizeBar extends React.Component<ResizerProps> { } }; - private get isActivated() { - const { toLeft, toRight } = this.props; - if (toLeft && toRight) { - if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel && StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } else if (toLeft) { - if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } else if (toRight) { - if (StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } - return false; - } - @action private onPointerUp = () => { window.removeEventListener('pointermove', this.onPointerMove); @@ -90,7 +70,7 @@ export default class ResizeBar extends React.Component<ResizerProps> { width: this.props.width, backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), }}> - <div className={'multiColumnResizer-hdl'} onPointerDown={e => this.registerResizing(e)} /> + <div className="multiColumnResizer-hdl" onPointerDown={e => this.registerResizing(e)} /> </div> ); } diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx index a9579d931..a7a0b3457 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx @@ -19,7 +19,7 @@ export default class WidthLabel extends React.Component<WidthLabelProps> { const getUnit = () => StrCast(layout.dimUnit); const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(3)); return ( - <div className={'label-wrapper'}> + <div className="label-wrapper"> <EditableView GetValue={getMagnitude} SetValue={value => { diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx index 878c7ff3c..66215f109 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/require-default-props */ import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -20,7 +21,7 @@ export default class HeightLabel extends React.Component<HeightLabelProps> { const getUnit = () => StrCast(layout.dimUnit); const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3)); return ( - <div className={'label-wrapper'}> + <div className="label-wrapper"> <EditableView GetValue={getMagnitude} SetValue={value => { diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index 73d08d5ef..ad77c327d 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/require-default-props */ import { action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -33,7 +34,7 @@ export default class ResizeBar extends React.Component<ResizerProps> { }; private onPointerMove = ({ movementY }: PointerEvent) => { - const { toTop: toTop, toBottom: toBottom, columnUnitLength } = this.props; + const { toTop, toBottom, columnUnitLength } = this.props; const movingDown = movementY > 0; const toNarrow = movingDown ? toBottom : toTop; const toWiden = movingDown ? toTop : toBottom; @@ -50,27 +51,6 @@ export default class ResizeBar extends React.Component<ResizerProps> { } }; - private get isActivated() { - const { toTop, toBottom } = this.props; - if (toTop && toBottom) { - if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel && StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } else if (toTop) { - if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } else if (toBottom) { - if (StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) { - return false; - } - return true; - } - return false; - } - @action private onPointerUp = () => { window.removeEventListener('pointermove', this.onPointerMove); @@ -88,7 +68,7 @@ export default class ResizeBar extends React.Component<ResizerProps> { height: this.props.height, backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), }}> - <div className={'multiRowResizer-hdl'} onPointerDown={e => this.registerResizing(e)} /> + <div className="multiRowResizer-hdl" onPointerDown={e => this.registerResizing(e)} /> </div> ); } diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 2823e1936..389fc66b3 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -1,5 +1,6 @@ +/* eslint-disable react/no-unused-prop-types */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable } from 'mobx'; +import { action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { setupMoveUpEvents } from '../../../../ClientUtils'; @@ -25,8 +26,6 @@ export interface SchemaColumnHeaderProps { @observer export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> { - @observable _ref: HTMLDivElement | null = null; - get fieldKey() { return this.props.columnKeys[this.props.columnIndex]; } @@ -35,9 +34,9 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> sortClicked = (e: React.PointerEvent) => { e.stopPropagation(); e.preventDefault(); - if (this.props.sortField == this.fieldKey && this.props.sortDesc) { + if (this.props.sortField === this.fieldKey && this.props.sortDesc) { this.props.setSort(undefined); - } else if (this.props.sortField == this.fieldKey) { + } else if (this.props.sortField === this.fieldKey) { this.props.setSort(this.fieldKey, true); } else { this.props.setSort(this.fieldKey, false); @@ -46,7 +45,7 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> @action onPointerDown = (e: React.PointerEvent) => { - this.props.isContentActive(true) && setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction, false); + this.props.isContentActive(true) && setupMoveUpEvents(this, e, moveEv => this.props.dragColumn(moveEv, this.props.columnIndex), emptyFunction, emptyFunction, false); }; render() { @@ -59,19 +58,18 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> onPointerDown={this.onPointerDown} ref={col => { if (col) { - this._ref = col; this.props.setColRef(this.props.columnIndex, col); } }}> - <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)}></div> + <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)} /> <div className="schema-column-title">{this.fieldKey}</div> <div className="schema-header-menu"> <div className="schema-header-button" onPointerDown={e => this.props.openContextMenu(e.clientX, e.clientY, this.props.columnIndex)}> <FontAwesomeIcon icon="ellipsis-h" /> </div> - <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField == this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}> - <FontAwesomeIcon icon="caret-right" style={this.props.sortField == this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} /> + <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField === this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}> + <FontAwesomeIcon icon="caret-right" style={this.props.sortField === this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} /> </div> </div> </div> diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 27a4493cb..61afe08cf 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -63,7 +63,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { } }; - onPointerEnter = (e: any) => { + onPointerEnter = () => { if (SnappingManager.IsDragging && this._props.isContentActive()) { document.removeEventListener('pointermove', this.onPointerMove); document.addEventListener('pointermove', this.onPointerMove); @@ -75,7 +75,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { if (this._ref && dragIsRow) { const rect = this._ref.getBoundingClientRect(); - const y = e.clientY - rect.top; //y position within the element. + const y = e.clientY - rect.top; // y position within the element. const height = this._ref.clientHeight; const halfLine = height / 2; if (y <= halfLine) { @@ -90,7 +90,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { } }; - onPointerLeave = (e: any) => { + onPointerLeave = () => { if (this._ref) { this._ref.style.borderTop = '0px'; this._ref.style.borderBottom = '0px'; @@ -131,15 +131,16 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { e, returnFalse, emptyFunction, - undoable(e => { - e.stopPropagation(); + undoable(clickEv => { + clickEv.stopPropagation(); Doc.toggleLockedPosition(this.Document); }, 'Delete Row') ) - }></IconButton> + } + /> <IconButton tooltip="close" - icon={<CgClose size={'16px'} />} + icon={<CgClose size="16px" />} size={Size.XSMALL} onPointerDown={e => setupMoveUpEvents( @@ -147,8 +148,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { e, returnFalse, emptyFunction, - undoable(e => { - e.stopPropagation(); + undoable(clickEv => { + clickEv.stopPropagation(); this._props.removeDocument?.(this.Document); }, 'Delete Row') ) @@ -164,8 +165,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { e, returnFalse, emptyFunction, - undoable(e => { - e.stopPropagation(); + undoable(clickEv => { + clickEv.stopPropagation(); this._props.addDocTab(this.Document, OpenWhere.addRight); }, 'Open schema Doc preview') ) |
