Browse Source

UI: continue new-menu work — collapsible rail polish, popover variant, and side-menu tweaks

pull/15888/head
Igor Kulikov 4 months ago
parent
commit
b9d0d55a43
  1. 44
      ui-ngx/src/app/modules/home/home.component.html
  2. 84
      ui-ngx/src/app/modules/home/home.component.scss
  3. 8
      ui-ngx/src/app/modules/home/home.component.ts
  4. 2
      ui-ngx/src/app/modules/home/menu/menu-link.component.html
  5. 5
      ui-ngx/src/app/modules/home/menu/menu-link.component.ts
  6. 28
      ui-ngx/src/app/modules/home/menu/menu-toggle.component.html
  7. 30
      ui-ngx/src/app/modules/home/menu/menu-toggle.component.scss
  8. 26
      ui-ngx/src/app/modules/home/menu/menu-toggle.component.ts
  9. 6
      ui-ngx/src/app/modules/home/menu/side-menu.component.html
  10. 19
      ui-ngx/src/app/modules/home/menu/side-menu.component.scss
  11. 7
      ui-ngx/src/app/modules/home/menu/side-menu.component.ts
  12. 32
      ui-ngx/src/app/shared/components/popover.component.scss
  13. 10
      ui-ngx/src/app/shared/components/popover.component.ts
  14. 26
      ui-ngx/src/app/shared/components/user-menu.component.html
  15. 58
      ui-ngx/src/app/shared/components/user-menu.component.scss
  16. 14
      ui-ngx/src/app/shared/components/user-menu.component.ts
  17. 5
      ui-ngx/src/assets/small_logo_title_black.svg
  18. 2
      ui-ngx/src/scss/constants.scss

44
ui-ngx/src/app/modules/home/home.component.html

@ -15,42 +15,40 @@
limitations under the License.
-->
<mat-sidenav-container>
<mat-sidenav-container [class.tb-desktop]="sidenavDesktop()"
[class.tb-collapsed]="sidenavCollapsed()">
<mat-sidenav #sidenav class="tb-site-sidenav mat-elevation-z2"
[class.tb-desktop]="sidenavDesktop()"
[disableClose]="sidenavOpened"
(click)="sidenavClicked()"
[mode]="sidenavMode"
[opened]="sidenavOpened && !forceFullscreen"
[style.width]="sidenavWidth()">
[opened]="sidenavOpened && !forceFullscreen">
<header class="tb-nav-header">
<mat-toolbar class="tb-nav-header-toolbar">
<div class="flex flex-1 flex-row justify-between">
@if (showLogo()) {
<tb-logo [src]="logo" class="tb-logo-title"></tb-logo>
}
@if (sidenavDesktop()) {
<button mat-icon-button class="tb-mat-32" (click)="toggleSidenav()">
@if (sidenavCollapsed()) {
<tb-icon class="tb-mat-20">sidebar-open</tb-icon>
} @else {
<tb-icon class="tb-mat-20">sidebar-close</tb-icon>
}
</button>
}
</div>
<tb-logo
[src]="logo" class="tb-logo-title">
</tb-logo>
@if (sidenavDesktop()) {
<button mat-icon-button class="tb-sidenav-toggle tb-mat-32" (click)="toggleSidenav()">
@if (sidenavCollapsed()) {
<div class="tb-collapsed-logo-container">
<img class="tb-collapsed-logo" [src]="collapsedLogo" aria-label="logo" alt="Logo"/>
<tb-icon class="tb-mat-20 tb-open-icon">sidebar-open</tb-icon>
</div>
} @else {
<tb-icon class="tb-mat-20">sidebar-close</tb-icon>
}
</button>
}
</mat-toolbar>
</header>
<mat-toolbar class="tb-side-menu-toolbar flex flex-1 flex-col" role="navigation">
<div class="w-full flex-1 overflow-y-auto">
<tb-side-menu></tb-side-menu>
<tb-side-menu [collapsed]="menuCollapsed()"></tb-side-menu>
</div>
<tb-user-menu></tb-user-menu>
<tb-user-menu [collapsed]="menuCollapsed()" (menuClicked)="sidenavClicked()"></tb-user-menu>
</mat-toolbar>
</mat-sidenav>
<mat-sidenav-content class="tb-site-content"
[class.tb-desktop]="sidenavDesktop()"
[style.margin-left]="sidenavWidth()">
<mat-sidenav-content class="tb-site-content">
<div class="flex flex-col" role="main" style="height: 100%;">
<mat-toolbar class="tb-primary-toolbar flex flex-row">
<button mat-icon-button id="main"

84
ui-ngx/src/app/modules/home/home.component.scss

