diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d0614db..b31e340 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,6 @@ "name": "frontend", "version": "0.0.0", "dependencies": { - "@angular/animations": "^21.2.10", "@angular/cdk": "^21.2.8", "@angular/common": "^21.2.0", "@angular/compiler": "^21.2.0", @@ -327,21 +326,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/animations": { - "version": "21.2.10", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.2.10.tgz", - "integrity": "sha512-sIzAcxwtRCJ/fu0tK4mo1ooiEaDxJ+Nl6s9nK1D1NP1em12VX03Jx8CMixp/kVtgh4mZnm1x6psBB0FUz3U3Ug==", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" - }, - "peerDependencies": { - "@angular/core": "21.2.10" - } - }, "node_modules/@angular/build": { "version": "21.2.8", "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.2.8.tgz", diff --git a/frontend/package.json b/frontend/package.json index 02eaba4..1e2cedb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,6 @@ "private": true, "packageManager": "npm@11.11.0", "dependencies": { - "@angular/animations": "^21.2.10", "@angular/cdk": "^21.2.8", "@angular/common": "^21.2.0", "@angular/compiler": "^21.2.0", diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index e66aad8..b1fd09d 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -1,6 +1,6 @@ import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; import { provideRouter } from '@angular/router'; -import { provideHttpClient, withFetch } from '@angular/common/http'; +import { provideHttpClient } from '@angular/common/http'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; import { routes } from './app.routes'; @@ -9,7 +9,7 @@ export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), provideRouter(routes), - provideHttpClient(withFetch()), + provideHttpClient(), provideAnimationsAsync(), ] }; \ No newline at end of file diff --git a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.html b/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.html deleted file mode 100644 index 71fe1c6..0000000 --- a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.html +++ /dev/null @@ -1,78 +0,0 @@ - -

- - Delete Filament Spool? -

- - -

- You are about to permanently remove this filament spool from inventory. -

- - -
-
- Material - {{ filament.materialBaseName }}{{ filament.materialFinishName ? ' — ' + filament.materialFinishName : '' }}{{ filament.materialModifierName ? ' (' + filament.materialModifierName + ')' : '' }} -
- -
- Brand - {{ filament.brand }} -
- -
- Color - - - - {{ filament.colorName }} - -
- -
- Serial - {{ filament.spoolSerial }} -
- -
- Remaining - {{ formatWeight(filament.weightRemainingGrams) }} / {{ formatWeight(filament.weightTotalGrams) }} -
- -
- Status - - - {{ filament.isActive ? 'Active' : 'Inactive' }} - - -
-
- -

- - This action cannot be undone. -

-
- - - - - \ No newline at end of file diff --git a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.scss b/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.scss deleted file mode 100644 index 6789bf4..0000000 --- a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.scss +++ /dev/null @@ -1,150 +0,0 @@ -/** - * Delete Filament Dialog Styles - * Touch-optimized confirmation dialog for spool removal - */ - -$spacing-unit: 8px; -$color-critical: #ef4444; -$color-inactive: #94a3b8; -$color-active: #22c55e; - -// Dialog title -h2[mat-dialog-title] { - display: flex; - align-items: center; - gap: $spacing-unit; - color: $color-critical; - - mat-icon { - font-size: 24px !important; - width: 24px !important; - height: 24px !important; - } -} - -// Description text -.dialog-description { - margin: 0 0 $spacing-unit * 2; - font-size: 14px; - line-height: 1.5; - color: var(--mat-sys-on-surface); -} - -// Spool details card -.spool-details { - display: flex; - flex-direction: column; - gap: $spacing-unit; - padding: $spacing-unit * 1.5; - background-color: var(--mat-sys-surface-container); - border-radius: 8px; - margin-bottom: $spacing-unit * 2; -} - -.detail-row { - display: flex; - justify-content: space-between; - align-items: center; - padding: $spacing-unit * 0.5 0; - font-size: 14px; - - &:not(:last-child) { - border-bottom: 1px solid var(--mat-sys-outline-variant); - padding-bottom: $spacing-unit; - } -} - -.detail-label { - font-weight: 500; - color: var(--mat-sys-on-surface-variant); - flex-shrink: 0; -} - -.detail-value { - font-weight: 400; - color: var(--mat-sys-on-surface); - text-align: right; -} - -// Color swatch inline -.color-swatch-inline { - display: inline-block; - width: 18px; - height: 18px; - border-radius: 50%; - border: 1.5px solid rgba(0, 0, 0, 0.12); - vertical-align: middle; - margin-right: 4px; -} - -.color-value { - display: flex; - align-items: center; - justify-content: flex-end; - gap: 4px; -} - -// Serial value — monospace -.serial-value { - font-family: 'JetBrains Mono', 'Roboto Mono', monospace; - font-size: 13px; - letter-spacing: 0.02em; -} - -// Status badge — matches filament table styling -.status-badge { - display: inline-flex; - align-items: center; - padding: 2px 8px; - border-radius: 10px; - font-size: 11px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.04em; - - &.active { - background-color: rgba($color-active, 0.12); - color: $color-active; - } - - &.inactive { - background-color: rgba($color-inactive, 0.12); - color: $color-inactive; - } -} - -// Warning text -.dialog-warning { - display: flex; - align-items: center; - gap: $spacing-unit; - margin: 0; - font-size: 13px; - color: $color-critical; - - mat-icon { - font-size: 18px !important; - width: 18px !important; - height: 18px !important; - } -} - -// Dialog action buttons -mat-dialog-actions { - padding-top: $spacing-unit * 2; - - .cancel-button { - min-width: 80px; - } - - .confirm-button { - min-width: 120px; - - mat-icon { - font-size: 18px !important; - width: 18px !important; - height: 18px !important; - margin-right: 4px; - } - } -} \ No newline at end of file diff --git a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.ts b/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.ts deleted file mode 100644 index d16a87a..0000000 --- a/frontend/src/app/components/delete-filament-dialog/delete-filament-dialog.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { - MAT_DIALOG_DATA, - MatDialogRef, - MatDialogModule, -} from '@angular/material/dialog'; -import { MatButtonModule } from '@angular/material/button'; -import { MatIconModule } from '@angular/material/icon'; -import { MatChipsModule } from '@angular/material/chips'; - -import { Filament } from '../../models/filament.model'; - -/** - * Data passed into the delete confirmation dialog. - */ -export interface DeleteFilamentDialogData { - filament: Filament; -} - -/** - * Delete confirmation dialog for filament spool removal. - * - * Displays spool details (material, brand, color, serial, remaining weight) - * and requires the user to confirm before deletion proceeds. - * Cancel dismisses the dialog with no action. - */ -@Component({ - selector: 'app-delete-filament-dialog', - standalone: true, - imports: [ - CommonModule, - MatDialogModule, - MatButtonModule, - MatIconModule, - MatChipsModule, - ], - templateUrl: './delete-filament-dialog.component.html', - styleUrl: './delete-filament-dialog.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DeleteFilamentDialogComponent { - private readonly dialogRef = inject( - MatDialogRef - ); - readonly data: DeleteFilamentDialogData = inject(MAT_DIALOG_DATA); - - /** The filament spool being considered for deletion */ - readonly filament = this.data.filament; - - /** Format weight for display in dialog */ - formatWeight(grams: number): string { - if (grams >= 1000) { - return `${(grams / 1000).toFixed(1)}kg`; - } - return `${Math.round(grams)}g`; - } - - /** Cancel — close dialog with false (no deletion) */ - onCancel(): void { - this.dialogRef.close(false); - } - - /** Confirm — close dialog with true (proceed with deletion) */ - onConfirm(): void { - this.dialogRef.close(true); - } -} \ No newline at end of file diff --git a/frontend/src/app/components/filament-table/filament-table.component.html b/frontend/src/app/components/filament-table/filament-table.component.html index e0aa433..b7929f2 100644 --- a/frontend/src/app/components/filament-table/filament-table.component.html +++ b/frontend/src/app/components/filament-table/filament-table.component.html @@ -1,6 +1,16 @@ - +
+ +
+

Filament Inventory

+ +
+ @if (criticalCount() > 0) {