From 984d8ab139fbb6bf002a6851b0ded120ae3acd9f Mon Sep 17 00:00:00 2001 From: Andrei Yurkouski Date: Tue, 2 Sep 2025 09:47:07 +0200 Subject: [PATCH 1/5] feat: add dynamic outlet switching for auth status --- src/app/app.css | 12 ------------ src/app/app.html | 12 +----------- src/app/app.ts | 13 +++++++++---- src/app/components/login-form/login-form.css | 4 ++++ src/app/components/login-form/login-form.html | 3 +++ src/app/outlet/private-outlet/private-outlet.css | 4 ++++ src/app/outlet/private-outlet/private-outlet.html | 5 +++++ src/app/outlet/private-outlet/private-outlet.ts | 11 +++++++++++ src/app/outlet/public-outlet/public-outlet.css | 6 ++++++ src/app/outlet/public-outlet/public-outlet.html | 3 +++ src/app/outlet/public-outlet/public-outlet.ts | 10 ++++++++++ 11 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 src/app/outlet/private-outlet/private-outlet.css create mode 100644 src/app/outlet/private-outlet/private-outlet.html create mode 100644 src/app/outlet/private-outlet/private-outlet.ts create mode 100644 src/app/outlet/public-outlet/public-outlet.css create mode 100644 src/app/outlet/public-outlet/public-outlet.html create mode 100644 src/app/outlet/public-outlet/public-outlet.ts diff --git a/src/app/app.css b/src/app/app.css index e126d2c..e69de29 100644 --- a/src/app/app.css +++ b/src/app/app.css @@ -1,12 +0,0 @@ -.private { - padding: 1rem; - container-type: inline-size; -} - -.public { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; -} - diff --git a/src/app/app.html b/src/app/app.html index 884fd2b..f0f7a9a 100644 --- a/src/app/app.html +++ b/src/app/app.html @@ -1,11 +1 @@ -@if (authStatus()?.authenticated) { -
- - - -
-} @else { -
- -
-} + diff --git a/src/app/app.ts b/src/app/app.ts index b209834..11e2d60 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,16 +1,21 @@ import { Component, inject } from '@angular/core' -import { RouterOutlet } from '@angular/router' -import { NavComponent } from './components/nav/nav.component' import { AuthService } from './services/auth-service' import { toSignal } from '@angular/core/rxjs-interop' +import { PrivateOutlet } from './outlet/private-outlet/private-outlet' +import { PublicOutlet } from './outlet/public-outlet/public-outlet' +import { NgComponentOutlet } from '@angular/common' @Component({ selector: 'app-root', - imports: [RouterOutlet, NavComponent], + imports: [NgComponentOutlet], templateUrl: './app.html', styleUrl: './app.css', }) export class App { private readonly authService = inject(AuthService) - protected readonly authStatus = toSignal(this.authService.$authStatus) + private readonly authStatus = toSignal(this.authService.$authStatus) + + getOutlet() { + return this.authStatus()?.authenticated ? PrivateOutlet : PublicOutlet + } } diff --git a/src/app/components/login-form/login-form.css b/src/app/components/login-form/login-form.css index ac5b999..46ba7b7 100644 --- a/src/app/components/login-form/login-form.css +++ b/src/app/components/login-form/login-form.css @@ -4,3 +4,7 @@ gap: 1rem; margin: 1rem 0; } + +.description { + max-width: 30ch; +} diff --git a/src/app/components/login-form/login-form.html b/src/app/components/login-form/login-form.html index 658e2ec..a58c371 100644 --- a/src/app/components/login-form/login-form.html +++ b/src/app/components/login-form/login-form.html @@ -1,5 +1,8 @@
+ + Login with your existing password and login. + Login + + + + diff --git a/src/app/outlet/private-outlet/private-outlet.ts b/src/app/outlet/private-outlet/private-outlet.ts new file mode 100644 index 0000000..c0b28f4 --- /dev/null +++ b/src/app/outlet/private-outlet/private-outlet.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core' +import { NavComponent } from '../../components/nav/nav.component' +import { RouterOutlet } from '@angular/router' + +@Component({ + selector: 'app-private-outlet', + imports: [NavComponent, RouterOutlet], + templateUrl: './private-outlet.html', + styleUrl: './private-outlet.css', +}) +export class PrivateOutlet {} diff --git a/src/app/outlet/public-outlet/public-outlet.css b/src/app/outlet/public-outlet/public-outlet.css new file mode 100644 index 0000000..971f48a --- /dev/null +++ b/src/app/outlet/public-outlet/public-outlet.css @@ -0,0 +1,6 @@ +.public { + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} diff --git a/src/app/outlet/public-outlet/public-outlet.html b/src/app/outlet/public-outlet/public-outlet.html new file mode 100644 index 0000000..807e82b --- /dev/null +++ b/src/app/outlet/public-outlet/public-outlet.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/outlet/public-outlet/public-outlet.ts b/src/app/outlet/public-outlet/public-outlet.ts new file mode 100644 index 0000000..30dd0b4 --- /dev/null +++ b/src/app/outlet/public-outlet/public-outlet.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core' +import { RouterOutlet } from '@angular/router' + +@Component({ + selector: 'app-public', + imports: [RouterOutlet], + templateUrl: './public-outlet.html', + styleUrl: './public-outlet.css', +}) +export class PublicOutlet {} From 79e72a41872290574fde45e581dd570196ed8b87 Mon Sep 17 00:00:00 2001 From: Andrei Yurkouski Date: Tue, 2 Sep 2025 11:02:41 +0200 Subject: [PATCH 2/5] feat: enhance auth page with app health status --- src/app/app.routes.ts | 1 + .../pages/auth-page/auth-page.component.css | 1 + .../pages/auth-page/auth-page.component.html | 8 ++++++ .../pages/auth-page/auth-page.component.ts | 26 ++++++++++++++++--- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 70e3c70..e3b59a1 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -63,6 +63,7 @@ export const routes: Routes = [ path: 'status', component: StatusPage, data: { title: 'Status' }, + canMatch: [authGuard], }, { path: '**', diff --git a/src/app/pages/auth-page/auth-page.component.css b/src/app/pages/auth-page/auth-page.component.css index e718862..a37ef5f 100644 --- a/src/app/pages/auth-page/auth-page.component.css +++ b/src/app/pages/auth-page/auth-page.component.css @@ -4,4 +4,5 @@ justify-content: center; align-items: center; padding: 2rem; + gap: 1rem; } diff --git a/src/app/pages/auth-page/auth-page.component.html b/src/app/pages/auth-page/auth-page.component.html index a6330d6..bc4a51d 100644 --- a/src/app/pages/auth-page/auth-page.component.html +++ b/src/app/pages/auth-page/auth-page.component.html @@ -8,3 +8,11 @@ + + diff --git a/src/app/pages/auth-page/auth-page.component.ts b/src/app/pages/auth-page/auth-page.component.ts index 00403b1..d0394e8 100644 --- a/src/app/pages/auth-page/auth-page.component.ts +++ b/src/app/pages/auth-page/auth-page.component.ts @@ -1,15 +1,35 @@ -import { Component } from '@angular/core' +import { Component, inject } from '@angular/core' import { MatFormFieldModule } from '@angular/material/form-field' import { FormsModule } from '@angular/forms' import { LoginForm } from '../../components/login-form/login-form' import { SignupForm } from '../../components/signup-form/signup-form' import { MatTab, MatTabGroup } from '@angular/material/tabs' import { MatCard } from '@angular/material/card' +import { MatIconButton } from '@angular/material/button' +import { HealthStatus } from '../../components/health-status/health-status' +import { MatBottomSheet } from '@angular/material/bottom-sheet' +import { MatIconModule } from '@angular/material/icon' @Component({ selector: 'app-auth', - imports: [MatFormFieldModule, FormsModule, LoginForm, SignupForm, MatTabGroup, MatTab, MatCard], + imports: [ + MatFormFieldModule, + FormsModule, + LoginForm, + SignupForm, + MatTabGroup, + MatTab, + MatCard, + MatIconModule, + MatIconButton, + ], templateUrl: './auth-page.component.html', styleUrl: './auth-page.component.css', }) -export class AuthPage {} +export class AuthPage { + private bottomSheet = inject(MatBottomSheet) + + showAppHealth() { + this.bottomSheet.open(HealthStatus) + } +} From e130e5d6395de509f151a0c54030bb8b6f373f01 Mon Sep 17 00:00:00 2001 From: Andrei Yurkouski Date: Tue, 2 Sep 2025 11:48:09 +0200 Subject: [PATCH 3/5] refactor: remove page-title component and associated files --- src/app/components/page-title/page-title.css | 10 ------ src/app/components/page-title/page-title.html | 3 -- src/app/components/page-title/page-title.ts | 36 ------------------- 3 files changed, 49 deletions(-) delete mode 100644 src/app/components/page-title/page-title.css delete mode 100644 src/app/components/page-title/page-title.html delete mode 100644 src/app/components/page-title/page-title.ts diff --git a/src/app/components/page-title/page-title.css b/src/app/components/page-title/page-title.css deleted file mode 100644 index 69a6e05..0000000 --- a/src/app/components/page-title/page-title.css +++ /dev/null @@ -1,10 +0,0 @@ -:host { - --background: var(--mat-sys-primary-container); - --border: 0; -} - -mat-toolbar { - background: var(--background); - border-radius: var(--border); - transition: border-radius 0.5s ease-in-out; -} diff --git a/src/app/components/page-title/page-title.html b/src/app/components/page-title/page-title.html deleted file mode 100644 index f657a5f..0000000 --- a/src/app/components/page-title/page-title.html +++ /dev/null @@ -1,3 +0,0 @@ - -

