Merge pull request #174 in TEA/mina-sidor-fa-web from feature/TV-724-refaktorera-deltagare to develop

Squashed commit of the following:

commit 4c6ced007ea583a31cc3a4a6e71a431e65cece7f
Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se>
Date:   Tue Oct 5 11:08:21 2021 +0200

    fix routing and make deltagare-card part of deltagare-details

commit fea3bd1acfc225687876de18a75eb7b22240f17c
Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se>
Date:   Tue Oct 5 10:42:36 2021 +0200

    refactor reports list

commit 96a0758fa52ef1c42a72f65973a2ce047244de00
Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se>
Date:   Tue Oct 5 10:37:37 2021 +0200

    refactor

commit ac35e321b70f0a624d99b315ea7c88ef507699cc
Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se>
Date:   Tue Oct 5 10:35:05 2021 +0200

    refaktorera deltagare

commit d3b88e88f7d798cc1450b8be3ea344cb8b2863b1
Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se>
Date:   Tue Oct 5 09:51:23 2021 +0200

    refactoring deltagare
This commit is contained in:
Daniel Appelgren
2021-10-05 14:00:12 +02:00
parent 07ec3c4aeb
commit c2e0bf10bd
105 changed files with 23184 additions and 22131 deletions

View File

@@ -1,42 +1,41 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DeltagareComponent } from './deltagare.component';
const routes: Routes = [
{
path: '',
component: DeltagareComponent,
loadChildren: () => import('./pages/deltagare-list/deltagare-list.module').then(m => m.DeltagareListModule),
},
{
path: ':genomforandeReferens',
data: { title: 'Deltagareinformation' },
loadChildren: () => import('./pages/deltagare-card/deltagare-card.module').then(m => m.DeltagareCardModule),
},
{
path: 'rapportera/:genomforandeReferens',
data: { title: 'Skapa rapport' },
// eslint-disable-next-line max-len
loadChildren: () =>
import('./pages/deltagare-report/pages/deltagare-avvikelse/deltagare-avvikelse.module').then(
m => m.DeltagareAvvikelseModule
),
},
{
path: 'planering/:genomforandeReferens',
data: { title: 'Skapa gemensam planering' },
loadChildren: () =>
import('./pages/deltagare-report/pages/deltagare-gemensam-planering/deltagare-gemensam-planering.module').then(
m => m.DeltagareGemensamPlaneringModule
),
},
{
path: 'periodisk-redovisning/:genomforandeReferens',
data: { title: 'Skapa periodisk redovisning' },
loadChildren: () =>
import('./pages/deltagare-report/pages/periodisk-redovisning/periodisk-redovisning.module').then(
m => m.PeriodiskRedovisningModule
),
import('./pages/deltagare-details/deltagare-details.module').then(m => m.DeltagareDetailsModule),
},
// {
// path: 'avvikelserapport',
// data: { title: 'Skapa rapport' },
// loadChildren: () =>
// import('./pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module').then(
// m => m.DeltagareAvvikelseModule
// ),
// },
// {
// path: 'gemensam-planering',
// data: { title: 'Skapa gemensam planering' },
// loadChildren: () =>
// import(
// './pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.module'
// ).then(m => m.DeltagareGemensamPlaneringModule),
// },
// {
// path: 'periodisk-redovisning',
// data: { title: 'Skapa periodisk redovisning' },
// loadChildren: () =>
// import(
// './pages/deltagare-details/pages/deltagare-reports/deltagare-periodisk-redovisning/deltagare-periodisk-redovisning.module'
// ).then(m => m.DeltagarePeriodiskRedovisningModule),
// },
];
@NgModule({

View File

@@ -1,47 +0,0 @@
<msfa-layout>
<digi-typography>
<ng-container *ngIf="(showUnauthorizedError$ | async) === false; else roleError">
<section class="deltagare" *ngIf="allDeltagareData$ | async as allDeltagareData; else loadingRef">
<header class="deltagare__header">
<h1>Deltagarlista</h1>
<p>
Här ser du en lista på de deltagare som tillhör din organisation. Klicka på deltagarens namn för att öppna
och se mer information om deltagarna.
</p>
</header>
<div class="deltagare__filter">
<digi-form-checkbox
class="deltagare__only-my-deltagare"
af-label="Visa endast mina tilldelade deltagare"
[afChecked]="onlyMyDeltagare$ | async"
(afOnChange)="setOnlyMyDeltagare($event.detail.target.checked)"
></digi-form-checkbox>
</div>
<msfa-deltagare-list
*ngIf="allDeltagareData.data.length; else noDeltagare"
[deltagare]="allDeltagareData.data"
[paginationMeta]="allDeltagareData.meta"
[deltagareLoading]="deltagareLoading$ | async"
[sort]="sort$ | async"
(sorted)="handleDeltagareSort($event)"
(paginated)="setNewPage($event)"
></msfa-deltagare-list>
</section>
</ng-container>
</digi-typography>
</msfa-layout>
<ng-template #loadingRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar deltagare"></digi-ng-skeleton-base>
</ng-template>
<ng-template #noDeltagare>
<p *ngIf="(deltagareLoading$ | async) === false">
Inga deltagare hittades{{(onlyMyDeltagare$ | async) ? '. Bocka ur "Visa endast mina tilldelade deltagare" för att se
deltagare som tillhör din organisation.' : ' som tillhör din organisation.' }}
</p>
</ng-template>
<ng-template #roleError>
<msfa-unauthorized-alert></msfa-unauthorized-alert>
</ng-template>

View File

@@ -1,22 +1,9 @@
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { UnauthorizedAlertModule } from '@msfa-shared/components/unauthorized-alert/unauthorized-alert.module';
import { DeltagareListModule } from './components/deltagare-list/deltagare-list.module';
import { DeltagareRoutingModule } from './deltagare-routing.module';
import { DeltagareComponent } from './deltagare.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareComponent],
imports: [
CommonModule,
DeltagareRoutingModule,
LayoutModule,
DeltagareListModule,
UnauthorizedAlertModule,
DigiNgSkeletonBaseModule,
],
imports: [CommonModule, DeltagareRoutingModule],
})
export class DeltagareModule {}

View File

@@ -0,0 +1,39 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
data: { title: 'Deltagareinformation' },
loadChildren: () => import('./pages/deltagare-card/deltagare-card.module').then(m => m.DeltagareCardModule),
},
{
path: 'avvikelserapport',
data: { title: 'Skapa rapport' },
loadChildren: () =>
import('./pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module').then(
m => m.DeltagareAvvikelseModule
),
},
{
path: 'gemensam-planering',
data: { title: 'Skapa gemensam planering' },
loadChildren: () =>
import('./pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.module').then(
m => m.DeltagareGemensamPlaneringModule
),
},
{
path: 'periodisk-redovisning',
data: { title: 'Skapa periodisk redovisning' },
loadChildren: () =>
import('./pages/deltagare-reports/deltagare-periodisk-redovisning/deltagare-periodisk-redovisning.module').then(
m => m.DeltagarePeriodiskRedovisningModule
),
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
})
export class DeltagareDetailsModule {}

