Skip to content

Commit af67fc4

Browse files
Event groups add link (#276)
* facility fixes * event group add/link * group event add/link * fix * fixes
1 parent 06cb72a commit af67fc4

20 files changed

+506
-19
lines changed

src/app/_constants/form-identifiers.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const EVENT_PARTICIPANTS_PROFILE_FORM_ID = 'event';
2828
export const EVENT_FILTERS_FORM_ID = 'eventFilters';
2929
export const EVENT_GROUP_FILTERS_FORM_ID = 'eventGroupFilters';
3030
export const EVENT_GROUPS_FORM_ID = 'eventGroups';
31+
export const ADD_EVENT_GROUP_FORM_ID = 'addEventGroup';
3132

3233
export const PERSON_DETAILS_FORM_ID = 'person';
3334
export const PERSON_FILTERS_FORM_ID = 'personFilters';

src/app/_services/api/event-group.service.ts

+9
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,13 @@ export class EventGroupService extends BaseService<EventGroupsIndexDto> {
3131
null
3232
);
3333
}
34+
35+
linkEvent(groupId: string, events: any[]): Observable<any> {
36+
const endpoint = this.endpoint.ENDPOINT;
37+
38+
return this.httpClient.post(
39+
`${this.helperService.getApiUrl()}/${endpoint}/${groupId}/linkEvents`,
40+
events
41+
);
42+
}
3443
}

