Skip to content

Commit

Permalink
refactor: implement breadcrumbs (#2552)
Browse files Browse the repository at this point in the history
  • Loading branch information
waterplea authored Jan 23, 2024
1 parent 90f5864 commit 92aa701
Show file tree
Hide file tree
Showing 26 changed files with 467 additions and 406 deletions.
7 changes: 7 additions & 0 deletions web/projects/shared/assets/img/icons/home.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions web/projects/ui/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<svg class="definitions" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="round-corners">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur" />
<feColorMatrix
in="blur"
type="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9"
result="flt_tag"
/>
<feComposite in="SourceGraphic" in2="flt_tag" operator="atop" />
</filter>
</defs>
</svg>
<tui-root
*ngIf="widgetDrawer$ | async as drawer"
tuiTheme="night"
Expand Down
9 changes: 8 additions & 1 deletion web/projects/ui/src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tui-root {

.menu {
:host-context(body[data-theme='Light']) & {
--ion-color-base: #F4F4F5 !important;
--ion-color-base: #f4f4f5 !important;
}
}

Expand Down Expand Up @@ -124,3 +124,10 @@ tui-root {
transform: rotate(45deg);
}
}

.definitions {
position: absolute;
width: 0;
height: 0;
visibility: hidden;
}
5 changes: 0 additions & 5 deletions web/projects/ui/src/app/app.providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import { ThemeSwitcherService } from './services/theme-switcher.service'
import { DateTransformerService } from './services/date-transformer.service'
import { DatetimeTransformerService } from './services/datetime-transformer.service'
import { MarketplaceService } from './services/marketplace.service'
import { RoutingStrategyService } from './apps/portal/services/routing-strategy.service'
import { CategoryService } from './services/category.service'

const {
Expand Down Expand Up @@ -80,10 +79,6 @@ export const APP_PROVIDERS: Provider[] = [
provide: AbstractMarketplaceService,
useClass: MarketplaceService,
},
{
provide: RouteReuseStrategy,
useExisting: RoutingStrategyService,
},
{
provide: AbstractCategoryService,
useClass: CategoryService,
Expand Down
13 changes: 0 additions & 13 deletions web/projects/ui/src/app/apps/portal/components/card.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
ChangeDetectionStrategy,
Component,
HostListener,
inject,
Input,
} from '@angular/core'
import {
Expand All @@ -15,9 +14,7 @@ import {
import { RouterLink } from '@angular/router'
import { TickerModule } from '@start9labs/shared'
import { TuiDataListModule, TuiHostedDropdownModule } from '@taiga-ui/core'
import { NavigationService } from '../services/navigation.service'
import { Action, ActionsComponent } from './actions.component'
import { toRouterLink } from '../utils/to-router-link'

@Component({
selector: '[appCard]',
Expand Down Expand Up @@ -123,8 +120,6 @@ import { toRouterLink } from '../utils/to-router-link'
],
})
export class CardComponent {
private readonly navigation = inject(NavigationService)

@Input({ required: true })
id!: string

Expand All @@ -144,14 +139,6 @@ export class CardComponent {
return !this.id.includes('/')
}

@HostListener('click')
onClick() {
const { id, icon, title } = this
const routerLink = toRouterLink(id)

this.navigation.addTab({ icon, title, routerLink })
}

// Prevents Firefox from starting a native drag
@HostListener('pointerdown.prevent')
onDown() {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {
ChangeDetectionStrategy,
Component,
HostBinding,
inject,
Input,
} from '@angular/core'
import { Breadcrumb } from '../../services/breadcrumbs.service'
import { TuiIconModule, TuiTitleModule } from '@taiga-ui/experimental'
import {
TUI_ANIMATION_OPTIONS,
tuiFadeIn,
tuiWidthCollapse,
} from '@taiga-ui/core'

@Component({
standalone: true,
selector: 'a[headerBreadcrumb]',
template: `
@if (item.icon?.startsWith('tuiIcon')) {
<tui-icon [icon]="item.icon || ''" />
} @else if (item.icon) {
<img [style.width.rem]="2" [src]="item.icon" [alt]="item.title" />
}
<span tuiTitle>
{{ item.title }}
@if (item.subtitle) {
<span tuiSubtitle="">{{ item.subtitle }}</span>
}
</span>
<ng-content />
`,
styles: [
`
:host {
display: flex;
align-items: center;
gap: 1rem;
min-width: 1.25rem;
white-space: nowrap;
text-transform: capitalize;
--clip-path: polygon(
calc(100% - 1.75rem) 0%,
calc(100% - 0.875rem) 50%,
100% 100%,
0% 100%,
0.875rem 50%,
0% 0%
);
&:not(.active) {
--clip-path: polygon(
calc(100% - 1.75rem) 0%,
calc(100% - 0.875rem) 50%,
calc(100% - 1.75rem) 100%,
0% 100%,
0.875rem 50%,
0% 0%
);
}
& > * {
font-weight: bold;
gap: 0;
border-radius: 100%;
}
&::before,
&::after {
content: '';
margin: 0.5rem;
}
&::before {
margin: 0.25rem;
}
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiIconModule, TuiTitleModule],
animations: [tuiWidthCollapse, tuiFadeIn],
})
export class HeaderBreadcrumbComponent {
@Input({ required: true, alias: 'headerBreadcrumb' })
item!: Breadcrumb

@HostBinding('@tuiFadeIn')
@HostBinding('@tuiWidthCollapse')
readonly animation = inject(TUI_ANIMATION_OPTIONS)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
import { AsyncPipe } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { TuiIconModule } from '@taiga-ui/experimental'
import { PatchDB } from 'patch-db-client'
import { combineLatest, map, Observable, startWith } from 'rxjs'
import { ConnectionService } from 'src/app/services/connection.service'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { AsyncPipe } from '@angular/common'

@Component({
standalone: true,
selector: 'header-connection',
template: `
<ng-content />
@if (connection$ | async; as connection) {
<tui-icon
[title]="connection.message"
[icon]="connection.icon"
[style.color]="connection.color"
[style.margin.rem]="0.5"
></tui-icon>
{{ connection.message }}
}
`,
styles: [
`
:host {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0 2rem;
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiIconModule, AsyncPipe],
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
ElementRef,
HostListener,
inject,
ViewChild,
} from '@angular/core'
import { Router } from '@angular/router'
import { TuiSidebarModule } from '@taiga-ui/addon-mobile'
import { tuiContainsOrAfter, tuiIsElement, TuiLetModule } from '@taiga-ui/cdk'
import {
TuiBadgedContentModule,
TuiBadgeNotificationModule,
TuiButtonModule,
} from '@taiga-ui/experimental'
import { Subject } from 'rxjs'
import { HeaderMenuComponent } from './menu.component'
import { HeaderNotificationsComponent } from './notifications.component'
import { SidebarDirective } from '../../../../app/sidebar-host.component'
import { NotificationService } from '../../services/notification.service'

@Component({
standalone: true,
selector: 'header-corner',
template: `
<ng-content />
<tui-badged-content
*tuiLet="notificationService.unreadCount$ | async as unread"
[style.--tui-radius.%]="50"
>
<tui-badge-notification *ngIf="unread" tuiSlot="top" size="s">
{{ unread }}
</tui-badge-notification>
<button
tuiIconButton
iconLeft="tuiIconBellLarge"
appearance="icon"
size="s"
[style.color]="'var(--tui-text-01)'"
(click)="handleNotificationsClick(unread || 0)"
>
Notifications
</button>
</tui-badged-content>
<header-menu></header-menu>
<header-notifications
(onEmpty)="this.open$.next(false)"
*tuiSidebar="!!(open$ | async); direction: 'right'; autoWidth: true"
/>
`,
styles: [
`
:host {
display: flex;
align-items: center;
gap: 0.25rem;
padding: 0 0.5rem 0 1.75rem;
--clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 1.75rem 100%);
}
`,
],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
HeaderMenuComponent,
HeaderNotificationsComponent,
SidebarDirective,
TuiBadgeNotificationModule,
TuiBadgedContentModule,
TuiButtonModule,
TuiLetModule,
TuiSidebarModule,
],
})
export class HeaderCornerComponent {
private readonly router = inject(Router)
readonly notificationService = inject(NotificationService)

@ViewChild(HeaderNotificationsComponent, { read: ElementRef })
private readonly panel?: ElementRef<HTMLElement>

private readonly _ = this.router.events.subscribe(() => {
this.open$.next(false)
})

readonly open$ = new Subject<boolean>()

@HostListener('document:click.capture', ['$event.target'])
onClick(target: EventTarget | null) {
if (
tuiIsElement(target) &&
this.panel?.nativeElement &&
!tuiContainsOrAfter(this.panel.nativeElement, target)
) {
this.open$.next(false)
}
}

handleNotificationsClick(unread: number) {
if (unread) {
this.open$.next(true)
} else {
this.router.navigateByUrl('/portal/system/notifications')
}
}
}
Loading

0 comments on commit 92aa701

Please sign in to comment.