Skip to content

Commit ff3f0f8

Browse files
Merge pull request #72 from Demonstrandum/cursor/collapsible-superimposed-section-b74a
Make superimposed section collapsible like other tag group sections
2 parents 3d93aef + 217c88b commit ff3f0f8

9 files changed

Lines changed: 94 additions & 17 deletions

File tree

tensorbored/webapp/metrics/actions/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ export const metricsTagGroupExpansionStateLoaded = createAction(
206206
props<{expandedGroups: Array<[string, boolean]>}>()
207207
);
208208

209+
export const metricsSuperimposedSectionExpansionChanged = createAction(
210+
'[Metrics] Superimposed Section Expansion Changed'
211+
);
212+
209213
export const cardFullWidthStateLoaded = createAction(
210214
'[Metrics] Card Full Width State Loaded From Storage',
211215
props<{fullWidthCardIds: string[]; fullWidthSuperimposedCardIds: string[]}>()

tensorbored/webapp/metrics/effects/index.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ import {
108108
getTagSymlogLinearThresholds,
109109
getSuperimposedCardsWithMetadata,
110110
getMetricsTagGroupExpansionMap,
111+
getMetricsSuperimposedSectionExpanded,
111112
getCardStateMap,
112113
getFullWidthSuperimposedCards,
113114
} from '../store';
@@ -875,22 +876,23 @@ export class MetricsEffects implements OnInitEffects {
875876
this.persistTagGroupExpansion$ = this.actions$.pipe(
876877
ofType(
877878
actions.metricsTagGroupExpansionChanged,
878-
actions.metricsTagMetadataLoaded
879+
actions.metricsTagMetadataLoaded,
880+
actions.metricsSuperimposedSectionExpansionChanged
879881
),
880882
debounceTime(200),
881-
withLatestFrom(this.store.select(getMetricsTagGroupExpansionMap)),
882-
tap(([, expansionMap]) => {
883+
withLatestFrom(
884+
this.store.select(getMetricsTagGroupExpansionMap),
885+
this.store.select(getMetricsSuperimposedSectionExpanded)
886+
),
887+
tap(([, expansionMap, superimposedExpanded]) => {
883888
const entries: Array<[string, boolean]> = Array.from(
884889
expansionMap.entries()
885890
);
886-
if (entries.length > 0) {
887-
window.localStorage.setItem(
888-
TAG_GROUP_EXPANSION_STORAGE_KEY,
889-
JSON.stringify({version: 1, groups: entries})
890-
);
891-
} else {
892-
window.localStorage.removeItem(TAG_GROUP_EXPANSION_STORAGE_KEY);
893-
}
891+
entries.push(['__superimposed__', superimposedExpanded]);
892+
window.localStorage.setItem(
893+
TAG_GROUP_EXPANSION_STORAGE_KEY,
894+
JSON.stringify({version: 1, groups: entries})
895+
);
894896
window.dispatchEvent(new CustomEvent('tb-tag-group-expansion-changed'));
895897
})
896898
);

tensorbored/webapp/metrics/store/metrics_reducers.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ const {initialState, reducers: namespaceContextedReducer} =
502502
superimposedCardMetadataMap: {},
503503
superimposedCardList: [],
504504
fullWidthSuperimposedCards: new Set<string>(),
505+
superimposedSectionExpanded: true,
505506
},
506507
{
507508
isSettingsPaneOpen: true,
@@ -1280,8 +1281,21 @@ const reducer = createReducer(
12801281
return {...state, tagGroupExpanded};
12811282
}),
12821283
on(actions.metricsTagGroupExpansionStateLoaded, (state, {expandedGroups}) => {
1283-
const tagGroupExpanded = new Map<string, boolean>(expandedGroups);
1284-
return {...state, tagGroupExpanded};
1284+
const superimposedEntry = expandedGroups.find(
1285+
([key]) => key === '__superimposed__'
1286+
);
1287+
const tagGroupExpanded = new Map<string, boolean>(
1288+
expandedGroups.filter(([key]) => key !== '__superimposed__')
1289+
);
1290+
const superimposedSectionExpanded =
1291+
superimposedEntry !== undefined ? superimposedEntry[1] : true;
1292+
return {...state, tagGroupExpanded, superimposedSectionExpanded};
1293+
}),
1294+
on(actions.metricsSuperimposedSectionExpansionChanged, (state) => {
1295+
return {
1296+
...state,
1297+
superimposedSectionExpanded: !state.superimposedSectionExpanded,
1298+
};
12851299
}),
12861300
on(
12871301
actions.cardFullWidthStateLoaded,

tensorbored/webapp/metrics/store/metrics_selectors.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ export const getMetricsTagGroupExpansionMap = createSelector(
473473
}
474474
);
475475

476+
export const getMetricsSuperimposedSectionExpanded = createSelector(
477+
selectMetricsState,
478+
(state: MetricsState): boolean => state.superimposedSectionExpanded
479+
);
480+
476481
export const getMetricsLinkedTimeEnabled = createSelector(
477482
selectMetricsState,
478483
(state: MetricsState): boolean => {

tensorbored/webapp/metrics/store/metrics_types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ export interface MetricsNamespacedState {
242242
* Set of superimposed card IDs that are displayed at full width.
243243
*/
244244
fullWidthSuperimposedCards: Set<SuperimposedCardId>;
245+
246+
/**
247+
* Whether the Superimposed section header is expanded (cards visible).
248+
* Defaults to true. Persisted in the same localStorage key as tagGroupExpanded,
249+
* using the reserved key '__superimposed__'.
250+
*/
251+
superimposedSectionExpanded: boolean;
245252
}
246253

247254
export interface MetricsSettings {

tensorbored/webapp/metrics/testing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ function buildBlankState(): MetricsState {
161161
superimposedCardMetadataMap: {},
162162
superimposedCardList: [],
163163
fullWidthSuperimposedCards: new Set<string>(),
164+
superimposedSectionExpanded: true,
164165
};
165166
}
166167

tensorbored/webapp/metrics/views/main_view/superimposed_cards_view_component.scss

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,21 @@ limitations under the License.
2121

2222
.group-toolbar {
2323
@include tb-theme-background-prop(background-color, background);
24-
@include tb-theme-foreground-prop(border-bottom, border, 1px solid);
24+
@include tb-theme-foreground-prop(color, text);
2525
align-items: center;
2626
background-color: #fff;
27+
border: 0;
28+
@include tb-theme-foreground-prop(border-bottom, border, 1px solid);
29+
cursor: pointer;
2730
display: flex;
2831
flex: none;
32+
font: inherit;
2933
height: 42px;
3034
margin-bottom: -1px;
3135
padding: 0 16px;
3236
position: sticky;
3337
top: 0;
38+
width: 100%;
3439
z-index: 1;
3540
box-shadow: 0px 2px 4px 0px rgba(#000, 15%);
3641
@include tb-dark-theme {
@@ -40,8 +45,10 @@ limitations under the License.
4045
.left-items {
4146
align-items: center;
4247
display: flex;
48+
flex-grow: 1;
4349
gap: 10px;
4450
overflow: hidden;
51+
text-align: left;
4552

4653
mat-icon {
4754
color: #673ab7;
@@ -70,6 +77,10 @@ limitations under the License.
7077
}
7178
}
7279

80+
.expand-group-icon {
81+
@include tb-theme-foreground-prop(color, secondary-text);
82+
}
83+
7384
.superimposed-cards-grid {
7485
display: grid;
7586
grid-template-columns: repeat(

tensorbored/webapp/metrics/views/main_view/superimposed_cards_view_component.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ limitations under the License.
1515
import {
1616
ChangeDetectionStrategy,
1717
Component,
18+
EventEmitter,
1819
Input,
1920
OnChanges,
21+
Output,
2022
SimpleChanges,
2123
} from '@angular/core';
2224
import {Store} from '@ngrx/store';
@@ -35,7 +37,14 @@ const MAX_CARD_MIN_WIDTH_IN_PX = 735;
3537
selector: 'superimposed-cards-view-component',
3638
template: `
3739
<ng-container *ngIf="superimposedCards.length > 0">
38-
<div class="group-toolbar">
40+
<button
41+
class="group-toolbar"
42+
i18n-aria-label="
43+
A button that allows user to expand the superimposed section.
44+
"
45+
aria-label="Expand superimposed section"
46+
(click)="expansionToggled.emit()"
47+
>
3948
<div class="left-items">
4049
<mat-icon svgIcon="group_work_24px"></mat-icon>
4150
<span class="group-text">
@@ -47,8 +56,18 @@ const MAX_CARD_MIN_WIDTH_IN_PX = 735;
4756
>
4857
</span>
4958
</div>
50-
</div>
59+
<span class="expand-group-icon">
60+
<mat-icon
61+
*ngIf="isExpanded; else expandMore"
62+
svgIcon="expand_less_24px"
63+
></mat-icon>
64+
<ng-template #expandMore>
65+
<mat-icon svgIcon="expand_more_24px"></mat-icon>
66+
</ng-template>
67+
</span>
68+
</button>
5169
<div
70+
*ngIf="isExpanded"
5271
class="superimposed-cards-grid"
5372
[style.grid-template-columns]="gridTemplateColumn"
5473
>
@@ -76,6 +95,8 @@ export class SuperimposedCardsViewComponent implements OnChanges {
7695
@Input() cardObserver!: CardObserver;
7796
@Input() superimposedCards: SuperimposedCardMetadata[] = [];
7897
@Input() cardMinWidth: number | null = null;
98+
@Input() isExpanded: boolean = true;
99+
@Output() expansionToggled = new EventEmitter<void>();
79100

80101
gridTemplateColumn = '';
81102

tensorbored/webapp/metrics/views/main_view/superimposed_cards_view_container.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import {Observable} from 'rxjs';
1818
import {startWith} from 'rxjs/operators';
1919
import {State} from '../../../app_state';
2020
import {getMetricsCardMinWidth} from '../../../selectors';
21-
import {getSuperimposedCardsWithMetadata} from '../../store';
21+
import {
22+
getSuperimposedCardsWithMetadata,
23+
getMetricsSuperimposedSectionExpanded,
24+
} from '../../store';
25+
import {metricsSuperimposedSectionExpansionChanged} from '../../actions';
2226
import {SuperimposedCardMetadata} from '../../types';
2327
import {CardObserver} from '../card_renderer/card_lazy_loader';
2428

@@ -30,6 +34,8 @@ import {CardObserver} from '../card_renderer/card_lazy_loader';
3034
[superimposedCards]="superimposedCards$ | async"
3135
[cardObserver]="cardObserver"
3236
[cardMinWidth]="cardMinWidth$ | async"
37+
[isExpanded]="isExpanded$ | async"
38+
(expansionToggled)="onExpansionToggled()"
3339
></superimposed-cards-view-component>
3440
`,
3541
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -39,11 +45,17 @@ export class SuperimposedCardsViewContainer {
3945

4046
readonly superimposedCards$: Observable<SuperimposedCardMetadata[]>;
4147
readonly cardMinWidth$: Observable<number | null>;
48+
readonly isExpanded$: Observable<boolean>;
4249

4350
constructor(private readonly store: Store<State>) {
4451
this.superimposedCards$ = this.store
4552
.select(getSuperimposedCardsWithMetadata)
4653
.pipe(startWith([]));
4754
this.cardMinWidth$ = this.store.select(getMetricsCardMinWidth);
55+
this.isExpanded$ = this.store.select(getMetricsSuperimposedSectionExpanded);
56+
}
57+
58+
onExpansionToggled() {
59+
this.store.dispatch(metricsSuperimposedSectionExpansionChanged());
4860
}
4961
}

0 commit comments

Comments
 (0)