Moved to Angular v20 and Tailwind v4 plus all related dependencies

Renamed Docker directory.

Also serving static files from FastAPI.
This commit is contained in:
2025-06-26 06:46:17 +00:00
parent 05b395af00
commit cb2b650375
253 changed files with 8626 additions and 1995 deletions
@@ -1,27 +1,28 @@
import { AsyncPipe, DecimalPipe } from '@angular/common';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AfterViewInit, Component, ElementRef, inject, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MatButton, MatIconButton } from '@angular/material/button';
import { MatCard, MatCardHeader, MatCardTitle, MatCardContent, MatCardActions } from '@angular/material/card';
import { MatCard, MatCardActions, MatCardContent, MatCardHeader, MatCardTitle } from '@angular/material/card';
import { MatOption } from '@angular/material/core';
import { MatDatepickerInput, MatDatepickerToggle, MatDatepicker } from '@angular/material/datepicker';
import { MatDatepicker, MatDatepickerInput, MatDatepickerToggle } from '@angular/material/datepicker';
import { MatDialog } from '@angular/material/dialog';
import { MatFormField, MatLabel, MatSuffix } from '@angular/material/form-field';
import { MatIcon } from '@angular/material/icon';
import { MatInput } from '@angular/material/input';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatSort } from '@angular/material/sort';
import {
MatTable,
MatColumnDef,
MatHeaderCellDef,
MatHeaderCell,
MatCellDef,
MatCell,
MatHeaderRowDef,
MatCellDef,
MatColumnDef,
MatHeaderCell,
MatHeaderCellDef,
MatHeaderRow,
MatRowDef,
MatHeaderRowDef,
MatRow,
MatRowDef,
MatTable,
} from '@angular/material/table';
import { ActivatedRoute, Router } from '@angular/router';
import moment from 'moment';
@@ -31,21 +32,18 @@ import { Period } from 'src/app/period/period';
import { Product } from '../../core/product';
import { ProductSku } from '../../core/product-sku';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ProductService } from '../../product/product.service';
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
import { MathService } from '../../shared/math.service';
import { Recipe } from '../recipe';
import { RecipeItem } from '../recipe-item';
import { RecipeService } from '../recipe.service';
import { RecipeDetailDatasource } from './recipe-detail-datasource';
@Component({
selector: 'app-product-group-detail',
templateUrl: './recipe-detail.component.html',
styleUrls: ['./recipe-detail.component.css'],
standalone: true,
imports: [
MatCard,
MatCardHeader,
@@ -82,6 +80,14 @@ import { RecipeDetailDatasource } from './recipe-detail-datasource';
],
})
export class RecipeDetailComponent implements OnInit, AfterViewInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar);
private math = inject(MathService);
private ser = inject(RecipeService);
private productSer = inject(ProductService);
@ViewChild('productElement', { static: true }) productElement!: ElementRef<HTMLInputElement>;
@ViewChild('ingredientElement', { static: true }) ingredientElement!: ElementRef<HTMLInputElement>;
public itemsObservable = new BehaviorSubject<RecipeItem[]>([]);
@@ -110,15 +116,7 @@ export class RecipeDetailComponent implements OnInit, AfterViewInit {
displayedColumns = ['product', 'quantity', 'action'];
constructor(
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private snackBar: MatSnackBar,
private math: MathService,
private ser: RecipeService,
private productSer: ProductService,
) {
constructor() {
this.product = null;
this.ingredient = null;
this.form = new FormGroup({
@@ -1,7 +1,7 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, inject, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatIconAnchor, MatAnchor } from '@angular/material/button';
import { MatCard, MatCardHeader, MatCardTitleGroup, MatCardTitle, MatCardContent } from '@angular/material/card';
import { MatAnchor, MatIconAnchor } from '@angular/material/button';
import { MatCard, MatCardContent, MatCardHeader, MatCardTitle, MatCardTitleGroup } from '@angular/material/card';
import { MatOption } from '@angular/material/core';
import { MatFormField, MatLabel } from '@angular/material/form-field';
import { MatIcon } from '@angular/material/icon';
@@ -9,16 +9,16 @@ import { MatPaginator } from '@angular/material/paginator';
import { MatSelect } from '@angular/material/select';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
MatTable,
MatColumnDef,
MatHeaderCellDef,
MatHeaderCell,
MatCellDef,
MatCell,
MatHeaderRowDef,
MatCellDef,
MatColumnDef,
MatHeaderCell,
MatHeaderCellDef,
MatHeaderRow,
MatRowDef,
MatHeaderRowDef,
MatRow,
MatRowDef,
MatTable,
} from '@angular/material/table';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
@@ -26,14 +26,12 @@ import { Period } from 'src/app/period/period';
import { ProductGroup } from '../../core/product-group';
import { Recipe } from '../recipe';
import { RecipeListDatasource } from './recipe-list-datasource';
@Component({
selector: 'app-role-list',
templateUrl: './recipe-list.component.html',
styleUrls: ['./recipe-list.component.css'],
standalone: true,
imports: [
MatCard,
MatCardHeader,
@@ -65,6 +63,9 @@ import { RecipeListDatasource } from './recipe-list-datasource';
],
})
export class RecipeListComponent implements OnInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
@ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
@ViewChild(MatSort, { static: true }) sort!: MatSort;
form: FormGroup<{
@@ -90,10 +91,7 @@ export class RecipeListComponent implements OnInit {
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['name', 'yield', 'date', 'source'];
constructor(
private route: ActivatedRoute,
private router: Router,
) {
constructor() {
this.form = new FormGroup({
period: new FormControl(new Period(), { nonNullable: true }),
productGroup: new FormControl<ProductGroup | string | null>(null),
+1 -2
View File
@@ -3,10 +3,9 @@ import { Routes } from '@angular/router';
import { authGuard } from '../auth/auth-guard.service';
import { periodListResolver } from '../period/period-list.resolver';
import { productGroupListResolver } from '../product-group/product-group-list.resolver';
import { RecipeDetailComponent } from './recipe-detail/recipe-detail.component';
import { RecipeListComponent } from './recipe-list/recipe-list.component';
import { recipeListResolver } from './recipe-list.resolver';
import { RecipeListComponent } from './recipe-list/recipe-list.component';
import { recipeResolver } from './recipe.resolver';
export const routes: Routes = [
+3 -6
View File
@@ -1,10 +1,9 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { Observable, of as observableOf } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ErrorLoggerService } from '../core/error-logger.service';
import { Recipe } from './recipe';
const url = '/api/recipes';
@@ -12,10 +11,8 @@ const serviceName = 'RecipeService';
@Injectable({ providedIn: 'root' })
export class RecipeService {
constructor(
private http: HttpClient,
private log: ErrorLoggerService,
) {}
private http = inject(HttpClient);
private log = inject(ErrorLoggerService);
get(id: string | null): Observable<Recipe> {
const getUrl: string = id === null ? `${url}` : `${url}/${id}`;
-1
View File
@@ -1,5 +1,4 @@
import { ProductSku } from '../core/product-sku';
import { RecipeItem } from './recipe-item';
export class Recipe {