migrate angular 21 finalize

This commit is contained in:
2026-03-09 22:56:31 +01:00
parent 26c99a0dae
commit bb08e46b0c
63 changed files with 738 additions and 783 deletions

View File

@@ -1,4 +1,4 @@
import {Component, Inject} from '@angular/core';
import {Component, inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent} from '@angular/material/dialog';
import {MatButton} from '@angular/material/button';
import QRCode from 'qrcode';
@@ -17,9 +17,13 @@ export interface ShareDialogData {
styleUrl: './share-dialog.component.less',
})
export class ShareDialogComponent {
public data = inject<ShareDialogData>(MAT_DIALOG_DATA);
public qrCode: string;
public constructor(@Inject(MAT_DIALOG_DATA) public data: ShareDialogData) {
public constructor() {
const data = this.data;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
QRCode.toDataURL(data.url, {
type: 'image/jpeg',

View File

@@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core';
import {Component, OnInit, inject} from '@angular/core';
import {ShowDataService} from '../services/show-data.service';
import {Observable, take} from 'rxjs';
import {Show} from '../services/show';
@@ -42,6 +42,10 @@ import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/s
],
})
export class EditComponent implements OnInit {
private showService = inject(ShowService);
private router = inject(Router);
private activatedRoute = inject(ActivatedRoute);
public shows$: Observable<Show[]>;
public showTypePublic = ShowService.SHOW_TYPE_PUBLIC;
public showTypePrivate = ShowService.SHOW_TYPE_PRIVATE;
@@ -52,12 +56,9 @@ export class EditComponent implements OnInit {
});
public faSave = faSave;
public constructor(
private showService: ShowService,
showDataService: ShowDataService,
private router: Router,
private activatedRoute: ActivatedRoute
) {
public constructor() {
const showDataService = inject(ShowDataService);
this.shows$ = showDataService.list$;
}

View File

@@ -1,4 +1,4 @@
import {Component, Input} from '@angular/core';
import {Component, Input, inject} from '@angular/core';
import {KeyValue} from '@angular/common';
import {ActivatedRoute, Router} from '@angular/router';
import {ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup} from '@angular/forms';
@@ -9,7 +9,6 @@ import {distinctUntilChanged, map, switchMap} from 'rxjs/operators';
import {combineLatest, Observable, of} from 'rxjs';
import {dynamicSort, onlyUnique} from '../../../../services/filter.helper';
import {UserService} from '../../../../services/user/user.service';
import {isEqual} from 'lodash';
import {MatFormField, MatLabel} from '@angular/material/form-field';
import {MatSelect} from '@angular/material/select';
import {MatOptgroup, MatOption} from '@angular/material/core';
@@ -22,6 +21,10 @@ import {ShowTypePipe} from '../../../../widget-modules/pipes/show-type-translate
imports: [ReactiveFormsModule, MatFormField, MatLabel, MatSelect, MatOption, MatOptgroup, ShowTypePipe],
})
export class FilterComponent {
private router = inject(Router);
private showService = inject(ShowService);
private userService = inject(UserService);
@Input() public route = '/shows/';
@Input() public shows: Show[] = [];
@@ -38,13 +41,10 @@ export class FilterComponent {
public owners: {key: string; value: string}[] = [];
public constructor(
private router: Router,
private showService: ShowService,
private userService: UserService,
activatedRoute: ActivatedRoute,
fb: UntypedFormBuilder
) {
public constructor() {
const activatedRoute = inject(ActivatedRoute);
const fb = inject(UntypedFormBuilder);
this.filterFormGroup = fb.group({
time: 1,
owner: null,
@@ -92,7 +92,7 @@ export class FilterComponent {
map(owners => {
return owners.sort(dynamicSort('value'));
}),
distinctUntilChanged(isEqual),
distinctUntilChanged((left, right) => this.sameOwners(left, right)),
map(_ => _ as {key: string; value: string}[])
);
};
@@ -104,4 +104,12 @@ export class FilterComponent {
});
await this.router.navigateByUrl(route);
}
private sameOwners(left: {key: string; value: string}[], right: {key: string; value: string}[]): boolean {
if (left.length !== right.length) {
return false;
}
return left.every((owner, index) => owner.key === right[index]?.key && owner.value === right[index]?.value);
}
}

View File

@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import {Component, inject} from '@angular/core';
import {combineLatest} from 'rxjs';
import {Show} from '../services/show';
import {fade} from '../../../animations';
@@ -22,8 +22,9 @@ import {SortByPipe} from '../../../widget-modules/pipes/sort-by/sort-by.pipe';
imports: [RoleDirective, ListHeaderComponent, FilterComponent, CardComponent, ListItemComponent, RouterLink, AsyncPipe, SortByPipe],
})
export class ListComponent {
public shows$ = this.showService.list$();
public privateShows$ = this.showService.list$().pipe(map(show => show.filter(_ => !_.published)));
private showService = inject(ShowService);
private activatedRoute = inject(ActivatedRoute);
public lastMonths$ = this.activatedRoute.queryParams.pipe(
map(params => {
const filterValues = params as FilterValues;
@@ -43,8 +44,9 @@ export class ListComponent {
return filterValues?.showType;
})
);
public shows$ = this.showService.list$();
public privateShows$ = this.showService.list$().pipe(map(show => show.filter(_ => !_.published)));
public queriedPublicShows$ = this.lastMonths$.pipe(switchMap(lastMonths => this.showService.listPublicSince$(lastMonths)));
public fallbackPublicShows$ = combineLatest([this.shows$, this.lastMonths$]).pipe(
map(([shows, lastMonths]) => {
const startDate = new Date();
@@ -54,7 +56,6 @@ export class ListComponent {
return shows.filter(show => show.published && !show.archived && show.date.toDate() >= startDate);
})
);
public publicShows$ = combineLatest([this.queriedPublicShows$, this.fallbackPublicShows$, this.owner$, this.showType$]).pipe(
map(([queriedShows, fallbackShows, owner, showType]) => {
const shows = queriedShows.length > 0 || fallbackShows.length === 0 ? queriedShows : fallbackShows;
@@ -63,10 +64,5 @@ export class ListComponent {
})
);
public constructor(
private showService: ShowService,
private activatedRoute: ActivatedRoute
) {}
public trackBy = (index: number, show: unknown) => (show as Show).id;
}

View File

@@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core';
import {Component, OnInit, inject} from '@angular/core';
import {ShowDataService} from '../services/show-data.service';
import {Observable} from 'rxjs';
import {Show} from '../services/show';
@@ -40,6 +40,9 @@ import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/s
],
})
export class NewComponent implements OnInit {
private showService = inject(ShowService);
private router = inject(Router);
public shows$: Observable<Show[]>;
public showTypePublic = ShowService.SHOW_TYPE_PUBLIC;
public showTypePrivate = ShowService.SHOW_TYPE_PRIVATE;
@@ -49,11 +52,9 @@ export class NewComponent implements OnInit {
});
public faSave = faSave;
public constructor(
private showService: ShowService,
showDataService: ShowDataService,
private router: Router
) {
public constructor() {
const showDataService = inject(ShowDataService);
this.shows$ = showDataService.list$;
}

View File

@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import {Injectable, inject} from '@angular/core';
import {Document, HeadingLevel, ISectionOptions, Packer, Paragraph} from 'docx';
import {ShowService} from './show.service';
import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/show-type.pipe';
@@ -26,13 +26,11 @@ export interface DownloadOptions {
providedIn: 'root',
})
export class DocxService {
public constructor(
private showService: ShowService,
private showSongService: ShowSongService,
private textRenderingService: TextRenderingService,
private userService: UserService,
private configService: ConfigService
) {}
private showService = inject(ShowService);
private showSongService = inject(ShowSongService);
private textRenderingService = inject(TextRenderingService);
private userService = inject(UserService);
private configService = inject(ConfigService);
public async create(showId: string, options: DownloadOptions = {}): Promise<void> {
const data = await this.prepareData(showId);
@@ -194,17 +192,17 @@ export class DocxService {
if (!config) return null;
const showSongs = await this.showSongService.list(showId);
const songsAsync = showSongs.map(showSong => {
const sections = this.textRenderingService.parse(showSong.text, {
baseKey: showSong.keyOriginal,
targetKey: showSong.key,
});
return {
showSong,
sections,
};
});
const songsLoaded = (await Promise.all(songsAsync))
const songsLoaded = showSongs
.map(showSong => {
const sections = this.textRenderingService.parse(showSong.text, {
baseKey: showSong.keyOriginal,
targetKey: showSong.key,
});
return {
showSong,
sections,
};
})
.filter(_ => !!_)
.map(
_ =>

View File

@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import {Injectable, inject} from '@angular/core';
import {Observable} from 'rxjs';
import {DbService} from '../../../services/db.service';
import {Show} from './show';
@@ -9,6 +9,8 @@ import {orderBy, QueryConstraint, Timestamp, where} from '@angular/fire/firestor
providedIn: 'root',
})
export class ShowDataService {
private dbService = inject(DbService);
private collection = 'shows';
public list$: Observable<Show[]> = this.dbService.col$<Show>(this.collection).pipe(
// server-side ordering cuts client work and keeps stable order across subscribers
@@ -19,8 +21,6 @@ export class ShowDataService {
})
);
public constructor(private dbService: DbService) {}
public listRaw$ = () => this.dbService.col$<Show>(this.collection);
public listPublicSince$(lastMonths: number): Observable<Show[]> {

View File

@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import {Injectable, inject} from '@angular/core';
import {DbService} from '../../../services/db.service';
import {Observable} from 'rxjs';
import {ShowSong} from './show-song';
@@ -9,12 +9,12 @@ import {shareReplay} from 'rxjs/operators';
providedIn: 'root',
})
export class ShowSongDataService {
private dbService = inject(DbService);
private collection = 'shows';
private subCollection = 'songs';
private listCache = new Map<string, Observable<ShowSong[]>>();
public constructor(private dbService: DbService) {}
public list$ = (showId: string, queryConstraints?: QueryConstraint[]): Observable<ShowSong[]> => {
if (queryConstraints && queryConstraints.length > 0) {
return this.dbService.col$(`${this.collection}/${showId}/${this.subCollection}`, queryConstraints);

View File

@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import {Injectable, inject} from '@angular/core';
import {ShowSongDataService} from './show-song-data.service';
import {firstValueFrom, Observable} from 'rxjs';
import {ShowSong} from './show-song';
@@ -10,12 +10,10 @@ import {ShowService} from './show.service';
providedIn: 'root',
})
export class ShowSongService {
public constructor(
private showSongDataService: ShowSongDataService,
private songDataService: SongDataService,
private userService: UserService,
private showService: ShowService
) {}
private showSongDataService = inject(ShowSongDataService);
private songDataService = inject(SongDataService);
private userService = inject(UserService);
private showService = inject(ShowService);
public async new$(showId: string, songId: string, addedLive = false): Promise<string | null> {
const song = await firstValueFrom(this.songDataService.read$(songId));

View File

@@ -1,4 +1,4 @@
import {Injectable} from '@angular/core';
import {Injectable, inject} from '@angular/core';
import {ShowDataService} from './show-data.service';
import {Show} from './show';
import {Observable} from 'rxjs';
@@ -10,15 +10,17 @@ import {User} from '../../../services/user/user';
providedIn: 'root',
})
export class ShowService {
private showDataService = inject(ShowDataService);
private userService = inject(UserService);
public static SHOW_TYPE = ['service-worship', 'service-praise', 'home-group-big', 'home-group', 'prayer-group', 'teens-group', 'kids-group', 'misc-public', 'misc-private'];
public static SHOW_TYPE_PUBLIC = ['service-worship', 'service-praise', 'home-group-big', 'teens-group', 'kids-group', 'misc-public'];
public static SHOW_TYPE_PRIVATE = ['home-group', 'prayer-group', 'misc-private'];
private user: User | null = null;
public constructor(
private showDataService: ShowDataService,
private userService: UserService
) {
public constructor() {
const userService = this.userService;
userService.user$.subscribe(_ => (this.user = _));
}

View File

@@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, HostListener, OnDestroy, OnInit} from '@angular/core';
import {ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, HostListener, OnDestroy, OnInit, inject} from '@angular/core';
import {filter, map, shareReplay, switchMap, tap} from 'rxjs/operators';
import {ActivatedRoute, Router} from '@angular/router';
import {ShowService} from '../services/show.service';
@@ -80,6 +80,16 @@ import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/s
],
})
export class ShowComponent implements OnInit, OnDestroy {
private activatedRoute = inject(ActivatedRoute);
private showService = inject(ShowService);
private songService = inject(SongService);
private showSongService = inject(ShowSongService);
private docxService = inject(DocxService);
private router = inject(Router);
private cRef = inject(ChangeDetectorRef);
public dialog = inject(MatDialog);
private guestShowService = inject(GuestShowService);
public show$: Observable<Show | null> | null = null;
public songs$: Observable<Song[] | null> | null = null;
public showSongs: ShowSong[] | null = null;
@@ -105,18 +115,6 @@ export class ShowComponent implements OnInit, OnDestroy {
public currentTime: Date;
private subs: Subscription[] = [];
public constructor(
private activatedRoute: ActivatedRoute,
private showService: ShowService,
private songService: SongService,
private showSongService: ShowSongService,
private docxService: DocxService,
private router: Router,
private cRef: ChangeDetectorRef,
public dialog: MatDialog,
private guestShowService: GuestShowService
) {}
public ngOnInit(): void {
this.currentTime = new Date();
setInterval(() => {

View File

@@ -1,4 +1,4 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {Component, Input, OnInit, ViewChild, inject} from '@angular/core';
import {ShowSongService} from '../../services/show-song.service';
import {ShowSong} from '../../services/show-song';
import {getScale} from '../../../songs/services/key.helper';
@@ -39,6 +39,8 @@ import {ButtonComponent} from '../../../../widget-modules/components/button/butt
],
})
export class SongComponent implements OnInit {
private showSongService = inject(ShowSongService);
@Input() public show: Show | null = null;
@Input() public showId: string | null = null;
@Input() public showText: boolean | null = null;
@@ -55,8 +57,6 @@ export class SongComponent implements OnInit {
public editSongControl = new UntypedFormControl();
@ViewChild('option') private keyOptions: MatSelect;
public constructor(private showSongService: ShowSongService) {}
@Input()
public set showSong(song: ShowSong) {
this.iSong = song;