Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tensorboard/webapp/metrics/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,11 @@ export const selectTimeEnableToggled = createAction(
export const useRangeSelectTimeToggled = createAction(
'[Metrics] Use Range Select Time Toggle'
);

export const metricsPromoDismissed = createAction(
'[Metrics] Metrics Promo Dismissed'
);

export const metricsPromoGoToScalars = createAction(
'[Metrics] Metrics Promo Go To Scalars'
);
11 changes: 11 additions & 0 deletions tensorboard/webapp/metrics/views/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,32 @@ tf_sass_binary(
src = "metrics_container.scss",
)

tf_sass_binary(
name = "metrics_promo_styles",
src = "metrics_promo_notice_component.scss",
)

tf_ng_module(
name = "views",
srcs = [
"metrics_container.ts",
"metrics_promo_notice_component.ts",
"metrics_promo_notice_container.ts",
"metrics_promo_notice_types.ts",
"metrics_views_module.ts",
],
assets = [
":metrics_container_styles",
":metrics_promo_styles",
"metrics_promo_notice_component.ng.html",
],
deps = [
"//tensorboard/webapp:app_state",
"//tensorboard/webapp:selectors",
"//tensorboard/webapp/angular:expect_angular_material_icon",
"//tensorboard/webapp/core",
"//tensorboard/webapp/customization",
"//tensorboard/webapp/metrics/actions",
"//tensorboard/webapp/metrics/views/main_view",
"//tensorboard/webapp/metrics/views/right_pane",
"//tensorboard/webapp/runs/views/runs_selector",
Expand Down Expand Up @@ -75,6 +85,7 @@ tf_ts_library(
"//tensorboard/webapp/angular:expect_angular_core_testing",
"//tensorboard/webapp/angular:expect_angular_platform_browser_animations",
"//tensorboard/webapp/angular:expect_ngrx_store_testing",
"//tensorboard/webapp/metrics/actions",
"//tensorboard/webapp/metrics/data_source",
"@npm//@angular/core",
"@npm//@angular/platform-browser",
Expand Down
7 changes: 6 additions & 1 deletion tensorboard/webapp/metrics/views/metrics_container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ limitations under the License.

:host {
display: flex;
height: 100%;
flex-direction: column;
height: 100%;
justify-content: stretch;
overflow: hidden;
}

.notice {
background-color: rgba(mat-color($mat-yellow, 200), 0.85);
border-bottom: 1px solid mat-color($mat-yellow, 500);
color: map-get($tb-foreground, text);
display: block;
flex: 0 0;
}

Expand Down
7 changes: 4 additions & 3 deletions tensorboard/webapp/metrics/views/metrics_container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {getIsTimeSeriesPromotionEnabled} from '../../selectors';
@Component({
selector: 'metrics-dashboard',
template: `
<div *ngIf="isButterBarEnabled$ | async" class="notice">
Temporary butter bar content.
</div>
<metrics-promo-notice
*ngIf="isButterBarEnabled$ | async"
class="notice"
></metrics-promo-notice>
<tb-dashboard-layout>
<runs-selector sidebar></runs-selector>
<metrics-main-view main></metrics-main-view>
Expand Down
41 changes: 38 additions & 3 deletions tensorboard/webapp/metrics/views/metrics_container_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core';
import {TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {Store} from '@ngrx/store';
import {Action, Store} from '@ngrx/store';
import {MockStore, provideMockStore} from '@ngrx/store/testing';

import {State} from '../../app_state';
import {getIsTimeSeriesPromotionEnabled} from '../../selectors';
import {metricsPromoDismissed, metricsPromoGoToScalars} from '../actions';
import {MetricsDashboardContainer} from './metrics_container';
import {MetricsPromoNoticeComponent} from './metrics_promo_notice_component';
import {MetricsPromoNoticeContainer} from './metrics_promo_notice_container';

describe('metrics view', () => {
Expand All @@ -30,7 +32,11 @@ describe('metrics view', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NoopAnimationsModule],
declarations: [MetricsDashboardContainer, MetricsPromoNoticeContainer],
declarations: [
MetricsDashboardContainer,
MetricsPromoNoticeContainer,
MetricsPromoNoticeComponent,
],
providers: [provideMockStore()],
// Ignore errors from components that are out-of-scope for this test:
// 'runs-selector'.
Expand All @@ -55,4 +61,33 @@ describe('metrics view', () => {

expect(fixture.debugElement.query(By.css('.notice'))).not.toBeNull();
});

describe('promotion', () => {
let actions: Action[];

function createComponent(): DebugElement {
actions = [];
spyOn(store, 'dispatch').and.callFake((action) => actions.push(action));

store.overrideSelector(getIsTimeSeriesPromotionEnabled, true);
const fixture = TestBed.createComponent(MetricsDashboardContainer);
fixture.detectChanges();

return fixture.debugElement.query(By.css('metrics-promo-notice'));
}

it('dispatches action when clicking on dismiss', () => {
const promoEl = createComponent();
promoEl.query(By.css('.dismiss')).nativeElement.click();

expect(actions).toEqual([metricsPromoDismissed()]);
});

it('dispatches action when clicking on "Go to scalars"', () => {
const promoEl = createComponent();
promoEl.query(By.css('.go-to-scalars')).nativeElement.click();

expect(actions).toEqual([metricsPromoGoToScalars()]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
Temporary butter bar content.
<tb-customization [customizableComponent]="customPromoMessage" class="message">
Welcome to new default experience of TensorBoard. Time Series lets you view
all visualizations at once, put them side-by-side with pins, and customize
colors. Scalars and other plugins are still available.
<button class="go-to-scalars" (click)="onGoToScalars.emit()">
Go to Scalars plugin</button
>.
</tb-customization>
<button class="dismiss" (click)="onDismiss.emit()">
<mat-icon inline svgIcon="close_24px"></mat-icon>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
@import 'tensorboard/webapp/theme/tb_theme';

:host {
display: flex;
font-size: 14px;
gap: 5px;
justify-content: space-between;
line-height: 20px;
padding: 5px 10px;
}

button {
background-color: transparent;
border: 0;
color: inherit;
cursor: pointer;
font: inherit;
padding: 0;

&:hover {
text-decoration: underline;
}
}

tb-customization button {
color: map-get($tb-foreground, link);
}

.dismiss {
align-self: baseline;
flex: none;
height: 20px;
width: 20px;
}
26 changes: 24 additions & 2 deletions tensorboard/webapp/metrics/views/metrics_promo_notice_component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,33 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Inject,
Optional,
Output,
Type,
} from '@angular/core';
import {METRICS_PROMO_MESSAGE_COMPONENT} from './metrics_promo_notice_types';

@Component({
selector: 'metrics-promo-notice-component',
templateUrl: 'metrics_promo_notice_component.ng.html',
styleUrls: ['metrics_promo_notice_component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MetricsPromoNoticeComponent {}
export class MetricsPromoNoticeComponent {
@Output()
readonly onDismiss = new EventEmitter();

@Output()
readonly onGoToScalars = new EventEmitter();

constructor(
@Optional()
@Inject(METRICS_PROMO_MESSAGE_COMPONENT)
readonly customPromoMessage: Type<Component>
) {}
}
21 changes: 19 additions & 2 deletions tensorboard/webapp/metrics/views/metrics_promo_notice_container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,27 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {Store} from '@ngrx/store';

import {State} from '../../app_state';
import {metricsPromoDismissed, metricsPromoGoToScalars} from '../actions';

@Component({
selector: 'metrics-promo-notice',
template: `<metrics-promo-notice-component></metrics-promo-notice-component>`,
template: `<metrics-promo-notice-component
(onDismiss)="onDismiss()"
(onGoToScalars)="onGoToScalars()"
></metrics-promo-notice-component>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MetricsPromoNoticeContainer {}
export class MetricsPromoNoticeContainer {
constructor(private readonly store: Store<State>) {}

onDismiss() {
this.store.dispatch(metricsPromoDismissed());
}

onGoToScalars() {
this.store.dispatch(metricsPromoGoToScalars());
}
}
24 changes: 24 additions & 0 deletions tensorboard/webapp/metrics/views/metrics_promo_notice_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

import {Component, InjectionToken, Type} from '@angular/core';

/**
* When this token exists, it will replace Metrics promotion message by the
* content of the provided component.
*/
export const METRICS_PROMO_MESSAGE_COMPONENT = new InjectionToken<
Type<Component>
>('[Metrics] METRICS_Promo Message Component');
4 changes: 4 additions & 0 deletions tensorboard/webapp/metrics/views/metrics_views_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ limitations under the License.
==============================================================================*/
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatIconModule} from '@angular/material/icon';

import {LayoutModule} from '../../core';
import {CustomizationModule} from '../../customization/customization_module';
import {RunsSelectorModule} from '../../runs/views/runs_selector/runs_selector_module';
import {MainViewModule} from './main_view/main_view_module';
import {MetricsDashboardContainer} from './metrics_container';
Expand All @@ -32,8 +34,10 @@ import {RightPaneModule} from './right_pane/right_pane_module';
exports: [MetricsDashboardContainer],
imports: [
CommonModule,
CustomizationModule,
LayoutModule,
MainViewModule,
MatIconModule,
RightPaneModule,
RunsSelectorModule,
],
Expand Down