Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Commit

Permalink
Improve recent and favourites display (#4421)
Browse files Browse the repository at this point in the history
* Improve recent and favourites display

* Remove debug logging

* Remove debug logging/subscription leak

* Unit test fix

* Tweaks following review

* Changes following review
- favourite & recent icon changes

Co-authored-by: Richard Cox <richard.cox@suse.com>
  • Loading branch information
nwmac and richard-cox committed Jul 9, 2020
1 parent e457a61 commit 0d021ed
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 315 deletions.
13 changes: 9 additions & 4 deletions src/frontend/packages/cloud-foundry/src/cf-entity-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1143,10 +1143,11 @@ function generateCfApplicationEntity(endpointDefinition: StratosEndpointExtensio
label: 'Application',
labelPlural: 'Applications',
endpoint: endpointDefinition,
icon: 'apps',
tableConfig: {
rowBuilders: [
['Name', (entity) => entity.entity.name],
['Creation Date', (entity) => entity.metadata.created_at]
['Created', (entity) => entity.metadata.created_at]
]
}
};
Expand All @@ -1172,7 +1173,7 @@ function generateCfApplicationEntity(endpointDefinition: StratosEndpointExtensio
getLink: metadata => `/applications/${metadata.cfGuid}/${metadata.guid}/summary`,
getGuid: metadata => metadata.guid,
getLines: () => ([
['Creation Date', (meta) => meta.createdAt]
['Created', (meta) => meta.createdAt]
])
},
actionBuilders: applicationActionBuilder
Expand All @@ -1191,6 +1192,8 @@ function generateCfSpaceEntity(endpointDefinition: StratosEndpointExtensionDefin
label: 'Space',
labelPlural: 'Spaces',
endpoint: endpointDefinition,
icon: 'virtual_space',
iconFont: 'stratos-icons'
};
cfEntityCatalog.space = new StratosCatalogEntity<ISpaceFavMetadata, APIResource<ISpace>, SpaceActionBuilders>(
spaceDefinition,
Expand All @@ -1210,7 +1213,7 @@ function generateCfSpaceEntity(endpointDefinition: StratosEndpointExtensionDefin
createdAt: moment(space.metadata.created_at).format('LLL'),
}),
getLines: () => ([
['Creation Date', (meta) => meta.createdAt]
['Created', (meta) => meta.createdAt]
]),
getLink: metadata => `/cloud-foundry/${metadata.cfGuid}/organizations/${metadata.orgGuid}/spaces/${metadata.guid}/summary`,
getGuid: metadata => metadata.guid
Expand All @@ -1227,6 +1230,8 @@ function generateCfOrgEntity(endpointDefinition: StratosEndpointExtensionDefinit
label: 'Organization',
labelPlural: 'Organizations',
endpoint: endpointDefinition,
icon: 'organization',
iconFont: 'stratos-icons'
};
cfEntityCatalog.org = new StratosCatalogEntity<
IOrgFavMetadata,
Expand All @@ -1252,7 +1257,7 @@ function generateCfOrgEntity(endpointDefinition: StratosEndpointExtensionDefinit
}),
getLink: metadata => `/cloud-foundry/${metadata.cfGuid}/organizations/${metadata.guid}`,
getLines: () => ([
['Creation Date', (meta) => meta.createdAt]
['Created', (meta) => meta.createdAt]
]),
getGuid: metadata => metadata.guid
}
Expand Down
4 changes: 3 additions & 1 deletion src/frontend/packages/core/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,18 +231,20 @@ export class AppModule {
}
);

