Skip to content

Commit

Permalink
Add range selection for runs (shift+click) (G-Research#104)
Browse files Browse the repository at this point in the history
* Fix playwright pipeline

* Upgrade playwright to 1.45.0

* Add with-deps

* Add playwright envs

* Change installation order

* Do everything in src directory

* Set working-directory

* Add range start state to Table

* Extend onRowSelect to allow range selection

* Plug together rangeStart state and callback

* Intercept and handle shift click event
  • Loading branch information
jescalada authored and vinayan3 committed Aug 28, 2024
1 parent 43de881 commit 32cea02
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 14 deletions.
8 changes: 8 additions & 0 deletions src/src/components/CustomTable/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ function Table(props) {
isAlwaysVisible={true}
onRowHover={props.onRowHover}
listWindow={props.listWindow}
shiftClickRangeStart={props.shiftClickRangeStart}
setShiftClickRangeStart={props.setShiftClickRangeStart}
/>
</div>
</ErrorBoundary>
Expand Down Expand Up @@ -445,6 +447,8 @@ function Table(props) {
selectedRows={props.selectedRows}
onRowSelect={props.onRowSelect}
listWindow={props.listWindow}
shiftClickRangeStart={props.shiftClickRangeStart}
setShiftClickRangeStart={props.setShiftClickRangeStart}
/>
</ErrorBoundary>
))}
Expand Down Expand Up @@ -522,6 +526,8 @@ function Table(props) {
}
colLeft={colLefts[index] ?? null}
listWindow={props.listWindow}
shiftClickRangeStart={props.shiftClickRangeStart}
setShiftClickRangeStart={props.setShiftClickRangeStart}
/>
</ErrorBoundary>
);
Expand Down Expand Up @@ -589,6 +595,8 @@ function Table(props) {
columnOptions={col.columnOptions}
selectedRows={props.selectedRows}
listWindow={props.listWindow}
shiftClickRangeStart={props.shiftClickRangeStart}
setShiftClickRangeStart={props.setShiftClickRangeStart}
/>
</ErrorBoundary>
))}
Expand Down
21 changes: 17 additions & 4 deletions src/src/components/CustomTable/TableColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ function Column({
colLeft,
listWindow,
noColumnActions,
shiftClickRangeStart,
setShiftClickRangeStart,
}) {
const [maxWidth, setMaxWidth] = React.useState(width);
const [isResizing, setIsResizing] = React.useState(false);
Expand Down Expand Up @@ -777,10 +779,21 @@ function Column({
checked={!!selectedRows[item.selectKey]}
onClick={(e) => {
e.stopPropagation();
onRowSelect({
data: item,
actionType: 'single',
});

if (e.shiftKey) {
onRowSelect({
actionType: 'range',
data: data,
rangeStart: shiftClickRangeStart,
rangeEnd: item.index,
});
} else {
setShiftClickRangeStart(item.index);
onRowSelect({
data: item,
actionType: 'single',
});
}
}}
/>
</>
Expand Down
6 changes: 6 additions & 0 deletions src/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ const Table = React.forwardRef(function Table(
availableSpace: 0,
});
const [isExporting, setIsExporting] = React.useState(false);
const [shiftClickRangeStart, setShiftClickRangeStart] =
React.useState<number>(null);

const handleExport = async () => {
setIsExporting(true);
Expand Down Expand Up @@ -1035,6 +1037,8 @@ const Table = React.forwardRef(function Table(
columnsColorScales={columnsColorScales}
onToggleColumnsColorScales={onToggleColumnsColorScales}
noColumnActions={noColumnActions}
shiftClickRangeStart={shiftClickRangeStart}
setShiftClickRangeStart={setShiftClickRangeStart}
{...props}
/>
</ErrorBoundary>
Expand Down Expand Up @@ -1076,6 +1080,8 @@ const Table = React.forwardRef(function Table(
onRowHover={onRowHover}
onRowClick={onRowClick}
disableRowClick={disableRowClick}
shiftClickRangeStart={shiftClickRangeStart}
setShiftClickRangeStart={setShiftClickRangeStart}
/>
</ErrorBoundary>
)
Expand Down
8 changes: 6 additions & 2 deletions src/src/services/models/explorer/metricsModelMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1916,11 +1916,15 @@ function getMetricsAppModelMethods(
onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
}: {
actionType: 'single' | 'selectAll' | 'removeAll';
actionType: 'single' | 'selectAll' | 'removeAll' | 'range';
data?: any;
rangeStart?: number;
rangeEnd?: number;
}): void {
return onRowSelect({ actionType, data, model });
return onRowSelect({ actionType, data, rangeStart, rangeEnd, model });
},
onRowsVisibilityChange(metricKeys: string[]): void {
return onRowsVisibilityChange({
Expand Down
15 changes: 13 additions & 2 deletions src/src/services/models/explorer/paramsModelMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1771,14 +1771,25 @@ function getParamsModelMethods(
updateModelData,
});
},

onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
}: {
actionType: 'single' | 'selectAll' | 'removeAll';
actionType: 'single' | 'selectAll' | 'removeAll' | 'range';
data?: any;
rangeStart?: number;
rangeEnd?: number;
}): void {
return onRowSelect({ actionType, data, model });
return onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
model,
});
},
onRowsVisibilityChange(metricKeys: string[]): void {
return onRowsVisibilityChange({
Expand Down
15 changes: 13 additions & 2 deletions src/src/services/models/explorer/runsModelMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1184,14 +1184,25 @@ function getRunsModelMethods(
updateModelData,
});
},

onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
}: {
actionType: 'single' | 'selectAll' | 'removeAll';
actionType: 'single' | 'selectAll' | 'removeAll' | 'range';
data?: any;
rangeStart?: number;
rangeEnd?: number;
}): void {
return onRowSelect({ actionType, data, model });
return onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
model,
});
},
onToggleColumnsColorScales(colKey: string): void {
onToggleColumnsColorScales({
Expand Down
14 changes: 12 additions & 2 deletions src/src/services/models/explorer/scattersModelMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1682,11 +1682,21 @@ function getScattersModelMethods(
onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
}: {
actionType: 'single' | 'selectAll' | 'removeAll';
actionType: 'single' | 'selectAll' | 'removeAll' | 'range';
data?: any;
rangeStart?: number;
rangeEnd?: number;
}): void {
return onRowSelect({ actionType, data, model });
return onRowSelect({
actionType,
data,
rangeStart,
rangeEnd,
model,
});
},
onRowsVisibilityChange(metricKeys: string[]): void {
return onRowsVisibilityChange({
Expand Down
36 changes: 34 additions & 2 deletions src/src/utils/app/onRowSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,28 @@ import _ from 'lodash-es';
import { IModel, State } from 'types/services/models/model';

/**
*
* Select row in table and update selectedRows state
* @param {string} key - key of table column
* @param {any} data - nested data
* @param {string} actionType - action type name
* @param {number} rangeStart - start range for range selection
* @param {number} rangeEnd - end range for range selection
* @param {IModel<M extends State>} model - instance of create model
*/

export interface IRowSelectProps {
actionType: 'single' | 'selectAll' | 'removeAll';
actionType: 'single' | 'selectAll' | 'removeAll' | 'range';
data?: any;
rangeStart?: number;
rangeEnd?: number;
model: IModel<State>;
}

export default function onRowSelect({
actionType,
data,
rangeStart = 0,
rangeEnd = 0,
model,
}: IRowSelectProps): any {
let selectedRows = model.getState()?.selectedRows || {};
Expand Down Expand Up @@ -86,6 +92,32 @@ export default function onRowSelect({
selectedRows = _.omit(selectedRows, hashArray);
}

break;
case 'range':
if (Array.isArray(data)) {
// Compute min and max to allow reverse selection (from bottom to top)
const rangeMin = Math.min(rangeStart, rangeEnd);
const rangeMax = Math.max(rangeStart, rangeEnd);
if (selectedRows[data[rangeEnd].selectKey]) {
// Remove all rows in range if last row was already selected
const hashes = data
.slice(rangeMin, rangeMax + 1)
.map((item: any) => item.selectKey);
selectedRows = _.omit(selectedRows, hashes);
} else {
// Add all rows in range otherwise
data.slice(rangeMin, rangeMax + 1).forEach((item: any) => {
if (!selectedRows[item.selectKey]) {
selectedRows[item.selectKey] = {
selectKey: item.selectKey,
isHidden: item.isHidden,
key: item.key,
...rawData[sliceRunHash(item.selectKey)],
};
}
});
}
}
break;
}

Expand Down

0 comments on commit 32cea02

Please sign in to comment.