+
-
+
{{ counters$[filter.key] | async }}
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.scss b/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.scss
index bf7d7fc6f1..f6f9371a13 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.scss
+++ b/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.scss
@@ -1,5 +1,7 @@
@mixin adf-cloud-task-filters-theme($theme) {
$primary: map-get($theme, primary);
+ $accent: map-get($theme, accent);
+ $background: map-get($theme, background);
.adf {
&-task-filters__entry {
@@ -7,7 +9,6 @@
padding: 12px 0 !important;
height: 24px;
width: 100%;
- cursor: pointer;
font-size: 14px !important;
font-weight: bold;
opacity: 1;
@@ -20,6 +21,7 @@
.adf-filter-action-button {
opacity: 0.54;
padding: 16px;
+ cursor: pointer;
.adf-filter-action-button__label {
padding-left: 20px;
@@ -29,13 +31,26 @@
.adf-filter-action-button__counter {
opacity: 0.54;
- padding-left: 10px;
- padding-top: 6px;
+ margin-left: 10px;
+ margin-top: 6px;
+
+ &.adf-active {
+ margin-left: 8px;
+ margin-top: 5px;
+ padding: 0 5px;
+ border-radius: 15px;
+ background-color: mat-color($accent);
+ color: mat-color($mat-grey, 50);
+ font-size: smaller;
+ }
}
+
&:hover {
color: mat-color($primary);
- .adf-filter-action-button__counter, .adf-filter-action-button {
+
+ .adf-filter-action-button__counter,
+ .adf-filter-action-button {
opacity: 1;
}
}
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.ts
index f0d7ecbe52..82b7628421 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/components/base-task-filters-cloud.component.ts
@@ -46,6 +46,7 @@ export abstract class BaseTaskFiltersCloudComponent implements OnDestroy {
error: EventEmitter
= new EventEmitter();
counters$: {[key: string]: Observable} = {};
+ updatedCounters: string[] = [];
protected onDestroy$ = new Subject();
@@ -53,4 +54,21 @@ export abstract class BaseTaskFiltersCloudComponent implements OnDestroy {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
+
+ wasFilterUpdated(filterKey: string): boolean {
+ return this.updatedCounters.includes(filterKey);
+ }
+
+ addToUpdatedCounters(filterKey: string) {
+ if (!this.updatedCounters.includes(filterKey)) {
+ this.updatedCounters.push(filterKey);
+ }
+ }
+
+ resetFilterCounter(filterKey: string) {
+ const filterIndex = this.updatedCounters.indexOf(filterKey);
+ if (filterIndex > -1) {
+ this.updatedCounters.splice(filterIndex, 1);
+ }
+ }
}
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.spec.ts
index c1a406fa34..1df66e2401 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.spec.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.spec.ts
@@ -26,7 +26,7 @@ import { TaskFiltersCloudComponent } from './task-filters-cloud.component';
import { By } from '@angular/platform-browser';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
import { TaskFiltersCloudModule } from '../task-filters-cloud.module';
-import { fakeGlobalFilter } from '../mock/task-filters-cloud.mock';
+import { fakeGlobalFilter, taskNotifications } from '../mock/task-filters-cloud.mock';
import { TranslateModule } from '@ngx-translate/core';
describe('TaskFiltersCloudComponent', () => {
@@ -34,7 +34,7 @@ describe('TaskFiltersCloudComponent', () => {
let taskFilterService: TaskFilterCloudService;
const fakeGlobalFilterObservable =
- new Observable(function(observer) {
+ new Observable(function (observer) {
observer.next(fakeGlobalFilter);
observer.complete();
});
@@ -69,12 +69,13 @@ describe('TaskFiltersCloudComponent', () => {
taskFilterService = TestBed.inject(TaskFilterCloudService);
spyOn(taskFilterService, 'getTaskFilterCounter').and.returnValue(of(11));
+ spyOn(taskFilterService, 'getTaskNotificationSubscription').and.returnValue(of(taskNotifications));
});
it('should attach specific icon for each filter if hasIcon is true', async(() => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
const change = new SimpleChange(undefined, 'my-app-1', true);
- component.ngOnChanges({'appName': change});
+ component.ngOnChanges({ 'appName': change });
fixture.detectChanges();
component.showIcons = true;
fixture.whenStable().then(() => {
@@ -93,7 +94,7 @@ describe('TaskFiltersCloudComponent', () => {
component.showIcons = false;
const change = new SimpleChange(undefined, 'my-app-1', true);
- component.ngOnChanges({'appName': change});
+ component.ngOnChanges({ 'appName': change });
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -107,7 +108,7 @@ describe('TaskFiltersCloudComponent', () => {
it('should display the filters', async(() => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
const change = new SimpleChange(undefined, 'my-app-1', true);
- component.ngOnChanges({'appName': change});
+ component.ngOnChanges({ 'appName': change });
fixture.detectChanges();
component.showIcons = true;
fixture.whenStable().then(() => {
@@ -126,7 +127,7 @@ describe('TaskFiltersCloudComponent', () => {
const appName = 'my-app-1';
const change = new SimpleChange(null, appName, true);
- component.ngOnChanges({'appName': change});
+ component.ngOnChanges({ 'appName': change });
component.error.subscribe((err) => {
expect(err).toBeDefined();
@@ -368,7 +369,7 @@ describe('TaskFiltersCloudComponent', () => {
it('should display filter counter if property set to true', async(() => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
const change = new SimpleChange(undefined, 'my-app-1', true);
- component.ngOnChanges({'appName': change});
+ component.ngOnChanges({ 'appName': change });
fixture.detectChanges();
component.showIcons = true;
fixture.whenStable().then(() => {
@@ -379,4 +380,44 @@ describe('TaskFiltersCloudComponent', () => {
expect(filterCounters[0].nativeElement.innerText).toContain('11');
});
}));
+
+ it('should update filter counter when notification received', async(() => {
+ spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
+ const change = new SimpleChange(undefined, 'my-app-1', true);
+ component.ngOnChanges({ 'appName': change });
+ fixture.detectChanges();
+ component.showIcons = true;
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ const updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active'));
+ expect(updatedFilterCounters.length).toBe(1);
+ expect(Object.keys(component.counters$).length).toBe(1);
+ expect(component.counters$['fake-involved-tasks']).toBeDefined();
+ });
+ }));
+
+ it('should reset filter counter notification when filter is selected', async(() => {
+ spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(fakeGlobalFilterObservable);
+ let change = new SimpleChange(undefined, 'my-app-1', true);
+ component.ngOnChanges({ 'appName': change });
+ fixture.detectChanges();
+ component.showIcons = true;
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ let updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active'));
+ expect(updatedFilterCounters.length).toBe(1);
+
+ component.filters = fakeGlobalFilter;
+ component.currentFilter = null;
+
+ change = new SimpleChange(null, { key: fakeGlobalFilter[0].key }, true);
+ component.ngOnChanges({ 'filterParam': change });
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active'));
+ expect(updatedFilterCounters.length).toBe(0);
+ });
+ });
+ }));
});
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.ts
index b4845bed6a..4d6fb46aaa 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters-cloud.component.ts
@@ -20,8 +20,10 @@ import { Observable } from 'rxjs';
import { TaskFilterCloudService } from '../services/task-filter-cloud.service';
import { TaskFilterCloudModel, FilterParamsModel } from '../models/filter-cloud.model';
import { TranslationService } from '@alfresco/adf-core';
-import { takeUntil } from 'rxjs/operators';
+import { map, takeUntil } from 'rxjs/operators';
import { BaseTaskFiltersCloudComponent } from './base-task-filters-cloud.component';
+import { TaskDetailsCloudModel } from '../../start-task/models/task-details-cloud.model';
+import { TaskCloudEngineEvent } from '../../../models/engine-event-cloud.model';
@Component({
selector: 'adf-cloud-task-filters',
@@ -37,10 +39,13 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
@Output()
filterClicked = new EventEmitter();
+ /** Emitted when filter counters are updated. */
+ @Output()
+ filterCounterUpdated: EventEmitter = new EventEmitter();
+
filters$: Observable;
filters: TaskFilterCloudModel[] = [];
currentFilter: TaskFilterCloudModel;
- counters = {};
constructor(private taskFilterCloudService: TaskFilterCloudService,
private translationService: TranslationService) {
@@ -48,6 +53,7 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
}
ngOnInit() {
+ this.initFilterCounterNotifications();
this.getFilters(this.appName);
}
@@ -89,6 +95,30 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
});
}
+ initFilterCounterNotifications() {
+ this.taskFilterCloudService.getTaskNotificationSubscription(this.appName)
+ .subscribe((result: TaskCloudEngineEvent[]) => {
+ result.map((taskEvent: TaskCloudEngineEvent) => {
+ this.updateFilterCounter(taskEvent.entity);
+ });
+ this.filterCounterUpdated.emit(result);
+ });
+ }
+
+ updateFilterCounter(filterNotification: TaskDetailsCloudModel) {
+ this.filters.map((filter) => {
+ if (this.isFilterPresent(filter, filterNotification)) {
+ this.counters$[filter.key] = this.counters$[filter.key].pipe(map((counter) => counter + 1));
+ this.addToUpdatedCounters(filter.key);
+ }
+ });
+ }
+
+ isFilterPresent(filter: TaskFilterCloudModel, filterNotification: TaskDetailsCloudModel): boolean {
+ return filter.status === filterNotification.status
+ && filter.assignee === filterNotification.assignee;
+ }
+
public selectFilter(paramFilter: FilterParamsModel) {
if (paramFilter) {
this.currentFilter = this.filters.find((filter, index) =>
@@ -104,7 +134,10 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
public selectFilterAndEmit(newParamFilter: FilterParamsModel) {
if (newParamFilter) {
this.selectFilter(newParamFilter);
- this.filterSelected.emit(this.currentFilter);
+ if (this.currentFilter) {
+ this.resetFilterCounter(this.currentFilter.key);
+ this.filterSelected.emit(this.currentFilter);
+ }
} else {
this.currentFilter = undefined;
}
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/mock/task-filters-cloud.mock.ts b/lib/process-services-cloud/src/lib/task/task-filters/mock/task-filters-cloud.mock.ts
index e97b6f760b..c20ccdda76 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/mock/task-filters-cloud.mock.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/mock/task-filters-cloud.mock.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { assignedTaskDetailsCloudMock } from '../../task-header/mocks/task-details-cloud.mock';
import { TaskFilterCloudModel, ServiceTaskFilterCloudModel } from '../models/filter-cloud.model';
export const fakeGlobalFilter = [
@@ -23,8 +24,8 @@ export const fakeGlobalFilter = [
key: 'fake-involved-tasks',
icon: 'adjust',
id: '10',
- status: 'open',
- assignee: 'fake-involved',
+ status: 'ASSIGNED',
+ assignee: 'AssignedTaskUser',
showCounter: true
}),
new TaskFilterCloudModel({
@@ -273,3 +274,16 @@ export const fakeTaskCloudFilters = [
order: 'DESC'
}
];
+
+export const taskNotifications = [
+ {
+ eventType: 'TASK_ASSIGNED',
+ entity: assignedTaskDetailsCloudMock
+ }
+];
+
+export const taskCloudEngineEventsMock = {
+ data: {
+ engineEvents: taskNotifications
+ }
+};
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.spec.ts
index 72d5a9fcd2..f379cc4a05 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.spec.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.spec.ts
@@ -33,15 +33,19 @@ import {
fakePreferenceWithNoTaskFilterPreference,
fakeTaskCloudFilters,
fakeTaskCloudPreferenceList,
- fakeTaskFilter
+ fakeTaskFilter,
+ taskCloudEngineEventsMock
} from '../mock/task-filters-cloud.mock';
import { UserPreferenceCloudService } from '../../../services/user-preference-cloud.service';
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TaskFilterCloudModel } from '../models/filter-cloud.model';
+import { NotificationCloudService } from '../../../services/notification-cloud.service';
+import { TaskCloudEngineEvent } from './../../../models/engine-event-cloud.model';
describe('TaskFilterCloudService', () => {
let service: TaskFilterCloudService;
+ let notificationCloudService: NotificationCloudService;
let getPreferencesSpy: jasmine.Spy;
let getPreferenceByKeySpy: jasmine.Spy;
@@ -53,7 +57,7 @@ describe('TaskFilterCloudService', () => {
setupTestBed({
imports: [
- HttpClientTestingModule
+ HttpClientTestingModule
],
providers: [
{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: UserPreferenceCloudService },
@@ -64,6 +68,7 @@ describe('TaskFilterCloudService', () => {
beforeEach(() => {
service = TestBed.inject(TaskFilterCloudService);
+ notificationCloudService = TestBed.inject(NotificationCloudService);
const preferenceCloudService = service.preferenceService;
createPreferenceSpy = spyOn(preferenceCloudService, 'createPreference').and.returnValue(of(fakeTaskCloudFilters));
@@ -229,6 +234,17 @@ describe('TaskFilterCloudService', () => {
expect(service.isDefaultFilter(defaultFilterName)).toBe(true);
expect(service.isDefaultFilter(fakeFilterName)).toBe(false);
});
+
+ it('should return engine event task subscription', (done) => {
+ spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(of(taskCloudEngineEventsMock));
+
+ service.getTaskNotificationSubscription('myAppName').subscribe((res: TaskCloudEngineEvent[]) => {
+ expect(res.length).toBe(1);
+ expect(res[0].eventType).toBe('TASK_ASSIGNED');
+ expect(res[0].entity.name).toBe('This is a new task');
+ done();
+ });
+ });
});
describe('Inject [LocalPreferenceCloudService] into the TaskFilterCloudService', () => {
@@ -240,9 +256,7 @@ describe('Inject [LocalPreferenceCloudService] into the TaskFilterCloudService',
const identityUserMock = { username: 'fakeusername', firstName: 'fake-identity-first-name', lastName: 'fake-identity-last-name', email: 'fakeIdentity@email.com' };
setupTestBed({
- imports: [
- HttpClientTestingModule
- ],
+ imports: [ HttpClientTestingModule ],
providers: [
{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }
]
diff --git a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts
index 65e09222fa..2d981f5185 100644
--- a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts
+++ b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts
@@ -24,6 +24,24 @@ import { BaseCloudService } from '../../../services/base-cloud.service';
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
import { TaskCloudNodePaging } from '../../task-list/models/task-cloud.model';
+import { NotificationCloudService } from '../../../services/notification-cloud.service';
+import { TaskCloudEngineEvent } from '../../../models/engine-event-cloud.model';
+
+const TASK_EVENT_SUBSCRIPTION_QUERY = `
+ subscription {
+ engineEvents(eventType: [
+ TASK_COMPLETED
+ TASK_ASSIGNED
+ TASK_ACTIVATED
+ TASK_SUSPENDED
+ TASK_CANCELLED
+ TASK_UPDATED
+ ]) {
+ eventType
+ entity
+ }
+ }
+`;
@Injectable({
providedIn: 'root'
@@ -37,7 +55,8 @@ export class TaskFilterCloudService extends BaseCloudService {
@Inject(TASK_FILTERS_SERVICE_TOKEN)
public preferenceService: PreferenceCloudServiceInterface,
apiService: AlfrescoApiService,
- appConfigService: AppConfigService) {
+ appConfigService: AppConfigService,
+ private notificationCloudService: NotificationCloudService) {
super(apiService, appConfigService);
this.filtersSubject = new BehaviorSubject([]);
this.filters$ = this.filtersSubject.asObservable();
@@ -315,4 +334,9 @@ export class TaskFilterCloudService extends BaseCloudService {
})
];
}
+
+ getTaskNotificationSubscription(appName: string): Observable {
+ return this.notificationCloudService.makeGQLQuery(appName, TASK_EVENT_SUBSCRIPTION_QUERY)
+ .pipe(map((events: any) => events.data.engineEvents));
+ }
}
diff --git a/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts b/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts
index ba1dc59baa..d1b2566499 100644
--- a/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts
+++ b/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts
@@ -21,7 +21,7 @@ export const fakeTaskDetailsCloud = {
'appVersion': '',
'id': '68d54a8f',
'assignee': 'Phil Woods',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': 1545048055900,
'dueDate': 1545091200000,
diff --git a/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts b/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts
index 10bbadd0c9..e0d5f16553 100644
--- a/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts
+++ b/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts
@@ -46,7 +46,7 @@ export const assignedTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': '68d54a8f-01f3-11e9-8e36-0a58646002ad',
'assignee': 'AssignedTaskUser',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(),
@@ -70,7 +70,7 @@ export const createdTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': '68d54a8f-01f3-11e9-8e36-0a58646002ad',
'assignee': 'CreatedTaskUser',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
@@ -94,7 +94,7 @@ export const emptyOwnerTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': '68d54a8f-01f3-11e9-8e36-0a58646002ad',
'assignee': 'AssignedTaskUser',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
@@ -118,7 +118,7 @@ export const createdStateTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': 'mock-task-id',
'assignee': '',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
@@ -142,7 +142,7 @@ export const completedTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': 'mock-task-id',
'assignee': 'CompletedTaskAssignee',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
@@ -166,7 +166,7 @@ export const cancelledTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': 'mock-task-id',
'assignee': 'CancelledTaskAssignee',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
@@ -190,7 +190,7 @@ export const suspendedTaskDetailsCloudMock: TaskDetailsCloudModel = {
'appVersion': 1,
'id': 'mock-task-id',
'assignee': 'SuspendedTaskAssignee',
- 'name': 'This is a new task ',
+ 'name': 'This is a new task',
'description': 'This is the description ',
'createdDate': new Date(1545048055900),
'dueDate': new Date(1545091200000),
diff --git a/lib/process-services-cloud/src/public-api.ts b/lib/process-services-cloud/src/public-api.ts
index 684e20185b..c697d066e0 100644
--- a/lib/process-services-cloud/src/public-api.ts
+++ b/lib/process-services-cloud/src/public-api.ts
@@ -29,3 +29,4 @@ export * from './lib/pipes/process-services-cloud-pipe.module';
export * from './lib/models/process-definition-cloud.model';
export * from './lib/models/date-cloud-filter.model';
export * from './lib/models/application-version.model';
+export * from './lib/models/engine-event-cloud.model';
diff --git a/lib/tsconfig.json b/lib/tsconfig.json
index 2498afa0c3..9520b73a1b 100644
--- a/lib/tsconfig.json
+++ b/lib/tsconfig.json
@@ -29,7 +29,7 @@
"@alfresco/adf-core": ["./core/"],
"@alfresco/adf-insights": ["./analytics"]
},
- "lib": ["es2018", "esnext.array", "dom"],
+ "lib": ["es2018", "esnext.array", "esnext.asynciterable", "dom"],
"suppressImplicitAnyIndexErrors": true
},
"exclude": [
diff --git a/package-lock.json b/package-lock.json
index 5f8dfb3297..f30ffd642e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1411,6 +1411,38 @@
"tslib": "^2.0.0"
}
},
+ "@apollo/client": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.10.tgz",
+ "integrity": "sha512-OL5y8q5evSbvsqMAHKZJgfgB/MS9PLGF7f0MtHEkGGCDvmcmA81lsjYwk0xpDm/3XdnrYp/duN2tYUu2LnpJmw==",
+ "requires": {
+ "@graphql-typed-document-node/core": "^3.0.0",
+ "@types/zen-observable": "^0.8.0",
+ "@wry/context": "^0.5.2",
+ "@wry/equality": "^0.3.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graphql-tag": "^2.12.0",
+ "hoist-non-react-statics": "^3.3.2",
+ "optimism": "^0.14.0",
+ "prop-types": "^15.7.2",
+ "symbol-observable": "^2.0.0",
+ "ts-invariant": "^0.6.0",
+ "tslib": "^1.10.0",
+ "zen-observable": "^0.8.14"
+ },
+ "dependencies": {
+ "symbol-observable": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz",
+ "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA=="
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -2936,6 +2968,11 @@
}
}
},
+ "@graphql-typed-document-node/core": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz",
+ "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg=="
+ },
"@istanbuljs/schema": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
@@ -5862,6 +5899,11 @@
"integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
"dev": true
},
+ "@types/ungap__global-this": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz",
+ "integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g=="
+ },
"@types/unist": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
@@ -5902,6 +5944,16 @@
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
"dev": true
},
+ "@types/zen-observable": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz",
+ "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg=="
+ },
+ "@ungap/global-this": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.4.tgz",
+ "integrity": "sha512-mHkm6FvepJECMNthFuIgpAEFmPOk71UyXuIxYfjytvFTnSDBIz7jmViO+LfHI/AjrazWije0PnSP3+/NlwzqtA=="
+ },
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -6077,6 +6129,51 @@
"@xtuc/long": "4.2.2"
}
},
+ "@wry/context": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.4.tgz",
+ "integrity": "sha512-/pktJKHUXDr4D6TJqWgudOPJW2Z+Nb+bqk40jufA3uTkLbnCRKdJPiYDIa/c7mfcPH8Hr6O8zjCERpg5Sq04Zg==",
+ "requires": {
+ "tslib": "^1.14.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@wry/equality": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.3.2.tgz",
+ "integrity": "sha512-yi0VRqw+ygqM/WVZUze5meAhe2evOHBFXqK8onNVdNNB+Tyn8/07FZpeDklECBHeT9KN9DY2JpCVGNQY6RCRDg==",
+ "requires": {
+ "tslib": "^1.14.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@wry/trie": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.2.2.tgz",
+ "integrity": "sha512-OxqBB39x6MfHaa2HpMiRMfhuUnQTddD32Ko020eBeJXq87ivX6xnSSnzKHVbA21p7iqBASz8n/07b6W5wW1BVQ==",
+ "requires": {
+ "tslib": "^1.14.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -6370,6 +6467,16 @@
"picomatch": "^2.0.4"
}
},
+ "apollo-angular": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/apollo-angular/-/apollo-angular-2.2.0.tgz",
+ "integrity": "sha512-/38ynj2gMJ1M/JlSDB6vv1fGYJy7WDukJn/3wQnoOYay5ZeU0rsAJdBaSZQiOPxqAJgVoGfU787/aXjIC1PWZg==",
+ "requires": {
+ "extract-files": "^9.0.0",
+ "semver": "^7.0.0",
+ "tslib": "^2.0.0"
+ }
+ },
"app-root-path": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
@@ -6645,8 +6752,7 @@
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
- "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
- "dev": true
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"asynckit": {
"version": "0.4.0",
@@ -6852,8 +6958,7 @@
"backo2": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
- "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
- "dev": true
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
},
"bail": {
"version": "1.0.5",
@@ -11579,8 +11684,7 @@
"extract-files": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
- "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==",
- "dev": true
+ "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
},
"extsprintf": {
"version": "1.3.0",
@@ -11628,8 +11732,7 @@
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"fast-levenshtein": {
"version": "2.0.6",
@@ -12820,6 +12923,21 @@
"form-data": "^3.0.0"
}
},
+ "graphql-tag": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.1.tgz",
+ "integrity": "sha512-LPewEE1vzGkHnCO8zdOGogKsHHBdtpGyihow1UuMwp6RnZa0lAS7NcbvltLOuo4pi5diQCPASAXZkQq44ffixA==",
+ "requires": {
+ "tslib": "^1.14.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"graphviz": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.8.tgz",
@@ -13076,6 +13194,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
"homedir-polyfill": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
@@ -14537,6 +14663,11 @@
"integrity": "sha512-O62gD5ADMUGtJoOoM9U6LQ7i4byPXUNoHJ6mqsmkQJcom331ZJGDApWgDESWyBMEHEJRjtHozgIiTzYo9RU4UA==",
"dev": true
},
+ "iterall": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz",
+ "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg=="
+ },
"jake": {
"version": "10.8.2",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
@@ -14899,8 +15030,7 @@
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"js-yaml": {
"version": "4.0.0",
@@ -16439,7 +16569,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
@@ -18531,8 +18660,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-copy": {
"version": "0.1.0",
@@ -18775,6 +18903,15 @@
}
}
},
+ "optimism": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.14.0.tgz",
+ "integrity": "sha512-ygbNt8n4DOCVpkwiLF+IrKKeNHOjtr9aXLWGP9HNJGoblSGsnVbJLstcH6/nE9Xy5ZQtlkSioFQNnthmENW6FQ==",
+ "requires": {
+ "@wry/context": "^0.5.2",
+ "@wry/trie": "^0.2.1"
+ }
+ },
"optimize-css-assets-webpack-plugin": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz",
@@ -20483,6 +20620,16 @@
"sisteransi": "^1.0.4"
}
},
+ "prop-types": {
+ "version": "15.7.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+ "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
+ }
+ },
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -21386,6 +21533,11 @@
"strip-json-comments": "~2.0.1"
}
},
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -25494,6 +25646,38 @@
}
}
},
+ "subscriptions-transport-ws": {
+ "version": "0.9.18",
+ "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz",
+ "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==",
+ "requires": {
+ "backo2": "^1.0.2",
+ "eventemitter3": "^3.1.0",
+ "iterall": "^1.2.1",
+ "symbol-observable": "^1.0.4",
+ "ws": "^5.2.0"
+ },
+ "dependencies": {
+ "eventemitter3": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
+ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
+ },
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
+ "ws": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+ "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
"sugarss": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz",
@@ -26200,6 +26384,23 @@
"glob": "^7.1.2"
}
},
+ "ts-invariant": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.6.0.tgz",
+ "integrity": "sha512-caoafsfgb8QxdrKzFfjKt627m4i8KTtfAiji0DYJfWI4A/S9ORNNpzYuD9br64kyKFgxn9UNaLLbSupam84mCA==",
+ "requires": {
+ "@types/ungap__global-this": "^0.3.1",
+ "@ungap/global-this": "^0.4.2",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"ts-loader": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz",
@@ -29053,6 +29254,11 @@
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
},
+ "zen-observable": {
+ "version": "0.8.15",
+ "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
+ "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ=="
+ },
"zone.js": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz",
diff --git a/package.json b/package.json
index 70ff4ad76a..217db7fff0 100644
--- a/package.json
+++ b/package.json
@@ -84,10 +84,12 @@
"@angular/platform-browser": "^10.0.4",
"@angular/platform-browser-dynamic": "^10.0.4",
"@angular/router": "^10.0.4",
+ "@apollo/client": "^3.3.7",
"@mat-datetimepicker/core": "^5.1.1",
"@mat-datetimepicker/moment": "^5.1.1",
"@ngx-translate/core": "^13.0.0",
"adf-tslint-rules": "0.0.7",
+ "apollo-angular": "^2.2.0",
"chart.js": "2.9.4",
"classlist.js": "1.1.20150312",
"custom-event-polyfill": "^1.0.7",
@@ -101,6 +103,7 @@
"raphael": "2.3.0",
"rxjs": "^6.6.3",
"snyk": "^1.452.0",
+ "subscriptions-transport-ws": "^0.9.18",
"tslib": "^2.0.3",
"zone.js": "~0.10.2"
},
diff --git a/tsconfig.json b/tsconfig.json
index 8a0c69a6a0..12bbe4286b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -25,6 +25,7 @@
"lib": [
"es2018",
"esnext.array",
+ "esnext.asynciterable",
"dom"
],
"paths": {