aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/components/Chart.scss54
-rw-r--r--src/client/views/nodes/DataVizBox/components/TableBox.tsx118
2 files changed, 157 insertions, 15 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/Chart.scss b/src/client/views/nodes/DataVizBox/components/Chart.scss
index 15d289abf..cf0007cfd 100644
--- a/src/client/views/nodes/DataVizBox/components/Chart.scss
+++ b/src/client/views/nodes/DataVizBox/components/Chart.scss
@@ -120,18 +120,62 @@
}
}
}
-.select-buttons {
+.tableBox-selectButtons {
margin-top: 5px;
margin-left: 25px;
display: inline-block;
- .selectTitle {
- display: inline-block;
-
+ padding: 2px;
+ .tableBox-selectTitle {
+ display: inline-flex;
+ flex-direction: row;
}
- .selectAll {
+ .tableBox-filtering {
display: flex;
flex-direction: row;
float: right;
margin-right: 10px;
+ .tableBox-filterAll {
+ min-width: 75px;
+ }
+ }
+}
+
+.tableBox-filterPopup {
+ background: $light-gray;
+ position: absolute;
+ min-width: 235px;
+ top: 60px;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ z-index: 2;
+ padding: 7px;
+ border-radius: 5px;
+ margin: 3px;
+ .tableBox-filterPopup-selectColumn {
+ margin-top: 5px;
+ flex-direction: row;
+ .tableBox-filterPopup-selectColumn-each {
+ margin-left: 25px;
+ border-radius: 3px;
+ background: $light-gray;
+ }
+ }
+ .tableBox-filterPopup-setValue {
+ margin-top: 5px;
+ display: flex;
+ flex-direction: row;
+ .tableBox-filterPopup-setValue-each {
+ margin-right: 5px;
+ border-radius: 3px;
+ background: $light-gray;
+ }
+ .tableBox-filterPopup-setValue-input {
+ margin: 5px;
+ }
+ }
+ .tableBox-filterPopup-setFilter {
+ margin-top: 5px;
+ align-self: center;
}
}
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index c9491da59..05429e82b 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -12,6 +12,7 @@ import { ObservableReactComponent } from '../../../ObservableReactComponent';
import { DocumentView } from '../../DocumentView';
import { DataVizView } from '../DataVizBox';
import './Chart.scss';
+import { undoBatch } from '../../../../util/UndoManager';
const { default: { DATA_VIZ_TABLE_ROW_HEIGHT } } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore
interface TableBoxProps {
Document: Doc;
@@ -36,7 +37,13 @@ interface TableBoxProps {
export class TableBox extends ObservableReactComponent<TableBoxProps> {
_inputChangedDisposer?: IReactionDisposer;
_containerRef: HTMLDivElement | null = null;
- @observable settingTitle: boolean = false;
+
+ @observable settingTitle: boolean = false; // true when setting a title column
+ @observable hasRowsToFilter: boolean = false; // true when any rows are selected
+ @observable filtering: boolean = false; // true when the filtering menu is open
+ @observable filteringColumn: any = ""; // column to filter
+ @observable filteringType: string = "Value"; // "Value" or "Range"
+ filteringVal: any[] = ["", ""]; // value or range to filter the column with
@observable _scrollTop = -1;
@observable _tableHeight = 0;
@@ -50,6 +57,8 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
// if the tableData changes (ie., when records are selected by the parent (input) visulization),
// 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;
this.handleScroll();
}
componentWillUnmount() {
@@ -65,9 +74,6 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
@computed get parentViz() {
return DocCast(this._props.Document.dataViz_parentViz);
- // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links
- // .filter(link => link.link_anchor_1 == this._props.Document.dataViz_parentViz) // get links where this chart doc is the target of the link
- // .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
}
@computed get columns() {
@@ -116,6 +122,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
} else selected?.push(rowId);
}
e.stopPropagation();
+ this.hasRowsToFilter = (selected.length>0)? true : false;
};
columnPointerDown = (e: React.PointerEvent, col: string) => {
@@ -173,6 +180,88 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
);
};
+ /**
+ * These functions handle the filtering popup for when the "filter" button is pressed to select rows
+ */
+ @undoBatch
+ filter = (e: any) => {
+ this._tableDataIds.forEach(rowID => {
+ if (this.filteringType=="Value"){
+ if (this._props.records[rowID][this.filteringColumn]==this.filteringVal[0]) {
+ this.tableRowClick(e, rowID);
+ }
+ }
+ else {
+ if (this.filteringVal[0]<=this._props.records[rowID][this.filteringColumn] && this._props.records[rowID][this.filteringColumn]<=this.filteringVal[1]){
+ this.tableRowClick(e, rowID);
+ }
+ }
+ })
+ this.filtering = false;
+ this.filteringColumn = "";
+ this.filteringVal = ["", ""];
+ }
+ @action
+ setFilterColumn = (e:any) => {
+ this.filteringColumn = e.currentTarget.value;
+ }
+ @action
+ setFilterType = (e:any) => {
+ this.filteringType = e.currentTarget.value;
+ }
+ changeFilterValue = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[0] = e.target.value;
+ });
+ changeFilterRange0 = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[0] = e.target.value;
+ });
+ changeFilterRange1 = action((e: React.ChangeEvent<HTMLInputElement>) => {
+ this.filteringVal[1] = e.target.value;
+ });
+ @computed get renderFiltering() {
+ if (this.filteringColumn==="") this.filteringColumn = this.columns[0];
+ return (
+ <div className="tableBox-filterPopup" style={{right: this._props.width*.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)}>
+ {this.columns.map(column => (
+ <option className="" key={column} value={column}> {column} </option>
+ ))}
+ </select>
+ </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"}> {"Value"} </option>
+ <option className="" key={"Range"} value={"Range"}> {"Range"} </option>
+ </select>
+ :
+ {this.filteringType=="Value"?
+ <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off"
+ onChange={this.changeFilterValue} onKeyDown={e => {e.stopPropagation();}}
+ type="text" placeholder="" id="search-input"
+ />
+ :
+ <div>
+ <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off"
+ onChange={this.changeFilterRange0} onKeyDown={e => {e.stopPropagation();}}
+ type="text" placeholder="" id="search-input" style={{width: this._props.width*.15}}
+ />
+ to
+ <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off"
+ onChange={this.changeFilterRange1} onKeyDown={e => {e.stopPropagation();}}
+ type="text" placeholder="" id="search-input" style={{width: this._props.width*.15}}
+ />
+ </div>
+ }
+ </div>
+ <div className="tableBox-filterPopup-setFilter">
+ <Button onClick={action((e) => this.filter(e))} text="Set Filter" type={Type.SEC} color={'black'} />
+ </div>
+ </div>
+ )
+ }
+
render() {
if (this._tableData.length > 0) {
return (
@@ -186,13 +275,22 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds);
}
}}>
- <div className="select-buttons">
- <div className="selectTitle">
- <Button onClick={action(() => (this.settingTitle = !this.settingTitle))} text="Select Title Column" type={Type.SEC} color={'black'} />
+ <div className="tableBox-selectButtons">
+ <div className="tableBox-selectTitle">
+ <Button onClick={action(() => (this.settingTitle = !this.settingTitle))} text="Select Title Column" tooltip="TOOLTIP TEST YAY" 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'} />
+ <div className="tableBox-filterAll">
+ {this.hasRowsToFilter? <Button onClick={action(() => {
+ this._props.layoutDoc.dataViz_selectedRows = new List<number>();
+ this.hasRowsToFilter = false; })} text="Deselect All" type={Type.SEC} color={'black'} tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." />
+ : <Button onClick={action(() => {
+ this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds)
+ this.hasRowsToFilter = true; })} text="Select All" type={Type.SEC} color={'black'} tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." />
+ }
</div>
- <div className="selectAll">
- <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds)))} text="Select All" type={Type.SEC} color={'black'} />
- <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>()))} text="Deselect All" type={Type.SEC} color={'black'} />
</div>
</div>
<div