Skip to content

Commit 56b38b7

Browse files
authored
Column Customization: Use dataTableColumnEdited action when dragging columns in data table (#6291)
* Motivation for features / changes Before this change, dragging the header in the data table called the dataTableColumnDrag action. This action relied on the global rangeSelectionEnabled boolean to decide if it edits the range of single selection headers. This boolean no longer is guaranteed to represent the table which is being edited which can lead to a bug where the single selection table shows the range selection headers and vise versa. * Technical description of changes This moves the decision on which columns to edit to the ScalarCardDataTable component. It also reuses the dataTableColumnEdited action which is used by the ScalarColumnEditor component. * Screenshots of UI changes This is the broken state which is possible before this change. Note that the single selection has the range columns. <img width="900" alt="Screenshot 2023-04-05 at 11 52 24 AM" src="https://user-images.githubusercontent.com/8672809/230177414-bdadc95c-e416-4cce-abcf-6cca55c9dd61.png">
1 parent 7fa2a3e commit 56b38b7

File tree

7 files changed

+92
-30
lines changed

7 files changed

+92
-30
lines changed

tensorboard/webapp/metrics/actions/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,6 @@ export const sortingDataTable = createAction(
234234
props<SortingInfo>()
235235
);
236236

237-
export const dataTableColumnDrag = createAction(
238-
'[Metrics] Data table column dragged',
239-
props<{
240-
newOrder: ColumnHeader[];
241-
}>()
242-
);
243-
244237
export const dataTableColumnEdited = createAction(
245238
'[Metrics] Data table columns edited in edit menu',
246239
props<HeaderEditInfo>()

tensorboard/webapp/metrics/store/metrics_reducers.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,19 +1252,6 @@ const reducer = createReducer(
12521252
linkedTimeSelection: null,
12531253
};
12541254
}),
1255-
on(actions.dataTableColumnDrag, (state, {newOrder}) => {
1256-
if (state.rangeSelectionEnabled) {
1257-
return {
1258-
...state,
1259-
rangeSelectionHeaders: newOrder,
1260-
};
1261-
}
1262-
1263-
return {
1264-
...state,
1265-
singleSelectionHeaders: newOrder,
1266-
};
1267-
}),
12681255
on(actions.dataTableColumnEdited, (state, {dataTableMode, headers}) => {
12691256
const enabledNewHeaders: ColumnHeader[] = [];
12701257
const disabledNewHeaders: ColumnHeader[] = [];

tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ng.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
[columnCustomizationEnabled]="columnCustomizationEnabled"
201201
[smoothingEnabled]="smoothingEnabled"
202202
(sortDataBy)="sortDataBy($event)"
203-
(orderColumns)="reorderColumnHeaders.emit($event)"
203+
(editColumnHeaders)="editColumnHeaders.emit($event)"
204204
>
205205
</scalar-card-data-table>
206206
</div>

tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
TooltipDatum,
4545
} from '../../../widgets/line_chart_v2/types';
4646
import {CardState} from '../../store';
47-
import {TooltipSort, XAxisType} from '../../types';
47+
import {HeaderEditInfo, TooltipSort, XAxisType} from '../../types';
4848
import {
4949
ColumnHeader,
5050
ColumnHeaderType,
@@ -108,7 +108,7 @@ export class ScalarCardComponent<Downloader> {
108108
@Output() onStepSelectorToggled =
109109
new EventEmitter<TimeSelectionToggleAffordance>();
110110
@Output() onDataTableSorting = new EventEmitter<SortingInfo>();
111-
@Output() reorderColumnHeaders = new EventEmitter<ColumnHeader[]>();
111+
@Output() editColumnHeaders = new EventEmitter<HeaderEditInfo>();
112112
@Output() openSlideoutColumnEditMenu = new EventEmitter<void>();
113113

114114
@Output() onLineChartZoom = new EventEmitter<Extent>();

tensorboard/webapp/metrics/views/card_renderer/scalar_card_container.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import {Extent} from '../../../widgets/line_chart_v2/lib/public_types';
6868
import {ScaleType} from '../../../widgets/line_chart_v2/types';
6969
import {
7070
cardMinMaxChanged,
71-
dataTableColumnDrag,
71+
dataTableColumnEdited,
7272
metricsCardFullSizeToggled,
7373
metricsCardStateUpdated,
7474
sortingDataTable,
@@ -92,12 +92,13 @@ import {
9292
getSingleSelectionHeaders,
9393
RunToSeries,
9494
} from '../../store';
95-
import {CardId, CardMetadata, XAxisType} from '../../types';
95+
import {CardId, CardMetadata, HeaderEditInfo, XAxisType} from '../../types';
9696
import {CardRenderer} from '../metrics_view_types';
9797
import {getTagDisplayName} from '../utils';
9898
import {DataDownloadDialogContainer} from './data_download_dialog_container';
9999
import {
100100
ColumnHeader,
101+
DataTableMode,
101102
MinMaxStep,
102103
PartialSeries,
103104
PartitionedSeries,
@@ -182,7 +183,7 @@ function isMinMaxStepValid(minMax: MinMaxStep | undefined): boolean {
182183
(onStepSelectorToggled)="onStepSelectorToggled($event)"
183184
(onDataTableSorting)="onDataTableSorting($event)"
184185
(onLineChartZoom)="onLineChartZoom($event)"
185-
(reorderColumnHeaders)="reorderColumnHeaders($event)"
186+
(editColumnHeaders)="editColumnHeaders($event)"
186187
(onCardStateChanged)="onCardStateChanged($event)"
187188
(openSlideoutColumnEditMenu)="openSlideoutColumnEditMenu()"
188189
></scalar-card-component>
@@ -663,8 +664,8 @@ export class ScalarCardContainer implements CardRenderer, OnInit, OnDestroy {
663664
);
664665
}
665666

666-
reorderColumnHeaders(headers: ColumnHeader[]) {
667-
this.store.dispatch(dataTableColumnDrag({newOrder: headers}));
667+
editColumnHeaders(headerEditInfo: HeaderEditInfo) {
668+
this.store.dispatch(dataTableColumnEdited(headerEditInfo));
668669
}
669670

670671
openSlideoutColumnEditMenu() {

tensorboard/webapp/metrics/views/card_renderer/scalar_card_data_table.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import {
2121
} from '@angular/core';
2222
import {TimeSelection} from '../../../widgets/card_fob/card_fob_types';
2323
import {findClosestIndex} from '../../../widgets/line_chart_v2/sub_view/line_chart_interactive_utils';
24+
import {HeaderEditInfo} from '../../types';
2425
import {
2526
ColumnHeader,
2627
ColumnHeaderType,
28+
DataTableMode,
2729
ScalarCardDataSeries,
2830
ScalarCardPoint,
2931
ScalarCardSeriesMetadataMap,
@@ -43,7 +45,7 @@ import {isDatumVisible} from './utils';
4345
[columnCustomizationEnabled]="columnCustomizationEnabled"
4446
[smoothingEnabled]="smoothingEnabled"
4547
(sortDataBy)="sortDataBy.emit($event)"
46-
(orderColumns)="orderColumns.emit($event)"
48+
(orderColumns)="orderColumns($event)"
4749
></tb-data-table>
4850
`,
4951
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -58,7 +60,7 @@ export class ScalarCardDataTable {
5860
@Input() smoothingEnabled!: boolean;
5961

6062
@Output() sortDataBy = new EventEmitter<SortingInfo>();
61-
@Output() orderColumns = new EventEmitter<ColumnHeader[]>();
63+
@Output() editColumnHeaders = new EventEmitter<HeaderEditInfo>();
6264

6365
getMinPointInRange(
6466
points: ScalarCardPoint[],
@@ -278,6 +280,15 @@ export class ScalarCardDataTable {
278280
return makeValueSortable(point[header]);
279281
}
280282
}
283+
284+
orderColumns(headers: ColumnHeader[]) {
285+
this.editColumnHeaders.emit({
286+
headers: headers,
287+
dataTableMode: this.stepOrLinkedTimeSelection.end
288+
? DataTableMode.RANGE
289+
: DataTableMode.SINGLE,
290+
});
291+
}
281292
}
282293

283294
function makeValueSortable(value: number | string | null | undefined) {

tensorboard/webapp/metrics/views/card_renderer/scalar_card_test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import {
8181
stepSelectorToggled,
8282
timeSelectionChanged,
8383
metricsSlideoutMenuOpened,
84+
dataTableColumnEdited,
8485
} from '../../actions';
8586
import {PluginType} from '../../data_source';
8687
import {
@@ -111,6 +112,7 @@ import {ScalarCardFobController} from './scalar_card_fob_controller';
111112
import {
112113
ColumnHeader,
113114
ColumnHeaderType,
115+
DataTableMode,
114116
ScalarCardPoint,
115117
ScalarCardSeriesMetadata,
116118
SeriesType,
@@ -3932,6 +3934,74 @@ describe('scalar card', () => {
39323934

39333935
expect(dataTableComponent).toBeFalsy();
39343936
}));
3937+
3938+
it('emits dataTableColumnEdited with DataTableMode.SINGLE when orderColumns is called while in Single Selection', fakeAsync(() => {
3939+
store.overrideSelector(getCardStateMap, {
3940+
card1: {
3941+
dataMinMax: {
3942+
minStep: 0,
3943+
maxStep: 100,
3944+
},
3945+
},
3946+
});
3947+
store.overrideSelector(getMetricsCardTimeSelection, {
3948+
start: {step: 1},
3949+
end: null,
3950+
});
3951+
store.overrideSelector(selectors.getMetricsStepSelectorEnabled, true);
3952+
const fixture = createComponent('card1');
3953+
fixture.detectChanges();
3954+
const scalarCardDataTable = fixture.debugElement.query(
3955+
By.directive(ScalarCardDataTable)
3956+
);
3957+
3958+
const headers = [
3959+
{type: ColumnHeaderType.RUN, enabled: true},
3960+
{type: ColumnHeaderType.VALUE, enabled: true},
3961+
];
3962+
scalarCardDataTable.componentInstance.orderColumns(headers);
3963+
3964+
expect(dispatchedActions).toEqual([
3965+
dataTableColumnEdited({
3966+
headers,
3967+
dataTableMode: DataTableMode.SINGLE,
3968+
}),
3969+
]);
3970+
}));
3971+
3972+
it('emits dataTableColumnEdited with DataTableMode.RANGE when orderColumns is called while in Range Selection', fakeAsync(() => {
3973+
store.overrideSelector(getCardStateMap, {
3974+
card1: {
3975+
dataMinMax: {
3976+
minStep: 0,
3977+
maxStep: 100,
3978+
},
3979+
},
3980+
});
3981+
store.overrideSelector(getMetricsCardTimeSelection, {
3982+
start: {step: 1},
3983+
end: {step: 20},
3984+
});
3985+
store.overrideSelector(selectors.getMetricsStepSelectorEnabled, true);
3986+
const fixture = createComponent('card1');
3987+
fixture.detectChanges();
3988+
const scalarCardDataTable = fixture.debugElement.query(
3989+
By.directive(ScalarCardDataTable)
3990+
);
3991+
3992+
const headers = [
3993+
{type: ColumnHeaderType.RUN, enabled: true},
3994+
{type: ColumnHeaderType.VALUE, enabled: true},
3995+
];
3996+
scalarCardDataTable.componentInstance.orderColumns(headers);
3997+
3998+
expect(dispatchedActions).toEqual([
3999+
dataTableColumnEdited({
4000+
headers,
4001+
dataTableMode: DataTableMode.RANGE,
4002+
}),
4003+
]);
4004+
}));
39354005
});
39364006
});
39374007
});

0 commit comments

Comments
 (0)