feat(export): Added export deltagare. (TV-872)
Squashed commit of the following: commit 9c06b7f1d44a4b48d7f31a22b6bfbd233e09d2f7 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 15:07:15 2021 +0100 Updated api endpoint commit f9bfbecda6d03b70d87febbada920d0eca798b1f Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 15:01:13 2021 +0100 Updated libs commit 9edb413d537288fa0708b8a04eb54f801ebc23a0 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:58:13 2021 +0100 Added @types/file-saver commit 624affac55ce771fd58e2770a0d4a98233a8e9ba Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:42:29 2021 +0100 Updated libs commit 65dae1d906bbcec474581692b2aced9e47d2484c Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:36:42 2021 +0100 Added utils lib config commit 223bd59724663523bdbaf87b5502396156ddb9eb Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 14:06:13 2021 +0100 Added validation commit 166dfcf0448155ac21c0eaa904b4ce1271f73193 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 13:25:35 2021 +0100 Changed styling and removed some fake data commit 3906f2793dd52b626b95c13e115495451332c894 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 13:18:52 2021 +0100 Added digi-ng datepicker commit de0d51434d15cac5476303d4b417c591da16fd8f Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Nov 2 12:31:48 2021 +0100 Added checkbox
This commit is contained in:
22
angular.json
22
angular.json
@@ -244,6 +244,28 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"projectType": "library",
|
||||
"root": "libs/utils",
|
||||
"sourceRoot": "libs/utils/src",
|
||||
"prefix": "mina-sidor-fa-web",
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": ["libs/utils/src/**/*.ts", "libs/utils/src/**/*.html"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/libs/utils"],
|
||||
"options": {
|
||||
"jestConfig": "libs/utils/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
@@ -23,8 +23,8 @@ import { UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model';
|
||||
import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
|
||||
import { ValidationErrorLink } from '@msfa-shared/components/error-list/error-list.component';
|
||||
import { TreeNodesSelectorService } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { EmployeeValidator } from '@msfa-utils/validators/employee.validator';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
import { EmployeeFormService } from '../services/employee-form.service';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ExportsComponent } from './exports.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', data: { title: 'Exporter' }, component: ExportsComponent },
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'deltagare',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'deltagare',
|
||||
data: { title: 'Skapa export för deltagare' },
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
<digi-typography>
|
||||
<header class="exports__header">
|
||||
<h1>Exporter</h1>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut corporis voluptatum magnam cumque fugiat, neque, totam explicabo est reprehenderit perspiciatis ratione error ad eveniet inventore, tempora facilis nostrum earum! Unde!</p>
|
||||
</header>
|
||||
<main class="exports__contents"></main>
|
||||
<main class="exports__contents">
|
||||
|
||||
</main>
|
||||
</digi-typography>
|
||||
</section>
|
||||
</msfa-layout>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { ExportsRoutingModule } from './exports-routing.module';
|
||||
import { ExportsComponent } from './exports.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ExportsComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: ExportsComponent }]), LayoutModule],
|
||||
imports: [CommonModule, ExportsRoutingModule, LayoutModule, ReactiveFormsModule],
|
||||
})
|
||||
export class ExportsModule {}
|
||||
|
||||
@@ -1,10 +1,62 @@
|
||||
<msfa-layout>
|
||||
<section class="deltagare-export">
|
||||
<digi-typography>
|
||||
<digi-typography>
|
||||
<header class="deltagare-export__header">
|
||||
<h1>Deltagare export</h1>
|
||||
<h1>Exportera information om deltagare</h1>
|
||||
<p>
|
||||
Här kan du exportera deltagarinformation. Informationen laddas ner till din dator i CSV-format. Du kan endast
|
||||
exportera deltagare som du har behörighet att se. Detta innebär att du bara kan få ut de deltagare som är
|
||||
kopplade till samma utförande verksamhet och adress som du är inloggad på. Du kan även välja att inkludera
|
||||
deltagare som exporterats vid tidigare tillfälle. Deltagare som exporterats tidigare markeras i filen.
|
||||
</p>
|
||||
</header>
|
||||
<main class="deltagare-export__contents"></main>
|
||||
<form class="deltagare-export__form" [formGroup]="formGroup" (ngSubmit)="fetchExportFile()">
|
||||
<div
|
||||
class="deltagare-export__period-wrapper"
|
||||
[ngClass]="{'deltagare-export__period-wrapper--error': showPeriodError}"
|
||||
>
|
||||
<div class="deltagare-export__period-inputs">
|
||||
<digi-ng-form-datepicker
|
||||
[afDisableValidStyle]="true"
|
||||
[afMaxDate]="maxDate"
|
||||
[afInvalid]="showPeriodError"
|
||||
afLabel="Från datum"
|
||||
[formControl]="startDateFormControl"
|
||||
></digi-ng-form-datepicker>
|
||||
<digi-ng-form-datepicker
|
||||
[afDisableValidStyle]="true"
|
||||
[afMaxDate]="maxDate"
|
||||
[afInvalid]="showPeriodError"
|
||||
afLabel="Till och med datum"
|
||||
[formControl]="endDateFormControl"
|
||||
></digi-ng-form-datepicker>
|
||||
</div>
|
||||
<div aria-atomic="true" role="alert">
|
||||
<digi-form-validation-message *ngIf="showPeriodError" af-variation="error"
|
||||
>{{formErrors.datesMismatch}}</digi-form-validation-message
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<ui-checkbox
|
||||
[formControl]="includeExportedDeltagareFormControl"
|
||||
uiLabel="Inkludera redan exporterade deltagare"
|
||||
></ui-checkbox>
|
||||
<footer class="deltagare-export__footer">
|
||||
<digi-notification-alert
|
||||
*ngIf="fetchError$ | async as error"
|
||||
class="deltagare-export__alert"
|
||||
af-variation="danger"
|
||||
af-heading="Någonting gick fel"
|
||||
>
|
||||
<p>Kunde inte hämta exportfilen för deltagare. Ladda om sidan och försök igen.</p>
|
||||
<p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p>
|
||||
</digi-notification-alert>
|
||||
<div class="deltagare-export__cta-wrapper">
|
||||
<digi-button af-type="submit" af-size="m">Exportera deltagare</digi-button>
|
||||
</div>
|
||||
</footer>
|
||||
</form>
|
||||
</digi-typography>
|
||||
</section>
|
||||
<ui-loader *ngIf="fetchIsLoading$ | async" uiType="absolute"></ui-loader>
|
||||
</section>
|
||||
</msfa-layout>
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/z-index';
|
||||
|
||||
.deltagare-export {
|
||||
&__contents {
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
position: relative;
|
||||
z-index: $msfa__z-index-default;
|
||||
|
||||
&__form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $digi--layout--gutter--l;
|
||||
margin-top: $digi--layout--gutter--l;
|
||||
}
|
||||
|
||||
&__period-inputs {
|
||||
display: flex;
|
||||
gap: $digi--layout--gutter--xl;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--digi--layout--gutter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { UiCheckboxModule } from '@ui/checkbox/checkbox.module';
|
||||
import { DeltagareExportComponent } from './deltagare-export.component';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
|
||||
describe('DeltagareExportComponent', () => {
|
||||
let component: DeltagareExportComponent;
|
||||
@@ -13,7 +17,15 @@ describe('DeltagareExportComponent', () => {
|
||||
void TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareExportComponent],
|
||||
imports: [HttpClientTestingModule, RouterTestingModule],
|
||||
imports: [
|
||||
HttpClientTestingModule,
|
||||
RouterTestingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
DigiNgFormDatepickerModule,
|
||||
UiCheckboxModule,
|
||||
],
|
||||
providers: [DeltagareExportService],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { CustomError } from '@msfa-models/error/custom-error';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { DeltagareExportFormData, DeltagareExportFormErrors } from './deltagare-export.model';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
import { DeltagareExportValidator } from './deltagare-export.validator';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-deltagare-export',
|
||||
@@ -6,4 +15,80 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
styleUrls: ['./deltagare-export.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagareExportComponent {}
|
||||
export class DeltagareExportComponent {
|
||||
maxDate = new Date();
|
||||
shouldValidate$ = new BehaviorSubject<boolean>(false);
|
||||
fetchIsLoading$ = new BehaviorSubject<boolean>(false);
|
||||
fetchError$ = new BehaviorSubject<CustomError>(null);
|
||||
formGroup = new FormGroup(
|
||||
{
|
||||
startDate: new FormControl(null),
|
||||
endDate: new FormControl(null),
|
||||
includeExportedDeltagare: new FormControl(false),
|
||||
},
|
||||
[DeltagareExportValidator.isDeltagareExportValid()]
|
||||
);
|
||||
constructor(private deltagareExportService: DeltagareExportService) {}
|
||||
|
||||
get startDateFormControl(): FormControl {
|
||||
return this.formGroup.get('startDate') as FormControl;
|
||||
}
|
||||
get endDateFormControl(): FormControl {
|
||||
return this.formGroup.get('endDate') as FormControl;
|
||||
}
|
||||
get includeExportedDeltagareFormControl(): FormControl {
|
||||
return this.formGroup.get('includeExportedDeltagare') as FormControl;
|
||||
}
|
||||
|
||||
get deltagagareExportFormData(): DeltagareExportFormData {
|
||||
return this.formGroup.value as DeltagareExportFormData;
|
||||
}
|
||||
|
||||
get formErrors(): DeltagareExportFormErrors {
|
||||
return this.formGroup.errors as DeltagareExportFormErrors;
|
||||
}
|
||||
|
||||
get showPeriodError(): boolean {
|
||||
return this.formErrors?.datesMismatch && this.shouldValidate$.getValue();
|
||||
}
|
||||
|
||||
fetchExportFile(): void {
|
||||
if (this.formGroup.invalid) {
|
||||
this.shouldValidate$.next(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const requestData = this._formDataToRequestData(this.deltagagareExportFormData);
|
||||
|
||||
this.fetchIsLoading$.next(true);
|
||||
this.deltagareExportService
|
||||
.fetchExportFile$(requestData)
|
||||
.pipe(take(1))
|
||||
.subscribe({
|
||||
next: response => {
|
||||
const blob = new Blob([response], { type: 'application/csv' });
|
||||
saveAs(blob, 'deltagare-export.csv');
|
||||
this.fetchIsLoading$.next(false);
|
||||
},
|
||||
error: (customError: CustomError) => {
|
||||
this.fetchError$.next({ ...customError, message: customError.error.message });
|
||||
this.fetchIsLoading$.next(false);
|
||||
throw { ...customError, avoidToast: true };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _formDataToRequestData(formData: DeltagareExportFormData): DeltagareExportRequest {
|
||||
const { startDate, endDate, includeExportedDeltagare } = formData;
|
||||
const requestData: DeltagareExportRequest = {
|
||||
includeExportedDeltagare,
|
||||
};
|
||||
if (startDate) {
|
||||
requestData.startDate = startDate;
|
||||
}
|
||||
if (endDate) {
|
||||
requestData.endDate = endDate;
|
||||
}
|
||||
return requestData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface DeltagareExportFormData {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
includeExportedDeltagare: boolean;
|
||||
}
|
||||
|
||||
export type DeltagareExportFormKeys = keyof DeltagareExportFormData;
|
||||
|
||||
export interface DeltagareExportFormErrors {
|
||||
datesMismatch?: string;
|
||||
}
|
||||
@@ -1,12 +1,27 @@
|
||||
import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { UiCheckboxModule } from '@ui/checkbox/checkbox.module';
|
||||
import { UiLoaderModule } from '@ui/loader/loader.module';
|
||||
import { DeltagareExportComponent } from './deltagare-export.component';
|
||||
import { DeltagareExportService } from './deltagare-export.service';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareExportComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: DeltagareExportComponent }]), LayoutModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{ path: '', component: DeltagareExportComponent }]),
|
||||
LayoutModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
UiCheckboxModule,
|
||||
UiLoaderModule,
|
||||
DigiNgFormDatepickerModule,
|
||||
],
|
||||
providers: [DeltagareExportService],
|
||||
})
|
||||
export class DeltagareExportModule {}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { ExportApiService } from '@msfa-services/api/export.api.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class DeltagareExportService {
|
||||
constructor(private exportApiService: ExportApiService) {}
|
||||
|
||||
public fetchExportFile$(requestData: DeltagareExportRequest): Observable<Blob> {
|
||||
return this.exportApiService.fetchDeltagareExportFile$(requestData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
import { DeltagareExportFormData, DeltagareExportFormErrors } from './deltagare-export.model';
|
||||
|
||||
export class DeltagareExportValidator {
|
||||
static isDeltagareExportValid(): ValidatorFn {
|
||||
return (c: AbstractControl): DeltagareExportFormErrors => {
|
||||
let errors: DeltagareExportFormErrors = null;
|
||||
const { startDate, endDate } = c.value as DeltagareExportFormData;
|
||||
|
||||
if (startDate && endDate && startDate > endDate) {
|
||||
errors = {
|
||||
...errors,
|
||||
datesMismatch: 'Från datum får inte vara senare än till och med datum',
|
||||
};
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { DropdownTriggerForDirective } from '@msfa-shared/components/dropdown/dropdown-trigger-for.directive';
|
||||
import { MultiselectFilterOption } from '@msfa-shared/components/multiselect/multiselect-filter-option';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
|
||||
interface PropagateChangeFn {
|
||||
(_: unknown): void;
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
import { TreeNode, TreeNodeModel, TreeNodesSelectorService } from '../../services/tree-nodes-selector.service';
|
||||
import { TreeNodesSelectorPanelComponent } from '../tree-nodes-selector-panel/tree-nodes-selector-panel.component';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { uuid } from '@msfa-utils/uuid.util';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
|
||||
export interface TreeNode {
|
||||
label: string;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface DeltagareExportRequest {
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
includeExportedDeltagare: boolean;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ErrorType } from '@msfa-enums/error-type.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import { CustomError } from '@msfa-models/error/custom-error';
|
||||
import { Observable } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ExportApiService {
|
||||
private _apiBaseUrl = `${environment.api.url}/export`;
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
|
||||
public fetchDeltagareExportFile$(requestData: DeltagareExportRequest): Observable<Blob> {
|
||||
const params: Params = {
|
||||
...requestData,
|
||||
includeExportedDeltagare: requestData.includeExportedDeltagare.toString(),
|
||||
};
|
||||
|
||||
return this.httpClient
|
||||
.get<Blob>(`${this._apiBaseUrl}/deltagare`, { params, responseType: 'blob' as 'json' })
|
||||
.pipe(
|
||||
catchError((error: Error) => {
|
||||
throw new CustomError({
|
||||
error,
|
||||
message: `Kunde inte hämta exportfilen för deltagare.\n\n${error.message}`,
|
||||
type: ErrorType.API,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ export function mapPathsToBreadcrumbs(
|
||||
} else if (isDeltagareReportingRoute(paths)) {
|
||||
breadcrumbs = breadcrumbs.slice(0, -1);
|
||||
breadcrumbs[breadcrumbs.length - 2].text = 'Deltagarinformation';
|
||||
} else if (isExportRoute(paths)) {
|
||||
breadcrumbs[breadcrumbs.length - 1].text = `Exportera ${paths[paths.length - 1]}`;
|
||||
}
|
||||
|
||||
return breadcrumbs;
|
||||
@@ -54,3 +56,7 @@ function isDeltagareReportingFormRoute(paths: string[]): boolean {
|
||||
function isDeltagareReportingRoute(paths: string[]): boolean {
|
||||
return paths.length === 4 && paths[0] === 'deltagare' && paths[2] in DELTAGARE_REPORTING_ROUTES;
|
||||
}
|
||||
|
||||
function isExportRoute(paths: string[]): boolean {
|
||||
return paths[0] === 'exporter';
|
||||
}
|
||||
|
||||
100
apps/mina-sidor-fa/src/assets/files/test.csv
Normal file
100
apps/mina-sidor-fa/src/assets/files/test.csv
Normal file
@@ -0,0 +1,100 @@
|
||||
Serial Number,Company Name,Employee Markme,Description,Leave
|
||||
9788189999599,TALES OF SHIVA,Mark,mark,0
|
||||
9780099578079,1Q84 THE COMPLETE TRILOGY,HARUKI MURAKAMI,Mark,0
|
||||
9780198082897,MY KUMAN,Mark,Mark,0
|
||||
9780007880331,THE GOD OF SMAAL THINGS,ARUNDHATI ROY,4TH HARPER COLLINS,2
|
||||
9780545060455,THE BLACK CIRCLE,Mark,4TH HARPER COLLINS,0
|
||||
9788126525072,THE THREE LAWS OF PERFORMANCE,Mark,4TH HARPER COLLINS,0
|
||||
9789381626610,CHAMarkKYA MANTRA,Mark,4TH HARPER COLLINS,0
|
||||
9788184513523,59.FLAGS,Mark,4TH HARPER COLLINS,0
|
||||
9780743234801,THE POWER OF POSITIVE THINKING FROM,Mark,A & A PUBLISHER,0
|
||||
9789381529621,YOU CAN IF YO THINK YO CAN,PEALE,A & A PUBLISHER,0
|
||||
9788183223966,DONGRI SE DUBAI TAK (MPH),Mark,A & A PUBLISHER,0
|
||||
9788187776005,MarkLANDA ADYTAN KOSH,Mark,AADISH BOOK DEPOT,0
|
||||
9788187776013,MarkLANDA VISHAL SHABD SAGAR,-,AADISH BOOK DEPOT,1
|
||||
8187776021,MarkLANDA CONCISE DICT(ENG TO HINDI),Mark,AADISH BOOK DEPOT,0
|
||||
9789384716165,LIEUTEMarkMarkT GENERAL BHAGAT: A SAGA OF BRAVERY AND LEADERSHIP,Mark,AAM COMICS,2
|
||||
9789384716233,LN. MarkIK SUNDER SINGH,N.A,AAN COMICS,0
|
||||
9789384850319,I AM KRISHMark,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9789384850357,DON'T TEACH ME TOLERANCE INDIA,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850364,MUJHE SAHISHNUTA MAT SIKHAO BHARAT,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850746,SECRETS OF DESTINY,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9789384850753,BHAGYA KE RAHASYA (HINDI) SECRET OF DESTINY,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,1
|
||||
9788192669038,MEIN MANN HOON,DEEP TRIVEDI,AATMAN INNOVATIONS PVT LTD,0
|
||||
9789384850098,I AM THE MIND,DEEP TRIVEDI,AATMARAM & SONS,0
|
||||
9780349121420,THE ART OF CHOOSING,SHEEMark IYENGAR,ABACUS,0
|
||||
9780349123462,IN SPITE OF THE GODS,EDWARD LUCE,ABACUS,1
|
||||
9788188440061,QUESTIONS & ANWERS ABOUT THE GREAT BIBLE,Mark,ABC PUBLISHERS DISTRIBUTORS,4
|
||||
9789382088189,NIBANDH EVAM KAHANI LEKHAN { HINDI },Mark,ABHI BOOKS,1
|
||||
9789332703759,INDIAN ECONOMY SINCE INDEPENDENCE 27TH /E,UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9788171888016,ECONOMIC DEVELOPMENT AND POLICY IN INDIA,UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9789332704343,INDIAN ECONOMY PERFORMANCE 18TH/E 2017-2018,UMA KAPILA,ACADEMIC FOUNDATION,2
|
||||
9789332703735,INDIAN ECONOMIC DEVELOPMENTSINCE 1947 (NO RETURMarkBLE),UMA KAPILA,ACADEMIC FOUNDATION,1
|
||||
9789383454143,PRELIMS SPECIAL READING COMPREHENSION PAPER II CSAT,MarkGENDRA PRATAP,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454204,THE CONSTITUTION OF INDIA 2ND / E,AR KHAN,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789386361011,"INDIAN HERITAGE ,ART & CULTURE",MADHUKAR,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454303,BHARAT KA SAMVIDHAN,AR KHAN,ACCESS PUBLISHING INDIA PVT.LTD,4
|
||||
9789383454471,"ETHICS, INTEGRITY & APTITUDE ( 3RD/E)","P N ROY ,G SUBBA RAO",ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454563,GENERAL STUDIES PAPER -- I (2016),Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454570,GENERAL STUDIES PAPER - II (2016),Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454693,INDIAN AND WORLD GEOGRAPHY 2E,D R KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,10
|
||||
9789383454709,VASTUNISTHA PRASHN SANGRAHA: BHARAT KA ITIHAS,MEEMarkKSHI KANT,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454723,"PHYSICAL, HUMAN AND ECONOMIC GEOGRAPHY",D R KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,4
|
||||
9789383454730,WORLD GEOGRAPHY,DR KHULLAR,ACCESS PUBLISHING INDIA PVT.LTD,5
|
||||
9789383454822,INDIA: MAP ENTRIES IN GEOGRAPHY,MAJID HUSAIN,ACCESS PUBLISHING INDIA PVT.LTD,5
|
||||
9789383454853,GOOD GOVERMarkNCE IN INDIA 2/ED.,G SUBBA RAO,ACCESS PUBLISHING INDIA PVT.LTD,1
|
||||
9789383454884,KAMYABI KE SUTRA-CIVIL SEWA PARIKSHA AAP KI MUTTHI MEIN,ASHOK KUMAR,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9789383454891,GENERAL SCIENCE PRELIRY EXAM,Mark,ACCESS PUBLISHING INDIA PVT.LTD,0
|
||||
9781742860190,SUCCESS AND DYSLEXIA,SUCCESS AND DYSLEXIA,ACER PRESS,0
|
||||
9781742860114,AN EXTRAORDIMarkRY SCHOOL,SARA JAMES,ACER PRESS,0
|
||||
9781742861463,POWERFUL PRACTICES FOR READING IMPROVEMENT,GLASSWELL,ACER PRESS,0
|
||||
9781742862859,EARLY CHILDHOOD PLAY MATTERS,SHOMark BASS,ACER PRESS,0
|
||||
9781742863641,LEADING LEARNING AND TEACHING,STEPHEN DINHAM,ACER PRESS,0
|
||||
9781742863658,READING AND LEARNING DIFFICULTIES,PETER WESTWOOD,ACER PRESS,0
|
||||
9781742863665,NUMERACY AND LEARNING DIFFICULTIES,PETER WOODLAND],ACER PRESS,0
|
||||
9781742863771,TEACHING AND LEARNING DIFFICULTIES,PETER WOODLAND,ACER PRESS,0
|
||||
9781742861678,USING DATA TO IMPROVE LEARNING,ANTHONY SHADDOCK,ACER PRESS,0
|
||||
9781742862484,PATHWAYS TO SCHOOL SYSTEM IMPROVEMENT,MICHAEL GAFFNEY,ACER PRESS,0
|
||||
9781742860176,FOR THOSE WHO TEACH,PHIL RIDDEN,ACER PRESS,0
|
||||
9781742860213,KEYS TO SCHOOL LEADERSHIP,PHIL RIDDEN & JOHN DE NOBILE,ACER PRESS,0
|
||||
9781742860220,DIVERSE LITERACIES IN EARLY CHILDHOOD,LEONIE ARTHUR,ACER PRESS,0
|
||||
9781742860237,CREATIVE ARTS IN THE LIVESOF YOUNG CHILDREN,ROBYN EWING,ACER PRESS,0
|
||||
9781742860336,SOCIAL AND EMOTIOMarkL DEVELOPMENT,ROS LEYDEN AND ERIN SHALE,ACER PRESS,0
|
||||
9781742860343,DISCUSSIONS IN SCIENCE,TIM SPROD,ACER PRESS,0
|
||||
9781742860404,YOUNG CHILDREN LEARNING MATHEMATICS,ROBERT HUNTING,ACER PRESS,0
|
||||
9781742860626,COACHING CHILDREN,KELLY SUMICH,ACER PRESS,1
|
||||
9781742860923,TEACHING PHYSICAL EDUCATIOMarkL IN PRIMARY SCHOOL,JANET L CURRIE,ACER PRESS,0
|
||||
9781742861111,ASSESSMENT AND REPORTING,PHIL RIDDEN AND SANDY,ACER PRESS,0
|
||||
9781742861302,COLLABORATION IN LEARNING,MAL LEE AND LORRAE WARD,ACER PRESS,0
|
||||
9780864315250,RE-IMAGINING EDUCATIMarkL LEADERSHIP,BRIAN J.CALDWELL,ACER PRESS,0
|
||||
9780864317025,TOWARDS A MOVING SCHOOL,FLEMING & KLEINHENZ,ACER PRESS,0
|
||||
9780864317230,DESINGNING A THINKING A CURRICULAM,SUSAN WILKS,ACER PRESS,0
|
||||
9780864318961,LEADING A DIGITAL SCHOOL,MAL LEE AND MICHEAL GAFFNEY,ACER PRESS,0
|
||||
9780864319043,NUMERACY,WESTWOOD,ACER PRESS,0
|
||||
9780864319203,TEACHING ORAL LANGUAGE,JOHN MUNRO,ACER PRESS,0
|
||||
9780864319449,SPELLING,WESTWOOD,ACER PRESS,0
|
||||
9788189999803,STORIES OF SHIVA,Mark,ACK,0
|
||||
9788189999988,JAMSET JI TATA: THE MAN WHO SAW TOMORROW,,ACK,0
|
||||
9788184820355,HEROES FROM THE MAHABHARTA { 5-IN-1 },Mark,ACK,0
|
||||
9788184820553,SURYA,,ACK,0
|
||||
9788184820645,TALES OF THE MOTHER GODDESS,-,ACK,0
|
||||
9788184820652,ADVENTURES OF KRISHMark,Mark,ACK,0
|
||||
9788184822113,MAHATMA GANDHI,Mark,ACK,1
|
||||
9788184822120,TALES FROM THE PANCHATANTRA 3-IN-1,-,ACK,0
|
||||
9788184821482,YET MORE TALES FROM THE JATAKAS { 3-IN-1 },AMarkNT PAI,ACK,0
|
||||
9788184825763,LEGENDARY RULERS OF INDIA,-,ACK,0
|
||||
9788184825862,GREAT INDIAN CLASSIC,Mark,ACK,0
|
||||
9788184823219,TULSIDAS ' RAMAYAMark,Mark,ACK,0
|
||||
9788184820782,TALES OF HANUMAN,-,ACK,0
|
||||
9788184820089,VALMIKI'S RAMAYAMark,A C K,ACK,1
|
||||
9788184825213,THE BEST OF INIDAN WIT AND WISDOM,Mark,ACK,0
|
||||
9788184820997,MORE TALES FROM THE PANCHTANTRA,AMarkNT PAL,ACK,0
|
||||
9788184824018,THE GREAT MUGHALS {5-IN-1},AMarkNT.,ACK,0
|
||||
9788184824049,FAMOUS SCIENTISTS,Mark,ACK,0
|
||||
9788184825978,KOMarkRK,Mark,ACK,0
|
||||
9788184826098,THE MUGHAL COURT,REEMark,ACK,0
|
||||
9788184821536,MORE STORIES FROM THE JATAKAS,Mark,ACK,0
|
||||
9788184821543,MORE TALES OF BIRBAL,-,ACK,0
|
||||
9788184821550,TALES FROM THE JATAKAS,-,ACK,0
|
||||
9788184821567,RAMarkS OF MEWAR,-,ACK,0
|
||||
9788184821574,THE SONS OF THE PANDAVAS,-,ACK,0
|
||||
|
@@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
projects: ['<rootDir>/apps/mina-sidor-fa', '<rootDir>/libs/ui', '<rootDir>/libs/styles'],
|
||||
projects: ['<rootDir>/apps/mina-sidor-fa', '<rootDir>/libs/ui', '<rootDir>/libs/styles', '<rootDir>/libs/utils'],
|
||||
};
|
||||
|
||||
18
libs/ui/src/checkbox/checkbox.component.html
Normal file
18
libs/ui/src/checkbox/checkbox.component.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="ui-checkbox" [ngClass]="{'ui-checkbox--invalid': uiInvalid && uiValidationMessage}">
|
||||
<digi-form-checkbox
|
||||
[afId]="uiId"
|
||||
[afIndeterminate]="uiIndeterminate"
|
||||
[afName]="uiName"
|
||||
[afRequired]="uiRequired"
|
||||
[afValidation]="uiInvalid ? 'error' : 'neutral'"
|
||||
[afVariation]="uiSecondary ? 'secondary' : 'primary'"
|
||||
[afLabel]="labelText"
|
||||
[afChecked]="currentValue"
|
||||
(afOnChange)="checkForChange($event.detail.target.checked)"
|
||||
></digi-form-checkbox>
|
||||
<div aria-atomic="true" role="alert">
|
||||
<digi-form-validation-message *ngIf="uiInvalid && uiValidationMessage" af-variation="error"
|
||||
>{{uiValidationMessage}}</digi-form-validation-message
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
8
libs/ui/src/checkbox/checkbox.component.scss
Normal file
8
libs/ui/src/checkbox/checkbox.component.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
.ui-checkbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&--invalid {
|
||||
gap: var(--digi--layout--gutter--xs);
|
||||
}
|
||||
}
|
||||
23
libs/ui/src/checkbox/checkbox.component.spec.ts
Normal file
23
libs/ui/src/checkbox/checkbox.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import { FormCheckboxComponent } from './form-checkbox.component';
|
||||
|
||||
export class MockInjector {
|
||||
get = jest.fn();
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class MockChangeDetectorRef {
|
||||
markForCheck = jest.fn();
|
||||
detach = jest.fn();
|
||||
detectChanges = jest.fn();
|
||||
reattach = jest.fn();
|
||||
checkNoChanges = jest.fn();
|
||||
}
|
||||
|
||||
describe('FormCheckboxComponent', () => {
|
||||
let component: FormCheckboxComponent;
|
||||
it('should create', () => {
|
||||
component = new FormCheckboxComponent(new MockInjector(), new MockChangeDetectorRef());
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
16
libs/ui/src/checkbox/checkbox.component.stories.ts
Normal file
16
libs/ui/src/checkbox/checkbox.component.stories.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { CheckboxComponent } from './checkbox.component';
|
||||
import { UiCheckboxModule } from './checkbox.module';
|
||||
|
||||
export default { title: 'Checkbox', component: CheckboxComponent };
|
||||
|
||||
const componentModule = {
|
||||
moduleMetadata: {
|
||||
imports: [ReactiveFormsModule, UiCheckboxModule],
|
||||
},
|
||||
};
|
||||
|
||||
export const standard = () => ({
|
||||
...componentModule,
|
||||
template: '<ui-checkbox></ui-checkbox>',
|
||||
});
|
||||
111
libs/ui/src/checkbox/checkbox.component.ts
Normal file
111
libs/ui/src/checkbox/checkbox.component.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Injector,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
} from '@angular/core';
|
||||
import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { uuid } from '@utils/uuid.util';
|
||||
|
||||
/**
|
||||
* A checkbox input. Implemented with control value accessor
|
||||
*
|
||||
* ## Usage
|
||||
* ``import {UiCheckboxModule} from '@ui/checkbox/checkbox.module';``
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-checkbox',
|
||||
templateUrl: './checkbox.component.html',
|
||||
styleUrls: ['./checkbox.component.scss'],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: CheckboxComponent,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CheckboxComponent implements AfterViewInit, ControlValueAccessor, OnChanges {
|
||||
@Input() uiInvalid: boolean;
|
||||
@Input() uiValidationMessage: string;
|
||||
@Input() uiSecondary: boolean;
|
||||
@Input() uiIndeterminate: boolean = false;
|
||||
@Input() uiLabel: string = '';
|
||||
@Input() uiRequired: boolean;
|
||||
@Input() uiId: string = uuid();
|
||||
@Input() uiName: string;
|
||||
@Input() uiAnnounceIfOptional: boolean = false;
|
||||
@Output() uiOnChange: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
name: string | number;
|
||||
|
||||
onTouched: () => {};
|
||||
private onChange: (value: any) => {};
|
||||
private _value: boolean;
|
||||
|
||||
constructor(private injector: Injector, private changeDetectorRef: ChangeDetectorRef) {}
|
||||
|
||||
get currentValue(): boolean {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
get labelText(): string {
|
||||
return `${this.uiLabel}${this._requiredText}`;
|
||||
}
|
||||
|
||||
private get _requiredText() {
|
||||
if (this.uiRequired && !this.uiAnnounceIfOptional) {
|
||||
return ' (obligatoriskt)';
|
||||
}
|
||||
|
||||
if (!this.uiRequired && this.uiAnnounceIfOptional) {
|
||||
return ' (frivilligt)';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
const ngControl: NgControl = this.injector.get(NgControl, null);
|
||||
if (ngControl) {
|
||||
this.name = ngControl.name;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const ngControl: NgControl = this.injector.get(NgControl, null);
|
||||
if (ngControl) {
|
||||
this.name = ngControl.name;
|
||||
}
|
||||
}
|
||||
|
||||
checkForChange(value: boolean): void {
|
||||
if (this._value !== !!value) {
|
||||
if (this.onChange) {
|
||||
this.onChange(!!value);
|
||||
}
|
||||
this._value = !!value;
|
||||
this.uiOnChange.emit(!!value);
|
||||
}
|
||||
}
|
||||
|
||||
writeValue(value: any): void {
|
||||
this._value = value;
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: string) => {}) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => {}) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
}
|
||||
11
libs/ui/src/checkbox/checkbox.module.ts
Normal file
11
libs/ui/src/checkbox/checkbox.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { CheckboxComponent } from './checkbox.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [CommonModule],
|
||||
declarations: [CheckboxComponent],
|
||||
exports: [CheckboxComponent],
|
||||
})
|
||||
export class UiCheckboxModule {}
|
||||
1
libs/ui/src/test-setup.ts
Normal file
1
libs/ui/src/test-setup.ts
Normal file
@@ -0,0 +1 @@
|
||||
import 'jest-preset-angular';
|
||||
22
libs/utils/.eslintrc.json
Normal file
22
libs/utils/.eslintrc.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
|
||||
"parserOptions": { "project": ["libs/utils/tsconfig.*?.json"] },
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{ "type": "attribute", "prefix": "mina-sidor-fa-web", "style": "camelCase" }
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{ "type": "element", "prefix": "mina-sidor-fa-web", "style": "kebab-case" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "files": ["*.html"], "extends": ["plugin:@nrwl/nx/angular-template"], "rules": {} }
|
||||
]
|
||||
}
|
||||
7
libs/utils/README.md
Normal file
7
libs/utils/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# utils
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test utils` to execute the unit tests.
|
||||
23
libs/utils/jest.config.js
Normal file
23
libs/utils/jest.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
displayName: 'utils',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
astTransformers: {
|
||||
before: [
|
||||
'jest-preset-angular/build/InlineFilesTransformer',
|
||||
'jest-preset-angular/build/StripStylesTransformer',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/libs/utils',
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/AngularSnapshotSerializer.js',
|
||||
'jest-preset-angular/build/HTMLCommentSerializer.js',
|
||||
],
|
||||
};
|
||||
1
libs/utils/src/test-setup.ts
Normal file
1
libs/utils/src/test-setup.ts
Normal file
@@ -0,0 +1 @@
|
||||
import 'jest-preset-angular';
|
||||
13
libs/utils/tsconfig.json
Normal file
13
libs/utils/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
19
libs/utils/tsconfig.lib.json
Normal file
19
libs/utils/tsconfig.lib.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": ["dom", "es2018"]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": ["src/test-setup.ts", "**/*.spec.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
10
libs/utils/tsconfig.spec.json
Normal file
10
libs/utils/tsconfig.spec.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
3
nx.json
3
nx.json
@@ -19,6 +19,7 @@
|
||||
"mina-sidor-fa": { "tags": [] },
|
||||
"mina-sidor-fa-e2e": { "tags": [], "implicitDependencies": ["mina-sidor-fa"] },
|
||||
"ui": { "tags": [] },
|
||||
"styles": { "tags": [] }
|
||||
"styles": { "tags": [] },
|
||||
"utils": { "tags": [] }
|
||||
}
|
||||
}
|
||||
|
||||
1429
package-lock.json
generated
1429
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,7 @@
|
||||
"@elastic/apm-rum-angular": "^2.1.1",
|
||||
"@nrwl/angular": "11.5.1",
|
||||
"date-fns": "^2.22.1",
|
||||
"file-saver": "^2.0.5",
|
||||
"ngx-markdown": "^11.1.3",
|
||||
"rxjs": "~6.6.3",
|
||||
"tslib": "^2.0.0",
|
||||
@@ -89,6 +90,7 @@
|
||||
"@semantic-release/git": "^9.0.0",
|
||||
"@semantic-release/npm": "^7.1.3",
|
||||
"@semantic-release/release-notes-generator": "^9.0.2",
|
||||
"@types/file-saver": "^2.0.3",
|
||||
"@types/jest": "26.0.8",
|
||||
"@types/node": "12.12.38",
|
||||
"@typescript-eslint/eslint-plugin": "4.3.0",
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
"@msfa-shared/*": ["apps/mina-sidor-fa/src/app/shared/*"],
|
||||
"@msfa-utils/*": ["apps/mina-sidor-fa/src/app/shared/utils/*"],
|
||||
"@msfa-validators/*": ["apps/mina-sidor-fa/src/app/shared/utils/validators/*"],
|
||||
"@ui/*": ["libs/ui/*"],
|
||||
"@mina-sidor-fa-web/styles": ["libs/styles/src/index.ts"]
|
||||
"@ui/*": ["libs/ui/src/*"],
|
||||
"@utils/*": ["libs/utils/src/*"]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
|
||||
Reference in New Issue
Block a user