{{ title() }}

-
diff --git a/src/app/components/page-title/page-title.ts b/src/app/components/page-title/page-title.ts deleted file mode 100644 index 37a949d..0000000 --- a/src/app/components/page-title/page-title.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Component, computed, HostBinding, HostListener, input } from '@angular/core' -import { MatToolbar } from '@angular/material/toolbar' - -@Component({ - selector: 'app-page-title', - imports: [MatToolbar], - templateUrl: './page-title.html', - styleUrl: './page-title.css', -}) -export class PageTitle { - title = input() - randomColor = computed(() => { - return `#${Math.floor(Math.random() * 16777215) - .toString(16) - .padStart(6, '0')}` - }) - - @HostBinding('style.--background') - value: string = this.randomColor() - - @HostListener('mouseenter', ['$event']) - onMouseEnter(event: MouseEvent) { - const element = event.target as HTMLElement - if (element) { - element.style.setProperty('--border', '50cqh') - } - } - - @HostListener('mouseleave', ['$event']) - onMouseLeave(event: MouseEvent) { - const element = event.target as HTMLElement - if (element) { - element.style.setProperty('--border', '0') - } - } -} From bf92e0473631cd638cb318d395f59422f4a96ff0 Mon Sep 17 00:00:00 2001 From: Andrei Yurkouski Date: Tue, 2 Sep 2025 12:08:37 +0200 Subject: [PATCH 4/5] refactor: rename and update routes/pages for consistency and clarity --- src/app/app.routes.ts | 14 +++++++------- src/app/components/login-form/login-form.ts | 2 +- src/app/components/nav/nav.component.ts | 2 +- ...article-page.component.css => article-page.css} | 0 ...ticle-page.component.html => article-page.html} | 0 .../{article-page.component.ts => article-page.ts} | 6 +++--- .../articles-page.css} | 0 .../articles-page.html} | 0 .../articles-page.ts} | 8 ++++---- .../bookmarks-page.css} | 0 .../bookmarks-page.html} | 0 .../bookmarks-page.ts} | 8 ++++---- .../subscriptions-page/subscriptions-page.html | 2 +- .../tags-page.css} | 0 .../tags-page.html} | 0 .../tags-page.ts} | 6 +++--- 16 files changed, 24 insertions(+), 24 deletions(-) rename src/app/pages/article-page/{article-page.component.css => article-page.css} (100%) rename src/app/pages/article-page/{article-page.component.html => article-page.html} (100%) rename src/app/pages/article-page/{article-page.component.ts => article-page.ts} (97%) rename src/app/pages/{bookmarks/bookmarks.css => articles-page/articles-page.css} (100%) rename src/app/pages/{home/home-page.component.html => articles-page/articles-page.html} (100%) rename src/app/pages/{home/home-page.component.ts => articles-page/articles-page.ts} (97%) rename src/app/pages/{home/home-page.component.css => bookmarks-page/bookmarks-page.css} (100%) rename src/app/pages/{bookmarks/bookmarks.html => bookmarks-page/bookmarks-page.html} (100%) rename src/app/pages/{bookmarks/bookmarks.ts => bookmarks-page/bookmarks-page.ts} (94%) rename src/app/pages/{tags/tags-page.component.css => tags-page/tags-page.css} (100%) rename src/app/pages/{tags/tags-page.component.html => tags-page/tags-page.html} (100%) rename src/app/pages/{tags/tags-page.component.ts => tags-page/tags-page.ts} (95%) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index e3b59a1..40c2bca 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -8,18 +8,18 @@ export const routes: Routes = [ { path: '', redirectTo: 'auth', pathMatch: 'full' }, { path: 'auth', component: AuthPage, data: { title: 'Authentication' } }, { - path: 'home', + path: 'articles', loadComponent: async () => { - const c = await import('./pages/home/home-page.component') - return c.HomePage + const c = await import('./pages/articles-page/articles-page') + return c.ArticlesPage }, canMatch: [authGuard], }, { path: 'bookmarks', loadComponent: async () => { - const c = await import('./pages/bookmarks/bookmarks') - return c.Bookmarks + const c = await import('./pages/bookmarks-page/bookmarks-page') + return c.BookmarksPage }, canMatch: [authGuard], }, @@ -35,7 +35,7 @@ export const routes: Routes = [ { path: 'subscription/:subscriptionId/article/:articleId', loadComponent: async () => { - const c = await import('./pages/article-page/article-page.component') + const c = await import('./pages/article-page/article-page') return c.ArticlePage }, data: { title: 'Article' }, @@ -44,7 +44,7 @@ export const routes: Routes = [ { path: 'tags', loadComponent: async () => { - const c = await import('./pages/tags/tags-page.component') + const c = await import('./pages/tags-page/tags-page') return c.TagsPage }, data: { title: 'Tags' }, diff --git a/src/app/components/login-form/login-form.ts b/src/app/components/login-form/login-form.ts index e31fc3a..7e0277f 100644 --- a/src/app/components/login-form/login-form.ts +++ b/src/app/components/login-form/login-form.ts @@ -53,7 +53,7 @@ export class LoginForm { .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((result) => { if (result) { - this.router.navigate(['/home']) + this.router.navigate(['/articles']) } }) } diff --git a/src/app/components/nav/nav.component.ts b/src/app/components/nav/nav.component.ts index 6098a80..bc871d6 100644 --- a/src/app/components/nav/nav.component.ts +++ b/src/app/components/nav/nav.component.ts @@ -55,7 +55,7 @@ export class NavComponent implements OnInit { private router = inject(Router) menuItems: { title: string; icon?: string; url: string }[] = [ - { title: 'Articles', url: '/home', icon: 'library_books' }, + { title: 'Articles', url: '/articles', icon: 'library_books' }, { title: 'Bookmarks', url: '/bookmarks', icon: 'bookmark' }, { title: 'Subscriptions', url: '/subscriptions', icon: 'rss_feed' }, { title: 'Tags', url: '/tags', icon: 'tag' }, diff --git a/src/app/pages/article-page/article-page.component.css b/src/app/pages/article-page/article-page.css similarity index 100% rename from src/app/pages/article-page/article-page.component.css rename to src/app/pages/article-page/article-page.css diff --git a/src/app/pages/article-page/article-page.component.html b/src/app/pages/article-page/article-page.html similarity index 100% rename from src/app/pages/article-page/article-page.component.html rename to src/app/pages/article-page/article-page.html diff --git a/src/app/pages/article-page/article-page.component.ts b/src/app/pages/article-page/article-page.ts similarity index 97% rename from src/app/pages/article-page/article-page.component.ts rename to src/app/pages/article-page/article-page.ts index a973b50..6ac1d09 100644 --- a/src/app/pages/article-page/article-page.component.ts +++ b/src/app/pages/article-page/article-page.ts @@ -17,7 +17,7 @@ import { TitleService } from '../../services/title-service' import { DomSanitizer, SafeHtml } from '@angular/platform-browser' @Component({ - selector: 'app-article', + selector: 'app-article-page', imports: [ MatToolbarModule, MatProgressBarModule, @@ -28,8 +28,8 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser' MatIconButton, MatDivider, ], - templateUrl: './article-page.component.html', - styleUrl: './article-page.component.css', + templateUrl: './article-page.html', + styleUrl: './article-page.css', }) export class ArticlePage implements OnInit { feedService = inject(FeedService) diff --git a/src/app/pages/bookmarks/bookmarks.css b/src/app/pages/articles-page/articles-page.css similarity index 100% rename from src/app/pages/bookmarks/bookmarks.css rename to src/app/pages/articles-page/articles-page.css diff --git a/src/app/pages/home/home-page.component.html b/src/app/pages/articles-page/articles-page.html similarity index 100% rename from src/app/pages/home/home-page.component.html rename to src/app/pages/articles-page/articles-page.html diff --git a/src/app/pages/home/home-page.component.ts b/src/app/pages/articles-page/articles-page.ts similarity index 97% rename from src/app/pages/home/home-page.component.ts rename to src/app/pages/articles-page/articles-page.ts index d3afcb8..16fabdc 100644 --- a/src/app/pages/home/home-page.component.ts +++ b/src/app/pages/articles-page/articles-page.ts @@ -23,7 +23,7 @@ import { AsyncPipe } from '@angular/common' import { SortOrder } from '../../entities/base/base.enums' @Component({ - selector: 'app-home', + selector: 'app-articles-page', imports: [ MatCardModule, MatToolbarModule, @@ -38,10 +38,10 @@ import { SortOrder } from '../../entities/base/base.enums' PageDisplayToggle, AsyncPipe, ], - templateUrl: './home-page.component.html', - styleUrl: './home-page.component.css', + templateUrl: './articles-page.html', + styleUrl: './articles-page.css', }) -export class HomePage implements OnInit { +export class ArticlesPage implements OnInit { feedService = inject(FeedService) router = inject(Router) route = inject(ActivatedRoute) diff --git a/src/app/pages/home/home-page.component.css b/src/app/pages/bookmarks-page/bookmarks-page.css similarity index 100% rename from src/app/pages/home/home-page.component.css rename to src/app/pages/bookmarks-page/bookmarks-page.css diff --git a/src/app/pages/bookmarks/bookmarks.html b/src/app/pages/bookmarks-page/bookmarks-page.html similarity index 100% rename from src/app/pages/bookmarks/bookmarks.html rename to src/app/pages/bookmarks-page/bookmarks-page.html diff --git a/src/app/pages/bookmarks/bookmarks.ts b/src/app/pages/bookmarks-page/bookmarks-page.ts similarity index 94% rename from src/app/pages/bookmarks/bookmarks.ts rename to src/app/pages/bookmarks-page/bookmarks-page.ts index 4db04b4..37a098a 100644 --- a/src/app/pages/bookmarks/bookmarks.ts +++ b/src/app/pages/bookmarks-page/bookmarks-page.ts @@ -14,12 +14,12 @@ import { PageService } from '../../services/page-service' import { PageDisplayToggle } from '../../components/page-display-toggle/page-display-toggle' @Component({ - selector: 'app-bookmarks', + selector: 'app-bookmarks-page', imports: [ArticleList, MatToolbarRow, Paginator, PageDisplayToggle], - templateUrl: './bookmarks.html', - styleUrl: './bookmarks.css', + templateUrl: './bookmarks-page.html', + styleUrl: './bookmarks-page.css', }) -export class Bookmarks implements OnInit { +export class BookmarksPage implements OnInit { feedService = inject(FeedService) destroyRef = inject(DestroyRef) tagService = inject(TagService) diff --git a/src/app/pages/subscriptions-page/subscriptions-page.html b/src/app/pages/subscriptions-page/subscriptions-page.html index da676ce..0707a86 100644 --- a/src/app/pages/subscriptions-page/subscriptions-page.html +++ b/src/app/pages/subscriptions-page/subscriptions-page.html @@ -25,7 +25,7 @@ @for (f of feeds(); track f._id) { diff --git a/src/app/pages/tags/tags-page.component.css b/src/app/pages/tags-page/tags-page.css similarity index 100% rename from src/app/pages/tags/tags-page.component.css rename to src/app/pages/tags-page/tags-page.css diff --git a/src/app/pages/tags/tags-page.component.html b/src/app/pages/tags-page/tags-page.html similarity index 100% rename from src/app/pages/tags/tags-page.component.html rename to src/app/pages/tags-page/tags-page.html diff --git a/src/app/pages/tags/tags-page.component.ts b/src/app/pages/tags-page/tags-page.ts similarity index 95% rename from src/app/pages/tags/tags-page.component.ts rename to src/app/pages/tags-page/tags-page.ts index 6005b1c..c2804a5 100644 --- a/src/app/pages/tags/tags-page.component.ts +++ b/src/app/pages/tags-page/tags-page.ts @@ -16,7 +16,7 @@ import { PageService } from '../../services/page-service' import { TitleService } from '../../services/title-service' @Component({ - selector: 'app-tags', + selector: 'app-tags-page', imports: [ MatCardModule, MatToolbarModule, @@ -27,8 +27,8 @@ import { TitleService } from '../../services/title-service' MatChipSet, Paginator, ], - templateUrl: './tags-page.component.html', - styleUrl: './tags-page.component.css', + templateUrl: './tags-page.html', + styleUrl: './tags-page.css', }) export class TagsPage implements OnInit { tagsService = inject(TagService) From 5af846cbe72e9b6c640cbf9186ef5bff8991474d Mon Sep 17 00:00:00 2001 From: Andrei Yurkouski Date: Tue, 2 Sep 2025 13:01:26 +0200 Subject: [PATCH 5/5] feat: add tag-based navigation and filtering options --- src/app/components/nav/nav.component.ts | 9 +---- .../page-display-toggle.html | 16 +++++---- .../page-display-toggle.ts | 3 +- .../pages/articles-page/articles-page.html | 30 ++++++++++------ src/app/pages/articles-page/articles-page.ts | 34 ++++++++++++++++--- src/app/pages/tags-page/tags-page.html | 6 +++- src/app/pages/tags-page/tags-page.ts | 7 ++++ src/app/services/tag-service.ts | 4 +++ 8 files changed, 78 insertions(+), 31 deletions(-) diff --git a/src/app/components/nav/nav.component.ts b/src/app/components/nav/nav.component.ts index bc871d6..58f2505 100644 --- a/src/app/components/nav/nav.component.ts +++ b/src/app/components/nav/nav.component.ts @@ -1,11 +1,4 @@ -import { - Component, - DestroyRef, - inject, - OnInit, - signal, - viewChild -} from '@angular/core' +import { Component, DestroyRef, inject, OnInit, signal, viewChild } from '@angular/core' import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout' import { AsyncPipe } from '@angular/common' import { MatToolbarModule } from '@angular/material/toolbar' diff --git a/src/app/components/page-display-toggle/page-display-toggle.html b/src/app/components/page-display-toggle/page-display-toggle.html index 55b2d97..9626151 100644 --- a/src/app/components/page-display-toggle/page-display-toggle.html +++ b/src/app/components/page-display-toggle/page-display-toggle.html @@ -1,12 +1,16 @@ - view_day - - + view_day + + diff --git a/src/app/components/page-display-toggle/page-display-toggle.ts b/src/app/components/page-display-toggle/page-display-toggle.ts index 329f223..4b8f4da 100644 --- a/src/app/components/page-display-toggle/page-display-toggle.ts +++ b/src/app/components/page-display-toggle/page-display-toggle.ts @@ -4,10 +4,11 @@ import { MatButtonToggle } from '@angular/material/button-toggle' import { MatIcon } from '@angular/material/icon' import { PageDisplay } from '../../entities/page/page.enums' import { AsyncPipe } from '@angular/common' +import { MatIconButton } from '@angular/material/button' @Component({ selector: 'app-page-display-toggle', - imports: [MatButtonToggle, MatIcon, MatButtonToggle, MatIcon, AsyncPipe], + imports: [MatButtonToggle, MatIcon, MatButtonToggle, MatIcon, AsyncPipe, MatIconButton], templateUrl: './page-display-toggle.html', styleUrl: './page-display-toggle.css', }) diff --git a/src/app/pages/articles-page/articles-page.html b/src/app/pages/articles-page/articles-page.html index 14df542..c681b17 100644 --- a/src/app/pages/articles-page/articles-page.html +++ b/src/app/pages/articles-page/articles-page.html @@ -10,24 +10,34 @@ - schedule - - + + schedule + + + diff --git a/src/app/pages/articles-page/articles-page.ts b/src/app/pages/articles-page/articles-page.ts index 16fabdc..084d0c9 100644 --- a/src/app/pages/articles-page/articles-page.ts +++ b/src/app/pages/articles-page/articles-page.ts @@ -3,7 +3,7 @@ import { MatCardModule } from '@angular/material/card' import { FeedService } from '../../services/feed-service' import { takeUntilDestroyed } from '@angular/core/rxjs-interop' import { HttpErrorResponse } from '@angular/common/http' -import { BehaviorSubject, catchError, combineLatest, of, switchMap } from 'rxjs' +import { BehaviorSubject, catchError, combineLatest, forkJoin, of, switchMap } from 'rxjs' import { MatButton, MatIconButton } from '@angular/material/button' import { MatToolbarModule } from '@angular/material/toolbar' import { MatButtonToggleModule } from '@angular/material/button-toggle' @@ -56,6 +56,7 @@ export class ArticlesPage implements OnInit { $readFilter = new BehaviorSubject(true) $favFilter = new BehaviorSubject(false) $subscriptionFilter = new BehaviorSubject(null) + $tagFilter = new BehaviorSubject(null) $dateOrder = new BehaviorSubject(SortOrder.Desc) favTagId = signal('') @@ -96,9 +97,10 @@ export class ArticlesPage implements OnInit { this.$favFilter, this.$readFilter, this.$subscriptionFilter, + this.$tagFilter, this.$dateOrder, ]).pipe( - switchMap(([perPage, pageNumber, fav, read, subscription, dateSort]) => { + switchMap(([perPage, pageNumber, fav, read, subscription, tag, dateSort]) => { const filters: Record = {} if (read) { @@ -113,6 +115,10 @@ export class ArticlesPage implements OnInit { filters['subscription'] = subscription } + if (tag) { + filters['tags'] = tag + } + return this.feedService.getAllArticles({ pagination: { perPage, @@ -142,20 +148,38 @@ export class ArticlesPage implements OnInit { takeUntilDestroyed(this.destroyRef), switchMap((params) => { const subscriptionId: string = params['subscription'] + const tagName: string = params['tag'] + const tag = this.userTags().find((t) => t.name === tagName) if (!subscriptionId) { - return of(null) + return forkJoin([of(null), this.tagService.getOne({ name: tagName })]) + } else { + return forkJoin([this.feedService.getOneSubscription({ subscriptionId }), of(null)]) } - return this.feedService.getOneSubscription({ subscriptionId }) }), catchError((e) => { console.error(e) return of(null) }), ) - .subscribe((feed) => { + .subscribe((results) => { + if (!results) { + return + } + + const [feed, tag] = results + if (feed) { this.titleService.setSubtitle(feed.title) this.$subscriptionFilter.next(feed._id) + this.$tagFilter.next(null) + } else if (tag) { + this.titleService.setSubtitle(tag.name) + this.$subscriptionFilter.next(null) + this.$tagFilter.next(tag._id) + } else { + this.titleService.setSubtitle(null) + this.$subscriptionFilter.next(null) + this.$tagFilter.next(null) } }) } diff --git a/src/app/pages/tags-page/tags-page.html b/src/app/pages/tags-page/tags-page.html index b5fd309..7c49acf 100644 --- a/src/app/pages/tags-page/tags-page.html +++ b/src/app/pages/tags-page/tags-page.html @@ -13,7 +13,11 @@ @defer { @for (t of tags(); track t._id) { - + {{ t.name }} @if (t.userId !== 'all') {