feat(employee): Now showing utförande verksamheter/adresser and tjänster correctly. (TV-554)

Squashed commit of the following:

commit 3d1d4a33905f41028f97e7f86131e6e284aebba9
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Sep 8 11:51:06 2021 +0200

    Fixed some tests and linting

commit 651300f244f8ef3ca71f290de421033c05f4a1ca
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Sep 8 11:43:34 2021 +0200

    Some style changes

commit bc0762ba3fa36dc3b85ac3316d87a8a942fe30ee
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Sep 8 09:13:57 2021 +0200

    Fixed issue with edit employee after api changes

commit 757f69ddcdf3913fcbc967df3fdcf8cbb6ed3eb5
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Sep 8 08:48:44 2021 +0200

    Added tjänst and utforandeverksamheter/adresser to employee card
This commit is contained in:
Erik Tiekstra
2021-09-08 13:32:56 +02:00
parent e589eec505
commit 26a56fdf1f
28 changed files with 405 additions and 376 deletions

View File

@@ -17,11 +17,11 @@
<a class="employee-card__edit-button" [routerLink]="['/administration/redigera-personalkonto', employee.id]" <a class="employee-card__edit-button" [routerLink]="['/administration/redigera-personalkonto', employee.id]"
>Redigera</a >Redigera</a
> >
<h1>{{ employee.fullName }}</h1> <h1>Personalkonto</h1>
</header> </header>
<p>Här kan du se och ändra personalkontots behörigheter. Ändra behörighet genom att klicka på redigera.</p> <p>Här ser ni personalkontot. Ändra behörighet genom att klicka på redigera.</p>
<div class="employee-card__contents"> <div class="employee-card__contents">
<div class="employee-card__column"> <div class="employee-card__block">
<h2>Personuppgifter</h2> <h2>Personuppgifter</h2>
<dl class="employee-card__description-list"> <dl class="employee-card__description-list">
<dt>Förnamn</dt> <dt>Förnamn</dt>
@@ -42,58 +42,67 @@
</dd> </dd>
</dl> </dl>
</div> </div>
<div class="employee-card__column"> <div class="employee-card__block">
<h2>Tjänst</h2> <h2>Behörigheter</h2>
<p>Här kan du se personalkontots behörigheter.</p>
</div>
<div class="employee-card__block">
<h3>Tjänst</h3>
<ul class="employee-card__list" *ngIf="employee.tjanster.length"> <ul class="employee-card__list" *ngIf="employee.tjanster.length">
<li *ngFor="let tjanst of employee.tjanster">{{ tjanst.name }}</li> <li *ngFor="let tjanst of employee.tjanster">
<digi-icon-check-circle
class="employee-card__authorization-icon employee-card__authorization-icon--authorized"
></digi-icon-check-circle>
{{ tjanst.name }}
</li>
</ul> </ul>
<p *ngIf="!employee.tjanster.length">Kontot har inga registrerade tjänster ännu.</p> <p *ngIf="!employee.tjanster.length">Kontot har inga registrerade tjänster ännu.</p>
</div> </div>
<div class="employee-card__utforandeverksamheter"> <div class="employee-card__block">
<h2>Utförande verksamheter och utförande adresser</h2> <h3>Utförande verksamheter och utförande adresser</h3>
<p *ngIf="employee.allaUtforandeVerksamheter; else specificUtforandeVerksamheter"> <p *ngIf="employee.allaUtforandeVerksamheter; else specificUtforandeVerksamheter">
Kontot har behörighet till alla utförande verksamheter och utförande adresser inom organisationen. Kontot har behörighet till alla utförande verksamheter och utförande adresser inom organisationen.
</p> </p>
<ng-template #specificUtforandeVerksamheter> <ng-template #specificUtforandeVerksamheter>
<p style="color: red"> <ul
OBS: BEHÖVER FIXAS, ÄVEN OM MAN HAR UTFÖRANDE VERKSAMHETER SÅ SYNS DOM INTE DÅ VI BARA FÅR UT ID
</p>
<div
*ngIf="employee.utforandeVerksamheter?.length; else missingUtforandeVerksamheter" *ngIf="employee.utforandeVerksamheter?.length; else missingUtforandeVerksamheter"
class="employee-card__utforandeverksamheter-cards" class="employee-card__utforandeverksamheter"
> >
<digi-info-card <li *ngFor="let utforandeVerksamhet of employee.utforandeVerksamheter">
*ngFor="let utforandeverksamhet of employee.utforandeVerksamhet" <digi-info-card
[afHeading]="utforandeverksamhet.namn" [afHeading]="utforandeVerksamhet.name"
af-heading-level="h2" af-heading-level="h4"
af-type="info" af-type="info"
class="employee-card__utforandeverksamheter-card" class="employee-card__utforandeverksamhet-card"
> >
<digi-ng-layout-expansion-panel *ngIf="utforandeverksamhet.adresser.length > 0"> <p *ngIf="utforandeVerksamhet.allaAdresser">Alla adresser inom utförande verksamheten valda.</p>
<span data-slot-trigger>
<!-- vad refererar accordionExpanded till här?? Templaten bygger inte om det inte finns en definition av variabeln.. {{ accordionExpanded ? 'Dölj' : 'Visa' }} {{utforandeverksamhet.adresser.length}} --> <digi-ng-layout-expansion-panel
{{utforandeverksamhet.adresser.length === 1 ? 'adress' : 'adresser'}} *ngIf="!utforandeVerksamhet.allaAdresser && utforandeVerksamhet.adresser.length > 0"
</span> [afExpanded]="isAccordionExpanded(utforandeVerksamhet.id)"
<ul class="employee-card__utforandeverksamheter-address-list"> (click)="toggleAccordionExpanded(utforandeVerksamhet.id)"
<li >
class="employee-card__utforandeverksamheter-address-list-item" <span data-slot-trigger>
*ngFor="let address of utforandeverksamhet.adresser" {{ isAccordionExpanded(utforandeVerksamhet.id) ? 'Dölj' : 'Visa' }}
> {{utforandeVerksamhet.adresser.length}} {{utforandeVerksamhet.adresser.length === 1 ? 'adress' :
<span>{{address.adressrad}}</span> 'adresser'}}
<span>{{address.postnummer}}</span> </span>
<span>{{address.postort}}</span> <ul class="employee-card__adresser">
</li> <li *ngFor="let address of utforandeVerksamhet.adresser; let last = last">
</ul> {{address.name}}{{last ? '' : ','}}
</digi-ng-layout-expansion-panel> </li>
</digi-info-card> </ul>
</div> </digi-ng-layout-expansion-panel>
</digi-info-card>
</li>
</ul>
<ng-template #missingUtforandeVerksamheter> <ng-template #missingUtforandeVerksamheter>
<p>Kontot har inga registrerade utförande verksamheter eller utförande adresser ännu.</p> <p>Kontot har inga registrerade utförande verksamheter eller utförande adresser ännu.</p>
</ng-template> </ng-template>
</ng-template> </ng-template>
</div> </div>
<div class="employee-card__column"> <div class="employee-card__block">
<h2>Behörigheter</h2> <h3>Roller</h3>
<ul class="employee-card__list"> <ul class="employee-card__list">
<li *ngFor="let role of allRoles"> <li *ngFor="let role of allRoles">
<digi-icon-check-circle <digi-icon-check-circle

