Skip to content

Commit 9937ee0

Browse files
authored
Adds feature flag to control whether or not to show scalar table context menus (#6742)
## Motivation for features / changes As per discussion in #6737, adding a feature flag in front of scalar table context menus before we implement them.
1 parent 311bbc7 commit 9937ee0

File tree

9 files changed

+78
-1
lines changed

9 files changed

+78
-1
lines changed

tensorboard/webapp/feature_flag/store/feature_flag_metadata.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ export const FeatureFlagMetadataMap: FeatureFlagMetadataMapType<FeatureFlags> =
110110
queryParamOverride: 'enableScalarColumnCustomization',
111111
parseValue: parseBoolean,
112112
},
113+
enableScalarColumnContextMenus: {
114+
defaultValue: false,
115+
queryParamOverride: 'enableScalarColumnContextMenus',
116+
parseValue: parseBoolean,
117+
},
113118
enableHparamsInTimeSeries: {
114119
defaultValue: true,
115120
queryParamOverride: 'enableHparamsInTimeSeries',

tensorboard/webapp/feature_flag/store/feature_flag_selectors.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ export const getIsScalarColumnCustomizationEnabled = createSelector(
147147
}
148148
);
149149

150+
export const getIsScalarColumnContextMenusEnabled = createSelector(
151+
getFeatureFlags,
152+
(flags: FeatureFlags): boolean => {
153+
return flags.enableScalarColumnContextMenus;
154+
}
155+
);
156+
150157
export const getEnableHparamsInTimeSeries = createSelector(
151158
getFeatureFlags,
152159
(flags: FeatureFlags): boolean => {

tensorboard/webapp/feature_flag/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export interface FeatureFlags {
4545
// Adds affordance for users to select and reorder the columns in the Scalar
4646
// Card Data Table
4747
enableScalarColumnCustomization: boolean;
48+
// Allows users to manipulate Scalar Card Table columns using context menus.
49+
enableScalarColumnContextMenus: boolean;
4850
// Adds hparam columns to the runs table and the scalar card data table.
4951
enableHparamsInTimeSeries: boolean;
5052
// Adds a new section at the top of the time series metrics view

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
[columnHeaders]="columnHeaders"
199199
[sortingInfo]="sortingInfo"
200200
[columnCustomizationEnabled]="columnCustomizationEnabled"
201+
[columnContextMenusEnabled]="columnContextMenusEnabled"
201202
[smoothingEnabled]="smoothingEnabled"
202203
[hparamsEnabled]="hparamsEnabled"
203204
(sortDataBy)="sortDataBy($event)"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export class ScalarCardComponent<Downloader> {
9595
@Input() useDarkMode!: boolean;
9696
@Input() forceSvg!: boolean;
9797
@Input() columnCustomizationEnabled!: boolean;
98+
@Input() columnContextMenusEnabled!: boolean;
9899
@Input() linkedTimeSelection: TimeSelectionView | undefined;
99100
@Input() stepOrLinkedTimeSelection: TimeSelection | undefined;
100101
@Input() minMaxStep!: MinMaxStep;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {ExperimentAlias} from '../../../experiments/types';
4040
import {
4141
getEnableHparamsInTimeSeries,
4242
getForceSvgFeatureFlag,
43+
getIsScalarColumnContextMenusEnabled,
4344
getIsScalarColumnCustomizationEnabled,
4445
} from '../../../feature_flag/store/feature_flag_selectors';
4546
import {
@@ -169,6 +170,7 @@ function areSeriesEqual(
169170
[stepOrLinkedTimeSelection]="stepOrLinkedTimeSelection$ | async"
170171
[forceSvg]="forceSvg$ | async"
171172
[columnCustomizationEnabled]="columnCustomizationEnabled$ | async"
173+
[columnContextMenusEnabled]="columnContextMenusEnabled$ | async"
172174
[minMaxStep]="minMaxSteps$ | async"
173175
[userViewBox]="userViewBox$ | async"
174176
[columnHeaders]="columnHeaders$ | async"
@@ -237,6 +239,9 @@ export class ScalarCardContainer implements CardRenderer, OnInit, OnDestroy {
237239
readonly columnCustomizationEnabled$ = this.store.select(
238240
getIsScalarColumnCustomizationEnabled
239241
);
242+
readonly columnContextMenusEnabled$ = this.store.select(
243+
getIsScalarColumnContextMenusEnabled
244+
);
240245
readonly xScaleType$ = this.store.select(getMetricsXAxisType).pipe(
241246
map((xAxisType) => {
242247
switch (xAxisType) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
[header]="header"
2929
[sortingInfo]="sortingInfo"
3030
[hparamsEnabled]="hparamsEnabled"
31-
disableContextMenu="true"
31+
[disableContextMenu]="!columnContextMenusEnabled"
3232
></tb-data-table-header-cell> </ng-container
3333
></ng-container>
3434

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export class ScalarCardDataTable {
5151
@Input() columnHeaders!: ColumnHeader[];
5252
@Input() sortingInfo!: SortingInfo;
5353
@Input() columnCustomizationEnabled!: boolean;
54+
@Input() columnContextMenusEnabled!: boolean;
5455
@Input() smoothingEnabled!: boolean;
5556
@Input() hparamsEnabled?: boolean;
5657

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ import * as commonSelectors from '../main_view/common_selectors';
128128
import {ContentCellComponent} from '../../../widgets/data_table/content_cell_component';
129129
import {ContentRowComponent} from '../../../widgets/data_table/content_row_component';
130130
import {HeaderCellComponent} from '../../../widgets/data_table/header_cell_component';
131+
import {getIsScalarColumnContextMenusEnabled} from '../../../selectors';
131132

132133
@Component({
133134
selector: 'line-chart',
@@ -385,6 +386,10 @@ describe('scalar card', () => {
385386
selectors.getIsScalarColumnCustomizationEnabled,
386387
false
387388
);
389+
store.overrideSelector(
390+
selectors.getIsScalarColumnContextMenusEnabled,
391+
false
392+
);
388393
store.overrideSelector(selectors.getMetricsStepSelectorEnabled, false);
389394
store.overrideSelector(
390395
selectors.getMetricsCardRangeSelectionEnabled('card1'),
@@ -4412,6 +4417,56 @@ describe('scalar card', () => {
44124417
expect(dataTableComponent).toBeFalsy();
44134418
}));
44144419

4420+
it('disables context menus if columnContextMenusEnabled is not set', fakeAsync(() => {
4421+
store.overrideSelector(getIsScalarColumnContextMenusEnabled, false);
4422+
store.overrideSelector(getCardStateMap, {
4423+
card1: {
4424+
dataMinMax: {
4425+
minStep: 0,
4426+
maxStep: 100,
4427+
},
4428+
},
4429+
});
4430+
store.overrideSelector(getMetricsCardTimeSelection, {
4431+
start: {step: 0},
4432+
end: {step: 100},
4433+
});
4434+
store.overrideSelector(selectors.getMetricsStepSelectorEnabled, true);
4435+
const fixture = createComponent('card1');
4436+
fixture.detectChanges();
4437+
4438+
const headerCellComponentInstance = fixture.debugElement.query(
4439+
By.directive(HeaderCellComponent)
4440+
).componentInstance;
4441+
4442+
expect(headerCellComponentInstance.disableContextMenu).toBeTrue();
4443+
}));
4444+
4445+
it('enables context menus if columnContextMenusEnabled is set', fakeAsync(() => {
4446+
store.overrideSelector(getIsScalarColumnContextMenusEnabled, true);
4447+
store.overrideSelector(getCardStateMap, {
4448+
card1: {
4449+
dataMinMax: {
4450+
minStep: 0,
4451+
maxStep: 100,
4452+
},
4453+
},
4454+
});
4455+
store.overrideSelector(getMetricsCardTimeSelection, {
4456+
start: {step: 0},
4457+
end: {step: 100},
4458+
});
4459+
store.overrideSelector(selectors.getMetricsStepSelectorEnabled, true);
4460+
const fixture = createComponent('card1');
4461+
fixture.detectChanges();
4462+
4463+
const headerCellComponentInstance = fixture.debugElement.query(
4464+
By.directive(HeaderCellComponent)
4465+
).componentInstance;
4466+
4467+
expect(headerCellComponentInstance.disableContextMenu).toBeFalse();
4468+
}));
4469+
44154470
it('emits dataTableColumnOrderChanged with DataTableMode.SINGLE when orderColumns is called while in Single Selection', fakeAsync(() => {
44164471
store.overrideSelector(getCardStateMap, {
44174472
card1: {

0 commit comments

Comments
 (0)