chore: update Angular dependencies to version 20.2.0 and refactor HTTP interceptors to use new functional API

- Updated Angular dependencies in package.json to version 20.2.0, including Angular Material and CDK.
- Refactored AuthInterceptor and LoadingInterceptor to use the new HttpInterceptorFn functional API.
- Modified the index file for interceptors to export the new functional interceptors.
- Enhanced the styling of the project detail popup with a dark theme and encapsulation settings.
- Updated main.ts to use the new interceptor setup with provideHttpClient.
- Added theming support for Angular Material in styles.scss, including light and dark themes.
This commit is contained in:
Bangara Raju Kottedi 2026-03-14 22:54:01 +05:30
parent b4c5fddf0d
commit 797163d1ba
9 changed files with 2722 additions and 3220 deletions

5763
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,22 +10,24 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^20.0.0",
"@angular/common": "^20.0.0",
"@angular/compiler": "^20.0.0",
"@angular/core": "^20.0.0",
"@angular/forms": "^20.0.0",
"@angular/platform-browser": "^20.0.0",
"@angular/platform-browser-dynamic": "^20.0.0",
"@angular/router": "^20.0.0",
"@angular/animations": "^20.2.0",
"@angular/cdk": "^20.2.0",
"@angular/common": "^20.2.0",
"@angular/compiler": "^20.2.0",
"@angular/core": "^20.2.0",
"@angular/forms": "^20.2.0",
"@angular/material": "^20.2.0",
"@angular/platform-browser": "^20.2.0",
"@angular/platform-browser-dynamic": "^20.2.0",
"@angular/router": "^20.2.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^20.0.0",
"@angular/cli": "~20.0.0",
"@angular/compiler-cli": "^20.0.0",
"@angular-devkit/build-angular": "^20.2.0",
"@angular/cli": "~20.2.0",
"@angular/compiler-cli": "^20.2.0",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.6.0",
"karma": "~6.4.0",

View File

@ -1,18 +1,14 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Observable } from "rxjs";
import { HttpInterceptorFn } from "@angular/common/http";
import { inject } from "@angular/core";
import { AuthService } from "../services/auth.service";
import { Injectable } from "@angular/core";
@Injectable()
export class AuthInterceptor implements HttpInterceptor{
constructor(public authSvc: AuthService){}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const apiKey = this.authSvc.getApiKey();
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const authSvc = inject(AuthService);
const apiKey = authSvc.getApiKey();
const authReq = req.clone({
headers: req.headers.set('XApiKey', apiKey)
});
return next.handle(authReq);
}
}
return next(authReq);
};

View File

@ -1,9 +1,4 @@
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { authInterceptor } from "./auth.interceptor";
import { loadingInterceptor } from "./loading.interceptor";
import { AuthInterceptor } from "./auth.interceptor";
import { LoadingInterceptor } from "./loading.interceptor";
export const httpInterceptorProviders = [
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true}
]
export const httpInterceptors = [authInterceptor, loadingInterceptor];

View File

@ -1,27 +1,22 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, finalize } from "rxjs";
import { HttpInterceptorFn } from "@angular/common/http";
import { inject } from "@angular/core";
import { finalize } from "rxjs";
import { LoaderService } from "../services/loader.service";
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
let totalRequests: number = 0;
private totalRequests: number = 0;
export const loadingInterceptor: HttpInterceptorFn = (req, next) => {
const loadingSvc = inject(LoaderService);
constructor(private loadingSvc: LoaderService) { }
totalRequests++;
loadingSvc.setLoading(true);
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.totalRequests++;
this.loadingSvc.setLoading(true);
return next.handle(req).pipe(
finalize(
() => {
this.totalRequests--;
if (this.totalRequests == 0) {
this.loadingSvc.setLoading(false);
return next(req).pipe(
finalize(() => {
totalRequests--;
if (totalRequests === 0) {
loadingSvc.setLoading(false);
}
}
)
})
);
}
}
};

View File

@ -8,6 +8,37 @@
border-radius: 14px;
}
/* Override Material Dialog container defaults - must be global due to ViewEncapsulation.None */
.dark-popup-panel {
border-radius: 14px !important;
overflow: hidden !important;
.mat-dialog-container {
background: var(--eerie-black-2, #1e1e1e) !important;
border-radius: 14px !important;
overflow: hidden !important;
border: 2px solid rgba(227, 179, 65, 0.9) !important;
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.08),
0 8px 32px rgba(0, 0, 0, 0.5) !important;
padding: 0 !important;
/* Ensure no white background shows */
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 14px;
pointer-events: none;
background: var(--eerie-black-2, #1e1e1e);
z-index: -1;
}
}
}
.detail-header {
display: flex;
align-items: flex-start;

View File

@ -1,4 +1,4 @@
import { Component, inject } from '@angular/core';
import { Component, inject, ViewEncapsulation } from '@angular/core';
import { CommonModule, DatePipe } from '@angular/common';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { IProject } from '../../models/project.model';
@ -8,7 +8,8 @@ import { IProject } from '../../models/project.model';
templateUrl: './project-detail-popup.html',
styleUrls: ['./project-detail-popup.scss'],
standalone: true,
imports: [CommonModule, DatePipe]
imports: [CommonModule, DatePipe],
encapsulation: ViewEncapsulation.None
})
export class ProjectDetailPopupComponent {
private dialogRef = inject(MatDialogRef<ProjectDetailPopupComponent>);

View File

@ -2,15 +2,14 @@ import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { provideRouter } from '@angular/router';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideHttpClient, withFetch, withInterceptors } from '@angular/common/http';
import { appRoutes } from './app/app-routing.module';
import { httpInterceptorProviders } from './app/http-interceptors';
import { httpInterceptors } from './app/http-interceptors';
bootstrapApplication(AppComponent, {
providers: [
provideRouter(appRoutes),
provideAnimations(),
provideHttpClient(),
httpInterceptorProviders
provideHttpClient(withInterceptors(httpInterceptors), withFetch())
]
}).catch(err => console.error(err));

View File

@ -1,3 +1,38 @@
// Include theming for Angular Material with `mat.theme()`.
// This Sass mixin will define CSS variables that are used for styling Angular Material
// components according to the Material 3 design spec.
// Learn more about theming and how to use it for your application's
// custom components at https://material.angular.dev/guide/theming
@use '@angular/material' as mat;
html {
@include mat.theme((
color: (
primary: mat.$azure-palette,
tertiary: mat.$blue-palette,
),
typography: Roboto,
density: 0,
));
}
body {
// Default the application to a light color theme. This can be changed to
// `dark` to enable the dark color theme, or to `light dark` to defer to the
// user's system settings.
color-scheme: light;
// Set a default background, font and text colors for the application using
// Angular Material's system-level CSS variables. Learn more about these
// variables at https://material.angular.dev/guide/system-variables
background-color: var(--mat-sys-surface);
color: var(--mat-sys-on-surface);
font: var(--mat-sys-body-medium);
// Reset the user agent margin.
margin: 0;
}
/*-----------------------------------*\
#style.css
\*-----------------------------------*/
@ -1890,3 +1925,6 @@
}
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }