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 { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { DeltagareComponent } from './deltagare.component';
const routes: Routes = [ const routes: Routes = [
{ {
path: '', path: '',
component: DeltagareComponent, loadChildren: () => import('./pages/deltagare-list/deltagare-list.module').then(m => m.DeltagareListModule),
}, },
{ {
path: ':genomforandeReferens', path: ':genomforandeReferens',
data: { title: 'Deltagareinformation' }, 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: () => loadChildren: () =>
import('./pages/deltagare-report/pages/deltagare-avvikelse/deltagare-avvikelse.module').then( import('./pages/deltagare-details/deltagare-details.module').then(m => m.DeltagareDetailsModule),
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
),
}, },
// {
// 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({ @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 { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 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 { DeltagareRoutingModule } from './deltagare-routing.module';
import { DeltagareComponent } from './deltagare.component';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareComponent], imports: [CommonModule, DeltagareRoutingModule],
imports: [
CommonModule,
DeltagareRoutingModule,
LayoutModule,
DeltagareListModule,
UnauthorizedAlertModule,
DigiNgSkeletonBaseModule,
],
}) })
export class DeltagareModule {} 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 { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { ReportsComponent } from './reports.component'; import { ReportsListComponent } from './reports-list.component';
describe('ReportsComponent', () => { describe('ReportsComponent', () => {
let component: ReportsComponent; let component: ReportsListComponent;
let fixture: ComponentFixture<ReportsComponent>; let fixture: ComponentFixture<ReportsListComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [ReportsComponent], declarations: [ReportsListComponent],
imports: [RouterTestingModule] imports: [RouterTestingModule],
}).compileComponents(); }).compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ReportsComponent); fixture = TestBed.createComponent(ReportsListComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

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

View File

@@ -2,12 +2,12 @@ import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { LocalDatePipeModule } from '@msfa-shared/pipes/local-date/local-date.module'; import { LocalDatePipeModule } from '@msfa-shared/pipes/local-date/local-date.module';
import { ReportsComponent } from './reports.component'; import { ReportsListComponent } from './reports-list.component';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [ReportsComponent], declarations: [ReportsListComponent],
imports: [CommonModule, RouterModule, LocalDatePipeModule], 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> <h3>Skapa ny rapport</h3>
<p>Här kan du skicka rapporter om deltagaren till arbetsförmedlingen.</p> <p>Här kan du skicka rapporter om deltagaren till arbetsförmedlingen.</p>
<digi-ng-form-select <digi-ng-form-select
[afDisableValidStyle]="true"
[afInvalid]="reportsFormControl.invalid && reportsFormControl.touched"
[afRequired]="true"
[afSelectItems]="selectableReportTypes"
[formControlName]="reportsFormControlName" [formControlName]="reportsFormControlName"
afLabel="Välj rapporttyp" afLabel="Välj rapporttyp"
afPlaceholder="Välj rapporttyp" afPlaceholder="Välj rapporttyp"
[afSelectItems]="selectableReportTypes"
[afDisableValidStyle]="true"
[afRequired]="true"
[afInvalid]="reportsFormControl.invalid && reportsFormControl.touched"
> >
</digi-ng-form-select> </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 Du måste välja en rapporttyp
</digi-form-validation-message> </digi-form-validation-message>
</form> </form>
<div <div
class="deltagare-tab-reports__cta-wrapper"
*ngIf="currentGenomforandeReferens$ | async as currentGenomforandeReferens" *ngIf="currentGenomforandeReferens$ | async as currentGenomforandeReferens"
class="deltagare-tab-reports__cta-wrapper"
> >
<digi-ng-link-button <digi-ng-link-button
afText="Skapa ny rapport"
(click)="onFormSubmitted($event, reportsFormControl.value, currentGenomforandeReferens)" (click)="onFormSubmitted($event, reportsFormControl.value, currentGenomforandeReferens)"
afText="Skapa ny rapport"
></digi-ng-link-button> ></digi-ng-link-button>
</div> </div>
<div> <div>
<h3>Inskickade rapporter</h3> <h3>Inskickade rapporter</h3>
<msfa-reports <msfa-reports-list
[reports]="reportsData.data"
[paginationMeta]="reportsData.meta"
(paginated)="setNewPage($event)" (paginated)="setNewPage($event)"
></msfa-reports> [paginationMeta]="reportsData.meta"
[reports]="reportsData.data"
></msfa-reports-list>
</div> </div>
</div> </div>

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
@import 'variables/z-index'; @import 'apps/mina-sidor-fa/src/styles/variables/z-index';
.deltagare-tab-sensitive-information { .deltagare-tab-sensitive-information {
display: contents; display: contents;

View File

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

View File

@@ -4,7 +4,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { DeltagareCardComponent } from './deltagare-card.component'; import { DeltagareCardComponent } from './deltagare-card.component';
import { DeltagareCardService } from './services/deltagare-card.service'; import { DeltagareCardService } from './deltagare-card.service';
describe('DeltagareCardComponent', () => { describe('DeltagareCardComponent', () => {
let component: 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 { HandledareService } from '@msfa-services/handledare.service';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators'; import { distinctUntilChanged, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
import { DeltagareCardService } from './services/deltagare-card.service'; import { DeltagareCardService } from './deltagare-card.service';
@Component({ @Component({
selector: 'msfa-deltagare-card', selector: 'msfa-deltagare-details',
templateUrl: './deltagare-card.component.html', templateUrl: './deltagare-card.component.html',
styleUrls: ['./deltagare-card.component.scss'], styleUrls: ['./deltagare-card.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class DeltagareCardComponent { 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( currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe(
map(params => params.genomforandeReferens as string), map(params => params.genomforandeReferens as string),
distinctUntilChanged( distinctUntilChanged(
@@ -75,12 +69,10 @@ export class DeltagareCardComponent {
distinctUntilChanged((prevAvrop, currAvrop) => prevAvrop.id === currAvrop.id), distinctUntilChanged((prevAvrop, currAvrop) => prevAvrop.id === currAvrop.id),
switchMap(avropInformation => this.handledareService.fetchAvailableHandledare$([avropInformation.id])) switchMap(avropInformation => this.handledareService.fetchAvailableHandledare$([avropInformation.id]))
); );
tab0Loading$: Observable<boolean> = combineLatest([this.contactInformation$, this.avropInformation$]).pipe( tab0Loading$: Observable<boolean> = combineLatest([this.contactInformation$, this.avropInformation$]).pipe(
map(([contactInformation, avropInformation]) => !(contactInformation && avropInformation)), map(([contactInformation, avropInformation]) => !(contactInformation && avropInformation)),
startWith(true) startWith(true)
); );
tab2Loading$: Observable<boolean> = combineLatest([ tab2Loading$: Observable<boolean> = combineLatest([
this.workExperiences$, this.workExperiences$,
this.highestEducation$, this.highestEducation$,
@@ -101,30 +93,10 @@ export class DeltagareCardComponent {
map(([disabilities, avropInformation, workLanguages]) => !(disabilities && avropInformation && workLanguages)), map(([disabilities, avropInformation, workLanguages]) => !(disabilities && avropInformation && workLanguages)),
startWith(true) startWith(true)
); );
private _activeFeatures: Feature[] = environment.activeFeatures;
get deltagareTjanstVisible(): boolean { private _activeTab$ = new BehaviorSubject<string>('0');
return this._userRoles?.some( activeTab$: Observable<string> = this._activeTab$.asObservable();
role => role.type === RoleEnum.MSFA_ReportAndPlanning || role.type === RoleEnum.MSFA_ReceiveDeltagare private _userRoles: Role[] = this.userService.userRolesSnapshot;
);
}
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)
);
}
constructor( constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@@ -133,6 +105,34 @@ export class DeltagareCardComponent {
private userService: UserService 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 { setActiveTab(tab: number): void {
this._activeTab$.next(tab.toString()); 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 { DeltagareTabPersonalInformationComponent } from './components/deltagare-tab-personal-information/deltagare-tab-personal-information.component';
import { DeltagareTabReportsComponent } from './components/deltagare-tab-reports/deltagare-tab-reports.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 { 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 { DeltagareCardComponent } from './deltagare-card.component';
import { DeltagareCardService } from './services/deltagare-card.service'; import { DeltagareCardService } from './deltagare-card.service';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -32,7 +32,7 @@ import { DeltagareCardService } from './services/deltagare-card.service';
CommonModule, CommonModule,
RouterModule.forChild([{ path: '', component: DeltagareCardComponent }]), RouterModule.forChild([{ path: '', component: DeltagareCardComponent }]),
ReactiveFormsModule, ReactiveFormsModule,
ReportsModule, ReportsListModule,
LayoutModule, LayoutModule,
BackLinkModule, BackLinkModule,
HideTextModule, HideTextModule,

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
@import 'variables/gutters'; @import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.deltagare-confirm { .deltagare-confirm {
margin-bottom: $digi--layout--gutter--xl; margin-bottom: $digi--layout--gutter--xl;

View File

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

View File

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

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 { KandaAvvikelseKoder, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import { import {
requiredAnnanKandOrsakValidator, RequiredDateValidator, requiredAnnanKandOrsakValidator,
requiredDayOrPartOfDayValidator, requiredDescriptionValidator, requiredEndTimeValidator, RequiredDateValidator,
requiredDayOrPartOfDayValidator,
requiredDescriptionValidator,
requiredEndTimeValidator,
requiredFraga1Validator, requiredFraga1Validator,
requiredfraga2Validator, requiredOrsakerValidator, requiredStartTimeValidator requiredfraga2Validator,
} from '@msfa-utils/validators/avvikelse-form-validator'; requiredOrsakerValidator,
import { RequiredValidator } from '@msfa-utils/validators/required.validator'; requiredStartTimeValidator,
} from '@msfa-validators/avvikelse-form-validator';
import { RequiredValidator } from '@msfa-validators/required.validator';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators'; 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'; import { avvikelseAlternatives, dayOrPartOfDay } from './report-alternatives';
@Component({ @Component({
@@ -45,14 +50,8 @@ export class DeltagareAvvikelseComponent implements OnInit {
readonly fraga2FormControlName = 'fraga2'; readonly fraga2FormControlName = 'fraga2';
readonly startTimeFormControlName = 'startTime'; readonly startTimeFormControlName = 'startTime';
readonly endTimeFormControlName = 'endTime'; readonly endTimeFormControlName = 'endTime';
private _showSuccessNotification$ = new BehaviorSubject<boolean>(false);
private _showDangerNotification$ = new BehaviorSubject<boolean>(false);
contactInformation$: Observable<ContactInformation> = this.activatedRoute.params.pipe( contactInformation$: Observable<ContactInformation> = this.activatedRoute.params.pipe(
switchMap(({ genomforandeReferens }) => switchMap(({ genomforandeReferens }) => this.deltagareApiService.fetchContactInformation$(genomforandeReferens))
this.deltagareApiService.fetchContactInformation$(genomforandeReferens)
)
); );
franvaroOrsaker$: Observable<OrsaksKoderFranvaro[]>; franvaroOrsaker$: Observable<OrsaksKoderFranvaro[]>;
avvikelseOrsaker$: Observable<OrsaksKoderAvvikelse[]>; avvikelseOrsaker$: Observable<OrsaksKoderAvvikelse[]>;
@@ -68,7 +67,9 @@ export class DeltagareAvvikelseComponent implements OnInit {
totalAmountOfSteps = 2; totalAmountOfSteps = 2;
currentStep = 1; currentStep = 1;
openConfirmDialog = false; openConfirmDialog = false;
private _showSuccessNotification$ = new BehaviorSubject<boolean>(false);
showSuccessNotification$ = this._showSuccessNotification$.asObservable(); showSuccessNotification$ = this._showSuccessNotification$.asObservable();
private _showDangerNotification$ = new BehaviorSubject<boolean>(false);
showDangerNotification$ = this._showDangerNotification$.asObservable(); showDangerNotification$ = this._showDangerNotification$.asObservable();
constructor( constructor(
@@ -76,35 +77,7 @@ export class DeltagareAvvikelseComponent implements OnInit {
private deltagareApiService: DeltagareApiService, private deltagareApiService: DeltagareApiService,
private router: Router, private router: Router,
private activatedRoute: ActivatedRoute 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 { get alternativeFormControl(): AbstractControl | undefined {
return this.avvikelseFormGroup?.get(this.alternativeFormControlName); return this.avvikelseFormGroup?.get(this.alternativeFormControlName);
@@ -146,30 +119,6 @@ export class DeltagareAvvikelseComponent implements OnInit {
return this.avvikelseFormGroup.get('timepickerFormGroup').get(this.endTimeFormControlName); 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 { get franvaro(): FranvaroAlternativ {
return { return {
avvikelseorsakskod: this.orsakerFormControl.value as string, 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 { setAlternative(): void {
if ((this.alternativeFormControl.value as string) == Alternative.FRANVARO) { if ((this.alternativeFormControl.value as string) == Alternative.FRANVARO) {
this.franvaroOrsaker$ = this.deltagareAvvikelseService.getOrsaksKoderFranvaro$(); 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 { previousStep(): void {
if (this.currentStep > 1) { if (this.currentStep > 1) {
this.currentStep--; this.currentStep--;
@@ -308,9 +307,9 @@ export class DeltagareAvvikelseComponent implements OnInit {
} }
backToDeltagare(): void { backToDeltagare(): void {
this.router.navigate(['./deltagare', this.activatedRoute.snapshot.params['genomforandeReferens']]) this.router
.catch(error => console.log(error, 'Failed to go back to deltagare') .navigate(['./deltagare', this.activatedRoute.snapshot.params['genomforandeReferens']])
); .catch(error => console.log(error, 'Failed to go back to deltagare'));
} }
private clearControlOnAlternativeChange(): void { private clearControlOnAlternativeChange(): void {

View File

@@ -7,14 +7,14 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ConfirmDialogModule } from '../../../../shared/confirm-dialog/confirm-dialog.module'; import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module';
import { ReportLayoutModule } from '../../../../shared/report-layout/report-layout.module'; import { ReportLayoutModule } from '../components/report-layout/report-layout.module';
import { DeltagareConfirmFormModule } from './components/deltagare-confirm-form/deltagare-confirm-form.module'; import { DeltagareConfirmFormModule } from './components/deltagare-confirm-form/deltagare-confirm-form.module';
import { DeltagareFragorFormModule } from './components/deltagare-fragor-form/deltagare-fragor-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 { DeltagareOrsaksFormModule } from './components/deltagare-orsaks-form/deltagare-orsaks-form.module';
import { DeltagareTimePickerModule } from './components/deltagare-time-picker/deltagare-time-picker.module'; import { DeltagareTimePickerModule } from './components/deltagare-time-picker/deltagare-time-picker.module';
import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component'; import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component';
import { DeltagareAvvikelseService } from './deltagare-avvikelse.service';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -33,8 +33,9 @@ import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component';
DeltagareTimePickerModule, DeltagareTimePickerModule,
DeltagareConfirmFormModule, DeltagareConfirmFormModule,
ReportLayoutModule, 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 { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@Injectable({ @Injectable()
providedIn: 'root'
})
export class DeltagareAvvikelseService { export class DeltagareAvvikelseService {
constructor(private avvikelseApiService: AvvikelseApiService) {}
constructor(private avvikelseApiService: AvvikelseApiService) { }
public getOrsaksKoderFranvaro$(): Observable<OrsaksKoderFranvaro[]> { public getOrsaksKoderFranvaro$(): Observable<OrsaksKoderFranvaro[]> {
return this.avvikelseApiService.getOrsaksKoderFranvaro$() return this.avvikelseApiService.getOrsaksKoderFranvaro$().pipe(
.pipe( map((orsaksKoder: OrsaksKoderFranvaro[]) => {
map((orsaksKoder: OrsaksKoderFranvaro[]) => { orsaksKoder.find(kod => {
orsaksKoder.find(kod => { if (kod.value === FranvaroOrsaksKodEnum.VAB) {
if (kod.value === FranvaroOrsaksKodEnum.VAB) { kod.name = 'Vård av barn';
kod.name = 'Vård av barn'; }
} });
}); return this.sortOrsaksKoder(orsaksKoder);
return this.sortOrsaksKoder(orsaksKoder) })
}) );
)
} }
public getOrsaksKoderAvvikelse$(): Observable<OrsaksKoderAvvikelse[]> { public getOrsaksKoderAvvikelse$(): Observable<OrsaksKoderAvvikelse[]> {
@@ -65,11 +61,9 @@ export class DeltagareAvvikelseService {
if (+orsak.value == FranvaroOrsaksKodEnum.Utbildning) { if (+orsak.value == FranvaroOrsaksKodEnum.Utbildning) {
orsak.index = 4; 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; return sortedOrsaksKoder;
} }
} }

View File

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

View File

@@ -6,7 +6,7 @@ import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planer
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar'; import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { ReactiveFormsModule } from '@angular/forms'; 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'; import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
@NgModule({ @NgModule({

View File

@@ -1,6 +1,8 @@
@import 'variables/gutters'; @import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.pr-form { .pr-form {
padding: $digi--layout--gutter--xl 0; padding: $digi--layout--gutter--xl 0;
&__space-top { &__space-top {
margin-top: $digi--layout--gutter--xl; margin-top: $digi--layout--gutter--xl;
} }

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,13 +4,13 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { IconModule } from '@msfa-shared/components/icon/icon.module'; import { IconModule } from '@msfa-shared/components/icon/icon.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { DeltagareListHandelserDialogComponent } from './deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component'; import { DeltagareListHandelserDialogComponent } from '../deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component';
import { DeltagareListComponent } from './deltagare-list.component'; import { DeltagareListTableComponent } from './deltagare-list-table.component';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareListComponent, DeltagareListHandelserDialogComponent], declarations: [DeltagareListTableComponent, DeltagareListHandelserDialogComponent],
imports: [CommonModule, RouterModule, IconModule, LoaderModule, DigiNgDialogModule], 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 { .deltagare {
&__header { &__header {

View File

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

View File

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