ui and feedback updates
This commit is contained in:
parent
005c192ef2
commit
ac3e7165e5
252
public/themes/default.css
Normal file
252
public/themes/default.css
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/* Note: Color palettes are generated from primary: #607c7c, secondary: #9cb4b8 */
|
||||||
|
html {
|
||||||
|
/* COLOR SYSTEM VARIABLES */
|
||||||
|
color-scheme: light;
|
||||||
|
|
||||||
|
/* Primary palette variables */
|
||||||
|
--mat-sys-primary: light-dark(#607c7c, #afcccc);
|
||||||
|
--mat-sys-on-primary: light-dark(#ffffff, #193535);
|
||||||
|
--mat-sys-primary-container: light-dark(#ffffff, #304b4c);
|
||||||
|
--mat-sys-on-primary-container: light-dark(#607c7c, #cae8e8);
|
||||||
|
--mat-sys-inverse-primary: light-dark(#afcccc, #486363);
|
||||||
|
--mat-sys-primary-fixed: light-dark(#cae8e8, #cae8e8);
|
||||||
|
--mat-sys-primary-fixed-dim: light-dark(#afcccc, #afcccc);
|
||||||
|
--mat-sys-on-primary-fixed: light-dark(#022020, #022020);
|
||||||
|
--mat-sys-on-primary-fixed-variant: light-dark(#304b4c, #304b4c);
|
||||||
|
|
||||||
|
/* Secondary palette variables */
|
||||||
|
--mat-sys-secondary: light-dark(#607c7c, #b3cbcf);
|
||||||
|
--mat-sys-on-secondary: light-dark(#ffffff, #1d3437);
|
||||||
|
--mat-sys-secondary-container: light-dark(#607c7c, #344a4e);
|
||||||
|
--mat-sys-on-secondary-container: light-dark(#ffffff, #cee7eb);
|
||||||
|
--mat-sys-secondary-fixed: light-dark(#cee7eb, #cee7eb);
|
||||||
|
--mat-sys-secondary-fixed-dim: light-dark(#b3cbcf, #b3cbcf);
|
||||||
|
--mat-sys-on-secondary-fixed: light-dark(#071f22, #071f22);
|
||||||
|
--mat-sys-on-secondary-fixed-variant: light-dark(#344a4e, #344a4e);
|
||||||
|
|
||||||
|
/* Tertiary palette variables */
|
||||||
|
--mat-sys-tertiary: light-dark(#635b72, #cdc2dd);
|
||||||
|
--mat-sys-on-tertiary: light-dark(#ffffff, #342d42);
|
||||||
|
--mat-sys-tertiary-container: light-dark(#e9def9, #4b4359);
|
||||||
|
--mat-sys-on-tertiary-container: light-dark(#1f182c, #e9def9);
|
||||||
|
--mat-sys-tertiary-fixed: light-dark(#e9def9, #e9def9);
|
||||||
|
--mat-sys-tertiary-fixed-dim: light-dark(#cdc2dd, #cdc2dd);
|
||||||
|
--mat-sys-on-tertiary-fixed: light-dark(#1f182c, #1f182c);
|
||||||
|
--mat-sys-on-tertiary-fixed-variant: light-dark(#4b4359, #4b4359);
|
||||||
|
|
||||||
|
/* Neutral palette variables */
|
||||||
|
--mat-sys-background: light-dark(#faf9f8, #121414);
|
||||||
|
--mat-sys-on-background: light-dark(#1a1c1c, #e3e2e2);
|
||||||
|
--mat-sys-surface: light-dark(#faf9f8, #121414);
|
||||||
|
--mat-sys-surface-dim: light-dark(#dadad9, #121414);
|
||||||
|
--mat-sys-surface-bright: light-dark(#faf9f8, #383939);
|
||||||
|
--mat-sys-surface-container-low: light-dark(#f4f3f3, #1a1c1c);
|
||||||
|
--mat-sys-surface-container-lowest: light-dark(#ffffff, #0d0e0e);
|
||||||
|
--mat-sys-surface-container: light-dark(#eeeeed, #1e2020);
|
||||||
|
--mat-sys-surface-container-high: light-dark(#e9e8e7, #292a2a);
|
||||||
|
--mat-sys-surface-container-highest: light-dark(#e3e2e2, #343535);
|
||||||
|
--mat-sys-on-surface: light-dark(#1a1c1c, #e3e2e2);
|
||||||
|
--mat-sys-shadow: light-dark(#000000, #000000);
|
||||||
|
--mat-sys-scrim: light-dark(#000000, #000000);
|
||||||
|
--mat-sys-surface-tint: light-dark(#486363, #afcccc);
|
||||||
|
--mat-sys-inverse-surface: light-dark(#2f3130, #e3e2e2);
|
||||||
|
--mat-sys-inverse-on-surface: light-dark(#f1f0f0, #2f3130);
|
||||||
|
--mat-sys-outline: light-dark(#727878, #8b9292);
|
||||||
|
--mat-sys-outline-variant: light-dark(#c1c8c7, #414848);
|
||||||
|
--mat-sys-neutral10: light-dark(#1a1c1c, #1a1c1c);
|
||||||
|
/* Variable used for the form field native select option text color */
|
||||||
|
|
||||||
|
/* Error palette variables */
|
||||||
|
--mat-sys-error: light-dark(#ba1a1a, #ffb4ab);
|
||||||
|
--mat-sys-on-error: light-dark(#ffffff, #690005);
|
||||||
|
--mat-sys-error-container: light-dark(#ffdad6, #93000a);
|
||||||
|
--mat-sys-on-error-container: light-dark(#410002, #ffdad6);
|
||||||
|
|
||||||
|
/* Neutral variant palette variables */
|
||||||
|
--mat-sys-surface-variant: light-dark(#dde4e3, #414848);
|
||||||
|
--mat-sys-on-surface-variant: light-dark(#414848, #c1c8c7);
|
||||||
|
--mat-sys-neutral-variant20: light-dark(#2b3232, #2b3232);
|
||||||
|
/* Variable used for the sidenav scrim (container background shadow when opened) */
|
||||||
|
|
||||||
|
/* TYPOGRAPHY SYSTEM VARIABLES */
|
||||||
|
|
||||||
|
/* Typography variables. Only used in the different typescale system variables. */
|
||||||
|
--mat-sys-brand-font-family: Roboto;
|
||||||
|
/* The font-family to use for brand text. */
|
||||||
|
--mat-sys-plain-font-family: Roboto;
|
||||||
|
/* The font-family to use for plain text. */
|
||||||
|
--mat-sys-bold-font-weight: 700;
|
||||||
|
/* The font-weight to use for bold text. */
|
||||||
|
--mat-sys-medium-font-weight: 500;
|
||||||
|
/* The font-weight to use for medium text. */
|
||||||
|
--mat-sys-regular-font-weight: 400;
|
||||||
|
/* The font-weight to use for regular text. */
|
||||||
|
|
||||||
|
/* Typescale variables. */
|
||||||
|
/* Warning: Risk of reduced fidelity from using the composite typography tokens (ex. --mat-sys-body-large) since
|
||||||
|
tracking cannot be represented in the "font" property shorthand. Consider using the discrete properties instead. */
|
||||||
|
--mat-sys-body-large: var(--mat-sys-body-large-weight) var(--mat-sys-body-large-size) / var(--mat-sys-body-large-line-height) var(--mat-sys-body-large-font);
|
||||||
|
--mat-sys-body-large-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-body-large-line-height: 1.5rem;
|
||||||
|
--mat-sys-body-large-size: 1rem;
|
||||||
|
--mat-sys-body-large-tracking: 0.031rem;
|
||||||
|
--mat-sys-body-large-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Body medium typescale */
|
||||||
|
--mat-sys-body-medium: var(--mat-sys-body-medium-weight) var(--mat-sys-body-medium-size) / var(--mat-sys-body-medium-line-height) var(--mat-sys-body-medium-font);
|
||||||
|
--mat-sys-body-medium-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-body-medium-line-height: 1.25rem;
|
||||||
|
--mat-sys-body-medium-size: 0.875rem;
|
||||||
|
--mat-sys-body-medium-tracking: 0.016rem;
|
||||||
|
--mat-sys-body-medium-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Body small typescale */
|
||||||
|
--mat-sys-body-small: var(--mat-sys-body-small-weight) var(--mat-sys-body-small-size) / var(--mat-sys-body-small-line-height) var(--mat-sys-body-small-font);
|
||||||
|
--mat-sys-body-small-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-body-small-line-height: 1rem;
|
||||||
|
--mat-sys-body-small-size: 0.75rem;
|
||||||
|
--mat-sys-body-small-tracking: 0.025rem;
|
||||||
|
--mat-sys-body-small-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Display large typescale */
|
||||||
|
--mat-sys-display-large: var(--mat-sys-display-large-weight) var(--mat-sys-display-large-size) / var(--mat-sys-display-large-line-height) var(--mat-sys-display-large-font);
|
||||||
|
--mat-sys-display-large-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-display-large-line-height: 4rem;
|
||||||
|
--mat-sys-display-large-size: 3.562rem;
|
||||||
|
--mat-sys-display-large-tracking: -0.016rem;
|
||||||
|
--mat-sys-display-large-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Display medium typescale */
|
||||||
|
--mat-sys-display-medium: var(--mat-sys-display-medium-weight) var(--mat-sys-display-medium-size) / var(--mat-sys-display-medium-line-height) var(--mat-sys-display-medium-font);
|
||||||
|
--mat-sys-display-medium-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-display-medium-line-height: 3.25rem;
|
||||||
|
--mat-sys-display-medium-size: 2.812rem;
|
||||||
|
--mat-sys-display-medium-tracking: 0;
|
||||||
|
--mat-sys-display-medium-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Display small typescale */
|
||||||
|
--mat-sys-display-small: var(--mat-sys-display-small-weight) var(--mat-sys-display-small-size) / var(--mat-sys-display-small-line-height) var(--mat-sys-display-small-font);
|
||||||
|
--mat-sys-display-small-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-display-small-line-height: 2.75rem;
|
||||||
|
--mat-sys-display-small-size: 2.25rem;
|
||||||
|
--mat-sys-display-small-tracking: 0;
|
||||||
|
--mat-sys-display-small-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Headline large typescale */
|
||||||
|
--mat-sys-headline-large: var(--mat-sys-headline-large-weight) var(--mat-sys-headline-large-size) / var(--mat-sys-headline-large-line-height) var(--mat-sys-headline-large-font);
|
||||||
|
--mat-sys-headline-large-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-headline-large-line-height: 2.5rem;
|
||||||
|
--mat-sys-headline-large-size: 2rem;
|
||||||
|
--mat-sys-headline-large-tracking: 0;
|
||||||
|
--mat-sys-headline-large-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Headline medium typescale */
|
||||||
|
--mat-sys-headline-medium: var(--mat-sys-headline-medium-weight) var(--mat-sys-headline-medium-size) / var(--mat-sys-headline-medium-line-height) var(--mat-sys-headline-medium-font);
|
||||||
|
--mat-sys-headline-medium-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-headline-medium-line-height: 2.25rem;
|
||||||
|
--mat-sys-headline-medium-size: 1.75rem;
|
||||||
|
--mat-sys-headline-medium-tracking: 0;
|
||||||
|
--mat-sys-headline-medium-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Headline small typescale */
|
||||||
|
--mat-sys-headline-small: var(--mat-sys-headline-small-weight) var(--mat-sys-headline-small-size) / var(--mat-sys-headline-small-line-height) var(--mat-sys-headline-small-font);
|
||||||
|
--mat-sys-headline-small-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-headline-small-line-height: 2rem;
|
||||||
|
--mat-sys-headline-small-size: 1.5rem;
|
||||||
|
--mat-sys-headline-small-tracking: 0;
|
||||||
|
--mat-sys-headline-small-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Label large typescale */
|
||||||
|
--mat-sys-label-large: var(--mat-sys-label-large-weight) var(--mat-sys-label-large-size) / var(--mat-sys-label-large-line-height) var(--mat-sys-label-large-font);
|
||||||
|
--mat-sys-label-large-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-label-large-line-height: 1.25rem;
|
||||||
|
--mat-sys-label-large-size: 0.875rem;
|
||||||
|
--mat-sys-label-large-tracking: 0.006rem;
|
||||||
|
--mat-sys-label-large-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
--mat-sys-label-large-weight-prominent: var(--mat-sys-bold-font-weight);
|
||||||
|
|
||||||
|
/* Label medium typescale */
|
||||||
|
--mat-sys-label-medium: var(--mat-sys-label-medium-weight) var(--mat-sys-label-medium-size) / var(--mat-sys-label-medium-line-height) var(--mat-sys-label-medium-font);
|
||||||
|
--mat-sys-label-medium-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-label-medium-line-height: 1rem;
|
||||||
|
--mat-sys-label-medium-size: 0.75rem;
|
||||||
|
--mat-sys-label-medium-tracking: 0.031rem;
|
||||||
|
--mat-sys-label-medium-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
--mat-sys-label-medium-weight-prominent: var(--mat-sys-bold-font-weight);
|
||||||
|
|
||||||
|
/* Label small typescale */
|
||||||
|
--mat-sys-label-small: var(--mat-sys-label-small-weight) var(--mat-sys-label-small-size) / var(--mat-sys-label-small-line-height) var(--mat-sys-label-small-font);
|
||||||
|
--mat-sys-label-small-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-label-small-line-height: 1rem;
|
||||||
|
--mat-sys-label-small-size: 0.688rem;
|
||||||
|
--mat-sys-label-small-tracking: 0.031rem;
|
||||||
|
--mat-sys-label-small-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
|
||||||
|
/* Title large typescale */
|
||||||
|
--mat-sys-title-large: var(--mat-sys-title-large-weight) var(--mat-sys-title-large-size) / var(--mat-sys-title-large-line-height) var(--mat-sys-title-large-font);
|
||||||
|
--mat-sys-title-large-font: var(--mat-sys-brand-font-family);
|
||||||
|
--mat-sys-title-large-line-height: 1.75rem;
|
||||||
|
--mat-sys-title-large-size: 1.375rem;
|
||||||
|
--mat-sys-title-large-tracking: 0;
|
||||||
|
--mat-sys-title-large-weight: var(--mat-sys-regular-font-weight);
|
||||||
|
|
||||||
|
/* Title medium typescale */
|
||||||
|
--mat-sys-title-medium: var(--mat-sys-title-medium-weight) var(--mat-sys-title-medium-size) / var(--mat-sys-title-medium-line-height) var(--mat-sys-title-medium-font);
|
||||||
|
--mat-sys-title-medium-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-title-medium-line-height: 1.5rem;
|
||||||
|
--mat-sys-title-medium-size: 1rem;
|
||||||
|
--mat-sys-title-medium-tracking: 0.009rem;
|
||||||
|
--mat-sys-title-medium-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
|
||||||
|
/* Title small typescale */
|
||||||
|
--mat-sys-title-small: var(--mat-sys-title-small-weight) var(--mat-sys-title-small-size) / var(--mat-sys-title-small-line-height) var(--mat-sys-title-small-font);
|
||||||
|
--mat-sys-title-small-font: var(--mat-sys-plain-font-family);
|
||||||
|
--mat-sys-title-small-line-height: 1.25rem;
|
||||||
|
--mat-sys-title-small-size: 0.875rem;
|
||||||
|
--mat-sys-title-small-tracking: 0.006rem;
|
||||||
|
--mat-sys-title-small-weight: var(--mat-sys-medium-font-weight);
|
||||||
|
|
||||||
|
/* ELEVATION SYSTEM VARIABLES */
|
||||||
|
|
||||||
|
/* Box shadow colors. Only used in the elevation level system variables. */
|
||||||
|
--mat-sys-umbra-color: color-mix(in srgb, var(--mat-sys-shadow), transparent 80%);
|
||||||
|
--mat-sys-penumbra-color: color-mix(in srgb, var(--mat-sys-shadow), transparent 86%);
|
||||||
|
--mat-sys-ambient-color: color-mix(in srgb, var(--mat-sys-shadow), transparent 88%);
|
||||||
|
|
||||||
|
/* Elevation level system variables. These are used as the value for box-shadow CSS property. */
|
||||||
|
--mat-sys-level0: 0px 0px 0px 0px var(--mat-sys-umbra-color), 0px 0px 0px 0px var(--mat-sys-penumbra-color), 0px 0px 0px 0px var(--mat-sys-ambient-color);
|
||||||
|
--mat-sys-level1: 0px 2px 1px -1px var(--mat-sys-umbra-color), 0px 1px 1px 0px var(--mat-sys-penumbra-color), 0px 1px 3px 0px var(--mat-sys-ambient-color);
|
||||||
|
--mat-sys-level2: 0px 3px 3px -2px var(--mat-sys-umbra-color), 0px 3px 4px 0px var(--mat-sys-penumbra-color), 0px 1px 8px 0px var(--mat-sys-ambient-color);
|
||||||
|
--mat-sys-level3: 0px 3px 5px -1px var(--mat-sys-umbra-color), 0px 6px 10px 0px var(--mat-sys-penumbra-color), 0px 1px 18px 0px var(--mat-sys-ambient-color);
|
||||||
|
--mat-sys-level4: 0px 5px 5px -3px var(--mat-sys-umbra-color), 0px 8px 10px 1px var(--mat-sys-penumbra-color), 0px 3px 14px 2px var(--mat-sys-ambient-color);
|
||||||
|
--mat-sys-level5: 0px 7px 8px -4px var(--mat-sys-umbra-color), 0px 12px 17px 2px var(--mat-sys-penumbra-color), 0px 5px 22px 4px var(--mat-sys-ambient-color);
|
||||||
|
|
||||||
|
/* SHAPE SYSTEM VARIABLES */
|
||||||
|
--mat-sys-corner-extra-large: 28px;
|
||||||
|
--mat-sys-corner-extra-large-top: 28px 28px 0 0;
|
||||||
|
--mat-sys-corner-extra-small: 4px;
|
||||||
|
--mat-sys-corner-extra-small-top: 4px 4px 0 0;
|
||||||
|
--mat-sys-corner-full: 9999px;
|
||||||
|
--mat-sys-corner-large: 16px;
|
||||||
|
--mat-sys-corner-large-end: 0 16px 16px 0;
|
||||||
|
--mat-sys-corner-large-start: 16px 0 0 16px;
|
||||||
|
--mat-sys-corner-large-top: 16px 16px 0 0;
|
||||||
|
--mat-sys-corner-medium: 12px;
|
||||||
|
--mat-sys-corner-none: 0;
|
||||||
|
--mat-sys-corner-small: 8px;
|
||||||
|
|
||||||
|
/* STATE SYSTEM VARIABLES */
|
||||||
|
--mat-sys-dragged-state-layer-opacity: 0.16;
|
||||||
|
--mat-sys-focus-state-layer-opacity: 0.12;
|
||||||
|
--mat-sys-hover-state-layer-opacity: 0.08;
|
||||||
|
--mat-sys-pressed-state-layer-opacity: 0.12;
|
||||||
|
|
||||||
|
/* CUSTOM BUTTON COLORS */
|
||||||
|
--custom-button-color: #ffffff;
|
||||||
|
--custom-button-background-color: #627f9a;
|
||||||
|
--custom-hover-color: #384857;
|
||||||
|
|
||||||
|
/* CUSTOM NAV COLORS */
|
||||||
|
--custom-nav-color: #ffffff;
|
||||||
|
--custom-nav-background-color: #607c7c;
|
||||||
|
}
|
||||||
@ -1,14 +1,14 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FooterComponent } from './common/footer/footer.component';
|
||||||
import { SecuredHeaderComponent } from './common/secured-header/secured-header.component';
|
import { SecuredHeaderComponent } from './common/secured-header/secured-header.component';
|
||||||
import { UserService } from './core/services/common/user.service';
|
import { UserService } from './core/services/common/user.service';
|
||||||
import { FooterComponent } from './common/footer/footer.component';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet, SecuredHeaderComponent, FooterComponent, CommonModule],
|
imports: [RouterOutlet, FooterComponent, CommonModule, SecuredHeaderComponent],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.scss'
|
styleUrl: './app.component.scss'
|
||||||
})
|
})
|
||||||
@ -17,9 +17,8 @@ export class AppComponent {
|
|||||||
isUserLoggedIn = false;
|
isUserLoggedIn = false;
|
||||||
private userSubscription!: Subscription;
|
private userSubscription!: Subscription;
|
||||||
|
|
||||||
constructor(private userService: UserService
|
private userService = inject(UserService);
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
this.isUserLoggedIn = this.userService.isLoggedIn();
|
this.isUserLoggedIn = this.userService.isLoggedIn();
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
withDefaultRegisterables,
|
withDefaultRegisterables,
|
||||||
} from 'ng2-charts';
|
} from 'ng2-charts';
|
||||||
import { AuthInterceptor } from './core/interceptors/auth.interceptor';
|
import { AuthInterceptor } from './core/interceptors/auth.interceptor';
|
||||||
|
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
||||||
|
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
@ -20,5 +21,7 @@ export const appConfig: ApplicationConfig = {
|
|||||||
provideHttpClient(),
|
provideHttpClient(),
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
provideCharts(withDefaultRegisterables()),
|
provideCharts(withDefaultRegisterables()),
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },]
|
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
|
||||||
|
{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { subscriptSizing: 'dynamic' } }
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<footer class="footer">
|
<footer class="footer" [ngClass]="{'general': !isUserLoggedIn}">
|
||||||
<div class="footer-content">
|
<div class="footer-content">
|
||||||
<div class="footer-links">
|
<div class="footer-links">
|
||||||
<a href="#">Privacy Policy</a>
|
<a href="#">Privacy Policy</a>
|
||||||
@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
© {{ currentYear }} USCIB Carnet Portal. All rights reserved.
|
© {{ currentYear }} {{currentServiceProviderName}}. All rights reserved.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1,11 +1,8 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
background-color: colors.$background-header;
|
color: var(--mat-sys-on-primary);
|
||||||
|
background: var(--mat-sys-primary);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
border-top: 1px solid colors.$divider-color;
|
border-top: 1px solid var(--mat-sys-outline-variant);
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
background-color: rgba(colors.$background-header, 0.9);
|
|
||||||
|
|
||||||
/* Fixed footer styles */
|
/* Fixed footer styles */
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -22,6 +19,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
background: var(--mat-sys-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-links {
|
.footer-links {
|
||||||
@ -29,22 +27,46 @@
|
|||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: colors.$text-secondary;
|
color: var(--mat-sys-on-primary);
|
||||||
|
background: var(--mat-sys-primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: colors.$primary-color;
|
transform: scale(103%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.copyright {
|
.copyright {
|
||||||
color: colors.$text-secondary;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* footer styles - not logged in users - not applicable for this site*/
|
||||||
|
// .footer.general {
|
||||||
|
// color: #000000;
|
||||||
|
// background: #ffffff;
|
||||||
|
|
||||||
|
// .footer-content {
|
||||||
|
// max-width: 1200px;
|
||||||
|
// margin: 0 auto;
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
// align-items: center;
|
||||||
|
// gap: 8px;
|
||||||
|
// background: #ffffff;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .footer-links {
|
||||||
|
// a {
|
||||||
|
// color: #000000;
|
||||||
|
// background: #ffffff;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.footer {
|
.footer {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|||||||
@ -1,12 +1,31 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, effect, inject, Input } from '@angular/core';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { User } from '../../core/models/user';
|
||||||
|
import { UserService } from '../../core/services/common/user.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-footer',
|
selector: 'app-footer',
|
||||||
imports: [AngularMaterialModule],
|
imports: [AngularMaterialModule, CommonModule],
|
||||||
templateUrl: './footer.component.html',
|
templateUrl: './footer.component.html',
|
||||||
styleUrl: './footer.component.scss'
|
styleUrl: './footer.component.scss'
|
||||||
})
|
})
|
||||||
export class FooterComponent {
|
export class FooterComponent {
|
||||||
currentYear = new Date().getFullYear();
|
currentYear = new Date().getFullYear();
|
||||||
|
currentServiceProviderName: string = 'USCIB Carnet Portal';
|
||||||
|
userDetails: User | null = {};
|
||||||
|
|
||||||
|
@Input() isUserLoggedIn = false;
|
||||||
|
|
||||||
|
private userService = inject(UserService);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
effect(() => {
|
||||||
|
this.userDetails = this.userService.userDetailsSignal();
|
||||||
|
if (this.userDetails?.userDetails && this.userDetails.userDetails.serviceProviderName) {
|
||||||
|
this.currentServiceProviderName = this.userDetails.userDetails.serviceProviderName || 'USCIB Carnet Portal';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,10 +5,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a class="nav-link" (click)="navigateTo('/home')">Home</a>
|
<button mat-button (click)="navigateTo('home')">Home</button>
|
||||||
<a class="nav-link" (click)="navigateTo('/manageusers')">Users</a>
|
<button mat-button (click)="navigateTo('/table-record')">Configurations</button>
|
||||||
<a class="nav-link" (click)="navigateTo('/regions')">Regions</a>
|
|
||||||
<a class="nav-link" (click)="navigateTo('/table-record')">Configurations</a>
|
|
||||||
|
|
||||||
<div class="profile-container">
|
<div class="profile-container">
|
||||||
<button mat-icon-button (click)="toggleProfileMenu()" class="profile-button">
|
<button mat-icon-button (click)="toggleProfileMenu()" class="profile-button">
|
||||||
@ -23,7 +21,7 @@
|
|||||||
|
|
||||||
<button mat-menu-item (click)="navigateTo('/usersettings')">
|
<button mat-menu-item (click)="navigateTo('/usersettings')">
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
<span>User Settings</span>
|
<span>User Preferences</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="logout()">
|
<button mat-menu-item (click)="logout()">
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
background-color: colors.$primary-color;
|
color: var(--custom-nav-color);
|
||||||
color: white;
|
background: var(--custom-nav-background-color);
|
||||||
box-shadow: var(--mat-sys-level2);
|
border-bottom: 1px solid var(--mat-sys-outline-variant);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 100; // Higher than footer's z-index
|
z-index: 100; // Higher than footer's z-index
|
||||||
|
|
||||||
@ -33,46 +31,70 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
|
||||||
.nav-link {
|
button {
|
||||||
cursor: pointer;
|
color: var(--custom-nav-color);
|
||||||
padding: 8px 12px;
|
background-color: var(--custom-nav-background-color);
|
||||||
border-radius: 4px;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
color: var(--custom-nav-background-color);
|
||||||
|
background-color: var(--custom-nav-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-mdc-button:hover>.mat-mdc-button-persistent-ripple::before {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .nav-link {
|
||||||
|
// cursor: pointer;
|
||||||
|
// padding: 8px 12px;
|
||||||
|
// border-radius: 4px;
|
||||||
|
// transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// background-color: var(--mat-sys-secondary-container);
|
||||||
|
// box-shadow: var(--mat-sys-level1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-container {
|
.profile-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.profile-button {
|
.profile-button {
|
||||||
color: white;
|
color: var(--custom-nav-background-color);
|
||||||
|
background-color: var(--custom-nav-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--custom-nav-color);
|
||||||
|
background-color: var(--custom-nav-background-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-menu {
|
.profile-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 48px;
|
top: 48px;
|
||||||
background-color: white;
|
color: var(--mat-sys-on-primary-container);
|
||||||
|
background-color: var(--mat-sys-primary-container);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: var(--mat-sys-level3);
|
box-shadow: var(--mat-sys-level3);
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 101;
|
z-index: 101;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
|
||||||
.profile-info {
|
.profile-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
border-bottom: 1px solid colors.$divider-color;
|
color: var(--mat-sys-on-primary-container);
|
||||||
color: colors.$text-primary;
|
background-color: var(--mat-sys-primary-container);
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
color: colors.$text-secondary;
|
color: var(--mat-sys-on-primary-container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,18 +104,30 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
color: colors.$text-primary;
|
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: var(--mat-sys-on-primary-container);
|
||||||
|
background-color: var(--mat-sys-primary-container);
|
||||||
|
|
||||||
mat-icon {
|
// mat-icon {
|
||||||
color: colors.$text-secondary;
|
// color: var(--mat-sys-on-primary-container);
|
||||||
|
// }
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--mat-sys-on-primary);
|
||||||
|
background-color: var(--mat-sys-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-mdc-menu-item:not([disabled]):hover {
|
||||||
|
color: var(--mat-sys-on-primary);
|
||||||
|
background-color: var(--mat-sys-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.navbar {
|
.navbar {
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { AuthService } from '../../core/services/common/auth.service';
|
import { AuthService } from '../../core/services/common/auth.service';
|
||||||
import { NavigationService } from '../../core/services/common/navigation.service';
|
import { NavigationService } from '../../core/services/common/navigation.service';
|
||||||
|
import { ThemeService } from '../../core/services/theme.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-secured-header',
|
selector: 'app-secured-header',
|
||||||
@ -18,9 +19,11 @@ export class SecuredHeaderComponent implements OnInit {
|
|||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private authService = inject(AuthService);
|
private authService = inject(AuthService);
|
||||||
private navigationService = inject(NavigationService);
|
private navigationService = inject(NavigationService);
|
||||||
|
private themeService = inject(ThemeService);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.userEmail = this.userService.getSafeUser();
|
this.userEmail = this.userService.getSafeUser();
|
||||||
|
this.themeService.setTheme('default');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleProfileMenu(): void {
|
toggleProfileMenu(): void {
|
||||||
|
|||||||
@ -7,4 +7,5 @@ export interface BasicFee {
|
|||||||
spid?: number;
|
spid?: number;
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,4 +6,5 @@ export interface CarnetFee {
|
|||||||
spid: number;
|
spid: number;
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,4 +7,5 @@ export interface ContinuationSheetFee {
|
|||||||
carnetType: string;
|
carnetType: string;
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,5 @@ export interface CounterfoilFee {
|
|||||||
rate: number,
|
rate: number,
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,5 @@ export interface ExpeditedFee {
|
|||||||
effectiveDate: Date;
|
effectiveDate: Date;
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,5 @@ export interface SecurityDeposit {
|
|||||||
spid: number;
|
spid: number;
|
||||||
dateCreated?: Date | null;
|
dateCreated?: Date | null;
|
||||||
createdBy?: string | null;
|
createdBy?: string | null;
|
||||||
|
expired?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,4 +17,5 @@ export interface UserDetail {
|
|||||||
urlKey: string;
|
urlKey: string;
|
||||||
logoName: string;
|
logoName: string;
|
||||||
themeName: string;
|
themeName: string;
|
||||||
|
serviceProviderName: string;
|
||||||
}
|
}
|
||||||
@ -12,6 +12,7 @@ import { CargoPolicy } from '../../models/cargo-policy';
|
|||||||
import { CargoSurety } from '../../models/cargo-surety';
|
import { CargoSurety } from '../../models/cargo-surety';
|
||||||
import { CarnetStatus } from '../../models/carnet-status';
|
import { CarnetStatus } from '../../models/carnet-status';
|
||||||
import { Country } from '../../models/country';
|
import { Country } from '../../models/country';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -21,9 +22,10 @@ export class CommonService {
|
|||||||
private apiDb = environment.apiDb;
|
private apiDb = environment.apiDb;
|
||||||
|
|
||||||
private http = inject(HttpClient);
|
private http = inject(HttpClient);
|
||||||
|
private userService = inject(UserService);
|
||||||
|
|
||||||
getCountries(spid: number = 0): Observable<Country[]> {
|
getCountries(): Observable<Country[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=002&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=002&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -34,8 +36,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStates(country: string, spid: number = 0): Observable<State[]> {
|
getStates(country: string): Observable<State[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=001&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=001&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -63,8 +65,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeliveryTypes(spid: number = 0): Observable<DeliveryType[]> {
|
getDeliveryTypes(): Observable<DeliveryType[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=006&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=006&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -75,8 +77,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTimezones(spid: number = 0): Observable<TimeZone[]> {
|
getTimezones(): Observable<TimeZone[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=010&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=010&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -87,8 +89,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFeeTypes(spid: number = 0): Observable<FeeType[]> {
|
getFeeTypes(): Observable<FeeType[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=009&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=009&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -99,8 +101,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBondSuretys(spid: number = 0): Observable<BondSurety[]> {
|
getBondSuretys(): Observable<BondSurety[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=003&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=003&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -111,8 +113,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCargoPolicies(spid: number = 0): Observable<CargoPolicy[]> {
|
getCargoPolicies(): Observable<CargoPolicy[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=004&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=004&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -123,8 +125,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCargoSuretys(spid: number = 0): Observable<CargoSurety[]> {
|
getCargoSuretys(): Observable<CargoSurety[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=005&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=005&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -135,8 +137,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCarnetStatuses(spid: number = 0): Observable<CarnetStatus[]> {
|
getCarnetStatuses(): Observable<CarnetStatus[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=011&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=011&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
|
|||||||
@ -136,7 +136,8 @@ export class UserService {
|
|||||||
locationid: userDetails.LOCATIONID,
|
locationid: userDetails.LOCATIONID,
|
||||||
urlKey: userDetails.ENCURLKEY,
|
urlKey: userDetails.ENCURLKEY,
|
||||||
logoName: userDetails.LOGONAME,
|
logoName: userDetails.LOGONAME,
|
||||||
themeName: userDetails.THEMENAME
|
themeName: userDetails.THEMENAME,
|
||||||
|
serviceProviderName: userDetails.SPNAME
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -89,8 +89,6 @@ export class ParamService {
|
|||||||
P_USERID: this.userService.getUser(),
|
P_USERID: this.userService.getUser(),
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(paramDetails);
|
|
||||||
|
|
||||||
return this.http.patch(`${this.apiUrl}/${this.apiDb}/UpdateParamRecord`, paramDetails);
|
return this.http.patch(`${this.apiUrl}/${this.apiDb}/UpdateParamRecord`, paramDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,8 @@ export class BasicFeeService {
|
|||||||
fees: item.FEES,
|
fees: item.FEES,
|
||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,8 @@ export class CarnetFeeService {
|
|||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
spid: item.SPID,
|
spid: item.SPID,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -80,7 +80,6 @@ export class ContactService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteContact(spContactId: string): Observable<any> {
|
deleteContact(spContactId: string): Observable<any> {
|
||||||
return this.http.post(`${this.apiUrl}/${this.apiDb}/InactivateSPContact/${spContactId}`, null);
|
return this.http.patch(`${this.apiUrl}/${this.apiDb}/InactivateSPContact/${spContactId}`, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,8 @@ export class ContinuationSheetFeeService {
|
|||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
rate: item.RATE,
|
rate: item.RATE,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,8 @@ export class CounterfoilFeeService {
|
|||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
rate: item.RATE,
|
rate: item.RATE,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,8 @@ export class ExpeditedFeeService {
|
|||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
spid: item.SPID,
|
spid: item.SPID,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,8 @@ export class SecurityDepositService {
|
|||||||
effectiveDate: item.EFFDATE,
|
effectiveDate: item.EFFDATE,
|
||||||
spid: item.SPID,
|
spid: item.SPID,
|
||||||
createdBy: item.CREATEDBY || null,
|
createdBy: item.CREATEDBY || null,
|
||||||
dateCreated: item.DATECREATED || null
|
dateCreated: item.DATECREATED || null,
|
||||||
|
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
44
src/app/core/services/stylemanager.service.ts
Normal file
44
src/app/core/services/stylemanager.service.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class StyleManagerService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stylesheet with the specified key.
|
||||||
|
*/
|
||||||
|
setStyle(key: string, href: string) {
|
||||||
|
getLinkElementForKey(key).setAttribute('href', href);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the stylesheet with the specified key.
|
||||||
|
*/
|
||||||
|
removeStyle(key: string) {
|
||||||
|
const existingLinkElement = getExistingLinkElementByKey(key);
|
||||||
|
if (existingLinkElement) {
|
||||||
|
document.head.removeChild(existingLinkElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkElementForKey(key: string) {
|
||||||
|
return getExistingLinkElementByKey(key) || createLinkElementWithKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExistingLinkElementByKey(key: string) {
|
||||||
|
return document.head.querySelector(`link[rel="stylesheet"].${getClassNameForKey(key)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLinkElementWithKey(key: string) {
|
||||||
|
const linkEl = document.createElement('link');
|
||||||
|
linkEl.setAttribute('rel', 'stylesheet');
|
||||||
|
linkEl.classList.add(getClassNameForKey(key));
|
||||||
|
document.head.appendChild(linkEl);
|
||||||
|
return linkEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClassNameForKey(key: string) {
|
||||||
|
return `style-manager-${key}`;
|
||||||
|
}
|
||||||
18
src/app/core/services/theme.service.ts
Normal file
18
src/app/core/services/theme.service.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { inject, Injectable } from '@angular/core';
|
||||||
|
import { StyleManagerService } from './stylemanager.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ThemeService {
|
||||||
|
|
||||||
|
private styleManager = inject(StyleManagerService);
|
||||||
|
|
||||||
|
setTheme(themeToSet: string) {
|
||||||
|
|
||||||
|
this.styleManager.setStyle(
|
||||||
|
"theme",
|
||||||
|
`themes/${themeToSet}.css`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import { ActivatedRoute, Router } from '@angular/router';
|
|||||||
import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service';
|
||||||
import { AuthService } from '../core/services/common/auth.service';
|
import { AuthService } from '../core/services/common/auth.service';
|
||||||
import { NotificationService } from '../core/services/common/notification.service';
|
import { NotificationService } from '../core/services/common/notification.service';
|
||||||
|
import { ThemeService } from '../core/services/theme.service';
|
||||||
import { AngularMaterialModule } from '../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../shared/module/angular-material.module';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ export class ForgotPasswordComponent {
|
|||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private notificationService = inject(NotificationService);
|
private notificationService = inject(NotificationService);
|
||||||
private errorHandler = inject(ApiErrorHandlerService);
|
private errorHandler = inject(ApiErrorHandlerService);
|
||||||
|
private themeService = inject(ThemeService);
|
||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -50,6 +52,10 @@ export class ForgotPasswordComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.themeService.setTheme('default');
|
||||||
|
}
|
||||||
|
|
||||||
onRequest(): void {
|
onRequest(): void {
|
||||||
if (this.forgotPasswordRequestForm.invalid) {
|
if (this.forgotPasswordRequestForm.invalid) {
|
||||||
this.forgotPasswordRequestForm.markAllAsTouched();
|
this.forgotPasswordRequestForm.markAllAsTouched();
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.dashboard-chart-container {
|
.dashboard-chart-container {
|
||||||
padding: 24px 0px;
|
padding: 24px 0px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
@ -36,7 +34,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-icon {
|
.edit-icon {
|
||||||
@ -44,7 +42,7 @@
|
|||||||
transition: color 0.2s ease;
|
transition: color 0.2s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
<!-- Chart Section -->
|
<!-- Chart Section -->
|
||||||
<div class="chart-section">
|
<div class="chart-section">
|
||||||
<app-chart [chartData]="carnetData" [carnetStatuses]="carnetStatuses" (carnetStatusData)="onCarnetStatusClick($event)"></app-chart>
|
<app-chart [chartData]="carnetData" [carnetStatuses]="carnetStatuses"
|
||||||
|
(carnetStatusData)="onCarnetStatusClick($event)"></app-chart>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Carnet Details Section -->
|
<!-- Carnet Details Section -->
|
||||||
@ -57,7 +58,7 @@
|
|||||||
|
|
||||||
<ng-container matColumnDef="carnetValue">
|
<ng-container matColumnDef="carnetValue">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Carnet Value</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Carnet Value</th>
|
||||||
<td mat-cell *matCellDef="let item">{{ item.carnetValue }}</td>
|
<td mat-cell *matCellDef="let item">{{ item.carnetValue | currency}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="issueDate">
|
<ng-container matColumnDef="issueDate">
|
||||||
@ -93,7 +94,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!"
|
||||||
|
[length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.login-container {
|
.login-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 85vh;
|
min-height: 85vh;
|
||||||
@ -26,7 +24,7 @@
|
|||||||
|
|
||||||
.welcome-title {
|
.welcome-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +74,7 @@
|
|||||||
.info-section {
|
.info-section {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 4rem;
|
padding: 4rem;
|
||||||
background-color: colors.$primary-color;
|
background-color: var(--mat-sys-primary);
|
||||||
color: white;
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { AngularMaterialModule } from '../shared/module/angular-material.module'
|
|||||||
import { User } from '../core/models/user';
|
import { User } from '../core/models/user';
|
||||||
import { UserService } from '../core/services/common/user.service';
|
import { UserService } from '../core/services/common/user.service';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { ThemeService } from '../core/services/theme.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
@ -23,6 +24,7 @@ export class LoginComponent {
|
|||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private navigationService = inject(NavigationService);
|
private navigationService = inject(NavigationService);
|
||||||
private fb = inject(FormBuilder);
|
private fb = inject(FormBuilder);
|
||||||
|
private themeService = inject(ThemeService);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loginForm = this.fb.group({
|
this.loginForm = this.fb.group({
|
||||||
@ -32,6 +34,8 @@ export class LoginComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.themeService.setTheme('default');
|
||||||
|
|
||||||
if (this.userService.isLoggedIn()) {
|
if (this.userService.isLoggedIn()) {
|
||||||
this.navigationService.navigate(['/home']);
|
this.navigationService.navigate(['/home']);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,15 +11,12 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
})
|
})
|
||||||
export class ManageParamRecordComponent {
|
export class ManageParamRecordComponent {
|
||||||
table_mode: TABLE_MODE = 'PARAM-RECORD'
|
table_mode: TABLE_MODE = 'PARAM-RECORD'
|
||||||
paramHeading: string = '';
|
paramHeading: string = 'Parameters';
|
||||||
|
|
||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
||||||
const param = this.route.snapshot.queryParamMap.get('param');
|
const param = this.route.snapshot.queryParamMap.get('param');
|
||||||
|
|
||||||
this.paramHeading = param || '';
|
this.paramHeading = param || '';
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<app-param-table [table_mode]="table_mode"></app-param-table>
|
<app-param-table [table_mode]="table_mode" [paramHeading]="paramHeading"></app-param-table>
|
||||||
@ -9,5 +9,6 @@ import { TABLE_MODE } from '../../core/models/param/types';
|
|||||||
styleUrl: './manage-table-record.component.scss'
|
styleUrl: './manage-table-record.component.scss'
|
||||||
})
|
})
|
||||||
export class ManageTableRecordComponent {
|
export class ManageTableRecordComponent {
|
||||||
table_mode: TABLE_MODE = 'TABLE-RECORD'
|
table_mode: TABLE_MODE = 'TABLE-RECORD';
|
||||||
|
paramHeading: string = 'Table Records';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
<h2 class="page-header">Manage - {{paramHeading | properCase}}</h2>
|
<h2 class="page-header">Manage - {{paramHeading | properCase}}</h2>
|
||||||
|
<div class="manage-container">
|
||||||
<div class="results-section">
|
|
||||||
<div class="loading-shade" *ngIf="isLoading">
|
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<mat-form-field appearance="outline" floatLabel="auto" class="full-width">
|
<mat-form-field appearance="outline" floatLabel="auto" class="full-width">
|
||||||
<mat-label>Search</mat-label>
|
<mat-label>Search</mat-label>
|
||||||
@ -13,7 +8,7 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions-bar" [ngClass]="{ 'mb-40': !isParamRecord, 'mb-10': isParamRecord }">
|
<div class="actions-bar">
|
||||||
<mat-slide-toggle (change)="toggleShowInactiveData()" *ngIf="isParamRecord" [disabled]="paramData.length === 0">
|
<mat-slide-toggle (change)="toggleShowInactiveData()" *ngIf="isParamRecord" [disabled]="paramData.length === 0">
|
||||||
<div class="icon-text">Show Inactive Records</div>
|
<div class="icon-text">Show Inactive Records</div>
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
@ -24,105 +19,111 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table mat-table [dataSource]="dataSource" class="results-table" matSort>
|
<div class="results-section">
|
||||||
|
<div class="loading-shade" *ngIf="isLoading">
|
||||||
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- PARAMTYPE Column -->
|
<table mat-table [dataSource]="dataSource" matSort>
|
||||||
<ng-container matColumnDef="ParamType">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
|
|
||||||
<td mat-cell *matCellDef="let client">{{ client.paramType }}</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- PARAMDESC Column -->
|
<!-- PARAMTYPE Column -->
|
||||||
<ng-container matColumnDef="ParamDesc">
|
<ng-container matColumnDef="ParamType">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.paramDesc || '--'}}</td>
|
<td mat-cell *matCellDef="let client">{{ client.paramType }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- PARAMVALUE Column -->
|
<!-- PARAMDESC Column -->
|
||||||
<ng-container matColumnDef="paramvalue">
|
<ng-container matColumnDef="ParamDesc">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.paramValue }}</td>
|
<td mat-cell *matCellDef="let client">{{ client.paramDesc || '--'}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- ADDLPARAMVALUE1 Column -->
|
<!-- PARAMVALUE Column -->
|
||||||
<ng-container matColumnDef="addlparamvalue1">
|
<ng-container matColumnDef="paramvalue">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 1</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.addlParamValue1 || '--' }}</td>
|
<td mat-cell *matCellDef="let client">{{ client.paramValue }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- ADDLPARAMVALUE2 Column -->
|
<!-- ADDLPARAMVALUE1 Column -->
|
||||||
<ng-container matColumnDef="addlparamvalue2">
|
<ng-container matColumnDef="addlparamvalue1">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 2</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 1</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.addlParamValue2 || '--'}}</td>
|
<td mat-cell *matCellDef="let client">{{ client.addlParamValue1 || '--' }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- ADDLPARAMVALUE3 Column -->
|
<!-- ADDLPARAMVALUE2 Column -->
|
||||||
<ng-container matColumnDef="addlparamvalue3">
|
<ng-container matColumnDef="addlparamvalue2">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 3</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 2</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.addlParamValue3 || '--' }}</td>
|
<td mat-cell *matCellDef="let client">{{ client.addlParamValue2 || '--'}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- ADDLPARAMVALUE4 Column -->
|
<!-- ADDLPARAMVALUE3 Column -->
|
||||||
<ng-container matColumnDef="addlparamvalue4">
|
<ng-container matColumnDef="addlparamvalue3">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 4</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 3</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.addlParamValue4 || '--' }}</td>
|
<td mat-cell *matCellDef="let client">{{ client.addlParamValue3 || '--' }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- ADDLPARAMVALUE5 Column -->
|
<!-- ADDLPARAMVALUE4 Column -->
|
||||||
<ng-container matColumnDef="addlparamvalue5">
|
<ng-container matColumnDef="addlparamvalue4">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 5</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 4</th>
|
||||||
<td mat-cell *matCellDef="let client">{{ client.addlParamValue5 || '--'}}</td>
|
<td mat-cell *matCellDef="let client">{{ client.addlParamValue4 || '--' }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Actions Column -->
|
<!-- ADDLPARAMVALUE5 Column -->
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="addlparamvalue5">
|
||||||
<th mat-header-cell *matHeaderCellDef class="actions-header">Actions</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Additional Value 5</th>
|
||||||
<td mat-cell *matCellDef="let client" class="actions-cell">
|
<td mat-cell *matCellDef="let client">{{ client.addlParamValue5 || '--'}}</td>
|
||||||
<div class="action-container">
|
</ng-container>
|
||||||
<button mat-icon-button color="primary" *ngIf="!isParamRecord"
|
|
||||||
(click)="onRecordClick(client?.paramValue , client?.paramDesc )"
|
|
||||||
[matTooltip]="client.paramDesc ">
|
|
||||||
<mat-icon>chevron_right</mat-icon>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button mat-icon-button color="primary" *ngIf="isParamRecord" (click)="onEditParam(client)"
|
<!-- Actions Column -->
|
||||||
[matTooltip]="'edit'">
|
<ng-container matColumnDef="actions">
|
||||||
<mat-icon>edit</mat-icon>
|
<th mat-header-cell *matHeaderCellDef class="actions-header">Actions</th>
|
||||||
</button>
|
<td mat-cell *matCellDef="let client" class="actions-cell">
|
||||||
|
<div class="action-container">
|
||||||
|
<button mat-icon-button color="primary" *ngIf="!isParamRecord"
|
||||||
|
(click)="onRecordClick(client?.paramValue , client?.paramDesc )"
|
||||||
|
[matTooltip]="client.paramDesc ">
|
||||||
|
<mat-icon>chevron_right</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button mat-icon-button color="warn"
|
<button mat-icon-button color="primary" *ngIf="isParamRecord" (click)="onEditParam(client)"
|
||||||
*ngIf="isParamRecord && (client.inactiveCodeFlag === 'N' || !client.inactiveCodeFlag)"
|
[matTooltip]="'edit'">
|
||||||
matTooltip="Inactivate" (click)="inActivateParamRecord(client.paramId)">
|
<mat-icon>edit</mat-icon>
|
||||||
<mat-icon>delete</mat-icon>
|
</button>
|
||||||
</button>
|
|
||||||
|
|
||||||
<button mat-icon-button color="warn" *ngIf="(isParamRecord) && client.inactiveCodeFlag === 'Y'"
|
<button mat-icon-button color="warn"
|
||||||
matTooltip="Reactivate" (click)="reActivateParamRecord(client.paramId)">
|
*ngIf="isParamRecord && (client.inactiveCodeFlag === 'N' || !client.inactiveCodeFlag)"
|
||||||
<mat-icon>delete_outline</mat-icon>
|
matTooltip="Inactivate" (click)="inActivateParamRecord(client.paramId)">
|
||||||
</button>
|
<mat-icon>delete</mat-icon>
|
||||||
</div>
|
</button>
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<button mat-icon-button color="warn" *ngIf="(isParamRecord) && client.inactiveCodeFlag === 'Y'"
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
matTooltip="Reactivate" (click)="reActivateParamRecord(client.paramId)">
|
||||||
|
<mat-icon>delete_outline</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<tr matNoDataRow *matNoDataRow>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<td [attr.colspan]="displayedColumns.length" class="no-data-message">
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
<mat-icon>info</mat-icon>
|
|
||||||
<span>No records found matching your criteria</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize || 2]"
|
<tr matNoDataRow *matNoDataRow>
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
<td [attr.colspan]="displayedColumns.length" class="no-data-message">
|
||||||
|
<mat-icon>info</mat-icon>
|
||||||
|
<span>No records found matching your criteria</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize || 2]"
|
||||||
|
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
|
</div>
|
||||||
<!-- Contact Form -->
|
<!-- Contact Form -->
|
||||||
<div class="form-container" *ngIf="showForm">
|
<div class="form-container" *ngIf="showForm">
|
||||||
<form [formGroup]="paramForm" (ngSubmit)="saveRecord()">
|
<form [formGroup]="paramForm" (ngSubmit)="saveRecord()">
|
||||||
<div class="form-header">
|
<div class="form-header">
|
||||||
<h3>{{ !isParamRecord ? 'Add New Table' : isEditing ? 'Edit Param' : 'Add New Param' }}
|
<h3> {{ !isParamRecord ? 'Add New Table' : isEditing ? `Edit Parameter` :
|
||||||
|
`Add New Parameter`}}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -253,7 +254,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="paramForm.invalid">
|
<button mat-raised-button color="primary" type="submit"
|
||||||
|
[disabled]="paramForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
|
|||||||
@ -4,17 +4,15 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.manage-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.actions-bar {
|
.actions-bar {
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
|
||||||
|
|
||||||
&.mb-40 {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mb-10 {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-slide-toggle {
|
mat-slide-toggle {
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
@ -27,7 +25,6 @@
|
|||||||
|
|
||||||
.icon-text {
|
.icon-text {
|
||||||
padding-left: 10px !important;
|
padding-left: 10px !important;
|
||||||
font-size: 18px !important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +52,7 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -98,7 +96,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
@ -107,7 +105,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.results-section {
|
.results-section {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -155,7 +152,7 @@
|
|||||||
color: rgba(0, 0, 0, 0.54);
|
color: rgba(0, 0, 0, 0.54);
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
font-size: 1rem;
|
font-size: 0.875rem;
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
margin-bottom: -3px;
|
margin-bottom: -3px;
|
||||||
|
|||||||
@ -15,7 +15,8 @@ import { ParamProperties } from '../../core/models/param/parameters';
|
|||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { TABLE_MODE } from '../../core/models/param/types';
|
import { TABLE_MODE } from '../../core/models/param/types';
|
||||||
import { ProperCasePipe } from '../../shared/pipes/properCase.pipe';
|
import { ProperCasePipe } from '../../shared/pipes/proper-case.pipe';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-param-table',
|
selector: 'app-param-table',
|
||||||
@ -31,6 +32,7 @@ export class ParamTableComponent {
|
|||||||
@Input() paramHeading: string = 'Table Records';
|
@Input() paramHeading: string = 'Table Records';
|
||||||
|
|
||||||
isLoading: boolean = false;
|
isLoading: boolean = false;
|
||||||
|
changeInProgress: boolean = false;
|
||||||
userPreferences: UserPreferences;
|
userPreferences: UserPreferences;
|
||||||
paramType: string | null = null;
|
paramType: string | null = null;
|
||||||
paramData: any = [];
|
paramData: any = [];
|
||||||
@ -180,16 +182,16 @@ export class ParamTableComponent {
|
|||||||
|
|
||||||
const P_PARAMTYPE: string = this.paramType ? this.paramType : '000';
|
const P_PARAMTYPE: string = this.paramType ? this.paramType : '000';
|
||||||
|
|
||||||
this.paramService.getParameters(P_PARAMTYPE).subscribe({
|
this.paramService.getParameters(P_PARAMTYPE).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (paramData: ParamProperties[]) => {
|
next: (paramData: ParamProperties[]) => {
|
||||||
this.paramData = paramData
|
this.paramData = paramData;
|
||||||
this.renderParamData()
|
this.renderParamData();
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to search preparers');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to search preparers');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading preparers:', error);
|
console.error('Error loading preparers:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -213,7 +215,10 @@ export class ParamTableComponent {
|
|||||||
? this.paramService.updateParamRecord(paramData as ParamProperties)
|
? this.paramService.updateParamRecord(paramData as ParamProperties)
|
||||||
: this.paramService.createParamRecord(paramData as ParamProperties);
|
: this.paramService.createParamRecord(paramData as ParamProperties);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Record ${this.isEditing && (this.table_mode !== 'TABLE-RECORD') ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Record ${this.isEditing && (this.table_mode !== 'TABLE-RECORD') ? 'updated' : 'added'} successfully`);
|
||||||
this.getParameters();
|
this.getParameters();
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { NotificationService } from '../core/services/common/notification.servic
|
|||||||
import { AngularMaterialModule } from '../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../shared/module/angular-material.module';
|
||||||
import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ThemeService } from '../core/services/theme.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-register',
|
selector: 'app-register',
|
||||||
@ -28,6 +29,7 @@ export class RegisterComponent {
|
|||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private notificationService = inject(NotificationService);
|
private notificationService = inject(NotificationService);
|
||||||
private errorHandler = inject(ApiErrorHandlerService);
|
private errorHandler = inject(ApiErrorHandlerService);
|
||||||
|
private themeService = inject(ThemeService);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.registrationForm = this.fb.group({
|
this.registrationForm = this.fb.group({
|
||||||
@ -47,6 +49,10 @@ export class RegisterComponent {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.themeService.setTheme('default');
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
if (this.registrationForm.invalid) {
|
if (this.registrationForm.invalid) {
|
||||||
this.registrationForm.markAllAsTouched();
|
this.registrationForm.markAllAsTouched();
|
||||||
|
|||||||
@ -176,8 +176,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="basicDetailsForm.invalid">
|
<button mat-raised-button color="primary" type="submit"
|
||||||
Save
|
[disabled]="basicDetailsForm.invalid || changeInProgress">
|
||||||
|
{{ isEditMode ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Component, Input, OnInit, Output, EventEmitter, OnDestroy, inject } from '@angular/core';
|
import { Component, Input, OnInit, Output, EventEmitter, OnDestroy, inject } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { finalize, takeUntil } from 'rxjs/operators';
|
||||||
import { BasicDetail } from '../../core/models/service-provider/basic-detail';
|
import { BasicDetail } from '../../core/models/service-provider/basic-detail';
|
||||||
import { Country } from '../../core/models/country';
|
import { Country } from '../../core/models/country';
|
||||||
import { Region } from '../../core/models/region';
|
import { Region } from '../../core/models/region';
|
||||||
@ -38,6 +38,7 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
cargoPolicies: CargoPolicy[] = [];
|
cargoPolicies: CargoPolicy[] = [];
|
||||||
|
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
|
changeInProgress = false;
|
||||||
countriesHasStates = ['US', 'CA', 'MX'];
|
countriesHasStates = ['US', 'CA', 'MX'];
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
@ -57,21 +58,24 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
// this.spidCreated.emit(this.spid?.toString());
|
// this.spidCreated.emit(this.spid?.toString());
|
||||||
// Patch edit form data
|
// Patch edit form data
|
||||||
if (this.spid > 0) {
|
if (this.spid > 0) {
|
||||||
this.basicDetailService.getBasicDetailsById(this.spid).subscribe({
|
this.isLoading = true;
|
||||||
|
this.basicDetailService.getBasicDetailsById(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (basicDetail: BasicDetail) => {
|
next: (basicDetail: BasicDetail) => {
|
||||||
if (basicDetail?.spid > 0) {
|
if (basicDetail?.spid > 0) {
|
||||||
this.patchFormData(basicDetail);
|
this.patchFormData(basicDetail);
|
||||||
this.serviceProviderName.emit(basicDetail.companyName);
|
this.serviceProviderName.emit(basicDetail.companyName);
|
||||||
}
|
}
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading basic details:', error);
|
console.error('Error loading basic details:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.loadStates('US');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +91,7 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
address1: ['', [Validators.required, Validators.maxLength(100)]],
|
address1: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
address2: ['', [Validators.maxLength(100)]],
|
address2: ['', [Validators.maxLength(100)]],
|
||||||
city: ['', [Validators.required, Validators.maxLength(50)]],
|
city: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
country: ['', Validators.required],
|
country: ['US', Validators.required],
|
||||||
state: ['', Validators.required],
|
state: ['', Validators.required],
|
||||||
zip: ['', [Validators.required, ZipCodeValidator('country')]],
|
zip: ['', [Validators.required, ZipCodeValidator('country')]],
|
||||||
issuingRegion: ['', Validators.required],
|
issuingRegion: ['', Validators.required],
|
||||||
@ -99,7 +103,7 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadLookupData(): void {
|
loadLookupData(): void {
|
||||||
this.commonService.getCountries(this.spid)
|
this.commonService.getCountries()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (countries) => {
|
next: (countries) => {
|
||||||
@ -107,7 +111,6 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load countries', error);
|
console.error('Failed to load countries', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -123,11 +126,9 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (regions) => {
|
next: (regions) => {
|
||||||
this.regions = regions;
|
this.regions = regions;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load regions', error);
|
console.error('Failed to load regions', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -135,9 +136,10 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
loadStates(country: string): void {
|
loadStates(country: string): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
||||||
this.commonService.getStates(country, this.spid)
|
this.commonService.getStates(country)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$), finalize(() => {
|
||||||
.subscribe({
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (states) => {
|
next: (states) => {
|
||||||
this.states = states;
|
this.states = states;
|
||||||
const stateControl = this.basicDetailsForm.get('state');
|
const stateControl = this.basicDetailsForm.get('state');
|
||||||
@ -147,11 +149,9 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
stateControl?.disable();
|
stateControl?.disable();
|
||||||
stateControl?.setValue('FN');
|
stateControl?.setValue('FN');
|
||||||
}
|
}
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load states', error);
|
console.error('Failed to load states', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -162,11 +162,9 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (bondSuretys) => {
|
next: (bondSuretys) => {
|
||||||
this.bondSuretys = bondSuretys;
|
this.bondSuretys = bondSuretys;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load bond suretys', error);
|
console.error('Failed to load bond suretys', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -177,11 +175,9 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (cargoSuretys) => {
|
next: (cargoSuretys) => {
|
||||||
this.cargoSuretys = cargoSuretys;
|
this.cargoSuretys = cargoSuretys;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load cargo suretys', error);
|
console.error('Failed to load cargo suretys', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -192,11 +188,9 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (cargoPolicies) => {
|
next: (cargoPolicies) => {
|
||||||
this.cargoPolicies = cargoPolicies;
|
this.cargoPolicies = cargoPolicies;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load cargo policies', error);
|
console.error('Failed to load cargo policies', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -220,6 +214,8 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
if (data.country) {
|
if (data.country) {
|
||||||
this.loadStates(data.country);
|
this.loadStates(data.country);
|
||||||
|
} else {
|
||||||
|
this.loadStates('US');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isEditMode) {
|
if (this.isEditMode) {
|
||||||
@ -270,12 +266,17 @@ export class BasicDetailsComponent implements OnInit, OnDestroy {
|
|||||||
? this.basicDetailService.updateBasicDetails(this.spid, basicDetailData)
|
? this.basicDetailService.updateBasicDetails(this.spid, basicDetailData)
|
||||||
: this.basicDetailService.createBasicDetails(basicDetailData);
|
: this.basicDetailService.createBasicDetails(basicDetailData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => this.changeInProgress = false)).subscribe({
|
||||||
next: (basicData: any) => {
|
next: (basicData: any) => {
|
||||||
this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`);
|
||||||
|
|
||||||
if (!this.isEditMode) {
|
if (!this.isEditMode) {
|
||||||
this.spidCreated.emit(basicData.SPID);
|
this.spidCreated.emit(basicData.SPID);
|
||||||
|
|
||||||
|
// change to edit mode after creation
|
||||||
|
this.isEditMode = true;
|
||||||
|
this.spid = basicData.SPID;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
<div class="basic-fee-container">
|
<div class="basic-fee-container">
|
||||||
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="table-container mat-elevation-z8">
|
<div class="table-container mat-elevation-z8">
|
||||||
<div class="loading-shade" *ngIf="isLoading">
|
<div class="loading-shade" *ngIf="isLoading">
|
||||||
@ -53,8 +58,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fee Form -->
|
<!-- Fee Form -->
|
||||||
@ -136,10 +141,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="feeForm.invalid">
|
[disabled]="feeForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,19 @@
|
|||||||
.basic-fee-container {
|
.basic-fee-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
|
||||||
|
.actions-bar {
|
||||||
|
clear: both;
|
||||||
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.table-container {
|
.table-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -62,7 +72,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -79,6 +89,7 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -130,7 +141,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
|
|||||||
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CustomPaginator } from '../../shared/custom-paginator';
|
import { CustomPaginator } from '../../shared/custom-paginator';
|
||||||
import { forkJoin } from 'rxjs';
|
import { finalize, forkJoin } from 'rxjs';
|
||||||
import { UserPreferences } from '../../core/models/user-preference';
|
import { UserPreferences } from '../../core/models/user-preference';
|
||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
@ -30,7 +30,10 @@ export class BasicFeeComponent {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentFeeId: number | null = null;
|
currentFeeId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showExpiredRecords = false;
|
||||||
|
basicFees: BasicFee[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -67,11 +70,14 @@ export class BasicFeeComponent {
|
|||||||
|
|
||||||
loadBasicFees(): void {
|
loadBasicFees(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.basicFeeService.getBasicFees(this.spid).subscribe({
|
this.basicFeeService.getBasicFees(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (fees) => {
|
next: (fees) => {
|
||||||
this.dataSource.data = fees;
|
this.basicFees = fees;
|
||||||
|
this.dataSource.data = this.basicFees;
|
||||||
|
this.renderRecods();
|
||||||
this.hasBasicFees.emit(fees.length > 0);
|
this.hasBasicFees.emit(fees.length > 0);
|
||||||
this.isLoading = false;
|
|
||||||
|
|
||||||
if (this.dataSource.data.length == 0) {
|
if (this.dataSource.data.length == 0) {
|
||||||
this.initializeDefaultFees();
|
this.initializeDefaultFees();
|
||||||
@ -80,14 +86,25 @@ export class BasicFeeComponent {
|
|||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic fees');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic fees');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading basic fees:', error);
|
console.error('Error loading basic fees:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.basicFees;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.basicFees.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initializeDefaultFees(): void {
|
initializeDefaultFees(): void {
|
||||||
this.isLoading = true;
|
|
||||||
const defaultFees: BasicFee[] = [
|
const defaultFees: BasicFee[] = [
|
||||||
{ basicFeeId: 0, startCarnetValue: 1, endCarnetValue: 9999, fees: 255, effectiveDate: new Date() },
|
{ basicFeeId: 0, startCarnetValue: 1, endCarnetValue: 9999, fees: 255, effectiveDate: new Date() },
|
||||||
{ basicFeeId: 0, startCarnetValue: 10000, endCarnetValue: 49999, fees: 300, effectiveDate: new Date() },
|
{ basicFeeId: 0, startCarnetValue: 10000, endCarnetValue: 49999, fees: 300, effectiveDate: new Date() },
|
||||||
@ -102,14 +119,16 @@ export class BasicFeeComponent {
|
|||||||
this.basicFeeService.createBasicFee(this.spid, fee)
|
this.basicFeeService.createBasicFee(this.spid, fee)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.changeInProgress = true;
|
||||||
|
|
||||||
// Execute all creations in parallel and wait for all to complete
|
// Execute all creations in parallel and wait for all to complete
|
||||||
forkJoin(creationObservables).subscribe({
|
forkJoin(creationObservables).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.loadBasicFees(); // Refresh the list after all creations are done
|
this.loadBasicFees(); // Refresh the list after all creations are done
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error initializing default fees:', error);
|
console.error('Error initializing default fees:', error);
|
||||||
// Even if some failed, try to load what was created
|
// Even if some failed, try to load what was created
|
||||||
this.loadBasicFees();
|
this.loadBasicFees();
|
||||||
@ -175,7 +194,11 @@ export class BasicFeeComponent {
|
|||||||
? this.basicFeeService.updateBasicFee(this.currentFeeId, feeData)
|
? this.basicFeeService.updateBasicFee(this.currentFeeId, feeData)
|
||||||
: this.basicFeeService.createBasicFee(this.spid, feeData);
|
: this.basicFeeService.createBasicFee(this.spid, feeData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Basic fee ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Basic fee ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadBasicFees();
|
this.loadBasicFees();
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<div class="fee-commission-container">
|
<div class="fee-commission-container">
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
<button mat-raised-button color="primary" *ngIf="!isEditMode" (click)="addNewFeeCommission()">
|
<button mat-raised-button color="primary" *ngIf="!isEditMode" (click)="addNewFeeCommission()">
|
||||||
<mat-icon>add</mat-icon> Add New Fee & Commission
|
<mat-icon>add</mat-icon> Add New Fee & Commission
|
||||||
</button>
|
</button>
|
||||||
@ -54,8 +57,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fee & Commission Form -->
|
<!-- Fee & Commission Form -->
|
||||||
@ -123,10 +126,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="feeCommissionForm.invalid">
|
[disabled]="feeCommissionForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -76,7 +81,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -93,6 +98,7 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -140,7 +146,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { ApiErrorHandlerService } from '../../core/services/common/api-error-han
|
|||||||
import { CommonService } from '../../core/services/common/common.service';
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { CarnetFeeService } from '../../core/services/service-provider/carnet-fee.service';
|
import { CarnetFeeService } from '../../core/services/service-provider/carnet-fee.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-carnet-fee',
|
selector: 'app-carnet-fee',
|
||||||
@ -33,8 +34,11 @@ export class CarnetFeeComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentFeeCommissionId: number | null = null;
|
currentFeeCommissionId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
feeTypes: FeeType[] = [];
|
feeTypes: FeeType[] = [];
|
||||||
|
showExpiredRecords = false;
|
||||||
|
carnetFees: CarnetFee[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -72,21 +76,36 @@ export class CarnetFeeComponent implements OnInit {
|
|||||||
|
|
||||||
loadFeeCommissions(): void {
|
loadFeeCommissions(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.feeCommissionService.getFeeCommissions(this.spid).subscribe({
|
this.feeCommissionService.getFeeCommissions(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (fees) => {
|
next: (fees) => {
|
||||||
this.dataSource.data = fees;
|
this.carnetFees = fees;
|
||||||
|
this.dataSource.data = this.carnetFees;
|
||||||
|
this.renderRecods();
|
||||||
this.hasFeeCommissions.emit(fees.length > 0);
|
this.hasFeeCommissions.emit(fees.length > 0);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load fee & commission data');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load fee & commission data');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading fee & commission data:', error);
|
console.error('Error loading fee & commission data:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.carnetFees;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.carnetFees.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadFeeTypes(): void {
|
loadFeeTypes(): void {
|
||||||
this.commonService.getFeeTypes().subscribe({
|
this.commonService.getFeeTypes().subscribe({
|
||||||
next: (types) => {
|
next: (types) => {
|
||||||
@ -151,7 +170,10 @@ export class CarnetFeeComponent implements OnInit {
|
|||||||
? this.feeCommissionService.updateFeeCommission(this.currentFeeCommissionId, feeCommissionData)
|
? this.feeCommissionService.updateFeeCommission(this.currentFeeCommissionId, feeCommissionData)
|
||||||
: this.feeCommissionService.createFeeCommission(this.spid, feeCommissionData);
|
: this.feeCommissionService.createFeeCommission(this.spid, feeCommissionData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Fee & commission ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Fee & commission ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadFeeCommissions();
|
this.loadFeeCommissions();
|
||||||
|
|||||||
@ -65,8 +65,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sequence Form -->
|
<!-- Sequence Form -->
|
||||||
@ -138,10 +138,11 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="sequenceForm.invalid">
|
[disabled]="sequenceForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.carnet-sequence-container {
|
.carnet-sequence-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Component, EventEmitter, inject, Input, OnInit, Output, ViewChild } from '@angular/core';
|
import { Component, EventEmitter, inject, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { CarnetSequence } from '../../core/models/service-provider/carnet-sequence';
|
import { CarnetSequence } from '../../core/models/service-provider/carnet-sequence';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { finalize, Subject, takeUntil } from 'rxjs';
|
||||||
import { Region } from '../../core/models/region';
|
import { Region } from '../../core/models/region';
|
||||||
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
|
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
@ -32,6 +32,7 @@ export class CarnetSequenceComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentSequenceId: string | null = null;
|
currentSequenceId: string | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
|
||||||
carnetTypes = [
|
carnetTypes = [
|
||||||
@ -98,11 +99,9 @@ export class CarnetSequenceComponent implements OnInit {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (regions) => {
|
next: (regions) => {
|
||||||
this.regions = regions;
|
this.regions = regions;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load regions', error);
|
console.error('Failed to load regions', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -113,17 +112,15 @@ export class CarnetSequenceComponent implements OnInit {
|
|||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
this.carnetSequenceService.getCarnetSequenceById(this.spid).subscribe({
|
this.carnetSequenceService.getCarnetSequenceById(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (carnetSequences: CarnetSequence[]) => {
|
next: (carnetSequences: CarnetSequence[]) => {
|
||||||
// this.sequences = carnetSequences;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.dataSource.data = carnetSequences;
|
this.dataSource.data = carnetSequences;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load sequences');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load sequences');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading sequences:', error);
|
console.error('Error loading sequences:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -141,7 +138,10 @@ export class CarnetSequenceComponent implements OnInit {
|
|||||||
lastNumber: this.sequenceForm.value.startNumber
|
lastNumber: this.sequenceForm.value.startNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
this.carnetSequenceService.createCarnetSequence(sequenceData).subscribe({
|
this.changeInProgress = true;
|
||||||
|
this.carnetSequenceService.createCarnetSequence(sequenceData).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Sequence added successfully');
|
this.notificationService.showSuccess('Sequence added successfully');
|
||||||
this.loadSequences();
|
this.loadSequences();
|
||||||
@ -182,7 +182,10 @@ export class CarnetSequenceComponent implements OnInit {
|
|||||||
spid: this.spid
|
spid: this.spid
|
||||||
};
|
};
|
||||||
|
|
||||||
this.carnetSequenceService.createCarnetSequence(sequenceData)
|
this.changeInProgress = true;
|
||||||
|
this.carnetSequenceService.createCarnetSequence(sequenceData).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
}))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Sequence added successfully');
|
this.notificationService.showSuccess('Sequence added successfully');
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
<mat-icon matPrefix>search</mat-icon>
|
<mat-icon matPrefix>search</mat-icon>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Search contacts...">
|
<input matInput (keyup)="applyFilter($event)" placeholder="Search contacts...">
|
||||||
</mat-form-field> -->
|
</mat-form-field> -->
|
||||||
|
<mat-slide-toggle (change)="toggleShowInactiveContacts()">
|
||||||
|
Show Inactive Contacts
|
||||||
|
</mat-slide-toggle>
|
||||||
|
|
||||||
<button mat-raised-button color="primary" (click)="addNewContact()">
|
<button mat-raised-button color="primary" (click)="addNewContact()">
|
||||||
<mat-icon>add</mat-icon> Add New Contact
|
<mat-icon>add</mat-icon> Add New Contact
|
||||||
</button>
|
</button>
|
||||||
@ -85,8 +89,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Contact Form -->
|
<!-- Contact Form -->
|
||||||
@ -243,10 +247,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="contactForm.invalid">
|
[disabled]="contactForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.contacts-container {
|
.contacts-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -81,7 +86,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -98,6 +103,7 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -141,7 +147,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { UserPreferences } from '../../core/models/user-preference';
|
|||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { ContactService } from '../../core/services/service-provider/contact.service';
|
import { ContactService } from '../../core/services/service-provider/contact.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contacts',
|
selector: 'app-contacts',
|
||||||
@ -32,7 +33,10 @@ export class ContactsComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentContactId: number | null = null;
|
currentContactId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showInactiveContacts = false;
|
||||||
|
contacts: Contact[] = [];
|
||||||
|
|
||||||
contactReadOnlyFields: any = {
|
contactReadOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -57,9 +61,9 @@ export class ContactsComponent implements OnInit {
|
|||||||
lastName: ['', [Validators.required, Validators.maxLength(50)]],
|
lastName: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
middleInitial: ['', [Validators.maxLength(1)]],
|
middleInitial: ['', [Validators.maxLength(1)]],
|
||||||
title: ['', [Validators.required, Validators.maxLength(100)]],
|
title: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
phone: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
phone: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
mobile: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
mobile: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
fax: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
fax: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
|
email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
|
||||||
defaultContact: [false]
|
defaultContact: [false]
|
||||||
});
|
});
|
||||||
@ -77,20 +81,34 @@ export class ContactsComponent implements OnInit {
|
|||||||
loadContacts(): void {
|
loadContacts(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
this.contactService.getContactsById(this.spid).subscribe({
|
this.contactService.getContactsById(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (contacts: Contact[]) => {
|
next: (contacts: Contact[]) => {
|
||||||
this.dataSource.data = contacts;
|
this.contacts = contacts;
|
||||||
this.isLoading = false;
|
this.renderContacts();
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load contacts');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load contacts');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading contacts:', error);
|
console.error('Error loading contacts:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowInactiveContacts(): void {
|
||||||
|
this.showInactiveContacts = !this.showInactiveContacts;
|
||||||
|
this.renderContacts();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContacts(): void {
|
||||||
|
if (this.showInactiveContacts) {
|
||||||
|
this.dataSource.data = this.contacts;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.contacts.filter(contact => !contact.isInactive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// applyFilter(event: Event): void {
|
// applyFilter(event: Event): void {
|
||||||
// const filterValue = (event.target as HTMLInputElement).value;
|
// const filterValue = (event.target as HTMLInputElement).value;
|
||||||
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
@ -144,7 +162,10 @@ export class ContactsComponent implements OnInit {
|
|||||||
? this.contactService.updateContact(this.currentContactId!, contactData)
|
? this.contactService.updateContact(this.currentContactId!, contactData)
|
||||||
: this.contactService.createContact(this.spid, contactData);
|
: this.contactService.createContact(this.spid, contactData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Contact ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Contact ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadContacts();
|
this.loadContacts();
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<div class="continuation-sheet-container">
|
<div class="continuation-sheet-container">
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
<button mat-raised-button color="primary" (click)="addNewContinuationSheet()">
|
<button mat-raised-button color="primary" (click)="addNewContinuationSheet()">
|
||||||
<mat-icon>add</mat-icon> Add New Continuation Sheet
|
<mat-icon>add</mat-icon> Add New Continuation Sheet
|
||||||
</button>
|
</button>
|
||||||
@ -65,8 +68,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Continuation Sheet Form -->
|
<!-- Continuation Sheet Form -->
|
||||||
@ -151,10 +154,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="continuationSheetForm.invalid">
|
[disabled]="continuationSheetForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.continuation-sheet-container {
|
.continuation-sheet-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -76,7 +81,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -93,10 +98,15 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-error {
|
.form-error {
|
||||||
@ -158,7 +168,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { MatSort } from '@angular/material/sort';
|
|||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { of } from 'rxjs';
|
import { finalize, of } from 'rxjs';
|
||||||
import { CustomPaginator } from '../../shared/custom-paginator';
|
import { CustomPaginator } from '../../shared/custom-paginator';
|
||||||
import { UserPreferences } from '../../core/models/user-preference';
|
import { UserPreferences } from '../../core/models/user-preference';
|
||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
@ -29,7 +29,10 @@ export class ContinuationSheetFeeComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentContinuationSheetId: number | null = null;
|
currentContinuationSheetId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showExpiredRecords = false;
|
||||||
|
continuationSheets: any[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -84,20 +87,35 @@ export class ContinuationSheetFeeComponent implements OnInit {
|
|||||||
if (!this.spid) return;
|
if (!this.spid) return;
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.continuationSheetFeeService.getContinuationSheets(this.spid).subscribe({
|
this.continuationSheetFeeService.getContinuationSheets(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (continuationSheets) => {
|
next: (continuationSheets) => {
|
||||||
this.dataSource.data = continuationSheets;
|
this.continuationSheets = continuationSheets;
|
||||||
this.isLoading = false;
|
this.dataSource.data = this.continuationSheets;
|
||||||
|
this.renderRecods();
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load continuation sheets');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load continuation sheets');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
return of([]);
|
return of([]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.continuationSheets;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.continuationSheets.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// applyFilter(event: Event): void {
|
// applyFilter(event: Event): void {
|
||||||
// const filterValue = (event.target as HTMLInputElement).value;
|
// const filterValue = (event.target as HTMLInputElement).value;
|
||||||
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
@ -153,7 +171,10 @@ export class ContinuationSheetFeeComponent implements OnInit {
|
|||||||
? this.continuationSheetFeeService.updateContinuationSheet(this.currentContinuationSheetId, continuationSheetData)
|
? this.continuationSheetFeeService.updateContinuationSheet(this.currentContinuationSheetId, continuationSheetData)
|
||||||
: this.continuationSheetFeeService.addContinuationSheet(this.spid, continuationSheetData);
|
: this.continuationSheetFeeService.addContinuationSheet(this.spid, continuationSheetData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Continuation Sheet ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Continuation Sheet ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadContinuationSheets();
|
this.loadContinuationSheets();
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<div class="counterfoil-container">
|
<div class="counterfoil-container">
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
<button mat-raised-button color="primary" (click)="addNewCounterfoil()">
|
<button mat-raised-button color="primary" (click)="addNewCounterfoil()">
|
||||||
<mat-icon>add</mat-icon> Add New Counterfoil
|
<mat-icon>add</mat-icon> Add New Counterfoil
|
||||||
</button>
|
</button>
|
||||||
@ -77,8 +80,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Counterfoil Form -->
|
<!-- Counterfoil Form -->
|
||||||
@ -197,10 +200,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="counterfoilForm.invalid">
|
[disabled]="counterfoilForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.counterfoil-container {
|
.counterfoil-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -76,7 +81,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -93,10 +98,15 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-error {
|
.form-error {
|
||||||
@ -158,7 +168,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { UserPreferences } from '../../core/models/user-preference';
|
|||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { CounterfoilFeeService } from '../../core/services/service-provider/counterfoil-fee.service';
|
import { CounterfoilFeeService } from '../../core/services/service-provider/counterfoil-fee.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-counterfoil-fee',
|
selector: 'app-counterfoil-fee',
|
||||||
@ -29,7 +30,10 @@ export class CounterfoilFeeComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentCounterfoilId: number | null = null;
|
currentCounterfoilId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showExpiredRecords = false;
|
||||||
|
counterfoilFees: CounterfoilFee[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -100,22 +104,37 @@ export class CounterfoilFeeComponent implements OnInit {
|
|||||||
if (!this.spid) return;
|
if (!this.spid) return;
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.counterfoilFeeService.getCounterfoils(this.spid)
|
this.counterfoilFeeService.getCounterfoils(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
}))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (
|
next: (
|
||||||
counterfoils: CounterfoilFee[]) => {
|
counterfoils: CounterfoilFee[]) => {
|
||||||
this.dataSource.data = counterfoils;
|
this.counterfoilFees = counterfoils;
|
||||||
this.isLoading = false;
|
this.dataSource.data = this.counterfoilFees;
|
||||||
|
this.renderRecods();
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load counterfoils');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load counterfoils');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading counterfoils:', error);
|
console.error('Error loading counterfoils:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.counterfoilFees;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.counterfoilFees.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// applyFilter(event: Event): void {
|
// applyFilter(event: Event): void {
|
||||||
// const filterValue = (event.target as HTMLInputElement).value;
|
// const filterValue = (event.target as HTMLInputElement).value;
|
||||||
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
@ -177,7 +196,10 @@ export class CounterfoilFeeComponent implements OnInit {
|
|||||||
? this.counterfoilFeeService.updateCounterfoil(this.currentCounterfoilId, counterfoilData)
|
? this.counterfoilFeeService.updateCounterfoil(this.currentCounterfoilId, counterfoilData)
|
||||||
: this.counterfoilFeeService.addCounterfoil(this.spid, counterfoilData);
|
: this.counterfoilFeeService.addCounterfoil(this.spid, counterfoilData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Counterfoil ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Counterfoil ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadCounterfoils();
|
this.loadCounterfoils();
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
margin: 0.5rem 0px;
|
margin: 0.5rem 0px;
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<div class="expedited-fee-container">
|
<div class="expedited-fee-container">
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
<button mat-raised-button color="primary" (click)="addNewFee()">
|
<button mat-raised-button color="primary" (click)="addNewFee()">
|
||||||
<mat-icon>add</mat-icon> Add New Expedited Fee
|
<mat-icon>add</mat-icon> Add New Expedited Fee
|
||||||
</button>
|
</button>
|
||||||
@ -65,8 +68,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fee Form -->
|
<!-- Fee Form -->
|
||||||
@ -195,10 +198,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="feeForm.invalid">
|
[disabled]="feeForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.expedited-fee-container {
|
.expedited-fee-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -76,7 +81,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -93,10 +98,15 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-error {
|
.form-error {
|
||||||
@ -158,7 +168,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { CustomPaginator } from '../../shared/custom-paginator';
|
|||||||
import { ExpeditedFee } from '../../core/models/service-provider/expedited-fee';
|
import { ExpeditedFee } from '../../core/models/service-provider/expedited-fee';
|
||||||
import { DeliveryType } from '../../core/models/delivery-type';
|
import { DeliveryType } from '../../core/models/delivery-type';
|
||||||
import { TimeZone } from '../../core/models/timezone';
|
import { TimeZone } from '../../core/models/timezone';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { finalize, Subject, takeUntil } from 'rxjs';
|
||||||
import { UserPreferences } from '../../core/models/user-preference';
|
import { UserPreferences } from '../../core/models/user-preference';
|
||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { CommonService } from '../../core/services/common/common.service';
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
@ -34,7 +34,10 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentFeeId: number | null = null;
|
currentFeeId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showExpiredRecords = false;
|
||||||
|
expeditedFees: ExpeditedFee[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -99,20 +102,35 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
|
|||||||
loadExpeditedFees(): void {
|
loadExpeditedFees(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
this.expeditedFeeService.getExpeditedFees(this.spid).subscribe({
|
this.expeditedFeeService.getExpeditedFees(this.spid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (fees: ExpeditedFee[]) => {
|
next: (fees: ExpeditedFee[]) => {
|
||||||
this.dataSource.data = fees;
|
this.expeditedFees = fees;
|
||||||
this.isLoading = false;
|
this.dataSource.data = this.expeditedFees;
|
||||||
|
this.renderRecods();
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load expedited fees');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load expedited fees');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading expedited fees:', error);
|
console.error('Error loading expedited fees:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.expeditedFees;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.expeditedFees.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadLookupData(): void {
|
loadLookupData(): void {
|
||||||
this.loadDeliveryTypes();
|
this.loadDeliveryTypes();
|
||||||
this.loadTimeZones();
|
this.loadTimeZones();
|
||||||
@ -124,17 +142,15 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (timeZones) => {
|
next: (timeZones) => {
|
||||||
this.timeZones = timeZones;
|
this.timeZones = timeZones;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load time zones', error);
|
console.error('Failed to load time zones', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDeliveryTypes(): void {
|
loadDeliveryTypes(): void {
|
||||||
this.commonService.getDeliveryTypes(this.spid)
|
this.commonService.getDeliveryTypes()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (deliveryTypes) => {
|
next: (deliveryTypes) => {
|
||||||
@ -142,7 +158,6 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load delivery types', error);
|
console.error('Failed to load delivery types', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -207,7 +222,10 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
|
|||||||
? this.expeditedFeeService.updateExpeditedFee(this.currentFeeId, feeData)
|
? this.expeditedFeeService.updateExpeditedFee(this.currentFeeId, feeData)
|
||||||
: this.expeditedFeeService.createExpeditedFee(this.spid, feeData);
|
: this.expeditedFeeService.createExpeditedFee(this.spid, feeData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Expedited fee ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Expedited fee ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadExpeditedFees();
|
this.loadExpeditedFees();
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<div class="security-deposit-container">
|
<div class="security-deposit-container">
|
||||||
<div class="actions-bar">
|
<div class="actions-bar">
|
||||||
|
<mat-slide-toggle (change)="toggleShowExpiredRecords()">
|
||||||
|
Show Expired Records
|
||||||
|
</mat-slide-toggle>
|
||||||
<button mat-raised-button color="primary" (click)="addNewDeposit()">
|
<button mat-raised-button color="primary" (click)="addNewDeposit()">
|
||||||
<mat-icon>add</mat-icon> Add New Security Deposit
|
<mat-icon>add</mat-icon> Add New Security Deposit
|
||||||
</button>
|
</button>
|
||||||
@ -79,8 +82,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-paginator [length]="dataSource.data.length" [pageSizeOptions]="[userPreferences.pageSize!]"
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
||||||
[hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Deposit Form -->
|
<!-- Deposit Form -->
|
||||||
@ -179,10 +182,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="depositForm.invalid">
|
[disabled]="depositForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.security-deposit-container {
|
.security-deposit-container {
|
||||||
padding: 24px;
|
padding: 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
@ -8,6 +8,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: -16px;
|
margin-bottom: -16px;
|
||||||
|
|
||||||
|
mat-slide-toggle {
|
||||||
|
transform: scale(0.8);
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
@ -81,7 +86,7 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
.form-header {
|
.form-header {
|
||||||
margin-bottom: 24px;
|
// margin-bottom: 24px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -98,10 +103,15 @@
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-error {
|
.form-error {
|
||||||
@ -163,7 +173,7 @@
|
|||||||
|
|
||||||
.readonly-value {
|
.readonly-value {
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
font-size: 0.9375rem;
|
font-size: 0.875rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { ApiErrorHandlerService } from '../../core/services/common/api-error-han
|
|||||||
import { CommonService } from '../../core/services/common/common.service';
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { SecurityDepositService } from '../../core/services/service-provider/security-deposit.service';
|
import { SecurityDepositService } from '../../core/services/service-provider/security-deposit.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-security-deposit',
|
selector: 'app-security-deposit',
|
||||||
@ -31,7 +32,10 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentDepositId: number | null = null;
|
currentDepositId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
|
showExpiredRecords = false;
|
||||||
|
securityDeposits: SecurityDeposit[] = [];
|
||||||
|
|
||||||
readOnlyFields: any = {
|
readOnlyFields: any = {
|
||||||
lastChangedDate: null,
|
lastChangedDate: null,
|
||||||
@ -67,7 +71,7 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
holderType: ['CORP', Validators.required],
|
holderType: ['CORP', Validators.required],
|
||||||
uscibMember: ['Y', Validators.required],
|
uscibMember: ['Y', Validators.required],
|
||||||
specialCommodity: [''],
|
specialCommodity: [''],
|
||||||
specialCountry: [''],
|
specialCountry: ['US'],
|
||||||
rate: [0, [Validators.required, Validators.min(0)]],
|
rate: [0, [Validators.required, Validators.min(0)]],
|
||||||
effectiveDate: ['', Validators.required]
|
effectiveDate: ['', Validators.required]
|
||||||
});
|
});
|
||||||
@ -85,20 +89,35 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
|
|
||||||
loadSecurityDeposits(): void {
|
loadSecurityDeposits(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.securityDepositService.getSecurityDeposits(this.spid).subscribe({
|
this.securityDepositService.getSecurityDeposits(this.spid).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: (deposits) => {
|
next: (deposits) => {
|
||||||
this.dataSource.data = deposits;
|
this.securityDeposits = deposits;
|
||||||
this.isLoading = false;
|
this.dataSource.data = this.securityDeposits;
|
||||||
|
this.renderRecods();
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load security deposits');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load security deposits');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading security deposits:', error);
|
console.error('Error loading security deposits:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleShowExpiredRecords(): void {
|
||||||
|
this.showExpiredRecords = !this.showExpiredRecords;
|
||||||
|
this.renderRecods();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRecods(): void {
|
||||||
|
if (this.showExpiredRecords) {
|
||||||
|
this.dataSource.data = this.securityDeposits;
|
||||||
|
} else {
|
||||||
|
this.dataSource.data = this.securityDeposits.filter(record => !record.expired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadCountries(): void {
|
loadCountries(): void {
|
||||||
this.commonService.getCountries().subscribe({
|
this.commonService.getCountries().subscribe({
|
||||||
next: (countries) => {
|
next: (countries) => {
|
||||||
@ -126,6 +145,7 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
this.depositForm.reset({
|
this.depositForm.reset({
|
||||||
holderType: 'CORP',
|
holderType: 'CORP',
|
||||||
uscibMember: 'N',
|
uscibMember: 'N',
|
||||||
|
specialCountry: 'US',
|
||||||
});
|
});
|
||||||
this.depositForm.patchValue({ rate: 0 });
|
this.depositForm.patchValue({ rate: 0 });
|
||||||
|
|
||||||
@ -174,7 +194,10 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
? this.securityDepositService.updateSecurityDeposit(this.currentDepositId, depositData)
|
? this.securityDepositService.updateSecurityDeposit(this.currentDepositId, depositData)
|
||||||
: this.securityDepositService.createSecurityDeposit(this.spid, depositData);
|
: this.securityDepositService.createSecurityDeposit(this.spid, depositData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Security deposit ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Security deposit ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadSecurityDeposits();
|
this.loadSecurityDeposits();
|
||||||
@ -222,6 +245,7 @@ export class SecurityDepositComponent implements OnInit {
|
|||||||
this.depositForm.reset({
|
this.depositForm.reset({
|
||||||
holderType: 'CORP',
|
holderType: 'CORP',
|
||||||
uscibMember: 'N',
|
uscibMember: 'N',
|
||||||
|
specialCountry: 'US',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,10 +9,10 @@ import { AngularMaterialModule } from '../../module/angular-material.module';
|
|||||||
<h2 mat-dialog-title>{{ data.title }}</h2>
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
||||||
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
|
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
|
||||||
<mat-dialog-actions align="end">
|
<mat-dialog-actions align="end">
|
||||||
<button mat-button [mat-dialog-close]="false">{{ data.cancelText || 'Cancel' }}</button>
|
|
||||||
<button mat-raised-button color="warn" [mat-dialog-close]="true">
|
<button mat-raised-button color="warn" [mat-dialog-close]="true">
|
||||||
{{ data.confirmText || 'Confirm' }}
|
{{ data.confirmText || 'Confirm' }}
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-button [mat-dialog-close]="false">{{ data.cancelText || 'Cancel' }}</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
`,
|
`,
|
||||||
styles: [`
|
styles: [`
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|||||||
import { MatAccordion, MatExpansionModule } from '@angular/material/expansion';
|
import { MatAccordion, MatExpansionModule } from '@angular/material/expansion';
|
||||||
import { MatStepperModule } from '@angular/material/stepper';
|
import { MatStepperModule } from '@angular/material/stepper';
|
||||||
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MatMomentDateModule } from '@angular/material-moment-adapter';
|
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||||
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [],
|
||||||
@ -53,7 +54,8 @@ import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MatMomentDateModule } from '@angular/m
|
|||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatAccordion,
|
MatAccordion,
|
||||||
MatStepperModule,
|
MatStepperModule,
|
||||||
MatMomentDateModule
|
MatMomentDateModule,
|
||||||
|
MatSlideToggleModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
@ -79,7 +81,8 @@ import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MatMomentDateModule } from '@angular/m
|
|||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatAccordion,
|
MatAccordion,
|
||||||
MatStepperModule,
|
MatStepperModule,
|
||||||
MatMomentDateModule
|
MatMomentDateModule,
|
||||||
|
MatSlideToggleModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
|
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
@use 'colors' as colors;
|
|
||||||
|
|
||||||
.settings-container {
|
.settings-container {
|
||||||
margin: 2rem auto;
|
margin: 2rem auto;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,7 +11,7 @@
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
color: colors.$primary-color;
|
color: var(--mat-sys-primary);
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
@ -30,6 +28,7 @@
|
|||||||
.label {
|
.label {
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
|
|||||||
109
src/styles.scss
109
src/styles.scss
@ -1,19 +1,114 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
|
||||||
// Compact density for all Material components
|
|
||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@include mat.theme((density: -3,
|
@include mat.theme((density: -5));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Roboto, "Helvetica Neue", sans-serif;
|
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
|
||||||
|
/*form field*/
|
||||||
|
@include mat.form-field-overrides((container-text-size: 0.875rem,
|
||||||
|
container-text-line-height:1.7, // line height should be atleast 1.5 times text size
|
||||||
|
outlined-label-text-size:0.875rem));
|
||||||
|
|
||||||
|
/* list */
|
||||||
|
@include mat.list-overrides((list-item-label-text-size:0.875rem,
|
||||||
|
list-item-label-text-line-height:1.7, // line height should be atleast 1.5 times text size
|
||||||
|
));
|
||||||
|
|
||||||
|
/*select*/
|
||||||
|
@include mat.select-overrides((trigger-text-size:0.875rem,
|
||||||
|
trigger-text-line-height:1.7, // line height should be atleast 1.5 times text size
|
||||||
|
));
|
||||||
|
|
||||||
|
/*select options*/
|
||||||
|
--mat-option-label-text-size: 0.875rem;
|
||||||
|
|
||||||
|
/* stepper */
|
||||||
|
@include mat.stepper-overrides((header-height:50px,
|
||||||
|
header-hover-state-layer-color:var(--mat-sys-primary),
|
||||||
|
header-focus-state-layer-color:var(--mat-sys-primary),
|
||||||
|
));
|
||||||
|
|
||||||
|
.mat-step-header:hover:not([aria-disabled]),
|
||||||
|
.mat-step-header:hover[aria-disabled=false] {
|
||||||
|
|
||||||
|
.mat-step-icon {
|
||||||
|
color: var(--mat-sys-on-primary-container);
|
||||||
|
background-color: var(--mat-sys-primary-container);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-step-label {
|
||||||
|
color: var(--mat-sys-on-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-step-header:focus:not([aria-disabled]),
|
||||||
|
.mat-step-header:focus[aria-disabled=false] {
|
||||||
|
|
||||||
|
.mat-step-icon {
|
||||||
|
color: var(--mat-sys-on-primary-container);
|
||||||
|
background-color: var(--mat-sys-primary-container);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-step-label {
|
||||||
|
color: var(--mat-sys-on-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expansion panel */
|
||||||
|
@include mat.expansion-overrides((header-hover-state-layer-color:var(--mat-sys-primary),
|
||||||
|
header-focus-state-layer-color:var(--mat-sys-primary),
|
||||||
|
));
|
||||||
|
|
||||||
|
.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover {
|
||||||
|
.mat-expansion-panel-header-title {
|
||||||
|
color: var(--mat-sys-on-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-expansion-indicator svg {
|
||||||
|
fill: var(--mat-sys-on-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* button */
|
||||||
|
@include mat.button-overrides((protected-container-color: var(--custom-button-background-color),
|
||||||
|
protected-container-elevation-shadow:var(--custom-button-hover-color),
|
||||||
|
protected-label-text-color:var(--custom-button-color)));
|
||||||
|
|
||||||
|
/* Nav bar */
|
||||||
|
.navbar-menu {
|
||||||
|
.mat-mdc-button:hover>.mat-mdc-button-persistent-ripple::before {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-container {
|
||||||
|
.profile-button:hover>.mat-mdc-button-persistent-ripple::before {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table */
|
||||||
|
@include mat.table-overrides((header-headline-color:var(--mat-sys-on-primary),
|
||||||
|
));
|
||||||
|
|
||||||
|
.mat-mdc-table .mat-mdc-header-cell {
|
||||||
|
background: var(--mat-sys-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort */
|
||||||
|
@include mat.sort-overrides((arrow-color: var(--mat-sys-on-primary),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
@ -1,69 +0,0 @@
|
|||||||
// Color palette
|
|
||||||
$primary-color: #597b7c;
|
|
||||||
$primary-light: #e8eaf6;
|
|
||||||
$primary-dark: #303f9f;
|
|
||||||
$accent-color: #ff4081;
|
|
||||||
$background-card: #ffffff;
|
|
||||||
$background-header: #f5f5f5;
|
|
||||||
$background-chip: #f0f0f0;
|
|
||||||
$divider-color: rgba(0, 0, 0, 0.12);
|
|
||||||
$text-primary: rgba(0, 0, 0, 0.87);
|
|
||||||
$text-secondary: rgba(0, 0, 0, 0.54);
|
|
||||||
$text-hint: rgba(0, 0, 0, 0.38);
|
|
||||||
$icon-color: rgba(0, 0, 0, 0.54);
|
|
||||||
|
|
||||||
// _colors.scss
|
|
||||||
|
|
||||||
// // Primary Colors
|
|
||||||
// $primary-color: #2c3e50; // Dark blue for navbar
|
|
||||||
// $primary-light: #3498db; // Lighter blue for accents
|
|
||||||
// $primary-dark: #1a252f; // Darker blue for hover states
|
|
||||||
|
|
||||||
// // Accent Colors
|
|
||||||
// $accent-color: #e74c3c; // Red for important actions
|
|
||||||
// $secondary-accent: #f39c12; // Orange for secondary actions
|
|
||||||
|
|
||||||
// // Background Colors
|
|
||||||
// $background-card: #ffffff; // Card backgrounds
|
|
||||||
// $background-header: #f8f9fa; // Light gray for header/footer
|
|
||||||
// $background-light: #f5f7fa; // Very light gray for subtle backgrounds
|
|
||||||
// $background-dark: #2c3e50; // Dark background (matches primary)
|
|
||||||
|
|
||||||
// // Text Colors
|
|
||||||
// $text-primary: #333333; // Main text color
|
|
||||||
// $text-secondary: #666666; // Secondary text
|
|
||||||
// $text-light: #ffffff; // Text on dark backgrounds
|
|
||||||
// $text-hint: #999999; // Disabled/hint text
|
|
||||||
// $text-error: #e74c3c; // Error messages
|
|
||||||
|
|
||||||
// // Functional Colors
|
|
||||||
// $success-color: #2ecc71; // Green for success states
|
|
||||||
// $warning-color: #f39c12; // Yellow/orange for warnings
|
|
||||||
// $error-color: #e74c3c; // Red for errors
|
|
||||||
|
|
||||||
// // Border/Divider Colors
|
|
||||||
// $border-color: #e0e0e0; // Light borders
|
|
||||||
// $divider-color: rgba(0, 0, 0, 0.12); // Material-like divider
|
|
||||||
|
|
||||||
// // Social Media Colors
|
|
||||||
// $facebook-blue: #3b5998;
|
|
||||||
// $twitter-blue: #1da1f2;
|
|
||||||
// $linkedin-blue: #0077b5;
|
|
||||||
// $youtube-red: #ff0000;
|
|
||||||
|
|
||||||
// // Shadows
|
|
||||||
// $shadow-color: rgba(0, 0, 0, 0.2);
|
|
||||||
|
|
||||||
// // Navbar Specific
|
|
||||||
// $navbar-bg: $primary-color;
|
|
||||||
// $navbar-text: $text-light;
|
|
||||||
// $navbar-hover: lighten($primary-color, 10%);
|
|
||||||
|
|
||||||
// // Footer Specific
|
|
||||||
// $footer-bg: $background-header;
|
|
||||||
// $footer-text: $text-secondary;
|
|
||||||
// $footer-link-hover: $primary-light;
|
|
||||||
|
|
||||||
// // Button States
|
|
||||||
// $button-hover: rgba(0, 0, 0, 0.04);
|
|
||||||
// $button-active: rgba(0, 0, 0, 0.1);
|
|
||||||
Loading…
x
Reference in New Issue
Block a user