View File

@@ -1,3 +1,4 @@
@import 'functions/rem';
@import 'variables/gutters'; @import 'variables/gutters';
@import 'variables/colors'; @import 'variables/colors';
@import 'mixins/buttons'; @import 'mixins/buttons';
@@ -10,39 +11,31 @@
gap: $digi--layout--gutter--l $digi--layout--gutter--l; gap: $digi--layout--gutter--l $digi--layout--gutter--l;
} }
&__column { &__block {
width: 100%; width: 100%;
max-width: var(--digi--typography--text--max-width); max-width: var(--digi--typography--text--max-width);
} }
&__utforandeverksamheter-cards { &__utforandeverksamheter {
@include msfa__reset-list;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: $digi--layout--gutter;
} }
&__utforandeverksamheter-card { &__utforandeverksamhet-card {
--digi-info-card--padding: --digi-info-card--padding: 1.5rem 1rem;
var(--digi--layout--padding--20)
var(--digi--layout--padding--40) ::ng-deep .digi-info-card__heading {
var(--digi--layout--padding--40) margin-top: 0;
var(--digi--layout--padding--40); }
} }
&__utforandeverksamheter-address-list { &__adresser {
@include msfa__reset-list; @include msfa__reset-list;
padding-top: var(--digi--layout--padding--10); padding-top: var(--digi--layout--padding--10);
} }
&__utforandeverksamheter-address-list-item span:not(:empty):not(:last-child):after {
content: ', ';
}
&__utforandeverksamheter {
display: flex;
flex-direction: column;
}
&__header, &__header,
&__footer { &__footer {
display: flex; display: flex;
@@ -78,12 +71,7 @@
} }
&__edit-button { &__edit-button {
@include msfa-button-template( @include msfa-button('secondary');
$msfa-button--background--secondary,
$msfa-button--text--secondary,
$msfa-button--hover--secondary
);
width: var(--digi-button--width);
} }
&__authorization-icon { &__authorization-icon {

View File

@@ -17,6 +17,7 @@ export class EmployeeCardComponent implements OnDestroy {
employee$: Observable<Employee> = this.employeeService.employee$; employee$: Observable<Employee> = this.employeeService.employee$;
lastUpdatedEmployeeId$: Observable<string> = this.employeeService.lastUpdatedEmployeeId$; lastUpdatedEmployeeId$: Observable<string> = this.employeeService.lastUpdatedEmployeeId$;
allRoles: Role[] = this.employeeService.allRoles; allRoles: Role[] = this.employeeService.allRoles;
accordionsExpanded = [];
constructor(private activatedRoute: ActivatedRoute, private employeeService: EmployeeService) { constructor(private activatedRoute: ActivatedRoute, private employeeService: EmployeeService) {
this.employeeService.setCurrentEmployeeId(this.employeeId); this.employeeService.setCurrentEmployeeId(this.employeeId);
@@ -34,7 +35,19 @@ export class EmployeeCardComponent implements OnDestroy {
return this._pendingSelectedParticipants$.getValue(); return this._pendingSelectedParticipants$.getValue();
} }
isAccordionExpanded(id: number): boolean {
return this.accordionsExpanded.includes(id);
}
closeUpdatedNotificationAlert(): void { closeUpdatedNotificationAlert(): void {
this.employeeService.resetLastUpdatedEmployeeId(); this.employeeService.resetLastUpdatedEmployeeId();
} }
toggleAccordionExpanded(currentId: number): void {
if (this.accordionsExpanded.includes(currentId)) {
this.accordionsExpanded = this.accordionsExpanded.filter(id => id !== currentId);
} else {
this.accordionsExpanded.push(currentId);
}
}
} }

View File

@@ -6,7 +6,6 @@
(ngSubmit)="onFormSubmitted()" (ngSubmit)="onFormSubmitted()"
> >
<digi-ng-form-input <digi-ng-form-input
class="edit-employee-form__input"
afId="edit-employee-form-email" afId="edit-employee-form-email"
afLabel="E-post adress" afLabel="E-post adress"
afType="email" afType="email"
@@ -16,94 +15,102 @@
[afInvalid]="emailFormControl.invalid && emailFormControl.touched" [afInvalid]="emailFormControl.invalid && emailFormControl.touched"
></digi-ng-form-input> ></digi-ng-form-input>
<fieldset> <div class="edit-employee-form__contents">
<legend>Tjänster</legend> <div class="edit-employee-form__block">
<p>Välj de tjänster du vill ge personalen tillgång till.</p> <h2>Behörigheter</h2>
<digi-ng-form-select <p>Här kan du ändra personalkontots behörigheter.</p>
[formControl]="tjansterFormControl" </div>
afLabel="Välj tjänster"
[afPlaceholder]="'Välj tjänst'"
[afSelectItems]="selectableTjansterFormItems"
[afDisableValidStyle]="true"
[afInvalid]="tjansterFormControl.invalid && tjansterFormControl.touched"
(afOnChange)="toggleTjanst()"
></digi-ng-form-select>
<digi-form-validation-message
*ngIf="tjansterFormControl.invalid && tjansterFormControl.touched"
af-variation="error"
>
Du måste välja minst en tjänst
</digi-form-validation-message>
<!-- Vi får se till att bygga en kontrol för att kunna välja flera tjänster här istället, en digi-ng-select får vara en temporär lösning.. -->
</fieldset>
<fieldset> <div class="edit-employee-form__block">
<legend>Utförande verksamheter och adresser</legend> <h3>Tjänster</h3>
<p>Välj de utförandeverksamheter och utförande adresser du vill ge personalen behörighet till.</p> <p>Välj de tjänster du vill ge personalen tillgång till.</p>
<p *ngIf="!availableUtforandeVerksamheter || availableUtforandeVerksamheter.length === 0"> <!-- Vi får se till att bygga en kontrol för att kunna välja flera tjänster här istället, en digi-ng-select får vara en temporär lösning.. -->
<strong>Du måste välja en eller flera tjänster för att kunna välja utförande verksamheter.</strong> <digi-ng-form-select
</p> [formControl]="tjansterFormControl"
<div class="edit-employee-form__choose_all-utforande-verksamh"> afLabel="Välj tjänster"
[afPlaceholder]="'Välj tjänst'"
[afSelectItems]="selectableTjansterFormItems"
[afDisableValidStyle]="true"
[afInvalid]="tjansterFormControl.invalid && tjansterFormControl.touched"
(afOnChange)="toggleTjanst()"
></digi-ng-form-select>
<digi-form-validation-message
*ngIf="tjansterFormControl.invalid && tjansterFormControl.touched"
af-variation="error"
>
Du måste välja minst en tjänst
</digi-form-validation-message>
</div>
<div class="edit-employee-form__block">
<h3>Utförande verksamheter och adresser</h3>
<p>Välj de utförandeverksamheter och utförande adresser du vill ge personalen behörighet till.</p>
<p *ngIf="!availableUtforandeVerksamheter || availableUtforandeVerksamheter.length === 0">
<strong>Du måste välja en eller flera tjänster för att kunna välja utförande verksamheter.</strong>
</p>
<digi-ng-form-checkbox <digi-ng-form-checkbox
class="edit-employee-form__choose-all-utforande-verksamheter"
[formControl]="toggleAllUtforandeVerksamhetFormControl" [formControl]="toggleAllUtforandeVerksamhetFormControl"
[afLabel]="'Välj alla utförande verksamheter och alla utförande adresser'" [afLabel]="'Välj alla utförande verksamheter och alla utförande adresser'"
(afOnChange)="toggleAllUtforandeVerksamheter($event)" (afOnChange)="toggleAllUtforandeVerksamheter($event)"
> ></digi-ng-form-checkbox>
</digi-ng-form-checkbox>
<msfa-tree-nodes-selector
*ngIf="!toggleAllUtforandeVerksamhetFormControl.value"
[headingText]="'Välj utförande verksamheter och adresser'"
[formControlName]="utforandeVerksamhetFormControlName"
[isInvalid]="utforandeVerksamhetFormControl?.invalid"
[showValidation]="utforandeVerksamhetFormControl?.touched"
[validationMessages]="utforandeVerksamhetFormControl.errors?.required ? ['Välj minst en utförande verksamhet'] : []"
(selectedTreeNodesChanged)="updateToggleAllUtforandeVerksamheter()"
></msfa-tree-nodes-selector>
</div> </div>
<msfa-tree-nodes-selector
*ngIf="!toggleAllUtforandeVerksamhetFormControl.value" <div class="edit-employee-form__block" *ngIf="rolesFormGroup && availableRoles" [formGroup]="rolesFormGroup">
[headingText]="'Välj utförande verksamheter och adresser'" <h3>Roller</h3>
[formControlName]="utforandeVerksamhetFormControlName" <p>
[isInvalid]="utforandeVerksamhetFormControl?.invalid" Här tilldelar du specifika roller i systemet. Välj nedan vilka arbetsuppgifter som användaren ska kunna
[showValidation]="utforandeVerksamhetFormControl?.touched" utföra. Tänk på att rollen i systemet är begränsad till de utförande verksamheter och adresser som användaren
[validationMessages]="utforandeVerksamhetFormControl.errors?.required ? ['Välj minst en utförande verksamhet'] : []" hör till. Användaren kan därför endast utföra uppgifter och se information inom den/ de utförande adresser som
(selectedTreeNodesChanged)="updateToggleAllUtforandeVerksamheter()" tilldelats användaren.
<digi-ng-button
class="edit-employee-form__roles-dialog-button"
[afVariation]="ButtonVariation.TERTIARY"
[afType]="ButtonType.BUTTON"
[afSize]="ButtonSize.S"
afAriaControls="roles-dialog"
[afAriaLabel]="'Öppnar en dialog med information om behörigheter'"
(afOnClick)="openRolesDialog()"
>
Läs mer om roller här
</digi-ng-button>
</p>
<fieldset class="edit-employee-form__fieldset">
<legend class="msfa__a11y-sr-only">Välj roller</legend>
<ul class="edit-employee-form__roles">
<li class="edit-employee-form__role" *ngFor="let role of availableRoles">
<digi-ng-form-checkbox
[afLabel]="role.name"
[formControlName]="getFormControlName(role)"
></digi-ng-form-checkbox>
</li>
</ul>
</fieldset>
</div>
<digi-notification-alert
*ngIf="errorWhileUpdating"
af-variation="danger"
af-heading="Kunde inte spara"
af-heading-level="h4"
[afCloseable]="true"
(afOnClose)="emitCloseError()"
> >
</msfa-tree-nodes-selector> <p>Personalkontot för {{employee.fullName}} kunde inte redigeras. Vänligen försök igen.</p>
</fieldset> <p class="msfa__small-text" *ngIf="errorWhileUpdating.message">{{errorWhileUpdating.message}}</p>
</digi-notification-alert>
<fieldset *ngIf="rolesFormGroup && availableRoles" [formGroup]="rolesFormGroup"> </div>
<legend>Behörigheter</legend>
<p>
Här tilldelar du specifika behörigheter i systemet. Välj nedan vilka arbetsuppgifter som användaren ska kunna
utföra. Tänk på att behörigheten i systemet är begränsad till de utförande verksamheter och adresser som
användaren hör till. Användaren kan därför endast utföra uppgifter och se information inom den/ de utförande
adresser som tilldelats användaren.
<digi-ng-button
class="edit-employee-form__open-roles-dialog-btn"
[afVariation]="ButtonVariation.TERTIARY"
[afType]="ButtonType.BUTTON"
[afSize]="ButtonSize.S"
afAriaControls="roles-dialog"
[afAriaLabel]="'Öppnar en dialog med information om behörigheter'"
(afOnClick)="openRolesDialog()"
>
Läs mer om behörigheter här
</digi-ng-button>
</p>
<ul class="edit-employee-form__roles">
<li class="edit-employee-form__roles-item" *ngFor="let role of availableRoles">
<digi-ng-form-checkbox
[afLabel]="role.name"
[formControlName]="getFormControlName(role)"
></digi-ng-form-checkbox>
</li>
</ul>
</fieldset>
<digi-notification-alert
*ngIf="errorWhileUpdating"
af-variation="danger"
af-heading="Kunde inte spara"
af-heading-level="h2"
[afCloseable]="true"
(afOnClose)="emitCloseError()"
>
<p>Personalkontot för {{employee.fullName}} kunde inte redigeras. Vänligen försök igen.</p>
<p class="msfa__small-text" *ngIf="errorWhileUpdating.message">{{errorWhileUpdating.message}}</p>
</digi-notification-alert>
<footer class="edit-employee-form__footer"> <footer class="edit-employee-form__footer">
<a <a
@@ -138,29 +145,29 @@
[afActive]="displayRolesDialog" [afActive]="displayRolesDialog"
(afOnInactive)="closeRolesDialog()" (afOnInactive)="closeRolesDialog()"
(afOnPrimaryClick)="closeRolesDialog()" (afOnPrimaryClick)="closeRolesDialog()"
afHeading="Om behörigheterna i systemet" afHeading="Om rollerna i systemet"
afHeadingLevel="h2" afHeadingLevel="h2"
afPrimaryButtonText="Stäng" afPrimaryButtonText="Stäng"
afSecondaryButtonText="" afSecondaryButtonText=""
> >
<p> <p>
Läs beskrivningarna nedan för att lära dig mer om de olika behörigheterna. Personalen kan tilldelas en behörighet, Läs beskrivningarna nedan för att lära dig mer om de olika rollerna. Personalen kan tilldelas en roll, eller flera
eller flera behörigheter, beroende på vad de arbetar med. Tänk på att behörigheten endast gäller inom de utförande roller, beroende på vad de arbetar med. Tänk på att rollen endast gäller inom de utförande verksamheter och adresser
verksamheter och adresser som personalen fått behörighet till. som personalen fått behörighet till.
</p> </p>
<p> <p>
All personal kommer att kunna se sitt eget personalkonto, där de kan se vilka behörigheter och utförande All personal kommer att kunna se sitt eget personalkonto, där de kan se vilka roller och utförande verksamheter och
verksamheter och adresser som tilldelats dem i systemet. De kommer även att se startsidan. adresser som tilldelats dem i systemet. De kommer även att se startsidan.
</p> </p>
<h3>Administrera behörigheter</h3> <h3>Administrera behörigheter</h3>
<p> <p>
Behörigheten passar personal som ska administrera behörigheter i systemet. Behörigheten bör begränsas till ett fåtal Rollen passar personal som ska administrera behörigheter i systemet. Rollen bör begränsas till ett fåtal personer
personer och kan användas av exempelvis firmatecknare, behörighetsadministratör, eller annan person som ska kunna och kan användas av exempelvis firmatecknare, behörighetsadministratör, eller annan person som ska kunna
administrera personalens behörigheter. Behörigheten gäller endast inom de utförande verksamheter och adresser som administrera personalens behörigheter. Rollen gäller endast inom de utförande verksamheter och adresser som getts
getts behörighet till. behörighet till.
</p> </p>
<p>Behörigheten ger tillgång till följande funktioner:</p> <p>Rollen ger tillgång till följande funktioner:</p>
<ul> <ul>
<li>Skapa nya personalkonton</li> <li>Skapa nya personalkonton</li>
<li>Se personallista</li> <li>Se personallista</li>
@@ -170,12 +177,12 @@
<h3>Ta emot nya deltagare</h3> <h3>Ta emot nya deltagare</h3>
<p> <p>
Behörigheten passar personal som ska se nya deltagare som inkommit i systemet och som ska tilldela handledare till Rollen passar personal som ska se nya deltagare som inkommit i systemet och som ska tilldela handledare till nya
nya deltagare. Behörigheten kan exempelvis användas av samordnande roller, handledare, administratörer, eller annan deltagare. Rollen kan exempelvis användas av samordnande roller, handledare, administratörer, eller annan personal
personal som ska kunna utföra dessa arbetsuppgifter. Behörigheten gäller endast inom de utförande verksamheter och som ska kunna utföra dessa arbetsuppgifter. Rollen gäller endast inom de utförande verksamheter och adresser som
adresser som getts behörighet till. getts behörighet till.
</p> </p>
<p>Behörigheten ger tillgång till följande funktioner:</p> <p>Rollen ger tillgång till följande funktioner:</p>
<ul> <ul>
<li>Se lista över nya deltagare som inkommit</li> <li>Se lista över nya deltagare som inkommit</li>
<li>Tilldela handledare till nya deltagare</li> <li>Tilldela handledare till nya deltagare</li>
@@ -184,12 +191,12 @@
<h3>Rapportering, planering och information om deltagare</h3> <h3>Rapportering, planering och information om deltagare</h3>
<p> <p>
Behörigheten passar personal som arbetar nära deltagare. Behörigheten kan användas av exempelvis handledare, Rollen passar personal som arbetar nära deltagare. Rollen kan användas av exempelvis handledare, coacher, studie-
coacher, studie- och yrkesvägledare, lärare eller andra roller som behöver se information om deltagare, planera och yrkesvägledare, lärare eller andra roller som behöver se information om deltagare, planera aktiviteter med
aktiviteter med deltagare eller hantera deltagares rapporter. Behörigheten gäller endast inom de utförande deltagare eller hantera deltagares rapporter. Rollen gäller endast inom de utförande verksamheter och adresser som
verksamheter och adresser som getts behörighet till. getts behörighet till.
</p> </p>
<p>Behörigheten ger tillgång till följande funktioner:</p> <p>Rollen ger tillgång till följande funktioner:</p>
<ul> <ul>
<li>Se lista över deltagare</li> <li>Se lista över deltagare</li>

View File

@@ -1,38 +1,24 @@
@import 'mixins/buttons';
@import 'mixins/list'; @import 'mixins/list';
@import 'variables/gutters'; @import 'variables/gutters';
@import '~@digi/core/dist/collection/components/_button/button/button.css'; @import '~@digi/core/dist/collection/components/_button/button/button.css';
.edit-employee-form { .edit-employee-form {
max-width: var(--digi--typography--text--max-width); &__contents {
fieldset {
margin: 2.5rem 0;
padding: 0;
border: 0 none transparent;
}
legend {
width: 100%;
padding: 0;
display: flex; display: flex;
align-items: center; flex-direction: column;
font-weight: var(--digi--typography--font-weight--semibold); gap: $digi--layout--gutter--l $digi--layout--gutter--l;
font-size: var(--digi--typography--font-size--h2--desktop);
margin-bottom: var(--digi-typography--margin--h2);
} }
&__service-tag { &__block {
padding-top: .5rem;
}
&__service-tag--item {
margin-right: 1rem;
}
&__input {
display: block;
width: 100%; width: 100%;
margin-bottom: var(--digi--layout--gutter); max-width: var(--digi--typography--text--max-width);
}
&__fieldset {
margin: 0;
padding: 0;
border-width: 0;
} }
&__roles { &__roles {
@@ -40,7 +26,7 @@
margin-bottom: var(--digi--layout--gutter); margin-bottom: var(--digi--layout--gutter);
} }
&__roles-item { &__role {
margin-top: var(--digi--layout--gutter); margin-top: var(--digi--layout--gutter);
::ng-deep label { ::ng-deep label {
@@ -48,7 +34,7 @@
} }
} }
&__open-roles-dialog-btn { &__roles-dialog-button {
::ng-deep button { ::ng-deep button {
padding: 0 !important; padding: 0 !important;
} }
@@ -61,40 +47,11 @@
} }
&__link-btn { &__link-btn {
font-family: var(--digi-button--font-family); @include msfa-button('secondary');
background: var(--digi-button--background);
color: var(--digi-button--color);
padding: var(--digi-button--padding);
border-radius: var(--digi-button--border-radius);
border: var(--digi-button--border);
border-color: var(--digi-button--border-color);
font-weight: var(--digi-button--font-weight);
font-size: var(--digi-button--font-size);
outline: var(--digi-button--outline);
text-align: var(--digi-button--text-align);
cursor: pointer;
width: var(--digi-button--width);
display: var(--digi-button--display);
text-align: var(--digi-button--text-align);
text-decoration: none;
} }
&__link-btn--secondary { &__choose-all-utforande-verksamheter {
--digi-button--background: var(--digi-button--background--secondary); display: block;
--digi-button--background--hover: var(--digi-button--background--secondary--hover);
--digi-button--color: var(--digi-button--color--secondary);
--digi-button--color--hover: var(--digi-button--color--secondary);
--digi-button--border-color--disabled: var(--digi-button--border-color--secondary--disabled);
&:focus,
&:hover {
--digi-button--background: var(--digi-button--background--hover);
--digi-button--border-color: var(--digi-button--border-color--hover);
--digi-button--color: var(--digi-button--color--hover);
--digi-button--outline: var(--digi-button--outline--focus);
}
}
&__choose_all-utforande-verksamh {
margin: 1.5rem 0; margin: 1.5rem 0;
} }
} }

View File

@@ -49,10 +49,6 @@ describe('EditEmployeeFormComponent', () => {
tjanster: [], tjanster: [],
allaUtforandeVerksamheter: false, allaUtforandeVerksamheter: false,
utforandeVerksamheter: [], utforandeVerksamheter: [],
tjanstCodes: [],
utforandeVerksamhetIds: [],
utforandeAdressIds: [],
}; };
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -17,10 +17,8 @@ import { Employee } from '@msfa-models/employee.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { Role } from '@msfa-models/role.model'; import { Role } from '@msfa-models/role.model';
import { Tjanst } from '@msfa-models/tjanst.model'; import { Tjanst } from '@msfa-models/tjanst.model';
import { import { UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model';
UtforandeVerksamhet, import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
UtforandeVerksamheterService,
} from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
import { import {
TreeNode, TreeNode,
TreeNodesSelectorService, TreeNodesSelectorService,
@@ -30,13 +28,6 @@ import { RequiredValidator } from '@msfa-utils/validators/required.validator';
import { TreeNodeValidator } from '@msfa-utils/validators/tree-node.validator'; import { TreeNodeValidator } from '@msfa-utils/validators/tree-node.validator';
import { EmployeeFormService } from '../services/employee-form.service'; import { EmployeeFormService } from '../services/employee-form.service';
export interface EditEmployeeFormData {
email: string;
tjanster: Tjanst[];
roles: Role[];
utforandeVerksamheter: UtforandeVerksamhet[];
}
@Component({ @Component({
selector: 'msfa-edit-employee-form', selector: 'msfa-edit-employee-form',
templateUrl: './edit-employee-form.component.html', templateUrl: './edit-employee-form.component.html',
@@ -146,9 +137,14 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
} }
private initializeEditEmployeeFormGroup(): void { private initializeEditEmployeeFormGroup(): void {
const currentTjanst = this.employee.tjanster[0];
const tjanstId = currentTjanst
? this.availableTjanster.find(tjanst => tjanst.code === currentTjanst.tjansteKod).tjanstId
: null;
this.editEmployeeFormGroup = new FormGroup({ this.editEmployeeFormGroup = new FormGroup({
email: new FormControl(this.employee.email, [RequiredValidator('E-postadress'), EmailValidator()]), email: new FormControl(this.employee.email, [RequiredValidator('E-postadress'), EmailValidator()]),
tjanster: new FormControl(this.employee.tjanster[0]?.tjanstId, [RequiredValidator('Tjänst')]), tjanster: new FormControl(tjanstId, [RequiredValidator('Tjänst')]),
roles: this.employeeFormService.getRolesFormGroup(this.availableRoles, this.employee.roles), roles: this.employeeFormService.getRolesFormGroup(this.availableRoles, this.employee.roles),
utforandeVerksamheter: new FormControl( utforandeVerksamheter: new FormControl(
this.utforandeVerksamheterService.getTreeNodeDataFromUtforandeVerksamheter(this.availableUtforandeVerksamheter), this.utforandeVerksamheterService.getTreeNodeDataFromUtforandeVerksamheter(this.availableUtforandeVerksamheter),

View File

@@ -37,6 +37,7 @@
</div> </div>
<div class="employee-form__block"> <div class="employee-form__block">
<msfa-edit-employee-form <msfa-edit-employee-form
*ngIf="employee && (tjanster$ | async)"
[employee]="employee" [employee]="employee"
[availableRoles]="availableRoles" [availableRoles]="availableRoles"
[availableTjanster]="tjanster$ | async" [availableTjanster]="tjanster$ | async"

View File

@@ -10,7 +10,6 @@
&__block { &__block {
max-width: var(--digi--typography--text--max-width); max-width: var(--digi--typography--text--max-width);
margin-bottom: $digi--layout--gutter--xl;
} }
&__input { &__input {

View File

@@ -5,12 +5,10 @@ import { Employee } from '@msfa-models/employee.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { Role } from '@msfa-models/role.model'; import { Role } from '@msfa-models/role.model';
import { Tjanst } from '@msfa-models/tjanst.model'; import { Tjanst } from '@msfa-models/tjanst.model';
import { UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model';
import { EmployeeService } from '@msfa-services/api/employee.service'; import { EmployeeService } from '@msfa-services/api/employee.service';
import { TjanstService } from '@msfa-services/api/tjanst.service'; import { TjanstService } from '@msfa-services/api/tjanst.service';
import { import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
UtforandeVerksamhet,
UtforandeVerksamheterService,
} from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators'; import { filter, switchMap } from 'rxjs/operators';
@@ -29,7 +27,7 @@ export class EmployeeFormComponent implements OnInit {
tjanster$: Observable<Tjanst[]> = this.tjanstService.tjanster$; tjanster$: Observable<Tjanst[]> = this.tjanstService.tjanster$;
availableUtforandeVerksamheter$: Observable<UtforandeVerksamhet[]> = this._selectedTjanstIds$.pipe( availableUtforandeVerksamheter$: Observable<UtforandeVerksamhet[]> = this._selectedTjanstIds$.pipe(
filter(selectedTjanstIds => !!selectedTjanstIds?.length), filter(selectedTjanstIds => !!selectedTjanstIds?.length),
switchMap(selectedTjanstIds => this.utforandeVerksamheterService.getUtforandeVerksamheter(selectedTjanstIds)) switchMap(selectedTjanstIds => this.utforandeVerksamheterService.fetchUtforandeVerksamheter$(selectedTjanstIds))
); );
availableRoles: Role[] = this.employeeService.allRoles; availableRoles: Role[] = this.employeeService.allRoles;

View File

@@ -2,7 +2,6 @@ import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
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 { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { SortOrder } from '@msfa-enums/sort-order.enum'; import { SortOrder } from '@msfa-enums/sort-order.enum';
import { EmployeeCompactResponse } from '@msfa-models/api/employee.response.model'; import { EmployeeCompactResponse } from '@msfa-models/api/employee.response.model';
@@ -13,7 +12,6 @@ import { employeesMock } from './employees-list.mock';
describe('EmployeesListComponent', () => { describe('EmployeesListComponent', () => {
let component: EmployeesListComponent; let component: EmployeesListComponent;
let fixture: ComponentFixture<EmployeesListComponent>; let fixture: ComponentFixture<EmployeesListComponent>;
const getEmployeeRows = () => fixture.debugElement.queryAll(By.css('.employees-list__row'));
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({

View File

@@ -33,15 +33,15 @@ export class AvropFiltersComponent {
this.avropService.setSelectedKommuner(filterOptions); this.avropService.setSelectedKommuner(filterOptions);
} }
removeKommun(kommunToRemove: MultiselectFilterOption) { removeKommun(kommunToRemove: MultiselectFilterOption): void {
this.avropService.removeKommun(kommunToRemove); this.avropService.removeKommun(kommunToRemove);
} }
removeUtforandeVerksamhet(utforandeVerksamhetToRemove: MultiselectFilterOption) { removeUtforandeVerksamhet(utforandeVerksamhetToRemove: MultiselectFilterOption): void {
this.avropService.removeUtforandeVerksamhet(utforandeVerksamhetToRemove); this.avropService.removeUtforandeVerksamhet(utforandeVerksamhetToRemove);
} }
removeTjanst(tjanstToRemove: MultiselectFilterOption) { removeTjanst(tjanstToRemove: MultiselectFilterOption): void {
this.avropService.removeTjanst(tjanstToRemove); this.avropService.removeTjanst(tjanstToRemove);
} }
} }

View File

@@ -0,0 +1,4 @@
export interface EmployeeAdressResponse {
id: number;
namn: string;
}

View File

@@ -0,0 +1,4 @@
export interface EmployeeTjanstResponse {
namn: string;
tjansteKod: string;
}

View File

@@ -0,0 +1,8 @@
import { EmployeeAdressResponse } from './employee-adress.response.model';
export interface EmployeeUtforandeVerksamhetResponse {
id: number;
namn: string;
allaAdresser: boolean;
adresser: EmployeeAdressResponse[];
}

View File

@@ -1,18 +1,7 @@
import { RoleEnum } from '@msfa-enums/role.enum'; import { RoleEnum } from '@msfa-enums/role.enum';
import { PaginationMeta } from '@msfa-models/pagination-meta.model'; import { PaginationMeta } from '@msfa-models/pagination-meta.model';
import { TjanstResponse } from './tjanst.response.model'; import { EmployeeTjanstResponse } from './employee-tjanst.response.model';
import { EmployeeUtforandeVerksamhetResponse } from './employee-utforande-verksamhet.response.model';
interface UtforandeVerksamhetResponse {
id: number;
name: string;
allaAdresser: boolean;
adresser?: AdressResponse[];
}
interface AdressResponse {
id: number;
name: string;
}
export interface EmployeeCompactResponse { export interface EmployeeCompactResponse {
ciamUserId: string; ciamUserId: string;
@@ -29,14 +18,9 @@ export interface EmployeeResponse {
email: string; email: string;
ssn: string; ssn: string;
roles: RoleEnum[]; roles: RoleEnum[];
tjanster: TjanstResponse[]; tjanster: EmployeeTjanstResponse[];
allaUtforandeVerksamheter: boolean; allaUtforandeVerksamheter: boolean;
utforandeVerksamheter: UtforandeVerksamhetResponse[]; utforandeVerksamheter: EmployeeUtforandeVerksamhetResponse[];
// Will be removed
tjansteKoder: string[];
utforandeVerksamhetIds: number[];
adressIds: number[];
} }
export interface EmployeesDataResponse { export interface EmployeesDataResponse {

View File

@@ -0,0 +1,4 @@
export interface UtforandeAdressResponse {
id: number;
namn: string;
}

View File

@@ -0,0 +1,7 @@
import { UtforandeAdressResponse } from './utforande-adress.response.model';
export interface UtforandeVerksamhetResponse {
id: number;
name: string;
adresser: UtforandeAdressResponse[];
}

View File

@@ -0,0 +1,15 @@
import { EmployeeAdressResponse } from './api/employee-adress.response.model';
export interface EmployeeAdress {
id: number;
name: string;
}
export function mapResponseToEmployeeAdress(data: EmployeeAdressResponse): EmployeeAdress {
const { id, namn } = data;
return {
id,
name: namn,
};
}

View File

@@ -0,0 +1,15 @@
import { EmployeeTjanstResponse } from './api/employee-tjanst.response.model';
export interface EmployeeTjanst {
name: string;
tjansteKod: string;
}
export function mapResponseToEmployeeTjanst(data: EmployeeTjanstResponse): EmployeeTjanst {
const { namn, tjansteKod } = data;
return {
name: namn,
tjansteKod,
};
}

View File

@@ -0,0 +1,22 @@
import { EmployeeUtforandeVerksamhetResponse } from './api/employee-utforande-verksamhet.response.model';
import { EmployeeAdress, mapResponseToEmployeeAdress } from './employee-adress.model';
export interface EmployeeUtforandeVerksamhet {
id: number;
name: string;
allaAdresser: boolean;
adresser: EmployeeAdress[];
}
export function mapResponseToEmployeeUtforandeVerksamhet(
data: EmployeeUtforandeVerksamhetResponse
): EmployeeUtforandeVerksamhet {
const { id, namn, allaAdresser, adresser } = data;
return {
id,
name: namn,
allaAdresser,
adresser: adresser.map(adress => mapResponseToEmployeeAdress(adress)),
};
}

View File

@@ -1,22 +1,14 @@
import { RoleEnum } from '@msfa-enums/role.enum'; import { RoleEnum } from '@msfa-enums/role.enum';
import { EmployeeCompactResponse, EmployeeResponse } from './api/employee.response.model'; import { EmployeeCompactResponse, EmployeeResponse } from './api/employee.response.model';
import { EmployeeTjanst, mapResponseToEmployeeTjanst } from './employee-tjanst.model';
import {
EmployeeUtforandeVerksamhet,
mapResponseToEmployeeUtforandeVerksamhet,
} from './employee-utforande-verksamhet.model';
import { PaginationMeta } from './pagination-meta.model'; import { PaginationMeta } from './pagination-meta.model';
import { mapResponseToTjanst, Tjanst } from './tjanst.model';
const CURRENT_YEAR = new Date().getFullYear().toString().slice(2, 4); const CURRENT_YEAR = new Date().getFullYear().toString().slice(2, 4);
interface UtforandeVerksamhet {
id: number;
name: string;
allaAdresser: boolean;
adresser?: Adress[];
}
interface Adress {
id: number;
name: string;
}
export interface EmployeeCompact { export interface EmployeeCompact {
id: string; id: string;
fullName: string; fullName: string;
@@ -33,13 +25,9 @@ export interface Employee {
email: string; email: string;
ssn: string; ssn: string;
roles: RoleEnum[]; roles: RoleEnum[];
tjanster: Tjanst[]; tjanster: EmployeeTjanst[];
allaUtforandeVerksamheter: boolean; allaUtforandeVerksamheter: boolean;
utforandeVerksamheter: UtforandeVerksamhet[]; utforandeVerksamheter: EmployeeUtforandeVerksamhet[];
tjanstCodes: string[];
utforandeVerksamhetIds: number[];
utforandeAdressIds: number[];
} }
export interface EmployeesData { export interface EmployeesData {
@@ -81,9 +69,6 @@ export function mapResponseToEmployee(data: EmployeeResponse): Employee {
tjanster, tjanster,
allaUtforandeVerksamheter, allaUtforandeVerksamheter,
utforandeVerksamheter, utforandeVerksamheter,
tjansteKoder,
utforandeVerksamhetIds,
adressIds,
} = data; } = data;
return { return {
id: ciamUserId, id: ciamUserId,
@@ -93,11 +78,10 @@ export function mapResponseToEmployee(data: EmployeeResponse): Employee {
email, email,
ssn: ssn ? mapResponseToSsn(ssn) : null, ssn: ssn ? mapResponseToSsn(ssn) : null,
roles: roles || [], roles: roles || [],
tjanster: tjanster?.map(tjanst => mapResponseToTjanst(tjanst)), tjanster: tjanster?.map(tjanst => mapResponseToEmployeeTjanst(tjanst)),
allaUtforandeVerksamheter, allaUtforandeVerksamheter,
utforandeVerksamheter, utforandeVerksamheter: utforandeVerksamheter.map(utforandeVerksamhet =>
tjanstCodes: tjansteKoder || [], mapResponseToEmployeeUtforandeVerksamhet(utforandeVerksamhet)
utforandeVerksamhetIds: utforandeVerksamhetIds || [], ),
utforandeAdressIds: adressIds || [],
}; };
} }

View File

@@ -1,12 +1,11 @@
import { Tjanst } from "./tjanst.model"; import { Tjanst } from './tjanst.model';
export interface FormTagData { export interface FormTagData {
tjanstekod: string, tjanstekod: string;
name: string; name: string;
} }
export function mapTjanstToFormTag(tjanstData: Tjanst): FormTagData { export function mapTjanstToFormTag(tjanstData: Tjanst): FormTagData {
const { name, code } = tjanstData; const { name, code } = tjanstData;
return { tjanstekod: code, name} return { tjanstekod: code, name };
} }

View File

@@ -0,0 +1,15 @@
import { UtforandeAdressResponse } from './api/utforande-adress.response.model';
export interface UtforandeAdress {
id: number;
name: string;
}
export function mapResponseToUtforandeAdress(data: UtforandeAdressResponse): UtforandeAdress {
const { id, namn } = data;
return {
id,
name: namn,
};
}

View File

@@ -0,0 +1,18 @@
import { UtforandeVerksamhetResponse } from './api/utforande-verksamhet.response.model';
import { mapResponseToUtforandeAdress, UtforandeAdress } from './utforande-adress.model';
export interface UtforandeVerksamhet {
id: number;
name: string;
adresser: UtforandeAdress[];
}
export function mapResponseToUtforandeVerksamhet(data: UtforandeVerksamhetResponse): UtforandeVerksamhet {
const { id, name, adresser } = data;
return {
id,
name,
adresser: adresser.map(adress => mapResponseToUtforandeAdress(adress)),
};
}

View File

@@ -24,7 +24,6 @@ import { Sort } from '@msfa-models/sort.model';
import { ErrorService } from '@msfa-services/error.service'; import { ErrorService } from '@msfa-services/error.service';
import { BehaviorSubject, combineLatest, Observable, of, throwError } from 'rxjs'; import { BehaviorSubject, combineLatest, Observable, of, throwError } from 'rxjs';
import { catchError, distinctUntilChanged, filter, map, switchMap, take, tap } from 'rxjs/operators'; import { catchError, distinctUntilChanged, filter, map, switchMap, take, tap } from 'rxjs/operators';
import { TjanstService } from './tjanst.service';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@@ -48,11 +47,7 @@ export class EmployeeService extends UnsubscribeDirective {
private _employeeToDelete$ = new BehaviorSubject<Employee>(null); private _employeeToDelete$ = new BehaviorSubject<Employee>(null);
public employeeToDelete$: Observable<Employee> = this._employeeToDelete$.asObservable(); public employeeToDelete$: Observable<Employee> = this._employeeToDelete$.asObservable();
constructor( constructor(private httpClient: HttpClient, private errorService: ErrorService) {
private httpClient: HttpClient,
private errorService: ErrorService,
private tjanstService: TjanstService
) {
super(); super();
super.unsubscribeOnDestroy( super.unsubscribeOnDestroy(
combineLatest([this._currentEmployeeId$, this._lastUpdatedEmployeeId$]) combineLatest([this._currentEmployeeId$, this._lastUpdatedEmployeeId$])
@@ -63,20 +58,7 @@ export class EmployeeService extends UnsubscribeDirective {
!currLastUpdatedEmployeeId && prevEmployeeId === currEmployeeId !currLastUpdatedEmployeeId && prevEmployeeId === currEmployeeId
), ),
switchMap(([currentEmployeeId]) => switchMap(([currentEmployeeId]) =>
combineLatest([this._fetchEmployee$(currentEmployeeId), this.tjanstService.tjanster$]).pipe( this._fetchEmployee$(currentEmployeeId).pipe(filter(employee => !!employee))
filter(([employee, allTjanster]) => !!(employee && allTjanster?.length)),
map(([employee, allTjanster]) => {
const tjanster = [];
employee.tjanstCodes?.forEach(code => {
const currentTjanst = allTjanster.find(tjanst => tjanst.code === code);
if (currentTjanst) {
tjanster.push(currentTjanst);
}
});
return { ...employee, tjanster };
})
)
) )
) )
.subscribe(employee => { .subscribe(employee => {

View File

@@ -2,39 +2,34 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { environment } from '@msfa-environment'; import { environment } from '@msfa-environment';
import { Params } from '@msfa-models/api/params.model'; import { Params } from '@msfa-models/api/params.model';
import { UtforandeVerksamhetResponse } from '@msfa-models/api/utforande-verksamhet.response.model';
import { UtforandeAdress } from '@msfa-models/utforande-adress.model';
import { mapResponseToUtforandeVerksamhet, UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model';
import { import {
TreeNode, TreeNode,
TreeNodesSelectorService, TreeNodesSelectorService,
} from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service'; } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
export interface UtforandeVerksamhetAdress {
id: number;
namn: string;
}
export interface UtforandeVerksamhet {
id: number;
name: string;
adresser: Array<UtforandeVerksamhetAdress>;
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class UtforandeVerksamheterService { export class UtforandeVerksamheterService {
private readonly apiBaseUrl = `${environment.api.url}/utforandeverksamheter`; private readonly _apiBaseUrl = `${environment.api.url}/utforandeverksamheter`;
constructor(private treeNodesSelectorService: TreeNodesSelectorService, private httpClient: HttpClient) {} constructor(private treeNodesSelectorService: TreeNodesSelectorService, private httpClient: HttpClient) {}
getUtforandeVerksamheter(tjanstIds: Array<number>): Observable<Array<UtforandeVerksamhet>> { fetchUtforandeVerksamheter$(tjanstIds: number[]): Observable<UtforandeVerksamhet[]> {
if (!tjanstIds.length) { if (!tjanstIds.length) {
return of<Array<UtforandeVerksamhet>>([]); return of<UtforandeVerksamhet[]>([]);
} }
const params: Params = { tjansteIds: tjanstIds.map(tjanstId => tjanstId.toString()) }; const params: Params = { tjansteIds: tjanstIds.map(tjanstId => tjanstId.toString()) };
return this.httpClient.get<Array<UtforandeVerksamhet>>(`${this.apiBaseUrl}`, { params }); return this.httpClient
.get<{ data: UtforandeVerksamhetResponse[] }>(`${this._apiBaseUrl}`, { params })
.pipe(map(({ data }) => data.map(uv => mapResponseToUtforandeVerksamhet(uv))));
} }
getSelectedAdressIdsFromTreeNode(treeNode: TreeNode): number[] { getSelectedAdressIdsFromTreeNode(treeNode: TreeNode): number[] {
@@ -43,7 +38,7 @@ export class UtforandeVerksamheterService {
return selectedUtforandeVerksamheter.map(uv => uv.adresser.map(adress => adress.id)).flat(); return selectedUtforandeVerksamheter.map(uv => uv.adresser.map(adress => adress.id)).flat();
} }
getTreeNodeDataFromUtforandeVerksamheter(utforandeVerksamhetList: Array<UtforandeVerksamhet>): TreeNode | null { getTreeNodeDataFromUtforandeVerksamheter(utforandeVerksamhetList: UtforandeVerksamhet[]): TreeNode | null {
let treeNode: TreeNode | null = null; let treeNode: TreeNode | null = null;
if (!utforandeVerksamhetList || utforandeVerksamhetList.length === 0 || !Array.isArray(utforandeVerksamhetList)) { if (!utforandeVerksamhetList || utforandeVerksamhetList.length === 0 || !Array.isArray(utforandeVerksamhetList)) {
@@ -67,7 +62,7 @@ export class UtforandeVerksamheterService {
childItemType: 'Adresser', childItemType: 'Adresser',
children: utforandeVerksamhet.adresser children: utforandeVerksamhet.adresser
? utforandeVerksamhet.adresser.map(adress => { ? utforandeVerksamhet.adresser.map(adress => {
return { label: adress.namn, isSelected: false, value: adress }; return { label: adress.name, isSelected: false, value: adress };
}) })
: [], : [],
}; };
@@ -80,8 +75,8 @@ export class UtforandeVerksamheterService {
return treeNode; return treeNode;
} }
getSelectedUtforandeVerksamheterFromTreeNode(treeNode: TreeNode): Array<UtforandeVerksamhet> { getSelectedUtforandeVerksamheterFromTreeNode(treeNode: TreeNode): UtforandeVerksamhet[] {
let utforandeVerksamhetList: Array<UtforandeVerksamhet> = []; let utforandeVerksamhetList: UtforandeVerksamhet[] = [];
if (!treeNode || !treeNode.children) { if (!treeNode || !treeNode.children) {
return utforandeVerksamhetList; return utforandeVerksamhetList;
@@ -95,7 +90,7 @@ export class UtforandeVerksamheterService {
name: originalUtforandeVerksamhet?.name, name: originalUtforandeVerksamhet?.name,
id: originalUtforandeVerksamhet?.id, id: originalUtforandeVerksamhet?.id,
adresser: utforandeVerksamhetNode.children.map(adressNode => { adresser: utforandeVerksamhetNode.children.map(adressNode => {
return adressNode.value as UtforandeVerksamhetAdress; return adressNode.value as UtforandeAdress;
}), }),
}; };
return utforandeVerksamhet; return utforandeVerksamhet;

View File

@@ -1,31 +1,42 @@
@import './variables/colors'; @mixin msfa-button($type: 'primary') {
padding: var(--digi-button--padding);
//Button properties border-radius: var(--digi-button--border-radius);
transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s;
$msfa-button--padding: var(--digi-button--padding);
$msfa-button--margin: 0.5rem;
$msfa-button--border-radius: var(--digi-button--border-radius);
$msfa-button--transition: background 0.2s, border-color 0.2s, box-shadow 0.2s;
$msfa-button--border: var(--digi-button--border);
$msfa-button--text-decoration: none;
$msfa-button--font-weight: var(--digi-button--font-weight);
$msfa-button--font-font-size: var(--digi-button--font-size);
//A basic link button
@mixin msfa-button-template($backgroundcolor, $textcolor, $hovercolor) {
background: $backgroundcolor;
padding: $msfa-button--padding;
margin: $msfa-button--margin;
border-radius: $msfa-button--border-radius;
transition: $msfa-button--transition;
border: $msfa-button--border;
text-decoration: none; text-decoration: none;
font-weight: $msfa-button--font-weight; font-weight: var(--digi-button--font-weight);
font-size: $msfa-button--font-font-size; font-size: var(--digi-button--font-size);
color: $textcolor; width: var(--digi-button--width);
display: var(--digi-button--display);
text-align: var(--digi-button--text-align);
border: var(--digi-button--border);
outline: var(--digi-button--outline);
border-color: var(--digi-button--border-color);
&:hover { @if $type == 'secondary' {
background: $hovercolor; background-color: var(--digi-button--background--secondary);
color: var(--digi-button--color--secondary);
} @else if $type == 'tertiary' {
background-color: transparent;
color: var(--digi-button--color--tertiary);
border-width: 0;
} @else {
background-color: var(--digi-button--background);
color: var(--digi-button--color);
}
&:hover,
&:focus {
outline: var(--digi-button--outline--focus);
border-color: var(--digi-button--border-color--hover);
@if $type == 'secondary' {
background-color: var(--digi-button--background--secondary--hover);
color: var(--digi-button--color--secondary);
} @else if $type == 'tertiary' {
color: var(--digi-button--color--tertiary--hover);
} @else {
background-color: var(--digi-button--background--hover);
color: var(--digi-button--color--hover);
}
} }
} }