Skip to content

Commit

Permalink
feat: Add descriptive statistics for number cells in data browser (#2529
Browse files Browse the repository at this point in the history
)
  • Loading branch information
AshishBarvaliya authored Feb 26, 2024
1 parent 09f48fc commit ead9ec4
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 4 deletions.
21 changes: 19 additions & 2 deletions src/components/BrowserCell/BrowserCell.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ export default class BrowserCell extends Component {
hidden,
width,
current,
onSelect,
onEditChange,
setCopyableValue,
onPointerCmdClick,
Expand All @@ -536,6 +535,8 @@ export default class BrowserCell extends Component {
onEditSelectedRow,
isRequired,
markRequiredFieldRow,
handleCellClick,
selectedCells,
} = this.props;

const classes = [...this.state.classes];
Expand Down Expand Up @@ -573,6 +574,22 @@ export default class BrowserCell extends Component {
);
}

if (selectedCells?.list.has(`${row}-${col}`)) {
if (selectedCells.rowStart === row) {
classes.push(styles.topBorder);
}
if (selectedCells.rowEnd === row) {
classes.push(styles.bottomBorder);
}
if (selectedCells.colStart === col) {
classes.push(styles.leftBorder);
}
if (selectedCells.colEnd === col) {
classes.push(styles.rightBorder);
}
classes.push(styles.selected);
}

return (
<span
ref={this.cellRef}
Expand All @@ -582,8 +599,8 @@ export default class BrowserCell extends Component {
if (e.metaKey === true && type === 'Pointer') {
onPointerCmdClick(value);
} else {
onSelect({ row, col });
setCopyableValue(hidden ? undefined : this.copyableValue);
handleCellClick(e, row, col);
}
}}
onDoubleClick={() => {
Expand Down
66 changes: 65 additions & 1 deletion src/components/BrowserCell/BrowserCell.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,71 @@
}
}

