Commit 616f2b2a authored by Hando Lukats's avatar Hando Lukats
Browse files

Merge branch 'develop' into 'master'

Release: merge 'develop' into 'master' created by Hando Lukats

See merge request teis/public-web-client!644
parents 0090cdab 9188b1ed
{
"name": "te-is",
"version": "1.25.0",
"version": "1.26.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......
{
"name": "te-is",
"version": "1.25.0",
"version": "1.26.0",
"license": "MIT",
"scripts": {
"ng": "ng",
......
......@@ -74,6 +74,7 @@ import { AssignmentsComponent } from '@official/features/company-details/contain
import { RiskAssessmentsListComponent } from '@official/features/office-risk-assessments/containers/risk-assessments-list/risk-assessments-list.component';
import { RiskAssessmentFilesComponent } from '@official/features/office-risk-assessments/containers/risk-assessment-files/risk-assessment-files.component';
import { ProceedingsTopicsComponent } from '@official/features/proceedings/containers/proceedings-topics/proceedings-topics.component';
import { ProceduralActTopicsComponent } from '@official/features/procedural-act/containers/procedural-act-topics/procedural-act-topics.component';
const routes: Routes = [
{
......@@ -338,6 +339,13 @@ const routes: Routes = [
privileges: ['TI_VIEW_VIOLATION'],
},
},
{
path: 'topics',
component: ProceduralActTopicsComponent,
data: {
privileges: ['TI_MANAGE_PROCEDURALACT'],
},
},
{ path: '', redirectTo: 'general', pathMatch: 'full' },
],
},
......
<button
(click)="toggle()"
*ngIf="checked"
teis-button
type="button"
class="ml-4 buttons"
variant="success-fade-square">
<teis-icon icon="icon-check"></teis-icon>
{{ 'is_inspected' | translate }}
</button>
<button
(click)="toggle()"
*ngIf="!checked"
teis-button
type="button"
class="ml-4 buttons"
variant="default-outline-square">
{{ 'will_inspect' | translate }}
</button>
\ No newline at end of file
<div class="buttons-container">
<button
(click)="toggleIrrelevant('IRRELEVANT')"
*ngIf="!irrelevant"
teis-button
type="button"
class="ml-4 buttons"
variant="default-outline-square">
{{ 'irrelevant' | translate }}
</button>
<button
(click)="toggleIrrelevant('NOT_INSPECTED')"
*ngIf="irrelevant"
teis-button
type="button"
class="ml-4 buttons"
variant="success-fade-square">
<teis-icon icon="icon-check"></teis-icon>
{{ 'irrelevant' | translate }}
</button>
<button
(click)="toggle('NOT_INSPECTED')"
*ngIf="checked"
teis-button
type="button"
class="ml-4 buttons"
variant="success-fade-square">
<teis-icon icon="icon-check"></teis-icon>
{{ 'is_inspected' | translate }}
</button>
<button
(click)="toggle('INSPECTED')"
*ngIf="!checked"
teis-button
type="button"
class="ml-4 buttons"
variant="default-outline-square">
{{ 'will_inspect' | translate }}
</button>
</div>
.buttons {
min-width: 11rem;
}
\ No newline at end of file
min-width: 8rem;
padding: 8px 0px;
margin-left: 5px!important;
margin-bottom: 10px;
}
.buttons-container {
display: flex;
}
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'teis-inspection-topic-status-toggler',
......@@ -7,10 +7,21 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
})
export class InspectionTopicStatusTogglerComponent {
@Input() checked = false;
@Output() change = new EventEmitter();
@Input() status;
@Input() irrelevant = false;
@Output() setChecked = new EventEmitter();
toggle() {
toggle(status) {
this.checked = !this.checked;
this.change.emit(this.checked);
this.irrelevant = false;
this.setChecked.emit(status);
}
toggleIrrelevant(status) {
this.checked = false;
this.irrelevant = !this.irrelevant;
this.setChecked.emit(status);
}
}
......@@ -62,7 +62,8 @@ export class InspectionToolbarComponent implements OnInit, OnDestroy {
.pipe(filter(proceduralAct => proceduralAct != null))
.subscribe((proceduralAct) => {
this.proceduralAct = proceduralAct;
this.canAddComment = ![
this.canAddComment = proceduralAct.conductedAct !== false
&& ![
ProceduralActStatusId.CLOSED,
ProceduralActStatusId.CANCELED,
].includes(this.proceduralAct.status.id);
......
......@@ -23,7 +23,9 @@
<teis-inspection-topic-status-toggler
[checked]="topic.inspected"
(change)="handleInspectedStatusButton(topic, $event)">
[checked]="topic.inspectionOutcome.code === 'INSPECTED'"
[status]="topic.inspectionOutcome.code"
[irrelevant]="topic.inspectionOutcome.code === 'IRRELEVANT'"
(setChecked)="handleInspectedStatusButton(topic, $event)">
</teis-inspection-topic-status-toggler>
</div>
\ No newline at end of file
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { InspectionFacadeService } from '../../inspection-facade.service';
import { TopicCommentsAndViolationsComponent } from '../topic-comments-and-violations/topic-comments-and-violations.component';
import { CreateViolationOrCommentComponent } from '../create-violation-or-comment/create-violation-or-comment.component';
import { Subscription } from 'rxjs';
import { ProceduralActInspectionTopicTreeNode } from '../../services/inspection-models';
import { DrawerPosition } from '@teis/modules/drawer/drawer.service';
import { ProceduralActInspectionTopicDto, ProceduralActStatusId } from '@teis/services/procedural-act/procedural-act.model';
import {
ProceduralActInspectionTopicDto,
ProceduralActStatusId
} from '@teis/services/procedural-act/procedural-act.model';
import { AuthorizationService } from '@teis/services/authorization/authorization.service';
@Component({
......@@ -50,10 +53,10 @@ export class InspectionTopicsLevelThreeComponent implements OnInit, OnDestroy {
this.facade.openDrawer(CreateViolationOrCommentComponent, config);
}
handleInspectedStatusButton(topic: ProceduralActInspectionTopicDto, value: boolean) {
handleInspectedStatusButton(topic: ProceduralActInspectionTopicDto, checked: string) {
if (this.proceduralActIsClosedOrCanceled) return;
if (!this.authorization.hasViewPermission(['TI_MANAGE_PROCEDURALACT'])) return;
// Todo in TEIS-652
this.facade.patchStatus(topic.id, checked).subscribe();
}
}
......@@ -7,7 +7,7 @@
<loader *ngIf="!proceduralAct; else content"></loader>
<ng-template #content>
<div class="ml-4">
<teis-header [title]="'Vaatlus' | translate"></teis-header>
<teis-header [title]="'Vaatlus' | translate"></teis-header>ss
</div>
<teis-current-inspection-topics></teis-current-inspection-topics>
......
import { Injectable } from '@angular/core';
import { DrawerService, DrawerOptions } from '@teis/modules/drawer/drawer.service';
import { DrawerOptions, DrawerService } from '@teis/modules/drawer/drawer.service';
import { BehaviorSubject } from 'rxjs';
import { InspectionService } from './services/inspection.service';
import { InspectionTopicsService } from './services/inspection-topics.service';
import { InspectionTopicsWithCommentsAndViolations, ProceduralActInspectionTopicTreeNode } from './services/inspection-models';
import {
InspectionTopicsWithCommentsAndViolations,
ProceduralActInspectionTopicTreeNode
} from './services/inspection-models';
import { FormGroup } from '@angular/forms';
import { MessageContext } from '@ska-angular/core';
import { InspectionViolationCommentService } from './services/inspection-violation-comment.service';
import { ModalService } from '@teis/modules/modal/modal.service';
import { ConfirmationOptions } from '@teis/modules/modal/confirmation/confirmation.component';
import { take, map } from 'rxjs/operators';
import { map, take } from 'rxjs/operators';
import { Router } from '@angular/router';
import { Drawer } from '@teis/modules/drawer/drawer';
import { FileReferenceDto } from '@teis/services/file/file.model';
import { FileService } from '@teis/services/file/file.service';
import { ProceduralActCommentDto, ProceduralActDto, ProceduralActInspectionTopicDto } from '@teis/services/procedural-act/procedural-act.model';
import {
ProceduralActCommentDto,
ProceduralActDto,
ProceduralActInspectionTopicDto
} from '@teis/services/procedural-act/procedural-act.model';
import { ViolationDto } from '@teis/services/violations/violations.model';
import { ClassifierItemDto } from '@teis/services/classifiers/classifiers.models';
......@@ -244,4 +251,8 @@ export class InspectionFacadeService {
if (violationLegislations && !(form.get('violationLegislations').value && form.get('violationLegislations').value.length)) form.get('violationLegislations').patchValue(violationLegislations);
});
}
patchStatus(id, status) {
return this.inspectionTopicsService.patchInspectionTopic(id, status);
}
}
......@@ -66,4 +66,8 @@ export class InspectionTopicsService {
return { ...output, children };
}
patchInspectionTopic(id: string, status:string) {
return this.proceduralActApi.patchTopicStatus(id, { code:status });
}
}
......@@ -32,6 +32,11 @@ export class ProceduralActDetailedComponent extends TabContainer implements OnIn
title:'general',
privileges: ['TI_VIEW_PROCEDURALACT'],
},
{
name: 'topics',
title: 'topics',
privileges: ['TI_MANAGE_PROCEDURALACT'],
},
{
name: 'violations',
title: 'violations',
......
......@@ -13,9 +13,21 @@
</button>
<loader
*ngIf="(loading | async)?.procceduralActProtocol"
*ngIf="(loading | async)?.proceduralActProtocol"
[type]="'inline'"
[label]="'procedural_act_protocol_loading' | translate"></loader>
<button
teis-button
variant="no-style"
type="button"
*ngIf="proceduralActsDetail?.proceduralActRelatedUserIds && canBeNotConducted"
(click)="updateProceduralActNotConducted()">
<span class="edit">
{{ 'procedural_act_not_conducted' | translate }}
</span>
</button>
</teis-header>
<div class="container-fluid px-0">
......@@ -61,6 +73,30 @@
</div>
</ng-container>
</teis-form-row>
<teis-form-row
[label]="'procedural_act_not_conducted_reason' | translate"
*ngIf="proceduralActsDetail?.act?.reasonOfNotConductedAct"
contentClass="col-xs-20 col-md-12 pr-5">
<strong>{{ proceduralActsDetail?.act?.reasonOfNotConductedAct || '-' }}</strong>
<ng-container actions *ngIf="proceduralActsDetail?.proceduralActRelatedUserIds && editableByStatus && proceduralActsDetail?.act?.reasonOfNotConductedAct">
<div class="actions" *canView="['TI_MANAGE_PROCEDURALACT']; authorizedIds: proceduralActsDetail?.proceduralActRelatedUserIds">
<teis-icon-button
icon="icon-edit"
iconSize="medium"
variant="no-style"
[id]="'editProceduralActReasonOfNotConductedAct'"
(click)="updateProceduralActNotConducted()">
</teis-icon-button>
<teis-icon-button
iconSize="medium"
icon="icon-delete"
variant="no-style"
[id]="'deleteProceduralActReasonOfNotConductedAct'"
(click)="deleteProceduralActNotConducted()">
</teis-icon-button>
</div>
</ng-container>
</teis-form-row>
<teis-form-row
[label]="'event_location' | translate"
contentClass="col-xs-20 col-md-12 pr-5">
......
......@@ -10,6 +10,9 @@ import { ProceduralActAdvanceNoticeEditComponent } from '../procedural-act-advan
import { FileReferenceDto } from '@teis/services/file/file.model';
import { ProceduralActEditFeedbackComponent } from '@official/features/procedural-act/containers/procedural-act-edit-feedback/procedural-act-edit-feedback.component';
import { ProceduralActStatusCode, ProceduralActStatusId } from '@teis/services/procedural-act/procedural-act.model';
import { ProceduralActReasonOfNotConductedCreateOrEditComponent } from '@official/features/procedural-act/containers/procedural-act-reason-of-not-conducted-create-or-edit/procedural-act-reason-of-not-conducted-create-or-edit.component';
import { ConfirmationOptions } from '@teis/modules/modal/confirmation/confirmation.component';
import { AuthorizationService } from '@teis/services/authorization/authorization.service';
@Component({
selector: 'procedural-act-general',
......@@ -30,10 +33,14 @@ export class ProceduralActGeneralComponent implements OnInit {
public advanceNotice = ProceduralActAdvanceNoticeEditComponent;
public editFeedback = ProceduralActEditFeedbackComponent;
public proceduralActProtocol: FileReferenceDto;
public hasNotes: boolean = null;
public hasViolations: boolean = null;
public canBeNotConducted: boolean;
private subscriptions$: Subscription[];
constructor(
private facade: ProceduralActFacadeService,
private authorization: AuthorizationService
) {}
ngOnInit() {
......@@ -48,6 +55,8 @@ export class ProceduralActGeneralComponent implements OnInit {
this.editableByStatus = !isNotEditableByStatus;
this.canceled = detail.act.status.id === ProceduralActStatusId.CANCELED && detail.act.reasonOfCancellation;
this.facade.getProceduralActFiles(this.proceduralActsDetail.act.id);
this.facade.getProceduralActNotes(this.proceduralActsDetail.act.id);
this.facade.getProceduralActViolations();
});
const proceduralActFiles$ = this.facade.proceduralActFiles.subscribe((files) => {
......@@ -56,13 +65,33 @@ export class ProceduralActGeneralComponent implements OnInit {
}
});
this.subscriptions$ = [proceduralActsDetails$, proceduralActFiles$];
const proceduralActNotes$ = this.facade.proceduralActNotes.subscribe((notes) => {
this.hasNotes = notes.length > 0;
if (this.hasViolations != null) {
this.setCanBeNotConducted();
}
});
const violations$ = this.facade.violations.subscribe((violations) => {
this.hasViolations = violations.length > 0;
if (this.hasNotes != null) {
this.setCanBeNotConducted();
}
});
this.subscriptions$ = [proceduralActsDetails$, proceduralActFiles$, proceduralActNotes$, violations$];
}
downloadProtocol() {
this.facade.downloadProceduralActProtocol(this.proceduralActsDetail.act.id, this.proceduralActProtocol);
}
setCanBeNotConducted() {
this.canBeNotConducted = this.authorization.hasSomePermission(['TI_MANAGE_PROCEDURALACT'])
&& this.editableByStatus && !this.hasNotes && !this.hasViolations
&& (this.proceduralActsDetail.act.reasonOfNotConductedAct == null || this.proceduralActsDetail.act.reasonOfNotConductedAct.length === 0);
}
ngOnDestroy() {
this.subscriptions$.forEach(subscription => subscription ? subscription.unsubscribe() : null);
}
......@@ -71,4 +100,16 @@ export class ProceduralActGeneralComponent implements OnInit {
this.facade.openModalWithComponent(component, { type, proceduralAct: this.proceduralActsDetail.act });
}
updateProceduralActNotConducted() {
this.facade.openModalWithComponent(ProceduralActReasonOfNotConductedCreateOrEditComponent, { proceduralAct: this.proceduralActsDetail.act });
}
deleteProceduralActNotConducted() {
const modalOptions: ConfirmationOptions = {
title: 'delete_reason_of_not_conducted_act',
question: 'delete_reason_of_not_conducted_act_confirmation',
};
this.facade.deleteReasonOfNotConductedAct(this.proceduralActsDetail.act, modalOptions);
}
}
<ng-container *ngIf="!form">
<ng-container *ngFor="let second of data">
<div class="inspection-topic-hierarchy" *ngIf="second.children.length">
<div class="inspection-topic-hierarchy__level__second">
<strong>{{ second?.name }}</strong>
</div>
<div class="inspection-topic-hierarchy__level__third" *ngFor="let third of second.children">
<span>{{ third?.name }}</span>
<span class="source">{{third?.source?.source?.name}}</span>
<p class="explanation">{{ third?.attributes[0]?.value }}</p>
</div>
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="form">
<ng-container [formGroup]="form" *ngFor="let second of data">
<div class="inspection-topic-hierarchy" *ngIf="second.children.length">
<div class="inspection-topic-hierarchy__level__second">
<teis-procedural-act-checkbox
[name]="second?.code"
[formControlName]="second?.code">
<strong>{{ second?.name }}</strong>
</teis-procedural-act-checkbox>
</div>
<div class="inspection-topic-hierarchy__level__third" *ngFor="let third of second.children">
<span class="source">{{ third?.source?.source?.name }}</span>
<teis-procedural-act-checkbox
[name]="third?.code"
[source]="third?.source?.source?.code"
[formControlName]="third?.code">
</teis-procedural-act-checkbox>
<span>{{ third?.name }}</span>
<p class="explanation">{{ third?.attributes[0]?.value }}</p>
</div>
</div>
</ng-container>
</ng-container>
\ No newline at end of file
@import '~@ska-angular/assets/assets/scss/abstracts/_custom-variables.scss';
.inspection-topic-hierarchy {
border-top: $gray-lighter 1px solid;
&:first-child {
border-top: unset;
}
&__level {
&__second {
padding: 1rem;
padding-left: 3rem;
border-bottom: $gray-lighter 1px solid;
&:last-child {
border-bottom: unset;
}
}
&__third {
padding: 1rem;
padding-left: 6rem;
border-bottom: $gray-lighter 1px solid;
.explanation {
font-style: italic;
color: $gray-light;
}
&:last-child {
border-bottom: unset;
}
}
}
}
.source {
float: right;
color: $gray-light;
}
\ No newline at end of file
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { InspectionTopicsItem } from '@teis/services/supervision-plan/supervision-plan.models';
@Component({
selector: 'teis-procedural-act-topic-hierarchy',
templateUrl: './procedural-act-topic-hierarchy.component.html',
styleUrls: ['./procedural-act-topic-hierarchy.component.scss'],
})
export class ProceduralActTopicHierarchyComponent {
@Input() data: InspectionTopicsItem[] = [];
@Input() form: FormGroup;
}
......@@ -37,7 +37,7 @@ export class ProceduralActNotesComponent implements OnInit {
ProceduralActStatusId.CANCELED,
].includes(this.proceduralAct.status.id);
this.displayAddNoteButton = this.relatedUserIds && !isStatusClosedOrCanceled;
this.displayAddNoteButton = this.relatedUserIds && !isStatusClosedOrCanceled && data.act.conductedAct !== false;
});
}
......
<teis-modal
icon="icon-edit"
[title]="title | translate">
<teis-form-layout [colsize]="20" *ngIf="form">
<form [formGroup]="form" (ngSubmit)="submit(proceduralAct, form)">
<form-row
[label]="'procedural_act_not_conducted_reason' | translate"
[comment]="'required' | translate">
<ska-input
formControlName="reasonOfNotConductedAct"
type="textarea"
[expandTextArea]="true"
rows="8"
minlength="3"
[preventErrorsWhileFocused]="true"
[required]="true">
</ska-input>
</form-row>
<teis-flex>
<form-button-with-confirmation
id="formCancel"
[form]="form"
buttonBackLabel="{{ 'cancel' | translate }}"
(confirm)="cancel()">
</form-button-with-confirmation>
<button