// This updates the names of any recents
debouncedApiRequestData$.pipe(
withLatestFrom(recents$)
).subscribe(
([entities, recents]) => {
Object.values(recents.entities).forEach(recentEntity => {
Object.values(recents).forEach(recentEntity => {
const mapper = this.favoritesConfigMapper.getMapperFunction(recentEntity);
const entityKey = entityCatalog.getEntityKey(recentEntity);
if (entities[entityKey] && entities[entityKey][recentEntity.entityId]) {
const entity = entities[entityKey][recentEntity.entityId];
const entityToMetadata = this.favoritesConfigMapper.getEntityMetadata(recentEntity, entity);
const name = mapper(entityToMetadata).name;
if (name && name !== recentEntity.name) {
// Update the entity name
this.store.dispatch(new SetRecentlyVisitedEntityAction({
...recentEntity,
name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $page-padding: 20px;
flex: 1;
flex-direction: column;
margin: 0 -#{$page-padding} -#{$page-padding};
padding: 24px;
padding: 20px;
@include breakpoint(tablet) {
margin: -#{$page-padding} -#{$page-padding} -#{$page-padding} $page-padding;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
[entityConfig]="entityConfig">
<app-meta-card-title class="fav-meta-card__header">
<div class="fav-meta-card__header">
<div *ngIf="!compact" class="fav-meta-card__icon-panel">
<img class="fav-meta-card__icon" *ngIf="iconUrl$ | async as imageUrl" [src]="imageUrl" />
<div *ngIf="!compact" class="fav-meta-card__logo-panel">
<img class="fav-meta-card__logo" *ngIf="icon.logoUrl" [src]="icon.logoUrl" />
</div>
<div *ngIf="compact" class="fav-meta-card__icon-panel">
<mat-icon class="fav-meta-card__icon" *ngIf="icon.icon && !icon.logoUrl" [fontSet]="icon.iconFont">{{ icon.icon }}</mat-icon>
</div>
<div class="fav-meta-card__header-text-panel">
<h2 class="fav-meta-card__header-text" *ngIf="!compact">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,26 @@
}
&__header {
display: flex;
white-space: nowrap;
}
&__icon-panel {
&__logo-panel {
display: flex;
justify-content: center;
justify-content: left;
width: 56px;
}
&__icon {
&__logo {
height: 48px;
margin-right: 8px;
width: auto;
}
&__icon {
margin-right: 4px;
opacity: .7;
}
&__icon-panel {
display: flex;
justify-content: left;
width: 32px;
}
&__panel {
display: flex;
:first-child {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import { isEndpointConnected } from '../../../features/endpoints/connect.service
import { ConfirmationDialogConfig } from '../confirmation-dialog.config';
import { ConfirmationDialogService } from '../confirmation-dialog.service';

interface FavoriteIconData {
hasIcon: boolean;
icon?: string;
iconFont?: string;
logoUrl?: string;
}

@Component({
selector: 'app-favorites-meta-card',
Expand Down Expand Up @@ -64,6 +70,9 @@ export class FavoritesMetaCardComponent {
// Optional icon for the favorite
public iconUrl$: Observable<string>;

// Optional icon for the favorite
public icon: FavoriteIconData;

@Input()
set favoriteEntity(favoriteEntity: IFavoriteEntity) {
if (!this.placeholder && favoriteEntity) {
Expand All @@ -88,6 +97,14 @@ export class FavoritesMetaCardComponent {
this.iconUrl$ = observableOf('');
}

const entityDef = entityCatalog.getEntity(this.favorite.endpointType, this.favorite.entityType);
this.icon = {
hasIcon: !!entityDef.definition.logoUrl || !!entityDef.definition.icon,
icon: entityDef.definition.icon,
iconFont: entityDef.definition.iconFont,
logoUrl: entityDef.definition.logoUrl,
};

this.setConfirmation(this.prettyName, favorite);

const config = cardMapper && favorite && favorite.metadata ? cardMapper(favorite.metadata) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
background-color: mat-color($foreground, divider);
}
&__history {
color: $subdued;
color: mat-color($foreground, text);
}
&__underflow {
background-color: $underflow-background;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TemplatePortal } from '@angular/cdk/portal';
import { AfterViewInit, Component, Input, OnDestroy, TemplateRef, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Store } from '@ngrx/store';
import * as moment from 'moment';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

Expand Down Expand Up @@ -96,6 +97,7 @@ export class PageHeaderComponent implements OnDestroy, AfterViewInit {
const { name, routerLink } = mapperFunction(favorite.metadata);
this.store.dispatch(new AddRecentlyVisitedEntityAction({
guid: favorite.guid,
date: moment().valueOf(),
entityType: favorite.entityType,
endpointType: favorite.endpointType,
entityId: favorite.entityId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
<!-- history is set when used in the dropdown menu to only show recent history-->

<mat-card *ngIf="!history && ((hasHits$ | async) === true)">
<mat-tab-group dynamicHeight="true" animationDuration="0ms"
mat-stretch-tabs>
<mat-tab label="Top">
<div class="recent-tab" *ngIf="frecentEntities$ | async as frecentEntities">
<div *ngIf="frecentEntities && frecentEntities.length > 0" class="recent-entities">
<div [routerLink]="countedEntity.entity.routerLink" [ngClass]="{clickable: !!countedEntity.entity.routerLink}"
class="recent-entity" *ngFor="let countedEntity of frecentEntities">
<a class="recent-entity--name" *ngIf="countedEntity.entity.routerLink as routerLink; else noLink">{{
countedEntity.entity.name }}</a>
<ng-template #noLink>
<div class="recent-entity--name">{{ countedEntity.entity.name }}</div>
</ng-template>
<div class="type-info">
<span>{{ countedEntity.subText$ | async }}</span>
</div>
</div>
</div>
</div>
</mat-tab>
<mat-tab label="Recent">
<ng-container *ngTemplateOutlet="historyTemplate"></ng-container>
</mat-tab>
</mat-tab-group>
<ng-container *ngTemplateOutlet="historyTemplate"></ng-container>
</mat-card>

<ng-container *ngIf="!history && ((hasHits$ | async) === false)">
Expand All @@ -39,16 +19,23 @@
<div *ngIf="recentEntities && recentEntities.length > 0" class="recent-entities">
<div [routerLink]="countedEntity.entity.routerLink" [ngClass]="{clickable: !!countedEntity.entity.routerLink}"
class="recent-entity" *ngFor="let countedEntity of recentEntities">
<a class="recent-entity--name" *ngIf="countedEntity.entity.routerLink as routerLink; else noLink">{{
countedEntity.entity.name }}</a>
<ng-template #noLink>
<div class="recent-entity--name">{{ countedEntity.entity.name }}</div>
</ng-template>
<div class="type-info" *ngIf="countedEntity.mostRecentHit">
{{ countedEntity.mostRecentHit | amTimeAgo }}
<div class="recent-entity__icon-container" *ngIf="countedEntity.icon">
<mat-icon class="recent-entity__icon" [fontSet]="countedEntity.iconFont">{{ countedEntity.icon }}</mat-icon>
</div>
<div class="type-info">
<span>{{ countedEntity.subText$ | async }}</span>
<div>
<a class="recent-entity--name" *ngIf="countedEntity.entity.routerLink as routerLink; else noLink">{{
countedEntity.entity.name }}</a>
<ng-template #noLink>
<div class="recent-entity--name">{{ countedEntity.entity.name }}</div>
</ng-template>
<!-- Don't show the date
<div class="type-info" *ngIf="countedEntity.mostRecentHit">
{{ countedEntity.mostRecentHit | amTimeAgo }}
</div>
-->
<div class="type-info">
<span>{{ countedEntity.subText$ | async }}</span>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ $spacing: 10px;
opacity: .6;
}
.recent-entity {
display: flex;
outline: 0;
padding: $spacing;
& + & {
Expand All @@ -21,14 +22,22 @@ $spacing: 10px;
&--name {
word-break: break-all;
}
&__icon {
opacity: .7;
}
&__icon-container {
display: flex;
height: 24px;
text-align: center;
width: 32px;
}
}

.clickable {
cursor: pointer;
}

.recent-tab {
padding-top: $spacing;
&.standalone {
padding-top: 0;
}
Expand Down
Loading

0 comments on commit 0d021ed

Please sign in to comment.