View File

@@ -2,22 +2,22 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ReportsComponent } from './reports.component';
import { ReportsListComponent } from './reports-list.component';
describe('ReportsComponent', () => {
let component: ReportsComponent;
let fixture: ComponentFixture<ReportsComponent>;
let component: ReportsListComponent;
let fixture: ComponentFixture<ReportsListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [ReportsComponent],
imports: [RouterTestingModule]
declarations: [ReportsListComponent],
imports: [RouterTestingModule],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ReportsComponent);
fixture = TestBed.createComponent(ReportsListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -3,12 +3,12 @@ import { PaginationMeta } from '@msfa-models/pagination-meta.model';
import { Report } from '@msfa-models/reports.model';
@Component({
selector: 'msfa-reports',
templateUrl: './reports.component.html',
styleUrls: ['./reports.component.scss'],
selector: 'msfa-reports-list',
templateUrl: './reports-list.component.html',
styleUrls: ['./reports-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReportsComponent {
export class ReportsListComponent {
@Input() reports: Report[];
@Input() paginationMeta: PaginationMeta;
@Output() paginated = new EventEmitter<number>();
@@ -16,7 +16,7 @@ export class ReportsComponent {
columnHeaders: { label: string; key: keyof Report }[] = [
{
label: 'Typ av rapport',
key: 'type'
key: 'type',
},
{
label: 'Inskickad datum',
@@ -25,7 +25,7 @@ export class ReportsComponent {
{
label: 'Status',
key: 'status',
}
},
];
get currentPage(): number {

View File

@@ -2,12 +2,12 @@ import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { LocalDatePipeModule } from '@msfa-shared/pipes/local-date/local-date.module';
import { ReportsComponent } from './reports.component';
import { ReportsListComponent } from './reports-list.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [ReportsComponent],
declarations: [ReportsListComponent],
imports: [CommonModule, RouterModule, LocalDatePipeModule],
exports: [ReportsComponent]
exports: [ReportsListComponent],
})
export class ReportsModule { }
export class ReportsListModule {}

View File

@@ -3,35 +3,35 @@
<h3>Skapa ny rapport</h3>
<p>Här kan du skicka rapporter om deltagaren till arbetsförmedlingen.</p>
<digi-ng-form-select
[afDisableValidStyle]="true"
[afInvalid]="reportsFormControl.invalid && reportsFormControl.touched"
[afRequired]="true"
[afSelectItems]="selectableReportTypes"
[formControlName]="reportsFormControlName"
afLabel="Välj rapporttyp"
afPlaceholder="Välj rapporttyp"
[afSelectItems]="selectableReportTypes"
[afDisableValidStyle]="true"
[afRequired]="true"
[afInvalid]="reportsFormControl.invalid && reportsFormControl.touched"
>
</digi-ng-form-select>
<digi-form-validation-message af-variation="error" *ngIf="reportsFormControl.invalid && reportsFormControl.touched">
<digi-form-validation-message *ngIf="reportsFormControl.invalid && reportsFormControl.touched" af-variation="error">
Du måste välja en rapporttyp
</digi-form-validation-message>
</form>
<div
class="deltagare-tab-reports__cta-wrapper"
*ngIf="currentGenomforandeReferens$ | async as currentGenomforandeReferens"
class="deltagare-tab-reports__cta-wrapper"
>
<digi-ng-link-button
afText="Skapa ny rapport"
(click)="onFormSubmitted($event, reportsFormControl.value, currentGenomforandeReferens)"
afText="Skapa ny rapport"
></digi-ng-link-button>
</div>
<div>
<h3>Inskickade rapporter</h3>
<msfa-reports
[reports]="reportsData.data"
[paginationMeta]="reportsData.meta"
<msfa-reports-list
(paginated)="setNewPage($event)"
></msfa-reports>
[paginationMeta]="reportsData.meta"
[reports]="reportsData.data"
></msfa-reports-list>
</div>
</div>

View File

@@ -5,7 +5,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { DeltagareCardService } from '../../services/deltagare-card.service';
import { DeltagareCardService } from '../../deltagare-card.service';
import { DeltagareTabReportsComponent } from './deltagare-tab-reports.component';
describe('DeltagareTabReportsComponent', () => {

View File

@@ -5,7 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { ReportsData } from '@msfa-models/reports.model';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map, shareReplay, switchMap } from 'rxjs/operators';
import { DeltagareCardService } from '../../services/deltagare-card.service';
import { DeltagareCardService } from '../../deltagare-card.service';
@Component({
selector: 'msfa-deltagare-tab-reports',
@@ -14,11 +14,7 @@ import { DeltagareCardService } from '../../services/deltagare-card.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeltagareTabReportsComponent {
private _limit$ = new BehaviorSubject<number>(20);
private _page$ = new BehaviorSubject<number>(1);
private _type$ = new BehaviorSubject<FormSelectItem>(null);
readonly reportsFormControlName = 'reports';
public currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe(
map(params => params.genomforandeReferens as string),
distinctUntilChanged(
@@ -26,7 +22,17 @@ export class DeltagareTabReportsComponent {
),
map(genomforandeReferens => +genomforandeReferens)
);
reportPickerFormGroup: FormGroup = this.formBuilder.group({
// eslint-disable-next-line @typescript-eslint/unbound-method
reports: this.formBuilder.control('', [Validators.required]),
});
selectableReportTypes: Array<FormSelectItem> = [
{ name: 'Avvikelse', value: 'avvikelse' },
{ name: 'Gemensam Planering', value: 'planering' },
];
selectedReportType: FormSelectItem;
private _limit$ = new BehaviorSubject<number>(20);
private _page$ = new BehaviorSubject<number>(1);
reportsData$: Observable<ReportsData> = combineLatest([
this.currentGenomforandeReferens$,
this._limit$,
@@ -37,17 +43,7 @@ export class DeltagareTabReportsComponent {
),
shareReplay(1)
);
reportPickerFormGroup: FormGroup = this.formBuilder.group({
// eslint-disable-next-line @typescript-eslint/unbound-method
reports: this.formBuilder.control('', [Validators.required]),
});
selectableReportTypes: Array<FormSelectItem> = [
{ name: 'Avvikelse', value: 'avvikelse' },
{ name: 'Gemensam Planering', value: 'planering' },
];
selectedReportType: FormSelectItem;
private _type$ = new BehaviorSubject<FormSelectItem>(null);
constructor(
private activatedRoute: ActivatedRoute,
@@ -66,16 +62,12 @@ export class DeltagareTabReportsComponent {
switch (reportType) {
case 'planering':
if (this.reportsFormControl.valid) {
this.router.navigate(['/deltagare/planering', genomforandeReferens]).catch(error => {
console.error(error);
});
void this.router.navigate([`/deltagare/${genomforandeReferens}/gemensam-planering`]);
}
break;
case 'avvikelse':
if (this.reportsFormControl.valid) {
this.router.navigate(['/deltagare/rapportera', genomforandeReferens]).catch(error => {
console.error(error);
});
void this.router.navigate([`/deltagare/${genomforandeReferens}/avvikelserapport`]);
}
break;
default:

View File

@@ -1,4 +1,4 @@
@import 'variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.deltagare-card {
&__tab-contents {

View File

@@ -4,7 +4,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { DeltagareCardComponent } from './deltagare-card.component';
import { DeltagareCardService } from './services/deltagare-card.service';
import { DeltagareCardService } from './deltagare-card.service';
describe('DeltagareCardComponent', () => {
let component: DeltagareCardComponent;

View File

@@ -16,21 +16,15 @@ import { UserService } from '@msfa-services/api/user.service';
import { HandledareService } from '@msfa-services/handledare.service';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
import { DeltagareCardService } from './services/deltagare-card.service';
import { DeltagareCardService } from './deltagare-card.service';
@Component({
selector: 'msfa-deltagare-card',
selector: 'msfa-deltagare-details',
templateUrl: './deltagare-card.component.html',
styleUrls: ['./deltagare-card.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeltagareCardComponent {
private _activeFeatures: Feature[] = environment.activeFeatures;
private _activeTab$ = new BehaviorSubject<string>('0');
private _userRoles: Role[] = this.userService.userRolesSnapshot;
activeTab$: Observable<string> = this._activeTab$.asObservable();
currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe(
map(params => params.genomforandeReferens as string),
distinctUntilChanged(
@@ -75,12 +69,10 @@ export class DeltagareCardComponent {
distinctUntilChanged((prevAvrop, currAvrop) => prevAvrop.id === currAvrop.id),
switchMap(avropInformation => this.handledareService.fetchAvailableHandledare$([avropInformation.id]))
);
tab0Loading$: Observable<boolean> = combineLatest([this.contactInformation$, this.avropInformation$]).pipe(
map(([contactInformation, avropInformation]) => !(contactInformation && avropInformation)),
startWith(true)
);
tab2Loading$: Observable<boolean> = combineLatest([
this.workExperiences$,
this.highestEducation$,
@@ -101,30 +93,10 @@ export class DeltagareCardComponent {
map(([disabilities, avropInformation, workLanguages]) => !(disabilities && avropInformation && workLanguages)),
startWith(true)
);
get deltagareTjanstVisible(): boolean {
return this._userRoles?.some(
role => role.type === RoleEnum.MSFA_ReportAndPlanning || role.type === RoleEnum.MSFA_ReceiveDeltagare
);
}
get handledarePickerVisible(): boolean {
return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare);
}
get reportingTabVisible(): boolean {
return (
this._activeFeatures.includes(Feature.REPORTING) &&
this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)
);
}
get experiencesVisible(): boolean {
return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning);
}
get sensitiveDataVisible(): boolean {
return (
this._activeFeatures.includes(Feature.SENSITIVE_INFORMATION) &&
this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)
);
}
private _activeFeatures: Feature[] = environment.activeFeatures;
private _activeTab$ = new BehaviorSubject<string>('0');
activeTab$: Observable<string> = this._activeTab$.asObservable();
private _userRoles: Role[] = this.userService.userRolesSnapshot;
constructor(
private activatedRoute: ActivatedRoute,
@@ -133,6 +105,34 @@ export class DeltagareCardComponent {
private userService: UserService
) {}
get deltagareTjanstVisible(): boolean {
return this._userRoles?.some(
role => role.type === RoleEnum.MSFA_ReportAndPlanning || role.type === RoleEnum.MSFA_ReceiveDeltagare
);
}
get handledarePickerVisible(): boolean {
return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare);
}
get reportingTabVisible(): boolean {
return (
this._activeFeatures.includes(Feature.REPORTING) &&
this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)
);
}
get experiencesVisible(): boolean {
return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning);
}
get sensitiveDataVisible(): boolean {
return (
this._activeFeatures.includes(Feature.SENSITIVE_INFORMATION) &&
this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)
);
}
setActiveTab(tab: number): void {
this._activeTab$.next(tab.toString());
}

View File

@@ -15,9 +15,9 @@ import { DeltagareTabExperiencesComponent } from './components/deltagare-tab-exp
import { DeltagareTabPersonalInformationComponent } from './components/deltagare-tab-personal-information/deltagare-tab-personal-information.component';
import { DeltagareTabReportsComponent } from './components/deltagare-tab-reports/deltagare-tab-reports.component';
import { DeltagareTabSensitiveInformationComponent } from './components/deltagare-tab-sensitive-information/deltagare-tab-sensitive-information.component';
import { ReportsModule } from './components/reports/reports.module';
import { ReportsListModule } from './components/deltagare-tab-reports/components/reports-list/reports-list.module';
import { DeltagareCardComponent } from './deltagare-card.component';
import { DeltagareCardService } from './services/deltagare-card.service';
import { DeltagareCardService } from './deltagare-card.service';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -32,7 +32,7 @@ import { DeltagareCardService } from './services/deltagare-card.service';
CommonModule,
RouterModule.forChild([{ path: '', component: DeltagareCardComponent }]),
ReactiveFormsModule,
ReportsModule,
ReportsListModule,
LayoutModule,
BackLinkModule,
HideTextModule,

View File

@@ -21,29 +21,37 @@ export class DeltagareCardService {
public fetchContactInformation$(genomforandeReferens: number): Observable<ContactInformation> {
return this.deltagareApiService.fetchContactInformation$(genomforandeReferens);
}
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
return this.avropNeedsUpdate$.pipe(
switchMap(() => this.deltagareApiService.fetchAvropInformation$(genomforandeReferens))
);
}
public fetchWorkExperiences$(genomforandeReferens: number): Observable<WorkExperience[]> {
return this.deltagareApiService.fetchWorkExperiences$(genomforandeReferens);
}
public fetchHighestEducation$(genomforandeReferens: number): Observable<HighestEducation> {
return this.deltagareApiService.fetchHighestEducation$(genomforandeReferens);
}
public fetchEducations$(genomforandeReferens: number): Observable<Education[]> {
return this.deltagareApiService.fetchEducations$(genomforandeReferens);
}
public fetchDriversLicense$(genomforandeReferens: number): Observable<DriversLicense> {
return this.deltagareApiService.fetchDriversLicense$(genomforandeReferens);
}
public fetchWorkLanguages$(genomforandeReferens: number): Observable<string[]> {
return this.deltagareApiService.fetchWorkLanguages$(genomforandeReferens);
}
public fetchDisabilities$(genomforandeReferens: number): Observable<Disability[]> {
return this.deltagareApiService.fetchDisabilities$(genomforandeReferens);
}
public fetchReports$(limit: number, page: number, genomforandeReferens: number): Observable<ReportsData> {
return this.deltagareApiService.fetchReports$(limit, page, genomforandeReferens);
}

View File

@@ -1,5 +1,4 @@
<section class="report-layout" *ngIf="contactInformation$ | async as contactInformation; else skeletonRef">
<digi-typography>
<h1>{{ reportTitle }}</h1>
<p class="report-layout__description">{{description}}</p>
<div class="report-layout__deltagare-info">
@@ -49,7 +48,6 @@
<div class="report-layout__main-content">
<ng-content></ng-content>
</div>
</digi-typography>
</section>
<ng-template #skeletonRef>

View File

@@ -1,4 +1,5 @@
@import 'variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.report-layout {
&__name {
margin-top: 0;

View File

@@ -1,7 +1,8 @@
@import 'variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.deltagare-timepicker {
margin-bottom: $digi--layout--gutter--xl;
&__heading {
font-weight: var(--digi--typography--font-weight--semibold);
}

View File

@@ -17,15 +17,20 @@ import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'
import { KandaAvvikelseKoder, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import {
requiredAnnanKandOrsakValidator, RequiredDateValidator,
requiredDayOrPartOfDayValidator, requiredDescriptionValidator, requiredEndTimeValidator,
requiredAnnanKandOrsakValidator,
RequiredDateValidator,
requiredDayOrPartOfDayValidator,
requiredDescriptionValidator,
requiredEndTimeValidator,
requiredFraga1Validator,
requiredfraga2Validator, requiredOrsakerValidator, requiredStartTimeValidator
} from '@msfa-utils/validators/avvikelse-form-validator';
import { RequiredValidator } from '@msfa-utils/validators/required.validator';
requiredfraga2Validator,
requiredOrsakerValidator,
requiredStartTimeValidator,
} from '@msfa-validators/avvikelse-form-validator';
import { RequiredValidator } from '@msfa-validators/required.validator';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { DeltagareAvvikelseService } from '../../services/deltagare-avvikelse.service';
import { DeltagareAvvikelseService } from './deltagare-avvikelse.service';
import { avvikelseAlternatives, dayOrPartOfDay } from './report-alternatives';
@Component({
@@ -45,14 +50,8 @@ export class DeltagareAvvikelseComponent implements OnInit {
readonly fraga2FormControlName = 'fraga2';
readonly startTimeFormControlName = 'startTime';
readonly endTimeFormControlName = 'endTime';
private _showSuccessNotification$ = new BehaviorSubject<boolean>(false);
private _showDangerNotification$ = new BehaviorSubject<boolean>(false);
contactInformation$: Observable<ContactInformation> = this.activatedRoute.params.pipe(
switchMap(({ genomforandeReferens }) =>
this.deltagareApiService.fetchContactInformation$(genomforandeReferens)
)
switchMap(({ genomforandeReferens }) => this.deltagareApiService.fetchContactInformation$(genomforandeReferens))
);
franvaroOrsaker$: Observable<OrsaksKoderFranvaro[]>;
avvikelseOrsaker$: Observable<OrsaksKoderAvvikelse[]>;
@@ -68,7 +67,9 @@ export class DeltagareAvvikelseComponent implements OnInit {
totalAmountOfSteps = 2;
currentStep = 1;
openConfirmDialog = false;
private _showSuccessNotification$ = new BehaviorSubject<boolean>(false);
showSuccessNotification$ = this._showSuccessNotification$.asObservable();
private _showDangerNotification$ = new BehaviorSubject<boolean>(false);
showDangerNotification$ = this._showDangerNotification$.asObservable();
constructor(
@@ -76,35 +77,7 @@ export class DeltagareAvvikelseComponent implements OnInit {
private deltagareApiService: DeltagareApiService,
private router: Router,
private activatedRoute: ActivatedRoute
) { }
ngOnInit(): void {
this.avvikelseFormGroup = new FormGroup(
{
alternative: new FormControl(null, [RequiredValidator()]),
description: new FormControl('', [requiredDescriptionValidator()]),
date: new FormControl(this.todayDate),
dayOrPartOfDay: new FormControl(null, [requiredDayOrPartOfDayValidator()]),
orsakerFormGroup: new FormGroup({
orsaker: new FormControl([], [requiredOrsakerValidator()]),
andraKandaOrsaker: new FormControl([], [requiredAnnanKandOrsakValidator()])
}),
fragorFormGroup: new FormGroup({
fraga1: new FormControl('', [requiredFraga1Validator()]),
fraga2: new FormControl('', [requiredfraga2Validator()])
}),
timepickerFormGroup: new FormGroup({
startTime: new FormControl('', [requiredStartTimeValidator()]),
endTime: new FormControl('', [requiredEndTimeValidator()])
}),
},
{
validators: [
RequiredDateValidator.CheckIfRequired()
]
}
);
}
) {}
get alternativeFormControl(): AbstractControl | undefined {
return this.avvikelseFormGroup?.get(this.alternativeFormControlName);
@@ -146,30 +119,6 @@ export class DeltagareAvvikelseComponent implements OnInit {
return this.avvikelseFormGroup.get('timepickerFormGroup').get(this.endTimeFormControlName);
}
setConfirmDialogChanged(confirm: ConfirmDialog): void {
this.openConfirmDialog = false;
if (confirm === ConfirmDialog.ACCEPTED) {
const postAvvikelse: Avvikelse = {
datum_for_rapportering: this.todayDate,
sokandeId: +this.activatedRoute.snapshot.params['genomforandeReferens'],
};
if ((this.alternativeFormControl.value as string) === Alternative.AVVIKELSE) {
postAvvikelse['avvikelsealternativ'] = this.avvikelse;
} else if ((this.alternativeFormControl.value as string) == Alternative.FRANVARO) {
postAvvikelse['franvaro'] = this.franvaro;
}
this.deltagareAvvikelseService
.createAvvikelse$(postAvvikelse, this.alternativeFormControl.value as string)
.subscribe({
error: () => this._showDangerNotification$.next(true),
next: () => this._showSuccessNotification$.next(true),
complete: () => this.avvikelseFormGroup.reset(),
});
}
}
get franvaro(): FranvaroAlternativ {
return {
avvikelseorsakskod: this.orsakerFormControl.value as string,
@@ -208,6 +157,98 @@ export class DeltagareAvvikelseComponent implements OnInit {
};
}
get showDescription(): boolean {
return (
(this.alternativeFormControl.value as string) == Alternative.FRANVARO &&
+this.orsakerFormControl.value === FranvaroOrsaksKodEnum.AnnanKandOrsak &&
+this.andraKandaOrsakerFormControl.value === KandaOrsakerEnum.AnnanOrsak
);
}
get showFragor(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.AVVIKELSE &&
(this.orsakerFormControl.value as boolean)
);
}
get showDatePicker(): boolean {
return this.orsakerFormControl.value as boolean;
}
get showDayOrPartOfDayPicker(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.FRANVARO &&
(this.orsakerFormControl.value as boolean)
);
}
get showTimePicker(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.FRANVARO &&
(this.dayOrPartOfDayFormControl.value as string) === DayOrPartOfDay.DEL_AV_DAG
);
}
get nextStep(): number {
console.log(this.avvikelseFormGroup);
this.avvikelseFormGroup.markAllAsTouched();
if (this.avvikelseFormGroup.valid && this.currentStep < this.totalAmountOfSteps) {
return this.currentStep++;
}
}
ngOnInit(): void {
this.avvikelseFormGroup = new FormGroup(
{
alternative: new FormControl(null, [RequiredValidator()]),
description: new FormControl('', [requiredDescriptionValidator()]),
date: new FormControl(this.todayDate),
dayOrPartOfDay: new FormControl(null, [requiredDayOrPartOfDayValidator()]),
orsakerFormGroup: new FormGroup({
orsaker: new FormControl([], [requiredOrsakerValidator()]),
andraKandaOrsaker: new FormControl([], [requiredAnnanKandOrsakValidator()]),
}),
fragorFormGroup: new FormGroup({
fraga1: new FormControl('', [requiredFraga1Validator()]),
fraga2: new FormControl('', [requiredfraga2Validator()]),
}),
timepickerFormGroup: new FormGroup({
startTime: new FormControl('', [requiredStartTimeValidator()]),
endTime: new FormControl('', [requiredEndTimeValidator()]),
}),
},
{
validators: [RequiredDateValidator.CheckIfRequired()],
}
);
}
setConfirmDialogChanged(confirm: ConfirmDialog): void {
this.openConfirmDialog = false;
if (confirm === ConfirmDialog.ACCEPTED) {
const postAvvikelse: Avvikelse = {
datum_for_rapportering: this.todayDate,
sokandeId: +this.activatedRoute.snapshot.params['genomforandeReferens'],
};
if ((this.alternativeFormControl.value as string) === Alternative.AVVIKELSE) {
postAvvikelse['avvikelsealternativ'] = this.avvikelse;
} else if ((this.alternativeFormControl.value as string) == Alternative.FRANVARO) {
postAvvikelse['franvaro'] = this.franvaro;
}
this.deltagareAvvikelseService
.createAvvikelse$(postAvvikelse, this.alternativeFormControl.value as string)
.subscribe({
error: () => this._showDangerNotification$.next(true),
next: () => this._showSuccessNotification$.next(true),
complete: () => this.avvikelseFormGroup.reset(),
});
}
}
setAlternative(): void {
if ((this.alternativeFormControl.value as string) == Alternative.FRANVARO) {
this.franvaroOrsaker$ = this.deltagareAvvikelseService.getOrsaksKoderFranvaro$();
@@ -257,48 +298,6 @@ export class DeltagareAvvikelseComponent implements OnInit {
}
}
get showDescription(): boolean {
return (
(this.alternativeFormControl.value as string) == Alternative.FRANVARO &&
+this.orsakerFormControl.value === FranvaroOrsaksKodEnum.AnnanKandOrsak &&
+this.andraKandaOrsakerFormControl.value === KandaOrsakerEnum.AnnanOrsak
);
}
get showFragor(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.AVVIKELSE &&
(this.orsakerFormControl.value as boolean)
);
}
get showDatePicker(): boolean {
return this.orsakerFormControl.value as boolean;
}
get showDayOrPartOfDayPicker(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.FRANVARO &&
(this.orsakerFormControl.value as boolean)
);
}
get showTimePicker(): boolean {
return (
(this.alternativeFormControl.value as string) === Alternative.FRANVARO &&
(this.dayOrPartOfDayFormControl.value as string) === DayOrPartOfDay.DEL_AV_DAG
);
}
get nextStep(): number {
console.log(this.avvikelseFormGroup);
this.avvikelseFormGroup.markAllAsTouched();
if (this.avvikelseFormGroup.valid && this.currentStep < this.totalAmountOfSteps) {
return this.currentStep++;
}
}
previousStep(): void {
if (this.currentStep > 1) {
this.currentStep--;
@@ -308,9 +307,9 @@ export class DeltagareAvvikelseComponent implements OnInit {
}
backToDeltagare(): void {
this.router.navigate(['./deltagare', this.activatedRoute.snapshot.params['genomforandeReferens']])
.catch(error => console.log(error, 'Failed to go back to deltagare')
);
this.router
.navigate(['./deltagare', this.activatedRoute.snapshot.params['genomforandeReferens']])
.catch(error => console.log(error, 'Failed to go back to deltagare'));
}
private clearControlOnAlternativeChange(): void {

View File

@@ -7,14 +7,14 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ConfirmDialogModule } from '../../../../shared/confirm-dialog/confirm-dialog.module';
import { ReportLayoutModule } from '../../../../shared/report-layout/report-layout.module';
import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module';
import { DeltagareConfirmFormModule } from './components/deltagare-confirm-form/deltagare-confirm-form.module';
import { DeltagareFragorFormModule } from './components/deltagare-fragor-form/deltagare-fragor-form.module';
import { DeltagareOrsaksFormModule } from './components/deltagare-orsaks-form/deltagare-orsaks-form.module';
import { DeltagareTimePickerModule } from './components/deltagare-time-picker/deltagare-time-picker.module';
import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component';
import { DeltagareAvvikelseService } from './deltagare-avvikelse.service';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -33,8 +33,9 @@ import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component';
DeltagareTimePickerModule,
DeltagareConfirmFormModule,
ReportLayoutModule,
ConfirmDialogModule
ConfirmDialogModule,
],
exports: [DeltagareAvvikelseComponent]
providers: [DeltagareAvvikelseService],
exports: [DeltagareAvvikelseComponent],
})
export class DeltagareAvvikelseModule { }
export class DeltagareAvvikelseModule {}

View File

@@ -8,25 +8,21 @@ import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
@Injectable()
export class DeltagareAvvikelseService {
constructor(private avvikelseApiService: AvvikelseApiService) { }
constructor(private avvikelseApiService: AvvikelseApiService) {}
public getOrsaksKoderFranvaro$(): Observable<OrsaksKoderFranvaro[]> {
return this.avvikelseApiService.getOrsaksKoderFranvaro$()
.pipe(
return this.avvikelseApiService.getOrsaksKoderFranvaro$().pipe(
map((orsaksKoder: OrsaksKoderFranvaro[]) => {
orsaksKoder.find(kod => {
if (kod.value === FranvaroOrsaksKodEnum.VAB) {
kod.name = 'Vård av barn';
}
});
return this.sortOrsaksKoder(orsaksKoder)
return this.sortOrsaksKoder(orsaksKoder);
})
)
);
}
public getOrsaksKoderAvvikelse$(): Observable<OrsaksKoderAvvikelse[]> {
@@ -65,11 +61,9 @@ export class DeltagareAvvikelseService {
if (+orsak.value == FranvaroOrsaksKodEnum.Utbildning) {
orsak.index = 4;
}
})
});
const sortedOrsaksKoder = orsaksKoder.sort((kodA, kodB) => kodA.index < kodB.index ? -1 : 1);
const sortedOrsaksKoder = orsaksKoder.sort((kodA, kodB) => (kodA.index < kodB.index ? -1 : 1));
return sortedOrsaksKoder;
}
}

View File

@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { RadiobuttonGroupDirection, RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group';
import { AbstractControl, FormArray, FormControl, FormControlName, FormGroup } from '@angular/forms';
import { RequiredValidator } from '@msfa-utils/validators/required.validator';
import { GemensamPlaneringService } from '../../services/gemensam-planering.service';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
import { RequiredValidator } from '@msfa-validators/required.validator';
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
@Component({
selector: 'msfa-deltagare-gemensam-planering',
@@ -28,7 +28,11 @@ export class DeltagareGemensamPlaneringComponent implements OnInit {
},
];
constructor(private gemensamPlaneringService: GemensamPlaneringService) {}
constructor(private gemensamPlaneringService: GemensamPlaneringApiService) {}
get participatedOnDistansFormControl(): AbstractControl | undefined {
return this.planeringFormGroup?.get(this.participatedOnDistansFormControlName);
}
ngOnInit(): void {
this.planeringFormGroup = new FormGroup({
@@ -55,9 +59,5 @@ export class DeltagareGemensamPlaneringComponent implements OnInit {
return val;
}
get participatedOnDistansFormControl(): AbstractControl | undefined {
return this.planeringFormGroup?.get(this.participatedOnDistansFormControlName);
}
onFormSubmitted(): void {}
}

View File

@@ -6,7 +6,7 @@ import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planer
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { ReactiveFormsModule } from '@angular/forms';
import { ReportLayoutModule } from '../../../../shared/report-layout/report-layout.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module';
import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
@NgModule({

View File

@@ -0,0 +1,66 @@
<msfa-layout>
<msfa-report-layout
[currentStep]="currentStep"
[endDate]="'2021-09-30'"
[isPeriodDate]="true"
[startDate]="'2021-09-01'"
[totalAmountOfSteps]="totalAmountOfSteps"
reportSubTitle="Skapa redovisning"
reportTitle="Periodisk Redovisning">
<form
*ngIf="periodiskRedovisningFormGroup"
[formGroup]="periodiskRedovisningFormGroup"
class="periodisk-redovisning">
<ng-container *ngIf="currentStep === 1">
<p>Har ni lämnat individuella förslag på arbeten till arbetssökande under perioden?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="lamnatJobbForslagFormControlName"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
*ngIf="submitted && lamnatJobbForslagFormControl.invalid"
af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
<p class="periodisk-redovisning__space-top">Har ni, under perioden, tillhandahållit språkstöd?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="providedSprakStodFormControlName"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
*ngIf="submitted && providedSprakStodFormControl.invalid"
af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
</ng-container>
<div class="periodisk-redovisning__step-buttons-wrapper">
<br/>
<ng-container *ngIf="currentStep > 1">
<digi-button (afOnClick)="previousStep()"
af-size="m" af-variation="secondary" class="periodisk-redovisning__step-buttons-wrapper--space-right">
Tillbaka
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep < (totalAmountOfSteps -1)">
<digi-button (afOnClick)="nextStep()"
af-size="m" class="periodisk-redovisning__step-buttons-wrapper">
Nästa
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === (totalAmountOfSteps -1)">
<digi-button (afOnClick)="nextStep()" af-size="m">
Förhandsgranska
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === totalAmountOfSteps">
<digi-button (afOnClick)="sendRequest(true)" af-size="m">
Skicka in
</digi-button>
</ng-container>
</div>
</form>
</msfa-report-layout>
</msfa-layout>

View File

@@ -1,4 +1,5 @@
@import 'variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.periodisk-redovisning {
&__step-buttons-wrapper--space-right {
margin-right: var(--digi--layout--gutter--s);

View File

@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
describe('PeriodiskRedovisningComponent', () => {
let component: DeltagarePeriodiskRedovisningComponent;
let fixture: ComponentFixture<DeltagarePeriodiskRedovisningComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DeltagarePeriodiskRedovisningComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DeltagarePeriodiskRedovisningComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,24 +1,21 @@
import { RadiobuttonGroupDirection } from '@af/digi-ng/_form/form-radiobutton-group';
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { Activity, SubActivity } from '@msfa-models/activity.model';
import { PeriodiskRedovisningService } from '../../services/periodisk-redovisning.service';
import { ActivitiesApiService } from '@msfa-services/api/activities-api.service';
@Component({
selector: 'msfa-periodisk-redovisning',
templateUrl: './periodisk-redovisning.component.html',
styleUrls: ['./periodisk-redovisning.component.scss'],
selector: 'msfa-deltagare-periodisk-redovisning',
templateUrl: './deltagare-periodisk-redovisning.component.html',
styleUrls: ['./deltagare-periodisk-redovisning.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PeriodiskRedovisningComponent implements OnInit {
//activities$ = this.periodiskRedovisningService.getActivities$();
export class DeltagarePeriodiskRedovisningComponent implements OnInit {
radiobuttonGroupDirection = RadiobuttonGroupDirection;
totalAmountOfSteps =3;
totalAmountOfSteps = 3;
currentStep = 1;
moveToNextStep = false;
// Form-related variables
periodiskRedovisningFormGroup: FormGroup;
submitted = false;
@@ -28,26 +25,27 @@ export class PeriodiskRedovisningComponent implements OnInit {
readonly datesForActivitiesFormArrayName = 'datesForActivities';
readonly subActivitiesFormArrayName = 'subActivities';
constructor(private periodiskRedovisningService: PeriodiskRedovisningService) {}
ngOnInit(): void {
this.periodiskRedovisningService.getActivities$().subscribe(
activities => this.initializePeriodiskRedovisningFormGroup(activities)
);
}
constructor(private activitiesApiService: ActivitiesApiService) {}
get lamnatJobbForslagFormControl(): AbstractControl {
return this.periodiskRedovisningFormGroup.get(this.lamnatJobbForslagFormControlName);
}
get providedSprakStodFormControl(): AbstractControl {
return this.periodiskRedovisningFormGroup.get(this.providedSprakStodFormControlName);
}
get activitiesFormArray(): FormArray {
return this.periodiskRedovisningFormGroup.get(this.activitiesFormArrayName) as FormArray;
}
initializePeriodiskRedovisningFormGroup(activitiesList: Activity[]):void {
ngOnInit(): void {
this.activitiesApiService
.getActivities$()
.subscribe(activities => this.initializePeriodiskRedovisningFormGroup(activities));
}
initializePeriodiskRedovisningFormGroup(activitiesList: Activity[]): void {
this.periodiskRedovisningFormGroup = new FormGroup({
lamnatJobbForslag: new FormControl(null, [Validators.required]),
providedSprakStod: new FormControl(null, [Validators.required]),
@@ -56,22 +54,20 @@ export class PeriodiskRedovisningComponent implements OnInit {
this.getActivitesFormArray(activitiesList);
}
getActivitesFormArray(activities: Activity[]):void {
getActivitesFormArray(activities: Activity[]): void {
activities.forEach(activity => {
const newActivity = [`activity${activity.id}`, 'datesForActivities', 'subActivities', 'comment'];
this.activitiesFormArray.push(
new FormGroup(
Object.fromEntries(
newActivity.map(formCtrlName => [
formCtrlName, this.getActivtiesFormField(formCtrlName, activity)
])
newActivity.map(formCtrlName => [formCtrlName, this.getActivtiesFormField(formCtrlName, activity)])
)
)
);
});
}
getActivtiesFormField(formCtrlName: string, activity: Activity):(FormArray | FormControl) {
getActivtiesFormField(formCtrlName: string, activity: Activity): FormArray | FormControl {
if (formCtrlName === 'datesForActivities') {
return new FormArray([]);
} else if (formCtrlName === 'subActivities') {
@@ -80,77 +76,64 @@ export class PeriodiskRedovisningComponent implements OnInit {
return new FormControl(null, []);
}
addSelectedDatesToFormArray(datesList: string[]):FormArray {
addSelectedDatesToFormArray(datesList: string[]): FormArray {
// TODO: Använd denna metod när datumen valts i kalendern!
const formcontrolNamesList = ['date', 'hours', 'doneOnRemote'];
const datesForActivitiesFormArray = new FormArray([]);
for (let i = 0; i < datesList.length; i++) {
datesForActivitiesFormArray.push(
new FormGroup(
Object.fromEntries(
formcontrolNamesList.map(formCtrlName => [
formCtrlName,
new FormControl(null, [])
])
)
Object.fromEntries(formcontrolNamesList.map(formCtrlName => [formCtrlName, new FormControl(null, [])]))
)
);
}
return datesForActivitiesFormArray;
}
addSubActivitesFormArray(subActivities: SubActivity[], activityId: number):FormArray {
addSubActivitesFormArray(subActivities: SubActivity[], activityId: number): FormArray {
// TODO: lägg till if-sats ex: if !subActivities etc.
if(!subActivities) {return;}
if (!subActivities) {
return;
}
const subActivitiesList = subActivities.map(activity => [`activity${activity.id}`]);
const subActivitiesFormArray = new FormArray([]);
if (activityId === 188 || activityId === 162) {
subActivitiesList.forEach(activity => {
subActivitiesFormArray.push(
new FormGroup(
Object.fromEntries(
activity.map(formCtrlName => [formCtrlName, new FormControl(null, [])])
)
)
new FormGroup(Object.fromEntries(activity.map(formCtrlName => [formCtrlName, new FormControl(null, [])])))
);
});
}
return subActivitiesFormArray;
}
getActivityId(formCtrlName: string):number {
if(!formCtrlName.startsWith('activity')) {
getActivityId(formCtrlName: string): number {
if (!formCtrlName.startsWith('activity')) {
return;
}
return Number(formCtrlName.replace('activity', ''));
}
nextStep():void {
nextStep(): void {
this.submitted = true;
console.log('TESSSSST:::', this.periodiskRedovisningFormGroup.getRawValue());
this.moveToNextStep = true;
if(
this.currentStep === 1 &&
this.lamnatJobbForslagFormControl.valid &&
this.providedSprakStodFormControl.valid
) {
if (this.currentStep === 1 && this.lamnatJobbForslagFormControl.valid && this.providedSprakStodFormControl.valid) {
this.moveToNextStep = false;
this.currentStep++;
} else if(this.periodiskRedovisningFormGroup.valid &&
this.currentStep === (this.totalAmountOfSteps-2)) {
} else if (this.periodiskRedovisningFormGroup.valid && this.currentStep === this.totalAmountOfSteps - 2) {
this.currentStep++;
}
}
previousStep():void {
previousStep(): void {
this.moveToNextStep = false;
if(this.currentStep > 1) {
if (this.currentStep > 1) {
this.currentStep--;
}
}
sendRequest(val: boolean):boolean {
sendRequest(val: boolean): boolean {
return val;
}
}

View File

@@ -3,23 +3,23 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ReportLayoutModule } from '../../../../shared/report-layout/report-layout.module';
import { PeriodiskRedovisningComponent } from './periodisk-redovisning.component';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module';
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
import { PeriodiskRedovisningFormModule } from './components/periodisk-redovisning-form/periodisk-redovisning-form.module';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [PeriodiskRedovisningComponent],
declarations: [DeltagarePeriodiskRedovisningComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: PeriodiskRedovisningComponent }]),
RouterModule.forChild([{ path: '', component: DeltagarePeriodiskRedovisningComponent }]),
LayoutModule,
ReactiveFormsModule,
ReportLayoutModule,
PeriodiskRedovisningFormModule,
DigiNgFormRadiobuttonGroupModule,
],
exports: [PeriodiskRedovisningComponent],
exports: [DeltagarePeriodiskRedovisningComponent],
})
export class PeriodiskRedovisningModule {}
export class DeltagarePeriodiskRedovisningModule {}

View File

@@ -1,5 +1,5 @@
@import 'variables/gutters';
@import 'variables/z-index';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/z-index';
.deltagare-list {
position: relative;
@@ -19,8 +19,7 @@
border-width: 0;
width: 100%;
text-align: left;
padding: var(--digi--layout--gutter--s) $digi--layout--gutter--l var(--digi--layout--gutter--s)
var(--digi--layout--gutter);
padding: var(--digi--layout--gutter--s) $digi--layout--gutter--l var(--digi--layout--gutter--s) var(--digi--layout--gutter);
margin: 0;
font-size: inherit;
font-weight: inherit;

View File

@@ -1,20 +1,20 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { DeltagareListComponent } from './deltagare-list.component';
import { DeltagareListTableComponent } from './deltagare-list-table.component';
describe('DeltagareListComponent', () => {
let component: DeltagareListComponent;
let fixture: ComponentFixture<DeltagareListComponent>;
let component: DeltagareListTableComponent;
let fixture: ComponentFixture<DeltagareListTableComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareListComponent],
declarations: [DeltagareListTableComponent],
imports: [RouterTestingModule],
}).compileComponents();
fixture = TestBed.createComponent(DeltagareListComponent);
fixture = TestBed.createComponent(DeltagareListTableComponent);
component = fixture.componentInstance;
});

View File

@@ -9,12 +9,12 @@ import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'msfa-deltagare-list',
templateUrl: './deltagare-list.component.html',
styleUrls: ['./deltagare-list.component.scss'],
selector: 'msfa-deltagare-list-table',
templateUrl: './deltagare-list-table.component.html',
styleUrls: ['./deltagare-list-table.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeltagareListComponent {
export class DeltagareListTableComponent {
@Input() deltagare: DeltagareCompact[];
@Input() paginationMeta: PaginationMeta;
@Input() deltagareLoading: boolean;

View File

@@ -4,13 +4,13 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { IconModule } from '@msfa-shared/components/icon/icon.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { DeltagareListHandelserDialogComponent } from './deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component';
import { DeltagareListComponent } from './deltagare-list.component';
import { DeltagareListHandelserDialogComponent } from '../deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component';
import { DeltagareListTableComponent } from './deltagare-list-table.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareListComponent, DeltagareListHandelserDialogComponent],
declarations: [DeltagareListTableComponent, DeltagareListHandelserDialogComponent],
imports: [CommonModule, RouterModule, IconModule, LoaderModule, DigiNgDialogModule],
exports: [DeltagareListComponent],
exports: [DeltagareListTableComponent],
})
export class DeltagareListModule {}
export class DeltagareListTableModule {}

View File

@@ -0,0 +1,45 @@
<msfa-layout>
<ng-container *ngIf="(showUnauthorizedError$ | async) === false; else roleError">
<section *ngIf="allDeltagareData$ | async as allDeltagareData; else loadingRef" class="deltagare">
<header class="deltagare__header">
<h1>Deltagarlista</h1>
<p>
Här ser du en lista på de deltagare som tillhör din organisation. Klicka på deltagarens namn för att öppna
och se mer information om deltagarna.
</p>
</header>
<div class="deltagare__filter">
<digi-form-checkbox
(afOnChange)="setOnlyMyDeltagare($event.detail.target.checked)"
[afChecked]="onlyMyDeltagare$ | async"
af-label="Visa endast mina tilldelade deltagare"
class="deltagare__only-my-deltagare"
></digi-form-checkbox>
</div>
<msfa-deltagare-list-table
(paginated)="setNewPage($event)"
(sorted)="handleDeltagareSort($event)"
*ngIf="allDeltagareData.data.length; else noDeltagare"
[deltagareLoading]="deltagareLoading$ | async"
[deltagare]="allDeltagareData.data"
[paginationMeta]="allDeltagareData.meta"
[sort]="sort$ | async"
></msfa-deltagare-list-table>
</section>
</ng-container>
</msfa-layout>
<ng-template #loadingRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar deltagare"></digi-ng-skeleton-base>
</ng-template>
<ng-template #noDeltagare>
<p *ngIf="(deltagareLoading$ | async) === false">
Inga deltagare hittades{{(onlyMyDeltagare$ | async) ? '. Bocka ur "Visa endast mina tilldelade deltagare" för att se
deltagare som tillhör din organisation.' : ' som tillhör din organisation.' }}
</p>
</ng-template>
߯
<ng-template #roleError>
<msfa-unauthorized-alert></msfa-unauthorized-alert>
</ng-template>

View File

@@ -1,4 +1,4 @@
@import 'variables/gutters';
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.deltagare {
&__header {

View File

@@ -2,16 +2,16 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { DeltagareComponent } from './deltagare.component';
import { DeltagareListComponent } from './deltagare-list.component';
describe('DeltagareComponent', () => {
let component: DeltagareComponent;
let fixture: ComponentFixture<DeltagareComponent>;
let component: DeltagareListComponent;
let fixture: ComponentFixture<DeltagareListComponent>;
beforeEach(
waitForAsync(() => {
void TestBed.configureTestingModule({
declarations: [DeltagareComponent],
declarations: [DeltagareListComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();
@@ -19,7 +19,7 @@ describe('DeltagareComponent', () => {
);
beforeEach(() => {
fixture = TestBed.createComponent(DeltagareComponent);
fixture = TestBed.createComponent(DeltagareListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -5,12 +5,12 @@ import { DeltagareService } from '@msfa-services/deltagare.service';
import { Observable } from 'rxjs';
@Component({
selector: 'msfa-deltagare',
templateUrl: './deltagare.component.html',
styleUrls: ['./deltagare.component.scss'],
selector: 'msfa-deltagare-list',
templateUrl: './deltagare-list.component.html',
styleUrls: ['./deltagare-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeltagareComponent {
export class DeltagareListComponent {
allDeltagareData$: Observable<DeltagareCompactData> = this.deltagareService.allDeltagareData$;
sort$: Observable<Sort<keyof DeltagareCompact>> = this.deltagareService.sort$;
onlyMyDeltagare$: Observable<boolean> = this.deltagareService.onlyMyDeltagare$;

View File

@@ -0,0 +1,27 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { DeltagareListComponent } from './deltagare-list.component';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { DeltagareListTableModule } from './components/deltagare-list-table/deltagare-list-table.module';
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
import { UnauthorizedAlertModule } from '@msfa-shared/components/unauthorized-alert/unauthorized-alert.module';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareListComponent],
imports: [
CommonModule,
RouterModule.forChild([
{
path: '',
component: DeltagareListComponent,
},
]),
LayoutModule,
DeltagareListTableModule,
DigiNgSkeletonBaseModule,
UnauthorizedAlertModule,
],
})
export class DeltagareListModule {}

View File

@@ -1,68 +0,0 @@
<msfa-layout>
<msfa-report-layout
reportTitle="Periodisk Redovisning"
reportSubTitle="Skapa redovisning"
[totalAmountOfSteps]="totalAmountOfSteps"
[currentStep]="currentStep"
[isPeriodDate]="true"
[startDate]="'2021-09-01'"
[endDate]="'2021-09-30'"
(currentStepEvent)="currentStep = $event"
(sendRequestEvent)="sendRequest = $event">
<form
class="periodisk-redovisning"
*ngIf="periodiskRedovisningFormGroup"
[formGroup]="periodiskRedovisningFormGroup">
<ng-container *ngIf="currentStep === 1">
<p>Har ni lämnat individuella förslag på arbeten till arbetssökande under perioden?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="lamnatJobbForslagFormControlName"
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
af-variation="error"
*ngIf="submitted && lamnatJobbForslagFormControl.invalid">
Ett val är obligatoriskt
</digi-form-validation-message>
<p class="periodisk-redovisning__space-top">Har ni, under perioden, tillhandahållit språkstöd?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="providedSprakStodFormControlName"
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
af-variation="error"
*ngIf="submitted && providedSprakStodFormControl.invalid">
Ett val är obligatoriskt
</digi-form-validation-message>
</ng-container>
<div class="periodisk-redovisning__step-buttons-wrapper">
<br />
<ng-container *ngIf="currentStep > 1">
<digi-button class="periodisk-redovisning__step-buttons-wrapper--space-right"
af-variation="secondary" af-size="m" (afOnClick)="previousStep()">
Tillbaka
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep < (totalAmountOfSteps -1)">
<digi-button class="periodisk-redovisning__step-buttons-wrapper"
af-size="m" (afOnClick)="nextStep()">
Nästa
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === (totalAmountOfSteps -1)">
<digi-button af-size="m" (afOnClick)="nextStep()">
Förhandsgranska
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === totalAmountOfSteps">
<digi-button af-size="m" (afOnClick)="sendRequest(true)">
Skicka in
</digi-button>
</ng-container>
</div>
</form>
</msfa-report-layout>
</msfa-layout>

View File

@@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PeriodiskRedovisningComponent } from './periodisk-redovisning.component';
describe('PeriodiskRedovisningComponent', () => {
let component: PeriodiskRedovisningComponent;
let fixture: ComponentFixture<PeriodiskRedovisningComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PeriodiskRedovisningComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PeriodiskRedovisningComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,16 +0,0 @@
import { Injectable } from '@angular/core';
import { Activity } from '@msfa-models/activity.model';
import { ActivityApiService } from '@msfa-services/api/activity-api.service';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DeltagareActivityService {
constructor(private activityApiService: ActivityApiService) { }
public getActivities$(): Observable<Activity[]> {
return this.activityApiService.getActivities$();
}
}

Some files were not shown because too many files have changed in this diff Show More