@ -14,7 +14,7 @@
* limitations under the License.
*/
$sidenav-anim-timing: 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
@import "constants";
:host {
display: flex;
@ -23,20 +23,43 @@ $sidenav-anim-timing: 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
mat-sidenav-container {
flex: 1;
&.tb-desktop {
mat-sidenav.tb-site-sidenav {
width: 250px;
transition: width $sidenav-anim-timing;
.tb-logo-title {
opacity: 1;
transition: opacity $sidenav-anim-timing;
}
}
mat-sidenav-content.tb-site-content {
margin-left: 250px !important;
transition: margin-left $sidenav-anim-timing;
}
&.tb-collapsed {
mat-sidenav.tb-site-sidenav {
width: 50px;
.tb-logo-title {
opacity: 0;
}
}
mat-sidenav-content.tb-site-content {
margin-left: 50px !important;
}
}
}
}
mat-sidenav.tb-site-sidenav {
width: 250px;
@media (max-width:456px) {
width: calc(100% - 56px);
}
&.tb-desktop {
transition: width $sidenav-anim-timing;
}
.tb-nav-header {
z-index: 2;
flex-shrink: 0;
white-space: nowrap;
.tb-nav-header-toolbar {
position: relative;
min-height: 56px;
height: inherit;
padding: 8px 12px 8px 16px;
@ -44,13 +67,46 @@ $sidenav-anim-timing: 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
flex-shrink: 0;
white-space: nowrap;
border-right: 1px solid rgba(0, 0, 0, 0.12);
& > div {
.tb-logo-title {
width: auto;
max-width: 100%;
height: 30px;
max-height: 100%;
margin: auto 0;
.tb-logo-title {
width: auto;
max-width: 100%;
height: 30px;
max-height: 100%;
margin: auto 0;
}
.tb-sidenav-toggle {
margin: 0;
position: absolute;
right: 9px;
top: 12px;
.tb-collapsed-logo-container {
position: relative;
width: 20px;
height: 20px;
margin-left: 6px;
.mat-icon, img {
width: 20px;
height: 20px;
position: absolute;
inset: 0;
transition: opacity $sidenav-anim-timing;
}
.tb-open-icon {
opacity: 0;
}
.tb-collapsed-logo {
opacity: 1;
}
}
&:hover {
.tb-collapsed-logo-container {
.tb-open-icon {
opacity: 1;
}
.tb-collapsed-logo {
opacity: 0;
}
}
}
}
}
@ -66,12 +122,6 @@ $sidenav-anim-timing: 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
}
}
}
mat-sidenav-content.tb-site-content {
&.tb-desktop {
margin-left: 250px;
transition: margin-left $sidenav-anim-timing;
}
}
.tb-primary-toolbar {
z-index: 2;
height: 56px;

8
ui-ngx/src/app/modules/home/home.component.ts

@ -42,8 +42,7 @@ import { instanceOfSearchableComponent, ISearchableComponent } from '@home/model
import { ActiveComponentService } from '@core/services/active-component.service';
import { RouterTabsComponent } from '@home/components/router-tabs.component';
import { FormBuilder } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { isDefined, isDefinedAndNotNull } from '@core/utils';
import { isDefinedAndNotNull } from '@core/utils';
@Component({
selector: 'tb-home',
@ -65,11 +64,10 @@ export class HomeComponent extends PageComponent implements AfterViewInit, OnIni
sidenavDesktop = signal(true);
sidenavCollapsed = signal(false);
sidenavWidth = computed(() => this.sidenavDesktop() ? (this.sidenavCollapsed() ? '50px' : '250px') : '');
menuCollapsed= computed(() => this.sidenavDesktop() && this.sidenavCollapsed());
logo = 'assets/logo_title_black.svg';
showLogo= computed(() => !this.sidenavDesktop() || !this.sidenavCollapsed());
collapsedLogo = 'assets/small_logo_title_black.svg';
@ViewChild('sidenav')
sidenav: MatSidenav;

2
ui-ngx/src/app/modules/home/menu/menu-link.component.html

@ -16,6 +16,8 @@
-->
<a mat-button routerLinkActive="tb-active" [routerLinkActiveOptions]="{paths: 'subset', queryParams: 'ignored', matrixParams: 'ignored', fragment: 'ignored'}" routerLink="{{section.path}}"
[matTooltip]="collapsed ? (section.customTranslate ? (section.name | customTranslate) : (section.name | translate)) : null"
matTooltipPosition="right"
[class.is-new]="section.isNew">
@if (section.icon !== null) {
<tb-icon matButtonIcon>{{section.icon}}</tb-icon>

5
ui-ngx/src/app/modules/home/menu/menu-link.component.ts

@ -16,6 +16,7 @@
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { MenuSection } from '@core/services/menu.models';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-menu-link',
@ -28,6 +29,10 @@ export class MenuLinkComponent implements OnInit {
@Input() section: MenuSection;
@Input()
@coerceBoolean()
collapsed = false;
constructor() {
}

28
ui-ngx/src/app/modules/home/menu/menu-toggle.component.html

@ -15,7 +15,19 @@
limitations under the License.
-->
<a mat-button class="tb-button-toggle" [class.tb-toggled]="section.opened" (click)="toggleSection($event)"
<a mat-button class="tb-button-toggle"
[class.tb-toggled]="section.opened && !collapsed"
[class.tb-hovered]="collapsed && menuPopover?.component?.tbVisible"
[class.tb-active]="toggleSectionActive()"
(click)="toggleSection($event)"
tb-popover
#menuPopover="tbPopover"
[tbPopoverTrigger]="collapsed ? 'hover' : null"
[tbPopoverMouseLeaveDelay]="0.05"
[tbPopoverMenu]="true"
[tbPopoverOverlayStyle]="{marginTop: '-8px'}"
[tbPopoverContent]="menuToggleMenuTpl"
[tbPopoverPlacement]="'rightTop'"
[class.is-new]="section.isNew">
@if (section.icon !== null) {
<tb-icon matButtonIcon>{{section.icon}}</tb-icon>
@ -31,3 +43,17 @@
</li>
}
</ul>
<ng-template #menuToggleMenuTpl>
<div class="tb-menu-content tb-toggle-menu-items">
<div class="tb-menu-toggle-header">
<span>{{section.customTranslate ? (section.name | customTranslate) : (section.name | translate)}}</span>
</div>
@for (page of section.pages; track trackBySectionPages($index, page)) {
<a mat-button routerLinkActive="tb-active" [routerLinkActiveOptions]="{paths: 'subset', queryParams: 'ignored', matrixParams: 'ignored', fragment: 'ignored'}"
routerLink="{{page.path}}" (click)="menuPopover?.hide();">
<span>{{page.customTranslate ? (page.name | customTranslate) : (page.name | translate)}}</span>
</a>
}
</div>
</ng-template>

30
ui-ngx/src/app/modules/home/menu/menu-toggle.component.scss

@ -73,3 +73,33 @@
}
}
}
.tb-toggle-menu-items {
min-width: 250px;
display: flex;
flex-direction: column;
.tb-menu-toggle-header {
display: flex;
align-items: center;
cursor: default;
font-weight: 500;
font-size: 14px;
line-height: 20px;
height: 40px;
padding: 8px 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
a.mat-mdc-button {
border-bottom: none;
&:hover {
background-color: rgba(0, 0, 0, .07);
border-bottom: none;
}
&:focus {
border-bottom: none;
}
&.tb-active {
background-color: rgba(0, 0, 0, .05);
}
}
}

26
ui-ngx/src/app/modules/home/menu/menu-toggle.component.ts

@ -20,6 +20,7 @@ import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { ActionPreferencesUpdateOpenedMenuSection } from '@core/auth/auth.actions';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-menu-toggle',
@ -32,6 +33,10 @@ export class MenuToggleComponent implements OnInit {
@Input() section: MenuSection;
@Input()
@coerceBoolean()
collapsed = false;
constructor(private router: Router,
private store: Store<AppState>) {
}
@ -40,7 +45,7 @@ export class MenuToggleComponent implements OnInit {
}
sectionHeight(): string {
if (this.section.opened) {
if (this.section.opened && !this.collapsed) {
return this.section.pages.length * 40 + 'px';
} else {
return '0px';
@ -49,8 +54,23 @@ export class MenuToggleComponent implements OnInit {
toggleSection(event: MouseEvent) {
event.stopPropagation();
this.section.opened = !this.section.opened;
this.store.dispatch(new ActionPreferencesUpdateOpenedMenuSection({path: this.section.path, opened: this.section.opened}));
if (this.collapsed) {
event.preventDefault();
} else {
this.section.opened = !this.section.opened;
this.store.dispatch(new ActionPreferencesUpdateOpenedMenuSection({
path: this.section.path,
opened: this.section.opened
}));
}
}
toggleSectionActive(): boolean {
if (this.collapsed) {
return this.router.isActive(this.router.parseUrl(this.section.path), {paths: 'subset', queryParams: 'ignored', matrixParams: 'ignored', fragment: 'ignored'});
} else {
return false;
}
}
trackBySectionPages(index: number, section: MenuSection){

6
ui-ngx/src/app/modules/home/menu/side-menu.component.html

@ -15,15 +15,15 @@
limitations under the License.
-->
<ul class="tb-side-menu flex flex-col items-stretch justify-start">
<ul class="tb-side-menu flex flex-col items-stretch justify-start" [class.tb-collapsed]="collapsed">
@for (section of menuSections$ | async; track trackByMenuSection($index, section)) {
<li>
@switch (section.type === 'link') {
@case (true) {
<tb-menu-link [section]="section"></tb-menu-link>
<tb-menu-link [section]="section" [collapsed]="collapsed"></tb-menu-link>
}
@case (false) {
<tb-menu-toggle [section]="section"></tb-menu-toggle>
<tb-menu-toggle [section]="section" [collapsed]="collapsed"></tb-menu-toggle>
}
}
</li>

19
ui-ngx/src/app/modules/home/menu/side-menu.component.scss

@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "constants";
:host {
width: 100%;
}
@ -24,6 +27,15 @@
margin: 0;
list-style: none;
--mat-button-text-label-text-weight: 400;
&.tb-collapsed {
a.mat-mdc-button.mat-mdc-button-base {
padding-right: 0;
min-width: 0;
span.mdc-button__label {
opacity: 0;
}
}
}
}
.tb-side-menu ul {
@ -42,14 +54,15 @@
border-radius: 0;
padding: 0 16px;
--mat-button-text-label-text-color: rgba(0, 0, 0, .76);
&:hover {
&:hover, &.tb-hovered {
background-color: rgba(0, 0, 0, .07);
border-bottom: none;
}
&:focus {
border-bottom: none;
}
&.tb-active {
background-color: rgba(0, 0, 0, .08);
background-color: rgba(0, 0, 0, .05);
}
.mat-icon {
margin-right: 8px;
@ -63,6 +76,8 @@
text-overflow: ellipsis;
white-space: nowrap;
display: inline-flex;
opacity: 1;
transition: opacity $sidenav-anim-timing;
& > span {
overflow: hidden;
text-overflow: ellipsis;

7
ui-ngx/src/app/modules/home/menu/side-menu.component.ts

@ -14,9 +14,10 @@
/// limitations under the License.
///
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { MenuService } from '@core/services/menu.service';
import { MenuSection } from '@core/services/menu.models';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-side-menu',
@ -27,6 +28,10 @@ import { MenuSection } from '@core/services/menu.models';
})
export class SideMenuComponent implements OnInit {
@Input()
@coerceBoolean()
collapsed = false;
menuSections$ = this.menuService.menuSections();
constructor(private menuService: MenuService) {

32
ui-ngx/src/app/shared/components/popover.component.scss

@ -220,4 +220,36 @@ $box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0,
&-placement-leftBottom > &-content > &-arrow {
bottom: 12px;
}
&.tb-menu {
padding: 0;
.tb-popover-arrow {
display: none;
}
.tb-popover-inner {
border-radius: 4px;
box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.08), 0 1px 8px 1px rgba(0, 0, 0, 0.08);
}
.tb-popover-inner-content {
padding: 8px 0;
}
.tb-menu-content {
--mat-button-text-label-text-size: 14px;
--mat-button-text-label-text-weight: 400;
--mat-button-text-container-height: 40px;
.mat-mdc-button:not(.mat-mdc-icon-button) {
justify-content: start;
padding: 8px 16px;
& > .mat-icon {
width: 18px;
height: 18px;
font-size: 18px;
margin-right: 8px;
}
.mdc-button__label {
line-height: 20px;
}
}
}
}
}

10
ui-ngx/src/app/shared/components/popover.component.ts

@ -96,6 +96,7 @@ export class TbPopoverDirective implements OnChanges, OnDestroy, AfterViewInit {
@Input('tbPopoverOverlayClassName') overlayClassName?: string;
@Input('tbPopoverOverlayStyle') overlayStyle?: { [klass: string]: any };
@Input() tbPopoverBackdrop = false;
@Input() tbPopoverMenu = false;
// eslint-disable-next-line @angular-eslint/no-output-rename
@Output('tbPopoverVisibleChange') readonly visibleChange = new EventEmitter<boolean>();
@ -242,7 +243,8 @@ export class TbPopoverDirective implements OnChanges, OnDestroy, AfterViewInit {
mouseLeaveDelay: ['tbMouseLeaveDelay', () => this.mouseLeaveDelay],
overlayClassName: ['tbOverlayClassName', () => this.overlayClassName],
overlayStyle: ['tbOverlayStyle', () => this.overlayStyle],
tbPopoverBackdrop: ['tbBackdrop', () => this.tbPopoverBackdrop]
tbPopoverBackdrop: ['tbBackdrop', () => this.tbPopoverBackdrop],
tbPopoverMenu: ['tbMenu', () => this.tbPopoverMenu]
};
(keys || Object.keys(mappingProperties).filter(key => !key.startsWith('directive'))).forEach(
@ -343,7 +345,7 @@ export class TbPopoverDirective implements OnChanges, OnDestroy, AfterViewInit {
<span class="tb-popover-arrow-content"></span>
</div>
<div class="tb-popover-inner" [style]="tbPopoverInnerStyle" role="tooltip">
@if (tbShowCloseButton) {
@if (tbShowCloseButton && !tbMenu) {
<div class="tb-popover-close-button" (click)="closeButtonClick($event)">×</div>
}
<div style="width: 100%; height: 100%;">
@ -389,6 +391,7 @@ export class TbPopoverComponent<T = any> implements OnDestroy, OnInit {
tbPopoverInnerStyle: { [klass: string]: any } = {};
tbPopoverInnerContentStyle: { [klass: string]: any } = {};
tbBackdrop = false;
tbMenu = false;
tbMouseEnterDelay?: number;
tbMouseLeaveDelay?: number;
tbHideOnClickOutside = true;
@ -672,7 +675,8 @@ export class TbPopoverComponent<T = any> implements OnDestroy, OnInit {
updateStyles(): void {
this.classMap = {
[`tb-popover-placement-${this.preferredPlacement}`]: true,
['tb-popover-hidden']: this.tbHidden || !this.lastIsIntersecting
['tb-popover-hidden']: this.tbHidden || !this.lastIsIntersecting,
['tb-menu']: this.tbMenu
};
if (this.tbOverlayClassName) {
this.classMap[this.tbOverlayClassName] = true;

26
ui-ngx/src/app/shared/components/user-menu.component.html

@ -15,10 +15,16 @@
limitations under the License.
-->
<button mat-button class="tb-user-menu" [matMenuTriggerFor]="userMenu" #menuButton
(click)="$event.stopPropagation();">
<button #menuButton #menuPopover="tbPopover" mat-button class="tb-user-menu" [class.tb-collapsed]="collapsed"
(click)="$event.stopPropagation();"
tb-popover
tbPopoverTrigger="click"
[tbPopoverMenu]="true"
[tbPopoverContent]="userMenuTpl"
[tbPopoverOverlayClassName]="collapsed ? 'tb-user-menu-collapsed' : ''"
[tbPopoverPlacement]="collapsed ? 'right' : 'topLeft'">
<tb-icon class="material-icons tb-mini-avatar">mdi:account-circle-outline</tb-icon>
<div class="flex flex-col items-stretch justify-center">
<div class="tb-user-info">
@if (userDisplayName$ | async; as userDisplayName) {
<span class="tb-user-display-name">{{ userDisplayName }}</span>
}
@ -27,17 +33,17 @@
}
</div>
</button>
<mat-menu #userMenu="matMenu" class="tb-user-menu-panel" xPosition="after">
<ng-template #userMenuTpl>
@if (authority$ | async; as authority) {
<div class="tb-user-menu-items" [style.width.px]="menuButton._elementRef.nativeElement.offsetWidth">
<button mat-menu-item (click)="openAccount()">
<tb-icon matMenuItemIcon>mdi:account-circle-outline</tb-icon>
<div class="tb-menu-content tb-user-menu-items" [style.width.px]="!collapsed ? menuButton._elementRef.nativeElement.offsetWidth : ''">
<button mat-button (click)="menuPopover?.hide(); openAccount()">
<tb-icon matButtonIcon>mdi:account-circle-outline</tb-icon>
<span translate>account.account</span>
</button>
<button class="tb-logout" mat-menu-item (click)="logout()">
<tb-icon matMenuItemIcon>logout</tb-icon>
<button mat-button class="tb-logout" (click)="menuPopover?.hide(); logout()">
<tb-icon matButtonIcon>logout</tb-icon>
<span translate>home.logout</span>
</button>
</div>
}
</mat-menu>
</ng-template>

58
ui-ngx/src/app/shared/components/user-menu.component.scss

@ -14,6 +14,8 @@
* limitations under the License.
*/
@import "constants";
tb-user-menu {
width: 100%;
@ -27,6 +29,15 @@ tb-user-menu {
gap: 8px;
line-height: 1.5;
.tb-user-info {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
opacity: 1;
transition: opacity $sidenav-anim-timing;
}
span {
text-transform: none;
text-align: start;
@ -52,29 +63,38 @@ tb-user-menu {
height: 32px;
font-size: 32px;
margin: 0;
transition: all $sidenav-anim-timing;
}
&.tb-collapsed {
min-width: 0;
.mat-icon.tb-mini-avatar {
width: 20px;
height: 20px;
font-size: 20px;
}
.tb-user-info {
opacity: 0;
}
}
}
}
.mat-mdc-menu-panel.tb-user-menu-panel {
max-width: 100%;
.tb-user-menu-items {
//min-width: 250px;
display: flex;
flex-direction: column;
gap: 8px;
--mat-menu-item-label-text-size: 14px;
--mat-menu-item-label-text-line-height: 20px;
--mat-menu-item-spacing: 8px;
--mat-menu-item-icon-size: 18px;
.mat-icon {
font-size: 18px;
}
.mat-mdc-menu-item {
min-height: 40px;
&.tb-logout {
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
.tb-popover.tb-menu.tb-user-menu-collapsed {
padding: 0 0 17px 0;
}
.tb-user-menu-items {
min-width: 250px;
display: flex;
flex-direction: column;
gap: 8px;
.mat-mdc-button {
&:hover {
background-color: rgba(0, 0, 0, .07);
}
}
.tb-logout {
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
}

14
ui-ngx/src/app/shared/components/user-menu.component.ts

@ -16,10 +16,10 @@
import {
ChangeDetectionStrategy,
Component,
Component, EventEmitter,
Input,
OnDestroy,
OnInit,
OnInit, Output,
ViewChild,
ViewEncapsulation
} from '@angular/core';
@ -32,6 +32,7 @@ import { map } from 'rxjs/operators';
import { AuthService } from '@core/auth/auth.service';
import { Router } from '@angular/router';
import { MatMenu, MatMenuTrigger } from '@angular/material/menu';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-user-menu',
@ -43,6 +44,13 @@ import { MatMenu, MatMenuTrigger } from '@angular/material/menu';
})
export class UserMenuComponent implements OnInit, OnDestroy {
@Input()
@coerceBoolean()
collapsed = false;
@Output()
menuClicked = new EventEmitter();
authorities = Authority;
authority$ = this.store.pipe(
@ -112,10 +120,12 @@ export class UserMenuComponent implements OnInit, OnDestroy {
}
openAccount(): void {
this.menuClicked.emit();
this.router.navigate(['account']);
}
logout(): void {
this.menuClicked.emit();
this.authService.logout();
}

5
ui-ngx/src/assets/small_logo_title_black.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
<path d="M8.5011 0C6.90566 0 5.41209 0.445179 4.13531 1.2113C3.77124 0.915337 3.31377 0.750592 2.83778 0.750468C2.83771 0.750468 2.83765 0.750468 2.83758 0.750468C1.70391 0.750509 0.774364 1.68005 0.77442 2.81357C0.77442 2.81377 0.77442 2.81397 0.77442 2.81417C0.774977 3.28743 0.939049 3.74122 1.23024 4.10365C0.452289 5.38768 3.37531e-05 6.89218 3.37531e-05 8.50016C-0.000729547 8.56539 0.0114602 8.63012 0.0358966 8.6906C0.0603331 8.75108 0.0965305 8.80612 0.142392 8.85251C0.188253 8.89891 0.242866 8.93574 0.303067 8.96088C0.363267 8.98602 0.427859 8.99896 0.493099 8.99896C0.558339 8.99896 0.622931 8.98602 0.683132 8.96088C0.743333 8.93574 0.797946 8.89891 0.843807 8.85251C0.889668 8.80612 0.925865 8.75108 0.950302 8.6906C0.974738 8.63012 0.986928 8.56539 0.986165 8.50016C0.986165 7.11085 1.36413 5.81467 2.01994 4.6996C2.2768 4.81122 2.55279 4.87674 2.83664 4.87718C2.83688 4.87718 2.83711 4.87718 2.83734 4.87718C3.97107 4.87721 4.90078 3.94765 4.90073 2.81407C4.90073 2.814 4.90073 2.81392 4.90073 2.81385C4.90064 2.53267 4.83668 2.25914 4.72732 2.00412C5.83641 1.35822 7.12275 0.986401 8.5009 0.986401C8.56613 0.987164 8.63087 0.974975 8.69136 0.950542C8.75185 0.926109 8.80689 0.889918 8.85329 0.844063C8.89969 0.798208 8.93653 0.743601 8.96168 0.683408C8.98682 0.623216 8.99976 0.558634 8.99976 0.493403C8.99976 0.428172 8.98682 0.36359 8.96168 0.303398C8.93653 0.243205 8.89969 0.188597 8.85329 0.142743C8.80689 0.0968878 8.75185 0.0606972 8.69136 0.0362641C8.63087 0.011831 8.56613 -0.000358125 8.5009 0.00040507L8.5011 0ZM2.83722 1.73678C3.16982 1.7369 3.46672 1.87807 3.67175 2.13481C3.67511 2.13889 3.67854 2.14291 3.68202 2.14688C3.8323 2.33697 3.91448 2.57168 3.91457 2.81408C3.91448 3.41459 3.43824 3.8908 2.83771 3.89103C2.59189 3.89057 2.35389 3.80616 2.1627 3.65173C2.16247 3.65156 2.16223 3.6514 2.162 3.65123C1.90808 3.44689 1.76061 3.13953 1.76013 2.8136C1.76027 2.21309 2.23658 1.7369 2.83722 1.73678Z" fill="black" fill-opacity="0.87"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.76812 5.78359C3.68419 5.87123 3.63501 5.99226 3.64112 6.12505C3.64654 6.24005 3.69249 6.35117 3.77259 6.43539C4.15539 6.82098 4.91015 7.57279 4.91015 7.57279L5.57639 6.90743C5.57639 6.90743 4.84664 6.17847 4.44147 5.77295C4.35124 5.68114 4.23054 5.6428 4.10329 5.64223C3.97064 5.6416 3.852 5.69588 3.76808 5.78352L3.76812 5.78359ZM5.57641 6.90732L3.51544 8.96806C3.29184 9.19169 3.29184 9.55417 3.51544 9.77779L8.03726 14.299C8.2609 14.5226 8.62351 14.5226 8.84716 14.299L14.4353 8.7116C14.6589 8.48795 14.6589 8.12543 14.4353 7.90181L13.3873 6.854L11.6014 5.06772L9.9133 3.38044C9.68964 3.15686 9.32711 3.15686 9.10346 3.38044L5.57654 6.90687L5.57641 6.90732ZM7.70893 4.77515C7.70893 4.77515 6.97919 4.04618 6.57401 3.64067C6.48379 3.54886 6.36308 3.51052 6.23583 3.50995C5.97052 3.50868 5.76141 3.72713 5.77363 3.9927C5.77904 4.1077 5.825 4.21882 5.9051 4.30303C6.28789 4.68863 7.04265 5.44044 7.04265 5.44044L7.70889 4.77508L7.70893 4.77515ZM11.6011 5.06836C11.6011 5.06836 12.3301 4.33871 12.7357 3.9336C12.8275 3.84338 12.8659 3.7227 12.8665 3.59547C12.8677 3.33019 12.6492 3.12111 12.3836 3.13332C12.2686 3.13873 12.1575 3.18469 12.0733 3.26477C11.6876 3.64751 10.9357 4.40217 10.9357 4.40217L11.6011 5.06831L11.6011 5.06836ZM13.3872 6.85424C13.3872 6.85424 14.1163 6.1246 14.5218 5.71948C14.6137 5.62927 14.652 5.50858 14.6526 5.38135C14.6539 5.11607 14.4354 4.90699 14.1698 4.9192C14.0547 4.92461 13.9436 4.97057 13.8594 5.05066C13.4737 5.4334 12.7218 6.18806 12.7218 6.18806L13.3873 6.8542L13.3872 6.85424ZM12.3742 10.7725C12.3742 10.7725 13.1039 11.5015 13.5092 11.9069C13.5994 11.9987 13.7201 12.037 13.8474 12.0376C14.1127 12.0389 14.3218 11.8204 14.3096 11.5549L14.3095 11.555C14.3041 11.44 14.2581 11.3288 14.178 11.2446C13.7952 10.859 13.0405 10.1072 13.0405 10.1072L12.3742 10.7726L12.3742 10.7725ZM10.2415 12.9049C10.2415 12.9049 10.9712 13.6339 11.3765 14.0393C11.4668 14.1311 11.5875 14.1694 11.7147 14.17C11.98 14.1713 12.1891 13.9528 12.1769 13.6872H12.1768C12.1714 13.5722 12.1254 13.4611 12.0453 13.3769C11.6625 12.9913 10.9078 12.2395 10.9078 12.2395L10.2415 12.9049L10.2415 12.9049ZM6.32269 12.5851C6.32269 12.5851 5.59362 13.3147 5.18817 13.7199C5.09634 13.8101 5.058 13.9308 5.05742 14.0581C5.05616 14.3233 5.27463 14.5324 5.54024 14.5202H5.54014C5.65515 14.5148 5.76629 14.4688 5.85051 14.3887C6.23617 14.006 6.98807 13.2513 6.98807 13.2513L6.32319 12.5854L6.32269 12.5851ZM4.53712 10.7999C4.53712 10.7999 3.80805 11.5295 3.4026 11.9348C3.31078 12.025 3.27244 12.1457 3.27186 12.2729C3.27059 12.5382 3.48907 12.7473 3.75468 12.735H3.75457C3.86959 12.7296 3.98072 12.6837 4.06495 12.6036C4.45061 12.2209 5.2025 11.4662 5.2025 11.4662L4.53711 10.7997L4.53712 10.7999ZM9.44426 5.70688C9.53873 5.6109 9.6674 5.55727 9.79848 5.55918C9.89201 5.56051 9.98146 5.59012 10.0551 5.64409L10.9832 6.32463C11.1633 6.45382 11.2163 6.69915 11.1087 6.90461C11.001 7.11006 10.7642 7.21531 10.549 7.15336L10.8934 8.50026C10.956 8.74501 10.8055 9.00463 10.5569 9.08052L8.04573 9.84717L8.50955 11.6404C8.57552 11.8861 8.42508 12.1491 8.1746 12.2257C7.92412 12.3023 7.66971 12.1632 7.60827 11.9161L7.0299 9.67936C6.96653 9.43438 7.11705 9.17403 7.36605 9.09792L9.87826 8.33093L9.6464 7.42441C9.49095 7.59675 9.23951 7.6386 9.05093 7.52348C8.86231 7.40836 8.79136 7.16973 8.88296 6.95841L9.33954 5.86426C9.36391 5.8059 9.39957 5.7524 9.4443 5.70693L9.44426 5.70688Z" fill="black" fill-opacity="0.87"/>
<path d="M9.49903 18C11.0945 18 12.588 17.5548 13.8649 16.7887C14.2289 17.0846 14.6864 17.2494 15.1624 17.2495C15.1625 17.2495 15.1626 17.2495 15.1626 17.2495C16.2964 17.2495 17.2259 16.3199 17.2258 15.1864C17.2258 15.1862 17.2258 15.186 17.2258 15.1858C17.2253 14.7125 17.0612 14.2587 16.77 13.8963C17.5477 12.6128 18 11.1082 18 9.50025C18.0008 9.43498 17.9887 9.3702 17.9643 9.30966C17.9399 9.24913 17.9037 9.19404 17.8578 9.14759C17.8119 9.10115 17.7573 9.06427 17.6971 9.0391C17.6368 9.01394 17.5722 9.00098 17.5069 9.00098C17.4417 9.00098 17.377 9.01394 17.3168 9.0391C17.2566 9.06427 17.2019 9.10115 17.1561 9.14759C17.1102 9.19404 17.074 9.24913 17.0496 9.30966C17.0252 9.3702 17.013 9.43498 17.0139 9.50025C17.0139 10.8896 16.6359 12.1858 15.9801 13.3009C15.7232 13.1892 15.4472 13.1237 15.1634 13.1233C15.1632 13.1233 15.1629 13.1233 15.1627 13.1233C14.029 13.1233 13.0993 14.0528 13.0993 15.1864C13.0994 15.4676 13.1634 15.7411 13.2727 15.9961C12.1636 16.642 10.8772 17.0138 9.49909 17.0138C9.43382 17.013 9.36903 17.0252 9.30848 17.0496C9.24794 17.074 9.19284 17.1101 9.14639 17.156C9.09994 17.2019 9.06306 17.2565 9.03789 17.3167C9.01272 17.3769 8.99976 17.4416 8.99976 17.5068C8.99976 17.5721 9.01272 17.6367 9.03789 17.697C9.06306 17.7572 9.09994 17.8118 9.14639 17.8577C9.19284 17.9035 9.24794 17.9397 9.30848 17.9641C9.36903 17.9885 9.43382 18.0007 9.49909 17.9998L9.49903 18ZM15.1629 16.2635C14.8303 16.2635 14.5334 16.1222 14.3284 15.8655C14.325 15.8614 14.3216 15.8574 14.3181 15.8534C14.1678 15.6633 14.0856 15.4286 14.0856 15.1862C14.0857 14.5857 14.5619 14.1095 15.1624 14.1093C15.4082 14.1097 15.6462 14.1941 15.8374 14.3486C15.8377 14.3487 15.8379 14.3489 15.8381 14.3491C16.092 14.5534 16.2395 14.8608 16.24 15.1867C16.2398 15.7872 15.7635 16.2635 15.1629 16.2635Z" fill="black" fill-opacity="0.87"/>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

2
ui-ngx/src/scss/constants.scss

@ -40,3 +40,5 @@ $tb-hue3-color: #a7c1de;
$tb-dark-primary-color: #9fa8da;
$tb-primary-color-light: #7986cb;
$sidenav-anim-timing: 400ms cubic-bezier(0.25, 0.8, 0.25, 1);

Loading…
Cancel
Save