Merge pull request #29 in TEA/dafa-web-monorepo from refactor/stricter-eslint to develop
Squashed commit of the following: commit 4e7a87134edb95c9d522514140dcf8ff8b5c9bfa Merge: c586d676f97f51Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Mon Jun 28 09:12:35 2021 +0200 Merge branch 'develop' into refactor/stricter-eslint # Conflicts: # apps/dafa-web/src/app/pages/administration/pages/employee-form/employee-form.component.ts commit c586d675ced7a0dd4bd88599f62dd7a72fe39723 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Jun 23 16:24:37 2021 +0200 Fix linting of avrop commit 70aa93e06c7677ce6b2e5068c74709ef5f9feecc Merge: ace99504afe9b5Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Jun 23 16:12:30 2021 +0200 Merge branch 'develop' into refactor/stricter-eslint # Conflicts: # apps/dafa-web/src/app/pages/avrop/avrop.component.spec.ts # apps/dafa-web/src/app/pages/ciam-landing/ciam-landing.component.spec.ts # apps/dafa-web/src/app/pages/logout/logout.component.spec.ts commit ace9950d3dc9517d8fe4e4b53af6813b6b175720 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Jun 23 10:53:00 2021 +0200 Fix remaining linting warnings/errors commit c15b0a4b8a62604928871d45095d9ad257add0a8 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Wed Jun 23 10:44:32 2021 +0200 fix more linting errors and warnings commit 924c925347dbf0a1029237859c748bf107cfd03c Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Tue Jun 22 17:07:26 2021 +0200 Fixed a lot of linting errors commit f730f04ebb2d28e150ba20c2507493fac64f0a2d Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Tue Jun 22 16:32:58 2021 +0200 fix some linting problems commit 64fe06c034586688fd7252198de0baf0caaccca2 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Tue Jun 22 16:15:32 2021 +0200 add recommended eslint rules with type-checking
This commit is contained in:
20
.prettierrc
20
.prettierrc
@@ -7,9 +7,23 @@
|
|||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ".prettierrc",
|
"files": ".prettierrc",
|
||||||
"options": { "parser": "json" }
|
"options": {
|
||||||
|
"parser": "json"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.component.html",
|
||||||
|
"options": {
|
||||||
|
"parser": "angular"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.html",
|
||||||
|
"options": {
|
||||||
|
"parser": "html"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
"files": ["*.ts"],
|
"files": ["*.ts"],
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:@nrwl/nx/angular",
|
"plugin:@nrwl/nx/angular",
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||||
"plugin:@angular-eslint/template/process-inline-templates"
|
"plugin:@angular-eslint/template/process-inline-templates"
|
||||||
],
|
],
|
||||||
"parserOptions": { "project": ["apps/dafa-web/tsconfig.*?.json"] },
|
"parserOptions": { "project": ["apps/dafa-web/tsconfig.*?.json"] },
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('FooterComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [FooterComponent],
|
declarations: [FooterComponent],
|
||||||
imports: [RouterTestingModule, IconModule],
|
imports: [RouterTestingModule, IconModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { NavigationBreadcrumbsItem } from '@af/digi-ng/_navigation/navigation-breadcrumbs';
|
import { NavigationBreadcrumbsItem } from '@af/digi-ng/_navigation/navigation-breadcrumbs';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { User } from '@dafa-models/user.model';
|
import { User } from '@dafa-models/user.model';
|
||||||
@@ -14,7 +14,7 @@ import { environment } from '@dafa-environment';
|
|||||||
selector: 'dafa-logged-in-shell',
|
selector: 'dafa-logged-in-shell',
|
||||||
templateUrl: './logged-in-shell.component.html',
|
templateUrl: './logged-in-shell.component.html',
|
||||||
styleUrls: ['./logged-in-shell.component.scss'],
|
styleUrls: ['./logged-in-shell.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class LoggedInShellComponent extends UnsubscribeDirective {
|
export class LoggedInShellComponent extends UnsubscribeDirective {
|
||||||
private startBreadcrumb: NavigationBreadcrumbsItem = {
|
private startBreadcrumb: NavigationBreadcrumbsItem = {
|
||||||
@@ -28,18 +28,17 @@ export class LoggedInShellComponent extends UnsubscribeDirective {
|
|||||||
return this._breadcrumbsItems$.getValue();
|
return this._breadcrumbsItems$.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
get isLoggedIn() {
|
get isLoggedIn(): boolean {
|
||||||
return this.authService.isLoggedIn();
|
return this.authService.isLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private router: Router, private authService: AuthenticationService, private userService: UserService) {
|
constructor(private router: Router, private authService: AuthenticationService, private userService: UserService) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if(this.authService.isLoggedOut()) {
|
if (this.authService.isLoggedOut()) {
|
||||||
this.router.navigateByUrl(environment.loginUrl);
|
void this.router.navigateByUrl(environment.loginUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
super.unsubscribeOnDestroy(
|
super.unsubscribeOnDestroy(
|
||||||
this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
||||||
const urlTree = this.router.parseUrl(this.router.url);
|
const urlTree = this.router.parseUrl(this.router.url);
|
||||||
@@ -52,5 +51,4 @@ export class LoggedInShellComponent extends UnsubscribeDirective {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('NavigationComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [NavigationComponent],
|
declarations: [NavigationComponent],
|
||||||
imports: [RouterTestingModule, IconModule],
|
imports: [RouterTestingModule, IconModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('SkipToContentComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [SkipToContentComponent],
|
declarations: [SkipToContentComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export class SkipToContentComponent extends UnsubscribeDirective {
|
|||||||
constructor(private router: Router, private changeDetectorRef: ChangeDetectorRef) {
|
constructor(private router: Router, private changeDetectorRef: ChangeDetectorRef) {
|
||||||
super();
|
super();
|
||||||
super.unsubscribeOnDestroy(
|
super.unsubscribeOnDestroy(
|
||||||
this.router.events.pipe(filter((event: any) => event instanceof NavigationEnd)).subscribe(({ url }) => {
|
this.router.events.pipe(filter((event: NavigationEnd) => event instanceof NavigationEnd)).subscribe(({ url }) => {
|
||||||
const mainContentId = `#${this.mainContentId}`;
|
const mainContentId = `#${this.mainContentId}`;
|
||||||
// Check if the current URL already includes the mainContentId.
|
// Check if the current URL already includes the mainContentId.
|
||||||
const existsInUrl: boolean = url.substring(url.length - mainContentId.length, url.length) === mainContentId;
|
const existsInUrl: boolean = url.substring(url.length - mainContentId.length, url.length) === mainContentId;
|
||||||
|
|||||||
@@ -2,16 +2,17 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
import { ToastListComponent } from './toast-list.component';
|
import { ToastListComponent } from './toast-list.component';
|
||||||
|
|
||||||
|
|
||||||
describe('ToastListComponent', () => {
|
describe('ToastListComponent', () => {
|
||||||
let component: ToastListComponent;
|
let component: ToastListComponent;
|
||||||
let fixture: ComponentFixture<ToastListComponent>;
|
let fixture: ComponentFixture<ToastListComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(
|
||||||
TestBed.configureTestingModule({
|
waitForAsync(() => {
|
||||||
declarations: [ToastListComponent],
|
void TestBed.configureTestingModule({
|
||||||
}).compileComponents();
|
declarations: [ToastListComponent],
|
||||||
}));
|
}).compileComponents();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ToastListComponent);
|
fixture = TestBed.createComponent(ToastListComponent);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe('ToastComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [ToastComponent],
|
declarations: [ToastComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { CustomError } from '@dafa-models/error/custom-error';
|
|||||||
})
|
})
|
||||||
export class ToastComponent implements AfterViewInit {
|
export class ToastComponent implements AfterViewInit {
|
||||||
@Input() error: CustomError;
|
@Input() error: CustomError;
|
||||||
@Output() closeToast: EventEmitter<CustomError> = new EventEmitter();
|
@Output() closeToast = new EventEmitter<CustomError>();
|
||||||
|
|
||||||
iconType = IconType;
|
iconType = IconType;
|
||||||
errorSeverity = ErrorSeverity;
|
errorSeverity = ErrorSeverity;
|
||||||
|
|||||||
@@ -24,21 +24,27 @@ export class CustomError implements Error {
|
|||||||
this.severity === ErrorSeverity.LOW ? 5000 : this.severity === ErrorSeverity.MEDIUM ? 10000 : 20000;
|
this.severity === ErrorSeverity.LOW ? 5000 : this.severity === ErrorSeverity.MEDIUM ? 10000 : 20000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getStack(error: Error): string {
|
static getStack(error: Error | { error: Error }): string {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (error.stack) {
|
|
||||||
|
if ('stack' in error) {
|
||||||
return error.stack;
|
return error.stack;
|
||||||
} else if ((error as any).error) {
|
} else if ('error' in error) {
|
||||||
return this.getStack((error as any).error);
|
return this.getStack(error.error);
|
||||||
} else {
|
} else {
|
||||||
return error as any;
|
return error as never;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getErrorType(error: Error): ErrorType {
|
static getErrorType(error: Error | (Error & { type: ErrorType })): ErrorType {
|
||||||
let type = (error as any).type || ErrorType.UNKNOWN;
|
let type: ErrorType;
|
||||||
|
if ('type' in error) {
|
||||||
|
type = error.type;
|
||||||
|
} else {
|
||||||
|
type = ErrorType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
if (error.name === 'HttpErrorResponse') {
|
if (error.name === 'HttpErrorResponse') {
|
||||||
type = ErrorType.API;
|
type = ErrorType.API;
|
||||||
@@ -48,20 +54,20 @@ export class CustomError implements Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function errorToCustomError(error: Error): CustomError {
|
export function errorToCustomError(error: Error & { ngDebugContext: unknown }): CustomError {
|
||||||
const type = CustomError.getErrorType(error);
|
const type = CustomError.getErrorType(error);
|
||||||
const message = error.message || (error as any);
|
const message = error.message || error;
|
||||||
const severity = ErrorSeverity.HIGH;
|
const severity = ErrorSeverity.HIGH;
|
||||||
|
|
||||||
// this is done to avoid circular references while running in debug mode
|
// this is done to avoid circular references while running in debug mode
|
||||||
if ((error as any).ngDebugContext) {
|
if ('ngDebugContext' in error) {
|
||||||
(error as any).ngDebugContext = {};
|
error.ngDebugContext = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CustomError({
|
return new CustomError({
|
||||||
error,
|
error,
|
||||||
type,
|
type,
|
||||||
severity,
|
severity,
|
||||||
message,
|
message: message as string,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { ErrorService } from '@dafa-services/error.service';
|
|||||||
export class CustomErrorHandler implements ErrorHandler {
|
export class CustomErrorHandler implements ErrorHandler {
|
||||||
constructor(private errorService: ErrorService) {}
|
constructor(private errorService: ErrorService) {}
|
||||||
|
|
||||||
handleError(error: any): void {
|
handleError(error: Error & { ngDebugContext: unknown }): void {
|
||||||
const customError: CustomError = errorToCustomError(error);
|
const customError: CustomError = errorToCustomError(error);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
this.errorService.add(customError);
|
this.errorService.add(customError);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('AdministrationComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [AdministrationComponent],
|
declarations: [AdministrationComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe('EmployeeCardComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [EmployeeCardComponent],
|
declarations: [EmployeeCardComponent],
|
||||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
})
|
})
|
||||||
export class EmployeeCardComponent {
|
export class EmployeeCardComponent {
|
||||||
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
|
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
|
||||||
private _employeeId$: Observable<string> = this.activatedRoute.params.pipe(map(({ employeeId }) => employeeId));
|
private _employeeId$: Observable<string> = this.activatedRoute.params.pipe(
|
||||||
authorizationsAsString$: Observable<string>;
|
map(({ employeeId }) => employeeId as string)
|
||||||
|
);
|
||||||
|
|
||||||
detailedEmployeeData$: Observable<Employee> = this._employeeId$.pipe(
|
detailedEmployeeData$: Observable<Employee> = this._employeeId$.pipe(
|
||||||
switchMap(employeeId => this.employeeService.fetchDetailedEmployeeData$(employeeId))
|
switchMap(employeeId => this.employeeService.fetchDetailedEmployeeData$(employeeId))
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('EmployeeFormComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [EmployeeFormComponent],
|
declarations: [EmployeeFormComponent],
|
||||||
imports: [
|
imports: [
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export class EmployeeFormComponent {
|
|||||||
map(services => services.map(({ name, id }) => ({ name, value: id })))
|
map(services => services.map(({ name, id }) => ({ name, value: id })))
|
||||||
);
|
);
|
||||||
toggleDialog = false;
|
toggleDialog = false;
|
||||||
modalAuthInfo: any = {'name': 'Test Behörighetsnamn'};
|
modalAuthInfo: { name: string } = { name: 'Test Behörighetsnamn' };
|
||||||
|
|
||||||
formGroup: FormGroup = this.formBuilder.group({
|
formGroup: FormGroup = this.formBuilder.group({
|
||||||
firstName: this.formBuilder.control('', [RequiredValidator('Förnamn')]),
|
firstName: this.formBuilder.control('', [RequiredValidator('Förnamn')]),
|
||||||
@@ -68,6 +68,7 @@ export class EmployeeFormComponent {
|
|||||||
|
|
||||||
return controlsWithErrors.map(key => ({
|
return controlsWithErrors.map(key => ({
|
||||||
id: key,
|
id: key,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
message: this.formGroup.controls[key].errors.message,
|
message: this.formGroup.controls[key].errors.message,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -80,7 +81,7 @@ export class EmployeeFormComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleAuthorization(authorization: Authorization, checked: boolean): void {
|
toggleAuthorization(authorization: Authorization, checked: boolean): void {
|
||||||
const currentAuthorizations = this.authorizationsControl.value;
|
const currentAuthorizations = this.authorizationsControl.value as { id: unknown }[];
|
||||||
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.authorizationsControl.patchValue([...currentAuthorizations, authorization]);
|
this.authorizationsControl.patchValue([...currentAuthorizations, authorization]);
|
||||||
@@ -92,7 +93,7 @@ export class EmployeeFormComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleService(service: Service, checked: boolean): void {
|
toggleService(service: Service, checked: boolean): void {
|
||||||
const currentServices = this.servicesControl.value;
|
const currentServices = this.servicesControl.value as { id: unknown }[];
|
||||||
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.servicesControl.patchValue([...currentServices, service]);
|
this.servicesControl.patchValue([...currentServices, service]);
|
||||||
@@ -101,8 +102,9 @@ export class EmployeeFormComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openDialog(val: boolean, authName?:any) {
|
openDialog(val: boolean, authName?: string): void {
|
||||||
if(authName) {
|
if (authName) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
this.modalAuthInfo.name = authName;
|
this.modalAuthInfo.name = authName;
|
||||||
}
|
}
|
||||||
this.toggleDialog = val;
|
this.toggleDialog = val;
|
||||||
@@ -127,12 +129,13 @@ export class EmployeeFormComponent {
|
|||||||
submitForm(): void {
|
submitForm(): void {
|
||||||
this.submitted = true;
|
this.submitted = true;
|
||||||
if (this.formGroup.valid) {
|
if (this.formGroup.valid) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const submittableValues = {
|
const submittableValues = {
|
||||||
...this.formGroup.value,
|
...this.formGroup.value,
|
||||||
};
|
};
|
||||||
const post = this.employeeService.postNewEmployee(submittableValues).subscribe({
|
const post = this.employeeService.postNewEmployee(submittableValues).subscribe({
|
||||||
next: id => {
|
next: id => {
|
||||||
this.router.navigate(['/administration', 'personal', id]);
|
void this.router.navigate(['/administration', 'personal', id]);
|
||||||
},
|
},
|
||||||
complete: () => {
|
complete: () => {
|
||||||
post.unsubscribe();
|
post.unsubscribe();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { EmployeesListComponent } from './employees-list.component';
|
import { EmployeesListComponent } from './employees-list.component';
|
||||||
@@ -12,7 +12,6 @@ describe('EmployeesListComponent', () => {
|
|||||||
let fixture: ComponentFixture<EmployeesListComponent>;
|
let fixture: ComponentFixture<EmployeesListComponent>;
|
||||||
const getEmployeeRows = () => fixture.debugElement.queryAll(By.css('.employees-list__row'));
|
const getEmployeeRows = () => fixture.debugElement.queryAll(By.css('.employees-list__row'));
|
||||||
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
@@ -31,17 +30,17 @@ describe('EmployeesListComponent', () => {
|
|||||||
describe('20 employees sorted by Full name Ascending', () => {
|
describe('20 employees sorted by Full name Ascending', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
component.employees = employeesMock;
|
component.employees = employeesMock;
|
||||||
component.paginationMeta = {count: employeesMock.length, limit: 50, page: 1, totalPages: 3};
|
component.paginationMeta = { count: employeesMock.length, limit: 50, page: 1, totalPages: 3 };
|
||||||
component.sort = {key: <keyof Employee>'fullName', order: SortOrder.ASC };
|
component.sort = { key: <keyof Employee>'fullName', order: SortOrder.ASC };
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should display the rows from employees object 20 rows regardless of pagination', () => {
|
it('should display the rows from employees object 20 rows regardless of pagination', () => {
|
||||||
expect(getEmployeeRows().length).toBe(20);
|
expect(getEmployeeRows().length).toBe(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the up caret next to Full name to indicate that it\'s sorted by full name Ascending', () => {
|
it('should display the up caret next to Full name to indicate that it´s sorted by full name Ascending', () => {
|
||||||
const fullNameUpCaret = fixture.debugElement.query(By.css('#sort-button-fullName > digi-icon-caret-up'));
|
const fullNameUpCaret = fixture.debugElement.query(By.css('#sort-button-fullName > digi-icon-caret-up'));
|
||||||
expect(fullNameUpCaret).toBeTruthy();
|
expect(fullNameUpCaret).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { Employee } from '@dafa-models/employee.model';
|
|||||||
import { PaginationMeta } from '@dafa-models/pagination-meta.model';
|
import { PaginationMeta } from '@dafa-models/pagination-meta.model';
|
||||||
import { Sort } from '@dafa-models/sort.model';
|
import { Sort } from '@dafa-models/sort.model';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dafa-employees-list',
|
selector: 'dafa-employees-list',
|
||||||
templateUrl: './employees-list.component.html',
|
templateUrl: './employees-list.component.html',
|
||||||
@@ -18,22 +17,36 @@ export class EmployeesListComponent {
|
|||||||
@Output() sorted = new EventEmitter<keyof Employee>();
|
@Output() sorted = new EventEmitter<keyof Employee>();
|
||||||
@Output() paginated = new EventEmitter<number>();
|
@Output() paginated = new EventEmitter<number>();
|
||||||
|
|
||||||
columnHeaders: {label: string, key: keyof Employee}[] = [{label: 'Namn', key: 'fullName'}, {label: 'Tjänst', key: 'services'}, {label: 'Utförandeverksamheter', key: 'organizations'}];
|
columnHeaders: { label: string; key: keyof Employee }[] = [
|
||||||
|
{ label: 'Namn', key: 'fullName' },
|
||||||
|
{
|
||||||
|
label: 'Tjänst',
|
||||||
|
key: 'services',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Utförandeverksamheter',
|
||||||
|
key: 'organizations',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
orderType = SortOrder;
|
orderType = SortOrder;
|
||||||
|
|
||||||
get currentPage(): number {
|
get currentPage(): number {
|
||||||
return this.paginationMeta.page;
|
return this.paginationMeta.page;
|
||||||
}
|
}
|
||||||
|
|
||||||
get totalPages(): number {
|
get totalPages(): number {
|
||||||
return this.paginationMeta?.totalPages;
|
return this.paginationMeta?.totalPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
get count(): number {
|
get count(): number {
|
||||||
return this.paginationMeta.count;
|
return this.paginationMeta.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentResultStart(): number {
|
get currentResultStart(): number {
|
||||||
return (this.currentPage - 1) * this.paginationMeta.limit + 1;
|
return (this.currentPage - 1) * this.paginationMeta.limit + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentResultEnd(): number {
|
get currentResultEnd(): number {
|
||||||
const end = this.currentResultStart + this.paginationMeta.limit - 1;
|
const end = this.currentResultStart + this.paginationMeta.limit - 1;
|
||||||
return end < this.count ? end : this.count;
|
return end < this.count ? end : this.count;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe('EmployeesComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [EmployeesComponent],
|
declarations: [EmployeesComponent],
|
||||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||||
@@ -25,6 +25,6 @@ describe('EmployeesComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
void expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export class EmployeesComponent {
|
|||||||
this.employeeService.setSearchFilter(this.searchValue);
|
this.employeeService.setSearchFilter(this.searchValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchValue($event: CustomEvent): void {
|
setSearchValue($event: CustomEvent<{ target: { value: string } }>): void {
|
||||||
this._searchValue$.next($event.detail.target.value);
|
this._searchValue$.next($event.detail.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { AvropService } from '../avrop.service';
|
import { AvropService } from '../avrop.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Deltagare } from '../models/Deltagare';
|
|
||||||
import { MultiselectFilterOption } from '../models/AvropFilterOptions';
|
import { MultiselectFilterOption } from '../models/AvropFilterOptions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -10,7 +9,7 @@ import { MultiselectFilterOption } from '../models/AvropFilterOptions';
|
|||||||
styleUrls: ['./avrop-filters.component.scss'],
|
styleUrls: ['./avrop-filters.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AvropFiltersComponent implements OnInit {
|
export class AvropFiltersComponent {
|
||||||
selectableTjanster$: Observable<MultiselectFilterOption[]> = this.avropService.selectableTjanster$;
|
selectableTjanster$: Observable<MultiselectFilterOption[]> = this.avropService.selectableTjanster$;
|
||||||
selectableUtforandeVerksamheter$: Observable<MultiselectFilterOption[]> = this.avropService
|
selectableUtforandeVerksamheter$: Observable<MultiselectFilterOption[]> = this.avropService
|
||||||
.selectableUtforandeVerksamheter$;
|
.selectableUtforandeVerksamheter$;
|
||||||
@@ -18,17 +17,15 @@ export class AvropFiltersComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private avropService: AvropService) {}
|
constructor(private avropService: AvropService) {}
|
||||||
|
|
||||||
ngOnInit(): void {}
|
updateSelectedTjanster(filterOptions: MultiselectFilterOption[]): void {
|
||||||
|
|
||||||
updateSelectedTjanster(filterOptions: MultiselectFilterOption[]) {
|
|
||||||
this.avropService.setSelectedTjanster(filterOptions);
|
this.avropService.setSelectedTjanster(filterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSelectedUtforandeVerksamheter(filterOptions: MultiselectFilterOption[]) {
|
updateSelectedUtforandeVerksamheter(filterOptions: MultiselectFilterOption[]): void {
|
||||||
this.avropService.setSelectedUtforandeVerksamheter(filterOptions);
|
this.avropService.setSelectedUtforandeVerksamheter(filterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSelectedKommuner(filterOptions: MultiselectFilterOption[]) {
|
updateSelectedKommuner(filterOptions: MultiselectFilterOption[]): void {
|
||||||
this.avropService.setSelectedKommuner(filterOptions);
|
this.avropService.setSelectedKommuner(filterOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy, Input, Output } from '@angular/core';
|
import { Component, OnInit, ChangeDetectionStrategy, Input, Output } from '@angular/core';
|
||||||
import { MultiselectFilterOption } from '../../models/AvropFilterOptions';
|
import { MultiselectFilterOption } from '../../models/AvropFilterOptions';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { Deltagare } from '../../models/Deltagare';
|
|
||||||
import { EventEmitter } from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -20,7 +19,6 @@ export class TemporaryFilterComponent implements OnInit {
|
|||||||
@Output() selectedOptionsChange = new EventEmitter<MultiselectFilterOption[]>();
|
@Output() selectedOptionsChange = new EventEmitter<MultiselectFilterOption[]>();
|
||||||
|
|
||||||
// THIS SHOULD BE REPLACED BY DIGI COMPONENT
|
// THIS SHOULD BE REPLACED BY DIGI COMPONENT
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._selectedAvropFilterOption$ = new BehaviorSubject<MultiselectFilterOption[]>(this.selectedOptions);
|
this._selectedAvropFilterOption$ = new BehaviorSubject<MultiselectFilterOption[]>(this.selectedOptions);
|
||||||
@@ -31,7 +29,7 @@ export class TemporaryFilterComponent implements OnInit {
|
|||||||
return this.selectedOptions?.includes(filterOption) ?? false;
|
return this.selectedOptions?.includes(filterOption) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptionState(filterOption: MultiselectFilterOption, isSelected: boolean) {
|
setOptionState(filterOption: MultiselectFilterOption, isSelected: boolean): void {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
return this._selectedAvropFilterOption$.next([...(this._selectedAvropFilterOption$.value ?? []), filterOption]);
|
return this._selectedAvropFilterOption$.next([...(this._selectedAvropFilterOption$.value ?? []), filterOption]);
|
||||||
}
|
}
|
||||||
@@ -40,7 +38,7 @@ export class TemporaryFilterComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitSelectedOptions() {
|
emitSelectedOptions(): void {
|
||||||
this.selectedOptionsChange.emit(this._selectedAvropFilterOption$.value);
|
this.selectedOptionsChange.emit(this._selectedAvropFilterOption$.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EventEmitter } from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
import { Component, OnInit, ChangeDetectionStrategy, Input, Output } from '@angular/core';
|
import { Component, ChangeDetectionStrategy, Input, Output } from '@angular/core';
|
||||||
import { Deltagare } from '../../models/Deltagare';
|
import { Deltagare } from '../../models/Deltagare';
|
||||||
import { Handledare } from '../../models/Handledare';
|
import { Handledare } from '../../models/Handledare';
|
||||||
|
|
||||||
@@ -9,18 +9,15 @@ import { Handledare } from '../../models/Handledare';
|
|||||||
styleUrls: ['./avrop-table-row.component.scss'],
|
styleUrls: ['./avrop-table-row.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AvropTableRowComponent implements OnInit {
|
export class AvropTableRowComponent {
|
||||||
@Input() deltagare: Deltagare;
|
@Input() deltagare: Deltagare;
|
||||||
@Input() isSelected: boolean;
|
@Input() isSelected: boolean;
|
||||||
@Input() isLocked: boolean;
|
@Input() isLocked: boolean;
|
||||||
@Output() isSelectedChange = new EventEmitter<boolean>();
|
@Output() isSelectedChange = new EventEmitter<boolean>();
|
||||||
@Input() handledare: Handledare;
|
@Input() handledare: Handledare;
|
||||||
@Input() handledareConfirmed: boolean;
|
@Input() handledareConfirmed: boolean;
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
ngOnInit(): void {}
|
emitSelectionChange(isSelected: boolean): void {
|
||||||
|
|
||||||
emitSelectionChange(isSelected: boolean) {
|
|
||||||
this.isSelectedChange.emit(isSelected);
|
this.isSelectedChange.emit(isSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ export class AvropTableComponent implements OnInit {
|
|||||||
return this.isLocked ? this.selectedDeltagareListInput : this.selectableDeltagareList;
|
return this.isLocked ? this.selectedDeltagareListInput : this.selectableDeltagareList;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._selectedDeltagare$
|
this._selectedDeltagare$
|
||||||
.pipe(filter(x => !!x))
|
.pipe(filter(x => !!x))
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('CallOffComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [AvropComponent],
|
declarations: [AvropComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
import { AvropService } from './avrop.service';
|
import { AvropService } from './avrop.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { MultiselectFilterOption } from './models/AvropFilterOptions';
|
import { MultiselectFilterOption } from './models/AvropFilterOptions';
|
||||||
@@ -11,7 +11,7 @@ import { Handledare } from './models/Handledare';
|
|||||||
styleUrls: ['./avrop.component.scss'],
|
styleUrls: ['./avrop.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AvropComponent implements OnInit {
|
export class AvropComponent {
|
||||||
steps = 3;
|
steps = 3;
|
||||||
|
|
||||||
currentStep$ = this.avropService.currentStep$;
|
currentStep$ = this.avropService.currentStep$;
|
||||||
@@ -27,41 +27,37 @@ export class AvropComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private avropService: AvropService) {}
|
constructor(private avropService: AvropService) {}
|
||||||
|
|
||||||
updateSelectedDeltagareList(deltagareList: Deltagare[]) {
|
updateSelectedDeltagareList(deltagareList: Deltagare[]): void {
|
||||||
this.avropService.setSelectedDeltagare(deltagareList);
|
this.avropService.setSelectedDeltagare(deltagareList);
|
||||||
}
|
}
|
||||||
|
|
||||||
lockSelectedDeltagare() {
|
lockSelectedDeltagare(): void {
|
||||||
this.avropService.lockSelectedDeltagare();
|
this.avropService.lockSelectedDeltagare();
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockSelectedDeltagare() {
|
unlockSelectedDeltagare(): void {
|
||||||
this.avropService.unlockSelectedDeltagare();
|
this.avropService.unlockSelectedDeltagare();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
confirmHandledare(): void {
|
||||||
// this.avropService.loadFromAPI();
|
|
||||||
}
|
|
||||||
|
|
||||||
confirmHandledare() {
|
|
||||||
this.avropService.confirmHandledare();
|
this.avropService.confirmHandledare();
|
||||||
}
|
}
|
||||||
|
|
||||||
unconfirmHandledare() {
|
unconfirmHandledare(): void {
|
||||||
this.avropService.unconfirmHandledare();
|
this.avropService.unconfirmHandledare();
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
async save(): Promise<void> {
|
||||||
this.avropService.save();
|
return this.avropService.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeHandledare(newHandledare: Event) {
|
changeHandledare(newHandledare: { target: HTMLInputElement }): void {
|
||||||
const handledareId = newHandledare.target['value'];
|
const handledareId = newHandledare.target.value;
|
||||||
|
|
||||||
this.avropService.setHandledareState(handledareId);
|
this.avropService.setHandledareState(handledareId);
|
||||||
}
|
}
|
||||||
|
|
||||||
goToStep1() {
|
goToStep1(): void {
|
||||||
this.avropService.goToStep1();
|
this.avropService.goToStep1();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,35 +109,35 @@ export class AvropService {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedDeltagare(deltagare: Deltagare[]) {
|
setSelectedDeltagare(deltagare: Deltagare[]): void {
|
||||||
this._selectedDeltagareList$.next(deltagare);
|
this._selectedDeltagareList$.next(deltagare);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private avropApiService: AvropApiService) {}
|
constructor(private avropApiService: AvropApiService) {}
|
||||||
|
|
||||||
lockSelectedDeltagare() {
|
lockSelectedDeltagare(): void {
|
||||||
if ((this._selectedDeltagareList$?.value?.length ?? -1) <= 0) {
|
if ((this._selectedDeltagareList$?.value?.length ?? -1) <= 0) {
|
||||||
throw new Error('För att låsa deltagare behöver några ha markerats först.');
|
throw new Error('För att låsa deltagare behöver några ha markerats först.');
|
||||||
}
|
}
|
||||||
this._deltagareListIsLocked$.next(true);
|
this._deltagareListIsLocked$.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockSelectedDeltagare() {
|
unlockSelectedDeltagare(): void {
|
||||||
this._deltagareListIsLocked$.next(false);
|
this._deltagareListIsLocked$.next(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmHandledare() {
|
confirmHandledare(): void {
|
||||||
if (!this._selectedHandledare$?.value) {
|
if (!this._selectedHandledare$?.value) {
|
||||||
throw new Error('För att kunna tilldela behövs en handledare väljas först.');
|
throw new Error('För att kunna tilldela behövs en handledare väljas först.');
|
||||||
}
|
}
|
||||||
this._handledareIsConfirmed$.next(true);
|
this._handledareIsConfirmed$.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
unconfirmHandledare() {
|
unconfirmHandledare(): void {
|
||||||
this._handledareIsConfirmed$.next(false);
|
this._handledareIsConfirmed$.next(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async save() {
|
async save(): Promise<void> {
|
||||||
if (!this._handledareIsConfirmed$) {
|
if (!this._handledareIsConfirmed$) {
|
||||||
throw new Error('Handledaren måste bekräftas innan avropet kan sparas');
|
throw new Error('Handledaren måste bekräftas innan avropet kan sparas');
|
||||||
}
|
}
|
||||||
@@ -148,27 +148,28 @@ export class AvropService {
|
|||||||
|
|
||||||
await this.avropApiService.tilldelaHandledare(this._selectedDeltagareList$.value, this._selectedHandledare$.value);
|
await this.avropApiService.tilldelaHandledare(this._selectedDeltagareList$.value, this._selectedHandledare$.value);
|
||||||
this._avropIsSaved$.next(true);
|
this._avropIsSaved$.next(true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setHandledareState(handledareId: string) {
|
setHandledareState(handledareId: string): void {
|
||||||
this.selectableHandledareList$.pipe(first()).subscribe(handledareList => {
|
this.selectableHandledareList$.pipe(first()).subscribe(handledareList => {
|
||||||
this._selectedHandledare$.next(handledareList.find(handledare => handledare.id === handledareId));
|
this._selectedHandledare$.next(handledareList.find(handledare => handledare.id === handledareId));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedTjanster(selectedFilterOptions: MultiselectFilterOption[]) {
|
setSelectedTjanster(selectedFilterOptions: MultiselectFilterOption[]): void {
|
||||||
this._selectedTjanster$.next(selectedFilterOptions);
|
this._selectedTjanster$.next(selectedFilterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedUtforandeVerksamheter(selectedFilterOptions: MultiselectFilterOption[]) {
|
setSelectedUtforandeVerksamheter(selectedFilterOptions: MultiselectFilterOption[]): void {
|
||||||
this._selectedUtforandeVerksamheter$.next(selectedFilterOptions);
|
this._selectedUtforandeVerksamheter$.next(selectedFilterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedKommuner(selectedFilterOptions: MultiselectFilterOption[]) {
|
setSelectedKommuner(selectedFilterOptions: MultiselectFilterOption[]): void {
|
||||||
this._selectedKommuner$.next(selectedFilterOptions);
|
this._selectedKommuner$.next(selectedFilterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
goToStep1() {
|
goToStep1(): void {
|
||||||
this._selectedHandledare$.next(null);
|
this._selectedHandledare$.next(null);
|
||||||
this._selectedDeltagareList$.next(null);
|
this._selectedDeltagareList$.next(null);
|
||||||
this._deltagareListIsLocked$.next(false);
|
this._deltagareListIsLocked$.next(false);
|
||||||
|
|||||||
@@ -7,32 +7,31 @@ import { AuthenticationService } from '@dafa-services/api/authentication.service
|
|||||||
selector: 'dafa-ciam-landing',
|
selector: 'dafa-ciam-landing',
|
||||||
templateUrl: './ciam-landing.component.html',
|
templateUrl: './ciam-landing.component.html',
|
||||||
styleUrls: ['./ciam-landing.component.scss'],
|
styleUrls: ['./ciam-landing.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class CiamLandingComponent implements OnInit {
|
export class CiamLandingComponent implements OnInit {
|
||||||
|
constructor(
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private authenticationService: AuthenticationService
|
||||||
|
) {}
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
ngOnInit(): void {
|
||||||
private router: Router,
|
this.route.queryParams
|
||||||
private authenticationService: AuthenticationService
|
.pipe(
|
||||||
) {
|
first(),
|
||||||
|
map(({ code }) => {
|
||||||
}
|
if (!code) {
|
||||||
|
throw new Error('Expected CIAM to return "code" in queryparams.');
|
||||||
ngOnInit() {
|
}
|
||||||
this.route.queryParams.pipe(
|
return code as string;
|
||||||
first(),
|
}),
|
||||||
map(({code}) => {
|
switchMap(code => {
|
||||||
if (!code) {
|
return this.authenticationService.login$(code);
|
||||||
throw new Error('Expected CIAM to return \'code\' in queryparams.');
|
})
|
||||||
}
|
)
|
||||||
return code as string;
|
|
||||||
}),
|
|
||||||
switchMap(code => {
|
|
||||||
return this.authenticationService.login$(code)
|
|
||||||
}))
|
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.router.navigateByUrl('/')
|
void this.router.navigateByUrl('/');
|
||||||
})
|
});
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
import { environment } from '@dafa-environment';
|
import { environment } from '@dafa-environment';
|
||||||
import { AuthenticationService } from '@dafa-services/api/authentication.service';
|
import { AuthenticationService } from '@dafa-services/api/authentication.service';
|
||||||
|
|
||||||
@@ -12,11 +11,7 @@ import { AuthenticationService } from '@dafa-services/api/authentication.service
|
|||||||
export class LogoutComponent implements OnInit {
|
export class LogoutComponent implements OnInit {
|
||||||
loginUrl = environment.loginUrl;
|
loginUrl = environment.loginUrl;
|
||||||
|
|
||||||
constructor(
|
constructor(private authenticationService: AuthenticationService) {}
|
||||||
private authenticationService: AuthenticationService
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.authenticationService.logout();
|
this.authenticationService.logout();
|
||||||
|
|||||||
@@ -3,15 +3,10 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { LogoutComponent } from './logout.component';
|
import { LogoutComponent } from './logout.component';
|
||||||
import { DigiNgButtonModule } from '@af/digi-ng/_button/button';
|
import { DigiNgButtonModule } from '@af/digi-ng/_button/button';
|
||||||
import { LoggedInShellModule } from '../../components/logged-in-shell/logged-in-shell.module';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [LogoutComponent],
|
declarations: [LogoutComponent],
|
||||||
imports: [
|
imports: [CommonModule, RouterModule.forChild([{ path: '', component: LogoutComponent }]), DigiNgButtonModule],
|
||||||
CommonModule,
|
|
||||||
RouterModule.forChild([{ path: '', component: LogoutComponent }]),
|
|
||||||
DigiNgButtonModule
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class LogoutModule {}
|
export class LogoutModule {}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('MessagesComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [MessagesComponent],
|
declarations: [MessagesComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('ReleasesComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
||||||
declarations: [MockLoginComponent],
|
declarations: [MockLoginComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -3,15 +3,10 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { MockLoginComponent } from './mock-login.component';
|
import { MockLoginComponent } from './mock-login.component';
|
||||||
import { DigiNgButtonModule } from '@af/digi-ng/_button/button';
|
import { DigiNgButtonModule } from '@af/digi-ng/_button/button';
|
||||||
import { LoggedInShellModule } from '../../components/logged-in-shell/logged-in-shell.module';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [MockLoginComponent],
|
declarations: [MockLoginComponent],
|
||||||
imports: [
|
imports: [CommonModule, RouterModule.forChild([{ path: '', component: MockLoginComponent }]), DigiNgButtonModule],
|
||||||
CommonModule,
|
|
||||||
RouterModule.forChild([{ path: '', component: MockLoginComponent }]),
|
|
||||||
DigiNgButtonModule
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class MockLoginModule {}
|
export class MockLoginModule {}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('PageNotFoundComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [PageNotFoundComponent],
|
declarations: [PageNotFoundComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
})
|
})
|
||||||
export class ParticipantCardComponent {
|
export class ParticipantCardComponent {
|
||||||
private _participantId$: Observable<string> = this.activatedRoute.params.pipe(
|
private _participantId$: Observable<string> = this.activatedRoute.params.pipe(
|
||||||
map(({ participantId }) => participantId)
|
map(({ participantId }) => participantId as string)
|
||||||
);
|
);
|
||||||
detailedParticipantData$: Observable<Participant> = this._participantId$.pipe(
|
detailedParticipantData$: Observable<Participant> = this._participantId$.pipe(
|
||||||
switchMap(participantId => this.participantsService.fetchDetailedParticipantData$(participantId))
|
switchMap(participantId => this.participantsService.fetchDetailedParticipantData$(participantId))
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { BackLinkModule } from '@dafa-shared/components/back-link/back-link.module';
|
import { BackLinkModule } from '@dafa-shared/components/back-link/back-link.module';
|
||||||
import { IconModule } from '@dafa-shared/components/icon/icon.module';
|
import { IconModule } from '@dafa-shared/components/icon/icon.module';
|
||||||
import { LoggedInShellModule } from 'apps/dafa-web/src/app/components/logged-in-shell/logged-in-shell.module';
|
|
||||||
import { ParticipantCardComponent } from './participant-card.component';
|
import { ParticipantCardComponent } from './participant-card.component';
|
||||||
|
import { LoggedInShellModule } from '../../../../components/logged-in-shell/logged-in-shell.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ describe('ParticipantsComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [ParticipantsComponent],
|
declarations: [ParticipantsComponent],
|
||||||
imports: [RouterTestingModule, HttpClientTestingModule, DigiNgSkeletonBaseModule, ParticipantsListModule],
|
imports: [RouterTestingModule, HttpClientTestingModule, DigiNgSkeletonBaseModule, ParticipantsListModule],
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export class ParticipantsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSearchInput($event: CustomEvent): void {
|
handleSearchInput($event: CustomEvent): void {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
this._searchValue$.next($event.detail.target.value);
|
this._searchValue$.next($event.detail.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('ReleasesComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
||||||
declarations: [ReleasesComponent],
|
declarations: [ReleasesComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('SettingsComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [SettingsComponent],
|
declarations: [SettingsComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('StartComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [StartComponent],
|
declarations: [StartComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
import { CardHeadingLevel, CardVariation } from '@af/digi-ng/_card/card';
|
|
||||||
import {
|
|
||||||
NotificationAlertHeadingLevel,
|
|
||||||
NotificationAlertSize,
|
|
||||||
NotificationAlertVariation,
|
|
||||||
} from '@af/digi-ng/_notification/notification-alert';
|
|
||||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
import { InfoCardHeadingLevel } from '@digi/core/dist/types/components/_info-card/info-card/info-card-heading-level.enum';
|
|
||||||
import { InfoCardType } from '@digi/core/dist/types/components/_info-card/info-card/info-card-type.enum';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dafa-start',
|
selector: 'dafa-start',
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('StatisticsComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
declarations: [StatisticsComponent],
|
declarations: [StatisticsComponent],
|
||||||
imports: [RouterTestingModule],
|
imports: [RouterTestingModule],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
import { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AuthenticationService } from './authentication.service';
|
import { AuthenticationService } from './authentication.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthInterceptor implements HttpInterceptor {
|
export class AuthInterceptor implements HttpInterceptor {
|
||||||
|
constructor(private auth: AuthenticationService) {}
|
||||||
|
|
||||||
constructor(private auth: AuthenticationService) {
|
intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||||
}
|
|
||||||
|
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler) {
|
|
||||||
const idToken = this.auth.getAuthorizationToken();
|
const idToken = this.auth.getAuthorizationToken();
|
||||||
|
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
const cloned = req.clone({
|
const cloned = req.clone({
|
||||||
headers: req.headers.set('Authorization', 'Bearer ' + idToken)
|
headers: req.headers.set('Authorization', 'Bearer ' + idToken),
|
||||||
});
|
});
|
||||||
|
|
||||||
return next.handle(cloned);
|
return next.handle(cloned);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return next.handle(req);
|
return next.handle(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ import { map, tap } from 'rxjs/operators';
|
|||||||
import {
|
import {
|
||||||
AuthenticationApiResponse,
|
AuthenticationApiResponse,
|
||||||
AuthenticationResult,
|
AuthenticationResult,
|
||||||
mapAuthApiResponseToAuthenticationResult
|
mapAuthApiResponseToAuthenticationResult,
|
||||||
} from '@dafa-models/authentication.model';
|
} from '@dafa-models/authentication.model';
|
||||||
import { add, isBefore } from 'date-fns';
|
import { add, isBefore } from 'date-fns';
|
||||||
|
|
||||||
const API_HEADERS = { headers: environment.api.headers };
|
const API_HEADERS = { headers: environment.api.headers };
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AuthenticationService {
|
export class AuthenticationService {
|
||||||
private static _authTokenApiUrl(code: string): string {
|
private static _authTokenApiUrl(code: string): string {
|
||||||
return `${environment.api.url}/get-token?code=${code}`;
|
return `${environment.api.url}/get-token?code=${code}`;
|
||||||
};
|
}
|
||||||
|
|
||||||
private static _setSession(authenticationResult: AuthenticationResult): void {
|
private static _setSession(authenticationResult: AuthenticationResult): void {
|
||||||
const expiresAt = add(new Date(), { seconds: authenticationResult.expiresIn });
|
const expiresAt = add(new Date(), { seconds: authenticationResult.expiresIn });
|
||||||
@@ -52,16 +52,13 @@ export class AuthenticationService {
|
|||||||
|
|
||||||
getExpiration(): number {
|
getExpiration(): number {
|
||||||
const expiration = localStorage.getItem('expires_at');
|
const expiration = localStorage.getItem('expires_at');
|
||||||
const expiresAt = JSON.parse(expiration);
|
return JSON.parse(expiration) as number;
|
||||||
return expiresAt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) {
|
constructor(private httpClient: HttpClient) {}
|
||||||
}
|
|
||||||
|
|
||||||
logout(): void {
|
logout(): void {
|
||||||
localStorage.removeItem('id_token');
|
localStorage.removeItem('id_token');
|
||||||
localStorage.removeItem('expires_at');
|
localStorage.removeItem('expires_at');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ const tempTjansterMock: MultiselectFilterOption[] = [
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AvropApiService {
|
export class AvropApiService {
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
getNyaDeltagare$(
|
getNyaDeltagare$(
|
||||||
tjanstIds: MultiselectFilterOption[],
|
tjanstIds: MultiselectFilterOption[],
|
||||||
kommunIds: MultiselectFilterOption[],
|
kommunIds: MultiselectFilterOption[],
|
||||||
@@ -98,8 +96,9 @@ export class AvropApiService {
|
|||||||
return of(tempKommunerMock).pipe(delay(300));
|
return of(tempKommunerMock).pipe(delay(300));
|
||||||
}
|
}
|
||||||
|
|
||||||
async tilldelaHandledare(deltagare: Deltagare[], handledare: Handledare) {
|
async tilldelaHandledare(deltagare: Deltagare[], handledare: Handledare): Promise<void> {
|
||||||
console.log('[API call] SAVE avrop. Inputs: deltagare, handledare', deltagare, handledare);
|
console.log('[API call] SAVE avrop. Inputs: deltagare, handledare', deltagare, handledare);
|
||||||
|
await of(null).pipe(delay(200)).toPromise();
|
||||||
// TODO anropa API
|
// TODO anropa API
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ export class EmployeeService {
|
|||||||
public sort$: Observable<Sort<keyof Employee>> = this._sort$.asObservable();
|
public sort$: Observable<Sort<keyof Employee>> = this._sort$.asObservable();
|
||||||
private _searchFilter$ = new BehaviorSubject<string>('');
|
private _searchFilter$ = new BehaviorSubject<string>('');
|
||||||
|
|
||||||
|
public employeesData$: Observable<EmployeesData> = combineLatest([
|
||||||
|
this._limit$,
|
||||||
|
this._page$,
|
||||||
|
this._sort$,
|
||||||
|
this._searchFilter$,
|
||||||
|
]).pipe(switchMap(([limit, page, sort, searchFilter]) => this._fetchEmployees$(limit, page, sort, searchFilter)));
|
||||||
|
|
||||||
private _fetchEmployees$(
|
private _fetchEmployees$(
|
||||||
limit: number,
|
limit: number,
|
||||||
page: number,
|
page: number,
|
||||||
@@ -57,13 +64,6 @@ export class EmployeeService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public employeesData$: Observable<EmployeesData> = combineLatest([
|
|
||||||
this._limit$,
|
|
||||||
this._page$,
|
|
||||||
this._sort$,
|
|
||||||
this._searchFilter$,
|
|
||||||
]).pipe(switchMap(([limit, page, sort, searchFilter]) => this._fetchEmployees$(limit, page, sort, searchFilter)));
|
|
||||||
|
|
||||||
public fetchDetailedEmployeeData$(id: string): Observable<Employee> {
|
public fetchDetailedEmployeeData$(id: string): Observable<Employee> {
|
||||||
return this.httpClient
|
return this.httpClient
|
||||||
.get<EmployeeApiResponse>(`${this._apiUrl}/${id}`, { ...API_HEADERS })
|
.get<EmployeeApiResponse>(`${this._apiUrl}/${id}`, { ...API_HEADERS })
|
||||||
@@ -72,25 +72,28 @@ export class EmployeeService {
|
|||||||
|
|
||||||
constructor(private httpClient: HttpClient) {}
|
constructor(private httpClient: HttpClient) {}
|
||||||
|
|
||||||
public setSearchFilter(value: string) {
|
public setSearchFilter(value: string): void {
|
||||||
this._searchFilter$.next(value);
|
this._searchFilter$.next(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSort(newSortKey: keyof Employee) {
|
public setSort(newSortKey: keyof Employee): void {
|
||||||
const currentSort = this._sort$.getValue();
|
const currentSort = this._sort$.getValue();
|
||||||
let order = currentSort.key === newSortKey && currentSort.order === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const order =
|
||||||
|
currentSort.key === newSortKey && currentSort.order === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
||||||
|
|
||||||
this._sort$.next({ key: newSortKey, order });
|
this._sort$.next({ key: newSortKey, order });
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPage(page: number) {
|
public setPage(page: number): void {
|
||||||
this._page$.next(page);
|
this._page$.next(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public postNewEmployee(employeeData: Employee): Observable<string> {
|
public postNewEmployee(employeeData: Employee): Observable<string> {
|
||||||
return this.httpClient.post<any>(this._apiUrl, mapEmployeeToEmployeeApiRequestData(employeeData), API_HEADERS).pipe(
|
return this.httpClient
|
||||||
map(({ id }) => id),
|
.post<{ id: string }>(this._apiUrl, mapEmployeeToEmployeeApiRequestData(employeeData), API_HEADERS)
|
||||||
catchError(error => throwError({ message: error, type: ErrorType.API }))
|
.pipe(
|
||||||
);
|
map(({ id }) => id),
|
||||||
|
catchError(error => throwError({ message: error as string, type: ErrorType.API }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,11 +83,11 @@ export class ParticipantsService {
|
|||||||
.pipe(map(result => mapParticipantApiResponseToParticipant(result.data)));
|
.pipe(map(result => mapParticipantApiResponseToParticipant(result.data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSearchFilter(value: string) {
|
public setSearchFilter(value: string): void {
|
||||||
this._searchFilter$.next(value);
|
this._searchFilter$.next(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setActiveParticipantsSortKey(key: keyof Participant) {
|
public setActiveParticipantsSortKey(key: keyof Participant): void {
|
||||||
const currentSortBy = this._activeParticipantsSortBy$.getValue();
|
const currentSortBy = this._activeParticipantsSortBy$.getValue();
|
||||||
let order = currentSortBy.order;
|
let order = currentSortBy.order;
|
||||||
if (currentSortBy?.key === key) {
|
if (currentSortBy?.key === key) {
|
||||||
@@ -96,7 +96,7 @@ export class ParticipantsService {
|
|||||||
this._activeParticipantsSortBy$.next({ key, order });
|
this._activeParticipantsSortBy$.next({ key, order });
|
||||||
}
|
}
|
||||||
|
|
||||||
public setFollowUpParticipantsSortKey(key: keyof Participant) {
|
public setFollowUpParticipantsSortKey(key: keyof Participant): void {
|
||||||
const currentSortBy = this._followUpParticipantsSortBy$.getValue();
|
const currentSortBy = this._followUpParticipantsSortBy$.getValue();
|
||||||
let order = currentSortBy.order;
|
let order = currentSortBy.order;
|
||||||
if (currentSortBy?.key === key) {
|
if (currentSortBy?.key === key) {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { map } from 'rxjs/operators';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ErrorService {
|
export class ErrorService {
|
||||||
private appRef: any;
|
private appRef: ApplicationRef;
|
||||||
private errorQueue$: BehaviorSubject<CustomError[]> = new BehaviorSubject([]);
|
private errorQueue$ = new BehaviorSubject<CustomError[]>([]);
|
||||||
|
|
||||||
public errors$: Observable<CustomError[]> = this.errorQueue$.pipe(
|
public errors$: Observable<CustomError[]> = this.errorQueue$.pipe(
|
||||||
map(errors => errors.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1)))
|
map(errors => errors.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1)))
|
||||||
@@ -20,12 +20,12 @@ export class ErrorService {
|
|||||||
setTimeout(() => (this.appRef = this.injector.get(ApplicationRef)));
|
setTimeout(() => (this.appRef = this.injector.get(ApplicationRef)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public add(error: CustomError) {
|
public add(error: CustomError): void {
|
||||||
this.errorQueue$.next([...this.errorQueue$.value, error]);
|
this.errorQueue$.next([...this.errorQueue$.value, error]);
|
||||||
this.appRef.tick();
|
this.appRef.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public remove(error: CustomError) {
|
public remove(error: CustomError): void {
|
||||||
const newErrorQueue = this.errorQueue$.value.filter(currentError => currentError.id !== error.id);
|
const newErrorQueue = this.errorQueue$.value.filter(currentError => currentError.id !== error.id);
|
||||||
this.errorQueue$.next(newErrorQueue);
|
this.errorQueue$.next(newErrorQueue);
|
||||||
this.appRef.tick();
|
this.appRef.tick();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('BackLinkComponent', () => {
|
|||||||
let fixture: ComponentFixture<BackLinkComponent>;
|
let fixture: ComponentFixture<BackLinkComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [BackLinkComponent],
|
declarations: [BackLinkComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
/* tslint:disable:no-unused-variable */
|
/* tslint:disable:no-unused-variable */
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { IconComponent } from './icon.component';
|
import { IconComponent } from './icon.component';
|
||||||
|
|
||||||
describe('IconComponent', () => {
|
describe('IconComponent', () => {
|
||||||
let component: IconComponent;
|
let component: IconComponent;
|
||||||
let fixture: ComponentFixture<IconComponent>;
|
let fixture: ComponentFixture<IconComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
void TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [IconComponent],
|
declarations: [IconComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(IconComponent);
|
fixture = TestBed.createComponent(IconComponent);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Navigation } from '@dafa-constants/navigation';
|
import { Navigation } from '@dafa-constants/navigation';
|
||||||
|
|
||||||
export function mapPathToPageName(path: string): string {
|
export function mapPathToPageName(path: string): string {
|
||||||
return Navigation[path] || `${path.charAt(0).toUpperCase()}${path.slice(1)}`;
|
return (Navigation[path] || `${path.charAt(0).toUpperCase()}${path.slice(1)}`) as string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ export function SocialSecurityNumberValidator(): ValidatorFn {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ssn = control.value;
|
const ssn = control.value as string;
|
||||||
|
|
||||||
if (/[^0-9-]/g.test(ssn)) {
|
if (/[^0-9-]/g.test(ssn)) {
|
||||||
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
}
|
}
|
||||||
|
|
||||||
let strippedSsn = control.value.replace(/[^0-9]/g, '');
|
let strippedSsn = ssn.replace(/[^0-9]/g, '');
|
||||||
|
|
||||||
// Year format 1991 -> 91
|
// Year format 1991 -> 91
|
||||||
if (strippedSsn.length === 12) {
|
if (strippedSsn.length === 12) {
|
||||||
@@ -26,14 +26,14 @@ export function SocialSecurityNumberValidator(): ValidatorFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check month
|
// Check month
|
||||||
if (strippedSsn.substr(2, 2) > 12 || strippedSsn.substr(2, 2) === '00') {
|
if (+strippedSsn.substr(2, 2) > 12 || strippedSsn.substr(2, 2) === '00') {
|
||||||
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check date (valid date + 60 is also apporved because of co-ordination number)
|
// Check date (valid date + 60 is also apporved because of co-ordination number)
|
||||||
if (
|
if (
|
||||||
(strippedSsn.substr(4, 2) > 31 || strippedSsn.substr(4, 2) === '00') &&
|
(+strippedSsn.substr(4, 2) > 31 || strippedSsn.substr(4, 2) === '00') &&
|
||||||
(strippedSsn.substr(4, 2) > 91 || strippedSsn.substr(4, 2) <= 60)
|
(+strippedSsn.substr(4, 2) > 91 || +strippedSsn.substr(4, 2) <= 60)
|
||||||
) {
|
) {
|
||||||
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
loginUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/oauth2/authorization?response_type=code&scope=openid&redirect_uri=https://localhost:4200/ciam-landing&client_id=5d08c2e4-763e-42f6-b858-24e4773bb83d',
|
loginUrl:
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
'https://ciam-test.arbetsformedlingen.se:8443/uas/oauth2/authorization?response_type=code&scope=openid&redirect_uri=https://localhost:4200/ciam-landing&client_id=5d08c2e4-763e-42f6-b858-24e4773bb83d',
|
||||||
production: false,
|
production: false,
|
||||||
api: {
|
api: {
|
||||||
url: '/api',
|
url: '/api',
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ platformBrowserDynamic()
|
|||||||
.bootstrapModule(AppModule)
|
.bootstrapModule(AppModule)
|
||||||
.catch(err => console.error(err));
|
.catch(err => console.error(err));
|
||||||
|
|
||||||
defineCustomElements();
|
void defineCustomElements();
|
||||||
|
|||||||
1871
package-lock.json
generated
1871
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@af/auth": "^11.1.0",
|
"@af/auth": "^11.1.0",
|
||||||
"@af/digi-ng": "^14.0.0",
|
"@af/digi-ng": "^14.0.0",
|
||||||
|
"@angular-eslint/schematics": "^1.2.0",
|
||||||
"@angular/animations": "^11.2.0",
|
"@angular/animations": "^11.2.0",
|
||||||
"@angular/cdk": "^11.2.12",
|
"@angular/cdk": "^11.2.12",
|
||||||
"@angular/common": "^11.2.0",
|
"@angular/common": "^11.2.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user