src/app/_services/form-actions.service.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ export class FormActionsService {
1212

1313
private fieldsArray: { [key: string]: string[] } = {};
1414

15-
setSave(formId: string, resource: Resource | null): void {
16-
this.subjectSave.next({ formId, resource });
15+
setSave(formId: string, resource: Resource | null, multiple = true): void {
16+
this.subjectSave.next({ formId, resource, multiple });
1717
}
1818

1919
getSave(): Observable<any> {
@@ -59,8 +59,8 @@ export class FormActionsService {
5959
return this.subjectDiscard.asObservable();
6060
}
6161

62-
setCloseFormModal(formId: string, closeModal: boolean): void {
63-
this.subjectModal.next({ formId, closeModal });
62+
setCloseFormModal(formId: string, closeModal: boolean, requestResponse: any = null): void {
63+
this.subjectModal.next({ formId, closeModal, requestResponse });
6464
}
6565

6666
getCloseFormModal(): Observable<any> {

src/app/dashboard/contacts/contacts.component.html

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
<app-dashboard-filters></app-dashboard-filters>
44
</mat-card>
55
<div class="width-60 width-100-lg">
6-
<div class="width-60">
7-
<mat-card class="mr-16">
6+
<div class="width-60 width-50-lg width-100-sm">
7+
<mat-card class="mr-16 mr-0-sm">
88
<app-dashboard-contacts></app-dashboard-contacts>
99
</mat-card>
1010
</div>
11-
<div class="width-40">
11+
<div class="width-40 width-50-lg width-100-sm">
1212
<mat-card class="mr-16 mr-0-lg">
1313
<app-dashboard-under-follow-up></app-dashboard-under-follow-up>
1414
</mat-card>
@@ -39,4 +39,7 @@
3939
<app-dashboard-case-map></app-dashboard-case-map>
4040
</mat-card>
4141
</div>
42+
<mat-card>
43+
<app-dashboard-transmission-chain></app-dashboard-transmission-chain>
44+
</mat-card>
4245
</div>

src/app/dashboard/contacts/contacts.component.scss

+16
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,24 @@
3434
width: 100%;
3535
}
3636

37+
.width-50-lg {
38+
width: 50%;
39+
}
40+
3741
.mr-0-lg {
3842
margin-right: 0;
3943
}
4044
}
4145
}
46+
47+
@media (max-width: map-get($grid-breakpoints, sm)) {
48+
.dashboard-contacts-wrapper {
49+
.width-100-sm {
50+
width: 100%;
51+
}
52+
53+
.mr-0-sm {
54+
margin-right: 0;
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { TableColumn } from '../../_models/common';
2+
3+
export const defaultColumnDefs: TableColumn[] = [
4+
{
5+
name: 'captions.EventGroup.uuid',
6+
dataKey: 'uuid',
7+
isSortable: true,
8+
essential: true,
9+
className: 'bold',
10+
},
11+
{
12+
name: 'captions.EventGroup.name',
13+
dataKey: 'name',
14+
isSortable: true,
15+
},
16+
{
17+
name: 'captions.EventGroup.eventCount',
18+
dataKey: 'eventCount',
19+
isSortable: true,
20+
},
21+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<div mat-dialog-title>
2+
<h2>{{ 'strings.headingPickOrCreateEventGroup' | translate }}</h2>
3+
<div mat-dialog-actions>
4+
<button mat-icon-button mat-dialog-close class="button-dialog-close">
5+
<mat-icon class="material-icons-round">highlight_off</mat-icon>
6+
</button>
7+
<button mat-stroked-button color="primary" class="cancel-btn" mat-dialog-close>
8+
{{ 'captions.actionCancel' | translate }}
9+
</button>
10+
<button [disabled]="!selectedEventGroup?.uuid" mat-flat-button color="primary" class="confirm-btn" (click)="confirm()">
11+
{{ 'captions.actionConfirm' | translate }}
12+
</button>
13+
</div>
14+
</div>
15+
16+
<div mat-dialog-content>
17+
<div class="top">
18+
<div class="text">
19+
<mat-icon class="material-icons-round">info</mat-icon>
20+
<p>{{ 'strings.infoPickOrCreateEventGroupForEvent' | translate }}</p>
21+
</div>
22+
<button mat-stroked-button color="primary" class="new-event-group-btn" (click)="newEventGroup()">
23+
{{ 'captions.eventNewEventGroup' | translate }}
24+
</button>
25+
</div>
26+
<form [formGroup]="filtersForm" class="filters-form">
27+
<mat-form-field
28+
id="searchEventGroup"
29+
appearance="outline"
30+
floatLabel="always"
31+
class="search-field"
32+
>
33+
<mat-icon matPrefix class="search-icon material-icons-round">search</mat-icon>
34+
<input
35+
value=""
36+
type="text"
37+
matInput
38+
appDebounce
39+
placeholder="{{ 'Search' | translate }}"
40+
formControlName="searchEventGroup"
41+
(debounce)="onFormChange()"
42+
/>
43+
</mat-form-field>
44+
</form>
45+
<app-table
46+
[resourceService]="eventGroupService"
47+
[tableColumns]="defaultColumns"
48+
[isSortable]="true"
49+
[isSelectable]="true"
50+
[isSelectableOnce]="true"
51+
[isSelectableCheckboxHidden]="true"
52+
[isHeaderSticky]="true"
53+
[allowToggleColumns]="false"
54+
[fullHeight]="true"
55+
[appearance]="tableAppearanceOptions.MINIMAL"
56+
(selectItem)="onSelectEventGroup($event)"
57+
></app-table>
58+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@use '/src/variables.scss' as *;
2+
3+
.mat-dialog-title {
4+
padding-top: 40px;
5+
6+
> h2 {
7+
margin: 0;
8+
font-size: 34px;
9+
}
10+
}
11+
12+
.mat-dialog-content {
13+
padding: 25px;
14+
background: $white;
15+
16+
#searchEventGroup {
17+
width: 212px;
18+
margin: 10px 0;
19+
margin-left: 40px;
20+
}
21+
22+
.search-field {
23+
.search-icon {
24+
width: 14px;
25+
height: 12px;
26+
color: map-get($sormas-accent, 200);
27+
font-size: 12px;
28+
}
29+
::placeholder {
30+
color: map-get($sormas-accent, 200);
31+
font-size: 12px;
32+
}
33+
}
34+
35+
.top {
36+
overflow: hidden;
37+
38+
.text {
39+
overflow: hidden;
40+
max-width: 600px;
41+
margin-left: 40px;
42+
float: left;
43+
.mat-icon {
44+
display: inline-block;
45+
color: mat-color($sormas-accent, 500);
46+
font-size: 18px;
47+
}
48+
49+
> p {
50+
display: inline-block;
51+
width: 70%;
52+
color: mat-color($sormas-accent, 500);
53+
font-size: 12px;
54+
vertical-align: top;
55+
}
56+
}
57+
.new-event-group-btn {
58+
float: right;
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { HttpClientTestingModule } from '@angular/common/http/testing';
4+
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
5+
import { TranslateModule } from '@ngx-translate/core';
6+
import { EventGroupAddEventsModalComponent } from './event-group-add-events-modal.component';
7+
8+
describe('EventGroupAddEventsModalComponent', () => {
9+
let component: EventGroupAddEventsModalComponent;
10+
let fixture: ComponentFixture<EventGroupAddEventsModalComponent>;
11+
12+
beforeEach(async () => {
13+
await TestBed.configureTestingModule({
14+
declarations: [EventGroupAddEventsModalComponent],
15+
imports: [TranslateModule.forRoot(), MatDialogModule, HttpClientTestingModule],
16+
providers: [
17+
{ provide: MAT_DIALOG_DATA, useValue: {} },
18+
{ provide: MatDialogRef, useValue: {} },
19+
],
20+
}).compileComponents();
21+
});
22+
23+
beforeEach(() => {
24+
fixture = TestBed.createComponent(EventGroupAddEventsModalComponent);
25+
component = fixture.componentInstance;
26+
fixture.detectChanges();
27+
});
28+
29+
it('should create', () => {
30+
expect(component).toBeTruthy();
31+
});
32+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Component, Inject, OnInit } from '@angular/core';
2+
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
3+
import { FormControl, FormGroup } from '@angular/forms';
4+
import { Filter, TableColumn } from '../../_models/common';
5+
import { FilterService } from '../../_services/filter.service';
6+
import { EventGroupService } from '../../_services/api/event-group.service';
7+
import { EventGroupsIndexDto } from '../../_models/eventGroupsIndexDto';
8+
import { TableAppearanceOptions } from '../../_constants/enums';
9+
import { defaultColumnDefs } from './event-group-add-events-modal-table-data';
10+
11+
@Component({
12+
selector: 'app-event-group-add-events-modal',
13+
templateUrl: './event-group-add-events-modal.component.html',
14+
styleUrls: ['./event-group-add-events-modal.component.scss'],
15+
})
16+
export class EventGroupAddEventsModalComponent implements OnInit {
17+
defaultColumns: TableColumn[] = [];
18+
filtersForm = new FormGroup({});
19+
selectedEventGroup: EventGroupsIndexDto | null;
20+
tableAppearanceOptions = TableAppearanceOptions;
21+
22+
constructor(
23+
public dialogRef: MatDialogRef<EventGroupAddEventsModalComponent>,
24+
@Inject(MAT_DIALOG_DATA) public data: any,
25+
public eventGroupService: EventGroupService,
26+
private filterService: FilterService
27+
) {}
28+
29+
ngOnInit(): void {
30+
this.defaultColumns = defaultColumnDefs;
31+
this.initFiltersForm();
32+
}
33+
34+
initFiltersForm(): void {
35+
this.filtersForm = new FormGroup({
36+
searchEventGroup: new FormControl(),
37+
});
38+
}
39+
40+
filtersToArray(): void {
41+
const filter: Filter = {
42+
field: 'searchEventGroup',
43+
value: this.filtersForm.value.searchEventGroup,
44+
};
45+
this.filterService.setFilters([filter]);
46+
}
47+
48+
onSelectEventGroup(event: any): void {
49+
this.selectedEventGroup = null;
50+
if (event.selected.length) {
51+
// eslint-disable-next-line prefer-destructuring
52+
this.selectedEventGroup = event.selected[0];
53+
}
54+
}
55+
56+
onFormChange(): void {
57+
this.filtersToArray();
58+
}
59+
60+
confirm(): void {
61+
this.dialogRef.close({
62+
selectedEventGroup: this.selectedEventGroup,
63+
});
64+
}
65+
66+
newEventGroup(): void {
67+
this.dialogRef.close({
68+
selectedEventGroup: null,
69+
});
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { FORM_DATA_INPUT } from '../../_constants/form-data';
2+
3+
export const FORM_DATA_EVENT_GROUP_ADD = [
4+
{
5+
id: '',
6+
title: '',
7+
hiddenLeftSection: true,
8+
fields: [
9+
{
10+
...FORM_DATA_INPUT,
11+
key: 'name',
12+
label: 'captions.EventGroup.name',
13+
className: 'size-full',
14+
validation: ['required'],
15+
newLine: true,
16+
},
17+
],
18+
},
19+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div mat-dialog-title>
2+
<h2>{{ 'strings.headingCreateNewEventGroup' | translate }}</h2>
3+
<div mat-dialog-actions>
4+
<button mat-icon-button mat-dialog-close class="button-dialog-close">
5+
<mat-icon class="material-icons-round">highlight_off</mat-icon>
6+
</button>
7+
<button mat-stroked-button color="primary" class="cancel-btn" mat-dialog-close>
8+
{{ 'captions.actionCancel' | translate }}
9+
</button>
10+
<button mat-flat-button color="primary" class="confirm-btn" (click)="save()">
11+
{{ 'captions.actionSave' | translate }}
12+
</button>
13+
</div>
14+
</div>
15+
16+
<div mat-dialog-content>
17+
<app-dynamic-form
18+
[formId]="formId"
19+
[formElements]="myFormElements"
20+
[resourceService]="eventGroupService"
21+
></app-dynamic-form>
22+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@use '/src/variables.scss' as *;
2+
3+
.mat-dialog-title {
4+
padding-top: 40px;
5+
6+
> h2 {
7+
margin: 0;
8+
font-size: 34px;
9+
}
10+
}

0 commit comments

Comments
 (0)