.hasMore{
.leftBorder {
position: relative;

&:after {
position: absolute;
pointer-events: none;
content: '';
border-left: 2px solid #555572;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}

.rightBorder {
position: relative;

&:after {
position: absolute;
pointer-events: none;
content: '';
border-right: 2px solid #555572;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}

.topBorder {
position: relative;

&:after {
position: absolute;
pointer-events: none;
content: '';
border-top: 2px solid #555572;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}

.bottomBorder {
position: relative;

&:after {
position: absolute;
pointer-events: none;
content: '';
border-bottom: 2px solid #555572;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}

.selected {
background-color: #e3effd;
}

.hasMore {
height: auto;
max-height: 25px;
overflow-y: scroll;
Expand Down
2 changes: 2 additions & 0 deletions src/components/BrowserRow/BrowserRow.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export default class BrowserRow extends Component {
showNote={this.props.showNote}
onRefresh={this.props.onRefresh}
scripts={this.props.scripts}
handleCellClick={this.props.handleCellClick}
selectedCells={this.props.selectedCells}
/>
);
})}
Expand Down
103 changes: 102 additions & 1 deletion src/components/Toolbar/Toolbar.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,110 @@
* the root directory of this source tree.
*/
import PropTypes from 'lib/PropTypes';
import React from 'react';
import React, { useEffect } from 'react';
import Icon from 'components/Icon/Icon.react';
import styles from 'components/Toolbar/Toolbar.scss';
import Popover from 'components/Popover/Popover.react';
import Position from 'lib/Position';
import { useNavigate, useNavigationType, NavigationType } from 'react-router-dom';

const POPOVER_CONTENT_ID = 'toolbarStatsPopover';

const Stats = ({ data }) => {
const [selected, setSelected] = React.useState(null);
const [open, setOpen] = React.useState(false);
const buttonRef = React.useRef();

const statsOptions = [
{
type: 'sum',
label: 'Sum',
getValue: data => data.reduce((sum, value) => sum + value, 0),
},
{
type: 'mean',
label: 'Mean',
getValue: data => data.reduce((sum, value) => sum + value, 0) / data.length,
},
{
type: 'count',
label: 'Count',
getValue: data => data.length,
},
{
type: 'p99',
label: 'P99',
getValue: data => {
const sorted = data.sort((a, b) => a - b);
return sorted[Math.floor(sorted.length * 0.99)];
},
},
];

const toggle = () => {
setOpen(!open);
};

const renderPopover = () => {
const node = buttonRef.current;
const position = Position.inDocument(node);
return (
<Popover
fixed={true}
position={position}
onExternalClick={toggle}
contentId={POPOVER_CONTENT_ID}
>
<div id={POPOVER_CONTENT_ID}>
<div
onClick={toggle}
style={{
cursor: 'pointer',
width: node.clientWidth,
height: node.clientHeight,
}}
></div>
<div className={styles.stats_popover_container}>
{statsOptions.map(item => {
const itemStyle = [styles.stats_popover_item];
if (item.type === selected?.type) {
itemStyle.push(styles.active);
}
return (
<div
key={item.type}
className={itemStyle.join(' ')}
onClick={() => {
setSelected(item);
toggle();
}}
>
<span>{item.label}</span>
</div>
);
})}
</div>
</div>
</Popover>
);
};

useEffect(() => {
setSelected(statsOptions[0]);
}, []);

return (
<>
{selected ? (
<button ref={buttonRef} className={styles.stats} onClick={toggle}>
{`${selected.label}: ${selected.getValue(data)}`}
</button>
) : null}
{open ? renderPopover() : null}
</>
);
};

const Toolbar = props => {
const action = useNavigationType();
const navigate = useNavigate();
Expand All @@ -34,6 +133,7 @@ const Toolbar = props => {
</div>
</div>
</div>
{props.selectedData.length ? <Stats data={props.selectedData} /> : null}
<div className={styles.actions}>{props.children}</div>
</div>
);
Expand All @@ -44,6 +144,7 @@ Toolbar.propTypes = {
subsection: PropTypes.string,
details: PropTypes.string,
relation: PropTypes.object,
selectedData: PropTypes.array,
};

export default Toolbar;
40 changes: 40 additions & 0 deletions src/components/Toolbar/Toolbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,43 @@ body:global(.expanded) {
right: 14px;
top: 4px;
}

.stats {
position: absolute;
right: 20px;
bottom: 10px;
background: $blue;
border-radius: 3px;
padding: 2px 6px;
font-size: 14px;
color: white;
box-shadow: none;
border: none;
}

.stats_popover_container {
display: flex;
flex-direction: column;
background: $blue;
border-radius: 3px;
margin-top: 1px;
gap: 2px;
padding: 2px 0px;
font-size: 14px;
color: white;
}

.stats_popover_item {
cursor: pointer;
padding: 0px 6px;

&:hover {
color: $blue;
background-color: white;
}
}

.active {
color: $blue;
background-color: white;
}
6 changes: 6 additions & 0 deletions src/dashboard/Data/Browser/BrowserTable.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ export default class BrowserTable extends React.Component {
showNote={this.props.showNote}
onRefresh={this.props.onRefresh}
scripts={this.context.scripts}
selectedCells={this.props.selectedCells}
handleCellClick={this.props.handleCellClick}
/>
<Button
value="Clone"
Expand Down Expand Up @@ -236,6 +238,8 @@ export default class BrowserTable extends React.Component {
showNote={this.props.showNote}
onRefresh={this.props.onRefresh}
scripts={this.context.scripts}
selectedCells={this.props.selectedCells}
handleCellClick={this.props.handleCellClick}
/>
<Button
value="Add"
Expand Down Expand Up @@ -312,6 +316,8 @@ export default class BrowserTable extends React.Component {
showNote={this.props.showNote}
onRefresh={this.props.onRefresh}
scripts={this.context.scripts}
selectedCells={this.props.selectedCells}
handleCellClick={this.props.handleCellClick}
/>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/dashboard/Data/Browser/BrowserToolbar.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ const BrowserToolbar = ({
login,
logout,
toggleMasterKeyUsage,

selectedData,
}) => {
const selectionLength = Object.keys(selection).length;
const isPendingEditCloneRows = editCloneRows && editCloneRows.length > 0;
Expand Down Expand Up @@ -238,6 +240,7 @@ const BrowserToolbar = ({
section={relation ? `Relation <${relation.targetClassName}>` : 'Class'}
subsection={subsection}
details={details.join(' \u2022 ')}
selectedData={selectedData}
>
{onAddRow && (
<a className={classes.join(' ')} onClick={onClick}>
Expand Down
Loading

0 comments on commit ead9ec4

Please sign in to comment.