diff options
author | bobzel <zzzman@gmail.com> | 2024-05-17 14:55:36 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-05-17 14:55:36 -0400 |
commit | 0b451af28e5aef6b749da61e8a9fcd0a840789ac (patch) | |
tree | bdee4e28ee4715b69299a8da1b615c70b6adc445 /src/client/views/nodes/DataVizBox/components/TableBox.tsx | |
parent | 8c1b420a143e4b72ec551277887c211ca6ca003b (diff) | |
parent | 38a382a03675d6a50ec7de75f05025efd093f570 (diff) |
merged with new master
Diffstat (limited to 'src/client/views/nodes/DataVizBox/components/TableBox.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/components/TableBox.tsx | 129 |
1 files changed, 74 insertions, 55 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 67e1c67bd..a1deb1625 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -1,19 +1,25 @@ +/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import { Button, Type } from 'browndash-components'; -import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../../Utils'; +import { ClientUtils, setupMoveUpEvents } from '../../../../../ClientUtils'; +import { emptyFunction } from '../../../../../Utils'; import { Doc, Field, NumListCast } from '../../../../../fields/Doc'; +import { DocData } from '../../../../../fields/DocSymbols'; import { List } from '../../../../../fields/List'; import { listSpec } from '../../../../../fields/Schema'; import { Cast, DocCast } from '../../../../../fields/Types'; import { DragManager } from '../../../../util/DragManager'; +import { undoable } from '../../../../util/UndoManager'; import { ObservableReactComponent } from '../../../ObservableReactComponent'; import { DocumentView } from '../../DocumentView'; import { DataVizView } from '../DataVizBox'; import './Chart.scss'; -import { undoable } from '../../../../util/UndoManager'; + const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore + interface TableBoxProps { Document: Doc; layoutDoc: Doc; @@ -58,7 +64,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { // then we need to remove any selected rows that are no longer part of the visualized dataset. this._inputChangedDisposer = reaction(() => this._tableData.slice(), this.filterSelectedRowsDown, { fireImmediately: true }); const selected = NumListCast(this._props.layoutDoc.dataViz_selectedRows); - if (selected.length > 0) this.hasRowsToFilter = true; + if (selected.length > 0) + runInAction(() => { + this.hasRowsToFilter = true; + }); this.handleScroll(); } componentWillUnmount() { @@ -77,7 +86,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { } @computed get columns() { - return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header != '' && header != undefined) : []; + return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header !== '' && header !== undefined) : []; } // updates the 'dataViz_selectedRows' and 'dataViz_highlightedRows' fields to no longer include rows that aren't in the table @@ -114,15 +123,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); else highlited?.push(rowId); if (!selected?.includes(rowId)) selected?.push(rowId); - } else { + } else if (selected?.includes(rowId)) { // selecting a row - if (selected?.includes(rowId)) { - if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); - selected.splice(selected.indexOf(rowId), 1); - } else selected?.push(rowId); - } + if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); + selected.splice(selected.indexOf(rowId), 1); + } else selected?.push(rowId); e.stopPropagation(); - this.hasRowsToFilter = selected.length > 0 ? true : false; + this.hasRowsToFilter = selected.length > 0; }; columnPointerDown = (e: React.PointerEvent, col: string) => { @@ -131,13 +138,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { setupMoveUpEvents( {}, e, - e => { + moveEv => { // dragging off a column to create a brushed DataVizBox const sourceAnchorCreator = () => this._props.docView?.()!.Document!; const targetCreator = (annotationOn: Doc | undefined) => { const embedding = Doc.MakeEmbedding(this._props.docView?.()!.Document!); embedding._dataViz = DataVizView.TABLE; - embedding._dataViz_axes = new List<string>([col, col]); + embedding._dataViz_axes = new List<string>([col]); embedding._dataViz_parentViz = this._props.Document; embedding.annotationOn = annotationOn; embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors); @@ -145,15 +152,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors); return embedding; }; - if (this._props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) { - DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { - dragComplete: e => { - if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) { - e.linkDocument.link_displayLine = true; - e.linkDocument.link_matchEmbeddings = true; - e.linkDocument.link_displayArrow = true; - // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this._props.Document; - // e.annoDragData.linkSourceDoc.followLinkZoom = false; + if (this._props.docView?.() && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) { + DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { + dragComplete: completeEv => { + if (!completeEv.aborted && completeEv.annoDragData && completeEv.annoDragData.linkSourceDoc && completeEv.annoDragData.dropDocument && completeEv.linkDocument) { + completeEv.linkDocument[DocData].link_matchEmbeddings = true; + completeEv.linkDocument[DocData].stroke_startMarker = true; + this._props.docView?.()?._props.addDocument?.(completeEv.linkDocument); } }, }); @@ -162,10 +167,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { return false; }, emptyFunction, - action(e => { - if (e.shiftKey || this.settingTitle) { + action(moveEv => { + if (moveEv.shiftKey || this.settingTitle) { if (this.settingTitle) this.settingTitle = false; - if (this._props.titleCol == col) this._props.titleCol = ''; + if (this._props.titleCol === col) this._props.titleCol = ''; else this._props.titleCol = col; this._props.selectTitleCol(this._props.titleCol); } else { @@ -183,16 +188,16 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { * These functions handle the filtering popup for when the "filter" button is pressed to select rows */ filter = undoable((e: any) => { - var start: any; - var end: any; - if (this.filteringType == 'Range') { - start = (this.filteringVal[0] as Number) ? Number(this.filteringVal[0]) : this.filteringVal[0]; - end = (this.filteringVal[1] as Number) ? Number(this.filteringVal[1]) : this.filteringVal[0]; + let start: any; + let end: any; + if (this.filteringType === 'Range') { + start = Number.isNaN(Number(this.filteringVal[0])) ? this.filteringVal[0] : Number(this.filteringVal[0]); + end = Number.isNaN(Number(this.filteringVal[1])) ? this.filteringVal[1] : Number(this.filteringVal[1]); } this._tableDataIds.forEach(rowID => { - if (this.filteringType == 'Value') { - if (this._props.records[rowID][this.filteringColumn] == this.filteringVal[0]) { + if (this.filteringType === 'Value') { + if (this._props.records[rowID][this.filteringColumn] === this.filteringVal[0]) { if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) { this.tableRowClick(e, rowID); } @@ -229,12 +234,12 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { this.filteringVal[1] = e.target.value; }); @computed get renderFiltering() { - if (this.filteringColumn === '') this.filteringColumn = this.columns[0]; + if (this.filteringColumn === '') [this.filteringColumn] = this.columns; return ( <div className="tableBox-filterPopup" style={{ right: this._props.width * 0.05 }}> <div className="tableBox-filterPopup-selectColumn"> Column: - <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn != '' ? this.filteringColumn : this.columns[0]} onChange={e => this.setFilterColumn(e)}> + <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn !== '' ? this.filteringColumn : this.columns[0]} onChange={e => this.setFilterColumn(e)}> {this.columns.map(column => ( <option className="" key={column} value={column}> {' '} @@ -245,17 +250,17 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { </div> <div className="tableBox-filterPopup-setValue"> <select className="tableBox-filterPopup-setValue-each" value={this.filteringType} onChange={e => this.setFilterType(e)}> - <option className="" key={'Value'} value={'Value'}> + <option className="" key="Value" value="Value"> {' '} {'Value'}{' '} </option> - <option className="" key={'Range'} value={'Range'}> + <option className="" key="Range" value="Range"> {' '} {'Range'}{' '} </option> </select> : - {this.filteringType == 'Value' ? ( + {this.filteringType === 'Value' ? ( <input className="tableBox-filterPopup-setValue-input" defaultValue="" @@ -301,7 +306,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { )} </div> <div className="tableBox-filterPopup-setFilter"> - <Button onClick={action(e => this.filter(e))} text="Set Filter" type={Type.SEC} color={'black'} /> + <Button onClick={action(e => this.filter(e))} text="Set Filter" type={Type.SEC} color="black" /> </div> </div> ); @@ -322,11 +327,25 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { }}> <div className="tableBox-selectButtons"> <div className="tableBox-selectTitle"> - <Button onClick={action(() => (this.settingTitle = !this.settingTitle))} text="Select Title Column" type={Type.SEC} color={'black'} /> + <Button + onClick={action(() => { + this.settingTitle = !this.settingTitle; + })} + text="Select Title Column" + type={Type.SEC} + color="black" + /> </div> <div className="tableBox-filtering"> {this.filtering ? this.renderFiltering : null} - <Button onClick={action(() => (this.filtering = !this.filtering))} text="Filter" type={Type.SEC} color={'black'} /> + <Button + onClick={action(() => { + this.filtering = !this.filtering; + })} + text="Filter" + type={Type.SEC} + color="black" + /> <div className="tableBox-filterAll"> {this.hasRowsToFilter ? ( <Button @@ -336,7 +355,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { })} text="Deselect All" type={Type.SEC} - color={'black'} + color="black" tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." /> ) : ( @@ -347,7 +366,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { })} text="Select All" type={Type.SEC} - color={'black'} + color="black" tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." /> )} @@ -391,7 +410,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { ? 'darkgreen' : this._props.axes.length > 2 && this._props.axes.lastElement() === col ? 'darkred' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) + : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) ? 'darkblue' : undefined, background: this.settingTitle @@ -400,7 +419,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { ? '#E3fbdb' : this._props.axes.length > 2 && this._props.axes.lastElement() === col ? '#Fbdbdb' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) + : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) ? '#c6ebf7' : undefined, fontWeight: 'bolder', @@ -424,11 +443,11 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { background: NumListCast(this._props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '', }}> {this.columns.map(col => { - var colSelected = false; - if (this._props.axes.length > 2) colSelected = this._props.axes[0] == col || this._props.axes[1] == col || this._props.axes[2] == col; - else if (this._props.axes.length > 1) colSelected = this._props.axes[0] == col || this._props.axes[1] == col; - else if (this._props.axes.length > 0) colSelected = this._props.axes[0] == col; - if (this._props.titleCol == col) colSelected = true; + let colSelected = false; + if (this._props.axes.length > 2) colSelected = this._props.axes[0] === col || this._props.axes[1] === col || this._props.axes[2] === col; + else if (this._props.axes.length > 1) colSelected = this._props.axes[0] === col || this._props.axes[1] === col; + else if (this._props.axes.length > 0) colSelected = this._props.axes[0] === col; + if (this._props.titleCol === col) colSelected = true; return ( <td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}> <div className="tableBox-cell">{this._props.records[rowId][col]}</div> @@ -443,10 +462,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { </div> </div> ); - } else - return ( - // when it is a brushed table and the incoming table doesn't have any rows selected - <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div> - ); + } + return ( + // when it is a brushed table and the incoming table doesn't have any rows selected + <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div> + ); } } |