mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
AAE-25271 Refresh button for processes (#10211)
* [AAE-25271] display process notifications * [AAE-25271] removed unnecessary conditional * [AAE-25271] replaced observable with promise * [AAE-25271] replaced observables with promises * [AAE-25271] updated unit tests * [AAE-25271] refactored tests to avoid circular dependency error * [AAE-25271] replaced automatic imports
This commit is contained in:
@@ -15,16 +15,21 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { NoopTranslateModule } from '@alfresco/adf-core';
|
||||||
import { AppListCloudModule } from './app-list-cloud.module';
|
import { AppListCloudModule } from './app-list-cloud.module';
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
describe('AppListCloudModule', () => {
|
describe('AppListCloudModule', () => {
|
||||||
let appListCloudModule: AppListCloudModule;
|
let appListCloudModule: AppListCloudModule;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
appListCloudModule = new AppListCloudModule();
|
TestBed.configureTestingModule({
|
||||||
});
|
imports: [AppListCloudModule, NoopTranslateModule]
|
||||||
|
});
|
||||||
|
appListCloudModule = TestBed.inject(AppListCloudModule);
|
||||||
|
});
|
||||||
|
|
||||||
it('should create an instance', () => {
|
it('should create an instance', () => {
|
||||||
expect(appListCloudModule).toBeTruthy();
|
expect(appListCloudModule).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -15,37 +15,53 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { SimpleChange } from '@angular/core';
|
|
||||||
import { AlfrescoApiService } from '@alfresco/adf-content-services';
|
import { AlfrescoApiService } from '@alfresco/adf-content-services';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
import { ADF_DATE_FORMATS, FullNamePipe, NoopTranslateModule, UserPreferencesService } from '@alfresco/adf-core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { HarnessLoader } from '@angular/cdk/testing';
|
||||||
|
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||||
|
import { SimpleChange } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { DateFnsAdapter } from '@angular/material-date-fns-adapter';
|
||||||
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
|
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||||
|
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||||
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatIconTestingModule } from '@angular/material/icon/testing';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { endOfDay, format, isValid, startOfDay, subYears } from 'date-fns';
|
||||||
|
import { enUS } from 'date-fns/locale';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component';
|
import { AppsProcessCloudService } from '../../../app/services/apps-process-cloud.service';
|
||||||
|
import { DateRangeFilterComponent } from '../../../common/date-range-filter/date-range-filter.component';
|
||||||
|
import { fakeEnvironmentList } from '../../../common/mock/environment.mock';
|
||||||
|
import { DateCloudFilterType } from '../../../models/date-cloud-filter.model';
|
||||||
|
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
|
||||||
|
import { PeopleCloudComponent } from '../../../people/components/people-cloud.component';
|
||||||
|
import { IdentityUserServiceMock } from '../../../people/mock/people-cloud.mock';
|
||||||
|
import { IDENTITY_USER_SERVICE_TOKEN } from '../../../people/services/identity-user-service.token';
|
||||||
|
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
|
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
||||||
|
import { NotificationCloudService } from '../../../services/notification-cloud.service';
|
||||||
|
import { ProcessCloudService } from '../../services/process-cloud.service';
|
||||||
|
import { mockAppVersions } from '../mock/process-filters-cloud.mock';
|
||||||
|
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
||||||
|
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
||||||
|
import { fakeApplicationInstance, fakeApplicationInstanceWithEnvironment } from './../../../app/mock/app-model.mock';
|
||||||
import {
|
import {
|
||||||
EditProcessFilterCloudComponent,
|
EditProcessFilterCloudComponent,
|
||||||
PROCESS_FILTER_ACTION_RESTORE,
|
PROCESS_FILTER_ACTION_RESTORE,
|
||||||
PROCESS_FILTER_ACTION_SAVE_DEFAULT
|
PROCESS_FILTER_ACTION_SAVE_DEFAULT
|
||||||
} from './edit-process-filter-cloud.component';
|
} from './edit-process-filter-cloud.component';
|
||||||
import { ProcessFiltersCloudModule } from '../process-filters-cloud.module';
|
import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component';
|
||||||
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
|
||||||
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
|
||||||
import { AppsProcessCloudService } from '../../../app/services/apps-process-cloud.service';
|
|
||||||
import { fakeApplicationInstance, fakeApplicationInstanceWithEnvironment } from './../../../app/mock/app-model.mock';
|
|
||||||
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
|
||||||
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
|
||||||
import { ProcessCloudService } from '../../services/process-cloud.service';
|
|
||||||
import { DateCloudFilterType } from '../../../models/date-cloud-filter.model';
|
|
||||||
import { MatIconTestingModule } from '@angular/material/icon/testing';
|
|
||||||
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
|
|
||||||
import { mockAppVersions } from '../mock/process-filters-cloud.mock';
|
|
||||||
import { fakeEnvironmentList } from '../../../common/mock/environment.mock';
|
|
||||||
import { endOfDay, format, startOfDay, subYears, isValid } from 'date-fns';
|
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
|
||||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
|
||||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
|
||||||
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
|
|
||||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
|
||||||
|
|
||||||
describe('EditProcessFilterCloudComponent', () => {
|
describe('EditProcessFilterCloudComponent', () => {
|
||||||
let loader: HarnessLoader;
|
let loader: HarnessLoader;
|
||||||
@@ -59,6 +75,7 @@ describe('EditProcessFilterCloudComponent', () => {
|
|||||||
let getRunningApplicationsSpy: jasmine.Spy;
|
let getRunningApplicationsSpy: jasmine.Spy;
|
||||||
let getProcessFilterByIdSpy: jasmine.Spy;
|
let getProcessFilterByIdSpy: jasmine.Spy;
|
||||||
let alfrescoApiService: AlfrescoApiService;
|
let alfrescoApiService: AlfrescoApiService;
|
||||||
|
let userPreferencesService: UserPreferencesService;
|
||||||
|
|
||||||
const fakeFilter = new ProcessFilterCloudModel({
|
const fakeFilter = new ProcessFilterCloudModel({
|
||||||
name: 'FakeRunningProcess',
|
name: 'FakeRunningProcess',
|
||||||
@@ -83,8 +100,30 @@ describe('EditProcessFilterCloudComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [ProcessFiltersCloudModule, ProcessServiceCloudTestingModule, MatIconTestingModule],
|
imports: [
|
||||||
providers: [MatDialog, { provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
|
MatIconTestingModule,
|
||||||
|
MatDialogModule,
|
||||||
|
NoopTranslateModule,
|
||||||
|
NoopAnimationsModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatAutocompleteModule,
|
||||||
|
FullNamePipe,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatChipsModule,
|
||||||
|
MatProgressBarModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService },
|
||||||
|
{ provide: MAT_DATE_LOCALE, useValue: enUS },
|
||||||
|
{ provide: DateAdapter, useClass: DateFnsAdapter },
|
||||||
|
{ provide: NotificationCloudService, useValue: { makeGQLQuery: () => of([]) } },
|
||||||
|
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS },
|
||||||
|
{ provide: IDENTITY_USER_SERVICE_TOKEN, useExisting: IdentityUserServiceMock }
|
||||||
|
],
|
||||||
|
declarations: [PeopleCloudComponent, DateRangeFilterComponent]
|
||||||
});
|
});
|
||||||
fixture = TestBed.createComponent(EditProcessFilterCloudComponent);
|
fixture = TestBed.createComponent(EditProcessFilterCloudComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
@@ -93,7 +132,9 @@ describe('EditProcessFilterCloudComponent', () => {
|
|||||||
appsService = TestBed.inject(AppsProcessCloudService);
|
appsService = TestBed.inject(AppsProcessCloudService);
|
||||||
processService = TestBed.inject(ProcessCloudService);
|
processService = TestBed.inject(ProcessCloudService);
|
||||||
alfrescoApiService = TestBed.inject(AlfrescoApiService);
|
alfrescoApiService = TestBed.inject(AlfrescoApiService);
|
||||||
|
userPreferencesService = TestBed.inject(UserPreferencesService);
|
||||||
dialog = TestBed.inject(MatDialog);
|
dialog = TestBed.inject(MatDialog);
|
||||||
|
|
||||||
spyOn(dialog, 'open').and.returnValue({
|
spyOn(dialog, 'open').and.returnValue({
|
||||||
afterClosed: () =>
|
afterClosed: () =>
|
||||||
of({
|
of({
|
||||||
@@ -105,6 +146,7 @@ describe('EditProcessFilterCloudComponent', () => {
|
|||||||
getProcessFilterByIdSpy = spyOn(service, 'getFilterById').and.returnValue(of(fakeFilter));
|
getProcessFilterByIdSpy = spyOn(service, 'getFilterById').and.returnValue(of(fakeFilter));
|
||||||
getRunningApplicationsSpy = spyOn(appsService, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
|
getRunningApplicationsSpy = spyOn(appsService, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
|
||||||
spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock);
|
spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock);
|
||||||
|
spyOn(userPreferencesService, 'select').and.returnValue(of({ localize: 'en', formatLong: {} }));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||||
});
|
});
|
||||||
|
@@ -9,15 +9,25 @@
|
|||||||
[class.adf-active]="currentFilter === filter"
|
[class.adf-active]="currentFilter === filter"
|
||||||
>
|
>
|
||||||
<div class="adf-process-filters__entry">
|
<div class="adf-process-filters__entry">
|
||||||
<adf-icon
|
<div>
|
||||||
data-automation-id="adf-filter-icon"
|
<adf-icon
|
||||||
*ngIf="showIcons"
|
data-automation-id="adf-filter-icon"
|
||||||
[value]="filter.icon">
|
*ngIf="showIcons"
|
||||||
</adf-icon>
|
[value]="filter.icon">
|
||||||
|
</adf-icon>
|
||||||
|
<span
|
||||||
|
data-automation-id="adf-filter-label"
|
||||||
|
class="adf-filter-action-button__label">
|
||||||
|
{{ filter.name | translate }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<span
|
<span
|
||||||
data-automation-id="adf-filter-label"
|
*ngIf="counters$[filter.key]"
|
||||||
class="adf-filter-action-button__label">
|
[attr.data-automation-id]="filter.key + '_filter-counter'"
|
||||||
{{ filter.name | translate }}
|
class="adf-process-filters__entry-counter"
|
||||||
|
[class.adf-active]="isFilterUpdated(filter.key)"
|
||||||
|
>
|
||||||
|
{{ counters$[filter.key] | async }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
color: var(--adf-theme-foreground-text-color-054);
|
color: var(--adf-theme-foreground-text-color-054);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
gap: var(--adf-theme-spacing);
|
gap: var(--adf-theme-spacing);
|
||||||
@@ -13,6 +14,17 @@
|
|||||||
&:hover {
|
&:hover {
|
||||||
color: var(--theme-primary-color);
|
color: var(--theme-primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-counter {
|
||||||
|
padding: 0 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
&.adf-active {
|
||||||
|
background-color: var(--theme-accent-color);
|
||||||
|
color: var(--theme-accent-color-default-contrast);
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-active {
|
.adf-active {
|
||||||
|
@@ -21,28 +21,46 @@ import { of, throwError } from 'rxjs';
|
|||||||
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
||||||
import { ProcessFiltersCloudComponent } from './process-filters-cloud.component';
|
import { ProcessFiltersCloudComponent } from './process-filters-cloud.component';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
|
||||||
import { ProcessFiltersCloudModule } from '../process-filters-cloud.module';
|
|
||||||
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
||||||
import { mockProcessFilters } from '../mock/process-filters-cloud.mock';
|
import { mockProcessFilters } from '../mock/process-filters-cloud.mock';
|
||||||
|
import { AppConfigService, AppConfigServiceMock, NoopTranslateModule } from '@alfresco/adf-core';
|
||||||
|
import { ProcessListCloudService } from '../../../process/process-list/services/process-list-cloud.service';
|
||||||
|
import { NotificationCloudService } from '../../../services/notification-cloud.service';
|
||||||
|
import { ApolloModule } from 'apollo-angular';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { MatListModule } from '@angular/material/list';
|
||||||
|
|
||||||
|
const ProcessFilterCloudServiceMock = {
|
||||||
|
getProcessFilters: () => of(mockProcessFilters),
|
||||||
|
getProcessNotificationSubscription: () => of([])
|
||||||
|
};
|
||||||
|
|
||||||
describe('ProcessFiltersCloudComponent', () => {
|
describe('ProcessFiltersCloudComponent', () => {
|
||||||
let processFilterService: ProcessFilterCloudService;
|
let processFilterService: ProcessFilterCloudService;
|
||||||
let component: ProcessFiltersCloudComponent;
|
let component: ProcessFiltersCloudComponent;
|
||||||
let fixture: ComponentFixture<ProcessFiltersCloudComponent>;
|
let fixture: ComponentFixture<ProcessFiltersCloudComponent>;
|
||||||
let getProcessFiltersSpy: jasmine.Spy;
|
let getProcessFiltersSpy: jasmine.Spy;
|
||||||
|
let getProcessNotificationSubscriptionSpy: jasmine.Spy;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [ProcessServiceCloudTestingModule, ProcessFiltersCloudModule],
|
imports: [NoopTranslateModule, NoopAnimationsModule, MatListModule],
|
||||||
providers: [{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
|
providers: [
|
||||||
|
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService },
|
||||||
|
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||||
|
{ provide: ProcessListCloudService, useValue: { getProcessCounter: () => of(10) } },
|
||||||
|
{ provide: ProcessFilterCloudService, useValue: ProcessFilterCloudServiceMock },
|
||||||
|
NotificationCloudService,
|
||||||
|
ApolloModule
|
||||||
|
]
|
||||||
});
|
});
|
||||||
fixture = TestBed.createComponent(ProcessFiltersCloudComponent);
|
fixture = TestBed.createComponent(ProcessFiltersCloudComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
processFilterService = TestBed.inject(ProcessFilterCloudService);
|
processFilterService = TestBed.inject(ProcessFilterCloudService);
|
||||||
getProcessFiltersSpy = spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(mockProcessFilters));
|
getProcessFiltersSpy = spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(mockProcessFilters));
|
||||||
|
getProcessNotificationSubscriptionSpy = spyOn(processFilterService, 'getProcessNotificationSubscription').and.returnValue(of([]));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -288,12 +306,14 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const clickOnFilter = async (filterKey: string) => {
|
const clickOnFilter = async (filterKey: string) => {
|
||||||
fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${filterKey}_filter"]`).click();
|
const button = fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${filterKey}_filter"]`);
|
||||||
|
button.click();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should apply active CSS class on filter click', async () => {
|
it('should apply active CSS class on filter click', async () => {
|
||||||
|
component.enableNotifications = true;
|
||||||
component.appName = 'mock-app-name';
|
component.appName = 'mock-app-name';
|
||||||
const appNameChange = new SimpleChange(null, 'mock-app-name', true);
|
const appNameChange = new SimpleChange(null, 'mock-app-name', true);
|
||||||
component.ngOnChanges({ appName: appNameChange });
|
component.ngOnChanges({ appName: appNameChange });
|
||||||
@@ -301,18 +321,24 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
|
||||||
await clickOnFilter(allProcessesFilterKey);
|
await clickOnFilter(allProcessesFilterKey);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
expect(getActiveFilterElement(allProcessesFilterKey)).toBeDefined();
|
expect(getActiveFilterElement(allProcessesFilterKey)).toBeDefined();
|
||||||
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
||||||
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeNull();
|
||||||
|
|
||||||
await clickOnFilter(runningProcessesFilterKey);
|
await clickOnFilter(runningProcessesFilterKey);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
expect(getActiveFilterElement(allProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(allProcessesFilterKey)).toBeNull();
|
||||||
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeDefined();
|
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeDefined();
|
||||||
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeNull();
|
||||||
|
|
||||||
await clickOnFilter(completedProcessesFilterKey);
|
await clickOnFilter(completedProcessesFilterKey);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
expect(getActiveFilterElement(allProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(allProcessesFilterKey)).toBeNull();
|
||||||
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
||||||
@@ -345,5 +371,77 @@ describe('ProcessFiltersCloudComponent', () => {
|
|||||||
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
expect(getActiveFilterElement(runningProcessesFilterKey)).toBeNull();
|
||||||
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeDefined();
|
expect(getActiveFilterElement(completedProcessesFilterKey)).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should made sbscription', () => {
|
||||||
|
component.enableNotifications = true;
|
||||||
|
component.appName = 'mock-app-name';
|
||||||
|
const appNameChange = new SimpleChange(null, 'mock-app-name', true);
|
||||||
|
component.ngOnChanges({ appName: appNameChange });
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getProcessNotificationSubscriptionSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit filter key when filter counter is set for first time', () => {
|
||||||
|
component.currentFiltersValues = {};
|
||||||
|
const fakeFilterKey = 'testKey';
|
||||||
|
const fakeFilterValue = 10;
|
||||||
|
const updatedFilterSpy = spyOn(component.updatedFilter, 'emit');
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, fakeFilterValue);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.currentFiltersValues).not.toEqual({});
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(fakeFilterValue);
|
||||||
|
expect(updatedFilterSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit filter key when filter counter has not changd', () => {
|
||||||
|
component.currentFiltersValues = {};
|
||||||
|
const fakeFilterKey = 'testKey';
|
||||||
|
const fakeFilterValue = 10;
|
||||||
|
const updatedFilterSpy = spyOn(component.updatedFilter, 'emit');
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, fakeFilterValue);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.currentFiltersValues).not.toEqual({});
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(fakeFilterValue);
|
||||||
|
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, fakeFilterValue);
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(fakeFilterValue);
|
||||||
|
expect(updatedFilterSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit filter key when filter counter is increased', () => {
|
||||||
|
component.currentFiltersValues = {};
|
||||||
|
const fakeFilterKey = 'testKey';
|
||||||
|
const updatedFilterSpy = spyOn(component.updatedFilter, 'emit');
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, 10);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updatedFilterSpy).not.toHaveBeenCalledWith(fakeFilterKey);
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(10);
|
||||||
|
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, 20);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updatedFilterSpy).toHaveBeenCalledWith(fakeFilterKey);
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit filter key when filter counter is decreased', () => {
|
||||||
|
component.currentFiltersValues = {};
|
||||||
|
const fakeFilterKey = 'testKey';
|
||||||
|
const updatedFilterSpy = spyOn(component.updatedFilter, 'emit');
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, 10);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updatedFilterSpy).not.toHaveBeenCalledWith(fakeFilterKey);
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(10);
|
||||||
|
|
||||||
|
component.checkIfFilterValuesHasBeenUpdated(fakeFilterKey, 5);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updatedFilterSpy).toHaveBeenCalledWith(fakeFilterKey);
|
||||||
|
expect(component.currentFiltersValues[fakeFilterKey]).toBe(5);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -19,9 +19,10 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, OnDes
|
|||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
|
||||||
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
||||||
import { TranslationService } from '@alfresco/adf-core';
|
import { AppConfigService, TranslationService } from '@alfresco/adf-core';
|
||||||
import { FilterParamsModel } from '../../../task/task-filters/models/filter-cloud.model';
|
import { FilterParamsModel } from '../../../task/task-filters/models/filter-cloud.model';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { debounceTime, takeUntil, tap } from 'rxjs/operators';
|
||||||
|
import { ProcessListCloudService } from '../../../process/process-list/services/process-list-cloud.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-process-filters',
|
selector: 'adf-cloud-process-filters',
|
||||||
@@ -58,19 +59,31 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges, OnDestro
|
|||||||
@Output()
|
@Output()
|
||||||
error = new EventEmitter<any>();
|
error = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/** Emitted when filter is updated. */
|
||||||
|
@Output()
|
||||||
|
updatedFilter: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
|
||||||
filters$: Observable<ProcessFilterCloudModel[]>;
|
filters$: Observable<ProcessFilterCloudModel[]>;
|
||||||
currentFilter?: ProcessFilterCloudModel;
|
currentFilter?: ProcessFilterCloudModel;
|
||||||
filters: ProcessFilterCloudModel[] = [];
|
filters: ProcessFilterCloudModel[] = [];
|
||||||
|
counters$: { [key: string]: Observable<number> } = {};
|
||||||
|
enableNotifications: boolean;
|
||||||
|
currentFiltersValues: { [key: string]: number } = {};
|
||||||
|
updatedFiltersSet = new Set<string>();
|
||||||
|
|
||||||
private onDestroy$ = new Subject<boolean>();
|
private onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
private readonly processFilterCloudService = inject(ProcessFilterCloudService);
|
private readonly processFilterCloudService = inject(ProcessFilterCloudService);
|
||||||
private readonly translationService = inject(TranslationService);
|
private readonly translationService = inject(TranslationService);
|
||||||
|
private readonly appConfigService = inject(AppConfigService);
|
||||||
|
private readonly processListCloudService = inject(ProcessListCloudService);
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.enableNotifications = this.appConfigService.get('notifications', true);
|
||||||
if (this.appName === '') {
|
if (this.appName === '') {
|
||||||
this.getFilters(this.appName);
|
this.getFilters(this.appName);
|
||||||
}
|
}
|
||||||
|
this.initProcessNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
@@ -97,6 +110,7 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges, OnDestro
|
|||||||
this.filters = res || [];
|
this.filters = res || [];
|
||||||
this.selectFilterAndEmit(this.filterParam);
|
this.selectFilterAndEmit(this.filterParam);
|
||||||
this.success.emit(res);
|
this.success.emit(res);
|
||||||
|
this.updateFilterCounters();
|
||||||
},
|
},
|
||||||
error: (err: any) => {
|
error: (err: any) => {
|
||||||
this.error.emit(err);
|
this.error.emit(err);
|
||||||
@@ -172,6 +186,8 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges, OnDestro
|
|||||||
if (filter) {
|
if (filter) {
|
||||||
this.selectFilter(filter);
|
this.selectFilter(filter);
|
||||||
this.filterClicked.emit(this.currentFilter);
|
this.filterClicked.emit(this.currentFilter);
|
||||||
|
this.updateFilterCounter(this.currentFilter);
|
||||||
|
this.updatedFiltersSet.delete(filter.key);
|
||||||
} else {
|
} else {
|
||||||
this.currentFilter = undefined;
|
this.currentFilter = undefined;
|
||||||
}
|
}
|
||||||
@@ -220,4 +236,47 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges, OnDestro
|
|||||||
isActiveFilter(filter: ProcessFilterCloudModel): boolean {
|
isActiveFilter(filter: ProcessFilterCloudModel): boolean {
|
||||||
return this.currentFilter.name === filter.name;
|
return this.currentFilter.name === filter.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initProcessNotification(): void {
|
||||||
|
if (this.appName && this.enableNotifications) {
|
||||||
|
this.processFilterCloudService
|
||||||
|
.getProcessNotificationSubscription(this.appName)
|
||||||
|
.pipe(debounceTime(1000), takeUntil(this.onDestroy$))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.updateFilterCounters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFilterCounters(): void {
|
||||||
|
this.filters.forEach((filter: ProcessFilterCloudModel) => {
|
||||||
|
if (filter?.status) {
|
||||||
|
this.updateFilterCounter(filter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFilterCounter(filter: ProcessFilterCloudModel): void {
|
||||||
|
this.counters$[filter.key] = this.processListCloudService.getProcessCounter(filter.appName, filter.status).pipe(
|
||||||
|
tap((filterCounter) => {
|
||||||
|
this.checkIfFilterValuesHasBeenUpdated(filter.key, filterCounter);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfFilterValuesHasBeenUpdated(filterKey: string, filterValue: number): void {
|
||||||
|
if (!this.currentFiltersValues[filterKey]) {
|
||||||
|
this.currentFiltersValues[filterKey] = filterValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.currentFiltersValues[filterKey] !== filterValue) {
|
||||||
|
this.currentFiltersValues[filterKey] = filterValue;
|
||||||
|
this.updatedFilter.emit(filterKey);
|
||||||
|
this.updatedFiltersSet.add(filterKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isFilterUpdated(filterName: string): boolean {
|
||||||
|
return this.updatedFiltersSet.has(filterName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -186,3 +186,25 @@ const mockAppVersion2: ApplicationVersionModel = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const mockAppVersions = [mockAppVersion1, mockAppVersion2];
|
export const mockAppVersions = [mockAppVersion1, mockAppVersion2];
|
||||||
|
|
||||||
|
export const processNotifications = [
|
||||||
|
{
|
||||||
|
eventType: 'PROCESS_CREATED',
|
||||||
|
entity: {
|
||||||
|
appVersion: '1',
|
||||||
|
id: 'bccc1217-7036-11ef-86f2-bae4749e773e',
|
||||||
|
processDefinitionId: 'Process_XmWTFMqf:1:1b30709b-6ff3-11ef-86f2-bae4749e773e',
|
||||||
|
processDefinitionKey: 'Process_XmWTFMqf',
|
||||||
|
initiator: 'hruser',
|
||||||
|
status: 'CREATED',
|
||||||
|
processDefinitionVersion: 1,
|
||||||
|
processDefinitionName: 'processchild'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const processCloudEngineEventsMock = {
|
||||||
|
data: {
|
||||||
|
engineEvents: processNotifications
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { of } from 'rxjs';
|
import { firstValueFrom, of } from 'rxjs';
|
||||||
import { ProcessFilterCloudService } from './process-filter-cloud.service';
|
import { ProcessFilterCloudService } from './process-filter-cloud.service';
|
||||||
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
||||||
@@ -26,10 +26,12 @@ import {
|
|||||||
fakeProcessCloudFilterEntries,
|
fakeProcessCloudFilterEntries,
|
||||||
fakeProcessCloudFilters,
|
fakeProcessCloudFilters,
|
||||||
fakeProcessCloudFilterWithDifferentEntries,
|
fakeProcessCloudFilterWithDifferentEntries,
|
||||||
fakeProcessFilter
|
fakeProcessFilter,
|
||||||
|
processCloudEngineEventsMock
|
||||||
} from '../mock/process-filters-cloud.mock';
|
} from '../mock/process-filters-cloud.mock';
|
||||||
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
|
||||||
import { IdentityUserService } from '../../../people/services/identity-user.service';
|
import { IdentityUserService } from '../../../people/services/identity-user.service';
|
||||||
|
import { NotificationCloudService } from '../../../services/notification-cloud.service';
|
||||||
|
|
||||||
describe('ProcessFilterCloudService', () => {
|
describe('ProcessFilterCloudService', () => {
|
||||||
let service: ProcessFilterCloudService;
|
let service: ProcessFilterCloudService;
|
||||||
@@ -38,6 +40,7 @@ describe('ProcessFilterCloudService', () => {
|
|||||||
let updatePreferenceSpy: jasmine.Spy;
|
let updatePreferenceSpy: jasmine.Spy;
|
||||||
let createPreferenceSpy: jasmine.Spy;
|
let createPreferenceSpy: jasmine.Spy;
|
||||||
let getCurrentUserInfoSpy: jasmine.Spy;
|
let getCurrentUserInfoSpy: jasmine.Spy;
|
||||||
|
let notificationCloudService: NotificationCloudService;
|
||||||
|
|
||||||
const identityUserMock = {
|
const identityUserMock = {
|
||||||
username: 'mock-username',
|
username: 'mock-username',
|
||||||
@@ -55,6 +58,7 @@ describe('ProcessFilterCloudService', () => {
|
|||||||
|
|
||||||
const preferenceCloudService = TestBed.inject(PROCESS_FILTERS_SERVICE_TOKEN);
|
const preferenceCloudService = TestBed.inject(PROCESS_FILTERS_SERVICE_TOKEN);
|
||||||
const identityUserService = TestBed.inject(IdentityUserService);
|
const identityUserService = TestBed.inject(IdentityUserService);
|
||||||
|
notificationCloudService = TestBed.inject(NotificationCloudService);
|
||||||
|
|
||||||
createPreferenceSpy = spyOn(preferenceCloudService, 'createPreference').and.returnValue(of(fakeProcessCloudFilters));
|
createPreferenceSpy = spyOn(preferenceCloudService, 'createPreference').and.returnValue(of(fakeProcessCloudFilters));
|
||||||
updatePreferenceSpy = spyOn(preferenceCloudService, 'updatePreference').and.returnValue(of(fakeProcessCloudFilters));
|
updatePreferenceSpy = spyOn(preferenceCloudService, 'updatePreference').and.returnValue(of(fakeProcessCloudFilters));
|
||||||
@@ -236,4 +240,13 @@ describe('ProcessFilterCloudService', () => {
|
|||||||
|
|
||||||
expect(updatePreferenceSpy).toHaveBeenCalledWith('mock-appName', 'process-filters-mock-appName-mock-username', fakeProcessCloudFilters);
|
expect(updatePreferenceSpy).toHaveBeenCalledWith('mock-appName', 'process-filters-mock-appName-mock-username', fakeProcessCloudFilters);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return engine event task subscription', async () => {
|
||||||
|
spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(of(processCloudEngineEventsMock));
|
||||||
|
|
||||||
|
const result = await firstValueFrom(service.getProcessNotificationSubscription('testApp'));
|
||||||
|
expect(result.length).toBe(1);
|
||||||
|
expect(result[0].eventType).toBe('PROCESS_CREATED');
|
||||||
|
expect(result[0].entity.status).toBe('CREATED');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -22,6 +22,25 @@ import { switchMap, map } from 'rxjs/operators';
|
|||||||
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
||||||
import { IdentityUserService } from '../../../people/services/identity-user.service';
|
import { IdentityUserService } from '../../../people/services/identity-user.service';
|
||||||
|
import { NotificationCloudService } from '../../../services/notification-cloud.service';
|
||||||
|
import { TaskCloudEngineEvent } from '../../../models/engine-event-cloud.model';
|
||||||
|
|
||||||
|
const PROCESS_EVENT_SUBSCRIPTION_QUERY = `
|
||||||
|
subscription {
|
||||||
|
engineEvents(eventType: [
|
||||||
|
PROCESS_CANCELLED
|
||||||
|
PROCESS_COMPLETED
|
||||||
|
PROCESS_CREATED
|
||||||
|
PROCESS_RESUMED
|
||||||
|
PROCESS_SUSPENDED
|
||||||
|
PROCESS_STARTED
|
||||||
|
]) {
|
||||||
|
eventType
|
||||||
|
entity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
@@ -31,6 +50,7 @@ export class ProcessFilterCloudService {
|
|||||||
|
|
||||||
private readonly preferenceService = inject<PreferenceCloudServiceInterface>(PROCESS_FILTERS_SERVICE_TOKEN);
|
private readonly preferenceService = inject<PreferenceCloudServiceInterface>(PROCESS_FILTERS_SERVICE_TOKEN);
|
||||||
private readonly identityUserService = inject(IdentityUserService);
|
private readonly identityUserService = inject(IdentityUserService);
|
||||||
|
private readonly notificationCloudService = inject(NotificationCloudService);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.filtersSubject = new BehaviorSubject([]);
|
this.filtersSubject = new BehaviorSubject([]);
|
||||||
@@ -377,4 +397,10 @@ export class ProcessFilterCloudService {
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getProcessNotificationSubscription(appName: string): Observable<TaskCloudEngineEvent[]> {
|
||||||
|
return this.notificationCloudService
|
||||||
|
.makeGQLQuery(appName, PROCESS_EVENT_SUBSCRIPTION_QUERY)
|
||||||
|
.pipe(map((events: any) => events?.data?.engineEvents));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,7 @@ import { PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN } from '../../../services/cloud
|
|||||||
import { ProcessListCloudPreferences } from '../models/process-cloud-preferences';
|
import { ProcessListCloudPreferences } from '../models/process-cloud-preferences';
|
||||||
import { PROCESS_LIST_CUSTOM_VARIABLE_COLUMN } from '../../../models/data-column-custom-data';
|
import { PROCESS_LIST_CUSTOM_VARIABLE_COLUMN } from '../../../models/data-column-custom-data';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { PreferenceCloudServiceInterface } from '@alfresco/adf-process-services-cloud';
|
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
import { HarnessLoader } from '@angular/cdk/testing';
|
||||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||||
|
@@ -20,6 +20,7 @@ import { ProcessListCloudService } from './process-list-cloud.service';
|
|||||||
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
||||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||||
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
|
||||||
describe('ProcessListCloudService', () => {
|
describe('ProcessListCloudService', () => {
|
||||||
let service: ProcessListCloudService;
|
let service: ProcessListCloudService;
|
||||||
@@ -36,9 +37,7 @@ describe('ProcessListCloudService', () => {
|
|||||||
|
|
||||||
beforeEach(fakeAsync(() => {
|
beforeEach(fakeAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [ProcessServiceCloudTestingModule]
|
||||||
ProcessServiceCloudTestingModule
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
adfHttpClient = TestBed.inject(AdfHttpClient);
|
adfHttpClient = TestBed.inject(AdfHttpClient);
|
||||||
service = TestBed.inject(ProcessListCloudService);
|
service = TestBed.inject(ProcessListCloudService);
|
||||||
@@ -71,8 +70,14 @@ describe('ProcessListCloudService', () => {
|
|||||||
|
|
||||||
it('should concat the sorting to append as parameters', (done) => {
|
it('should concat the sorting to append as parameters', (done) => {
|
||||||
const processRequest = {
|
const processRequest = {
|
||||||
appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service',
|
appName: 'fakeName',
|
||||||
sorting: [{ orderBy: 'NAME', direction: 'DESC' }, { orderBy: 'TITLE', direction: 'ASC' }]
|
skipCount: 0,
|
||||||
|
maxItems: 20,
|
||||||
|
service: 'fake-service',
|
||||||
|
sorting: [
|
||||||
|
{ orderBy: 'NAME', direction: 'DESC' },
|
||||||
|
{ orderBy: 'TITLE', direction: 'ASC' }
|
||||||
|
]
|
||||||
} as ProcessQueryCloudRequestModel;
|
} as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallQueryParameters);
|
requestSpy.and.callFake(returnCallQueryParameters);
|
||||||
service.getProcessByRequest(processRequest).subscribe((res) => {
|
service.getProcessByRequest(processRequest).subscribe((res) => {
|
||||||
@@ -87,7 +92,7 @@ describe('ProcessListCloudService', () => {
|
|||||||
const processRequest = { appName: null } as ProcessQueryCloudRequestModel;
|
const processRequest = { appName: null } as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallUrl);
|
requestSpy.and.callFake(returnCallUrl);
|
||||||
service.getProcessByRequest(processRequest).subscribe(
|
service.getProcessByRequest(processRequest).subscribe(
|
||||||
() => { },
|
() => {},
|
||||||
(error) => {
|
(error) => {
|
||||||
expect(error).toBe('Appname not configured');
|
expect(error).toBe('Appname not configured');
|
||||||
done();
|
done();
|
||||||
@@ -95,8 +100,19 @@ describe('ProcessListCloudService', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getAdminProcessRequest', () => {
|
it('should return number of total items of processes ', async () => {
|
||||||
|
const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 1, service: 'fake-service' } as ProcessQueryCloudRequestModel;
|
||||||
|
requestSpy.and.callFake(returnCallQueryParameters);
|
||||||
|
const result = await firstValueFrom(service.getProcessByRequest(processRequest));
|
||||||
|
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result).not.toBeNull();
|
||||||
|
expect(result.skipCount).toBe(0);
|
||||||
|
expect(result.maxItems).toBe(1);
|
||||||
|
expect(result.service).toBe('fake-service');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAdminProcessRequest', () => {
|
||||||
it('should append to the call all the parameters', async () => {
|
it('should append to the call all the parameters', async () => {
|
||||||
const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' } as ProcessQueryCloudRequestModel;
|
const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' } as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallQueryParameters);
|
requestSpy.and.callFake(returnCallQueryParameters);
|
||||||
@@ -121,8 +137,14 @@ describe('ProcessListCloudService', () => {
|
|||||||
|
|
||||||
it('should concat the sorting to append as parameters', async () => {
|
it('should concat the sorting to append as parameters', async () => {
|
||||||
const processRequest = {
|
const processRequest = {
|
||||||
appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service',
|
appName: 'fakeName',
|
||||||
sorting: [{ orderBy: 'NAME', direction: 'DESC' }, { orderBy: 'TITLE', direction: 'ASC' }]
|
skipCount: 0,
|
||||||
|
maxItems: 20,
|
||||||
|
service: 'fake-service',
|
||||||
|
sorting: [
|
||||||
|
{ orderBy: 'NAME', direction: 'DESC' },
|
||||||
|
{ orderBy: 'TITLE', direction: 'ASC' }
|
||||||
|
]
|
||||||
} as ProcessQueryCloudRequestModel;
|
} as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallQueryParameters);
|
requestSpy.and.callFake(returnCallQueryParameters);
|
||||||
const request = await service.getAdminProcessByRequest(processRequest).toPromise();
|
const request = await service.getAdminProcessByRequest(processRequest).toPromise();
|
||||||
@@ -140,7 +162,7 @@ describe('ProcessListCloudService', () => {
|
|||||||
await service.getAdminProcessByRequest(processRequest).toPromise();
|
await service.getAdminProcessByRequest(processRequest).toPromise();
|
||||||
|
|
||||||
fail('Should have thrown error');
|
fail('Should have thrown error');
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
expect(error).toBe('Appname not configured');
|
expect(error).toBe('Appname not configured');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -155,7 +177,13 @@ describe('ProcessListCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not have variable keys as part of query parameters', async () => {
|
it('should not have variable keys as part of query parameters', async () => {
|
||||||
const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service', variableKeys: ['test-one', 'test-two'] } as ProcessQueryCloudRequestModel;
|
const processRequest = {
|
||||||
|
appName: 'fakeName',
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: 20,
|
||||||
|
service: 'fake-service',
|
||||||
|
variableKeys: ['test-one', 'test-two']
|
||||||
|
} as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallQueryParameters);
|
requestSpy.and.callFake(returnCallQueryParameters);
|
||||||
const requestParams = await service.getAdminProcessByRequest(processRequest).toPromise();
|
const requestParams = await service.getAdminProcessByRequest(processRequest).toPromise();
|
||||||
|
|
||||||
@@ -165,7 +193,13 @@ describe('ProcessListCloudService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should send right variable keys as post body', async () => {
|
it('should send right variable keys as post body', async () => {
|
||||||
const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service', variableKeys: ['test-one', 'test-two'] } as ProcessQueryCloudRequestModel;
|
const processRequest = {
|
||||||
|
appName: 'fakeName',
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: 20,
|
||||||
|
service: 'fake-service',
|
||||||
|
variableKeys: ['test-one', 'test-two']
|
||||||
|
} as ProcessQueryCloudRequestModel;
|
||||||
requestSpy.and.callFake(returnCallBody);
|
requestSpy.and.callFake(returnCallBody);
|
||||||
const requestBodyParams = await service.getAdminProcessByRequest(processRequest).toPromise();
|
const requestBodyParams = await service.getAdminProcessByRequest(processRequest).toPromise();
|
||||||
|
|
||||||
|
@@ -67,6 +67,48 @@ export class ProcessListCloudService extends BaseCloudService {
|
|||||||
return this.getProcess(callback, defaultQueryUrl, requestNode, queryUrl);
|
return this.getProcess(callback, defaultQueryUrl, requestNode, queryUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a process using an object with optional query properties.
|
||||||
|
*
|
||||||
|
* @param appName app name
|
||||||
|
* @param status filter status
|
||||||
|
* @returns Total items
|
||||||
|
*/
|
||||||
|
getProcessCounter(appName: string, status: string): Observable<any> {
|
||||||
|
const callback = (url: string, queryParams: any) => this.get(url, queryParams);
|
||||||
|
let queryUrl: string;
|
||||||
|
const defaultQueryUrl = 'query/v1/process-instances';
|
||||||
|
const requestNode: ProcessQueryCloudRequestModel = {
|
||||||
|
appName,
|
||||||
|
appVersion: '',
|
||||||
|
initiator: null,
|
||||||
|
id: '',
|
||||||
|
name: null,
|
||||||
|
processDefinitionId: '',
|
||||||
|
processDefinitionName: null,
|
||||||
|
processDefinitionKey: '',
|
||||||
|
status,
|
||||||
|
businessKey: '',
|
||||||
|
startFrom: null,
|
||||||
|
startTo: null,
|
||||||
|
completedFrom: null,
|
||||||
|
completedTo: null,
|
||||||
|
suspendedFrom: null,
|
||||||
|
suspendedTo: null,
|
||||||
|
completedDate: '',
|
||||||
|
maxItems: 1,
|
||||||
|
skipCount: 0,
|
||||||
|
sorting: [
|
||||||
|
{
|
||||||
|
orderBy: 'startDate',
|
||||||
|
direction: 'DESC'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.getProcess(callback, defaultQueryUrl, requestNode, queryUrl).pipe(map((tasks) => tasks?.list?.pagination?.totalItems));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a process using an object with optional query properties in admin app.
|
* Finds a process using an object with optional query properties in admin app.
|
||||||
*
|
*
|
||||||
|
@@ -49,7 +49,8 @@ import { ProcessServiceCloudTestingModule } from '../../../testing/process-servi
|
|||||||
import { ProcessNameCloudPipe } from '../../../pipes/process-name-cloud.pipe';
|
import { ProcessNameCloudPipe } from '../../../pipes/process-name-cloud.pipe';
|
||||||
import { ProcessInstanceCloud } from '../models/process-instance-cloud.model';
|
import { ProcessInstanceCloud } from '../models/process-instance-cloud.model';
|
||||||
import { ESCAPE } from '@angular/cdk/keycodes';
|
import { ESCAPE } from '@angular/cdk/keycodes';
|
||||||
import { ProcessDefinitionCloud, TaskVariableCloud } from '@alfresco/adf-process-services-cloud';
|
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
|
||||||
|
import { TaskVariableCloud } from '../../../form/models/task-variable-cloud.model';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
import { HarnessLoader } from '@angular/cdk/testing';
|
||||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||||
|
@@ -52,7 +52,7 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp
|
|||||||
filters: TaskFilterCloudModel[] = [];
|
filters: TaskFilterCloudModel[] = [];
|
||||||
currentFilter: TaskFilterCloudModel;
|
currentFilter: TaskFilterCloudModel;
|
||||||
enableNotifications: boolean;
|
enableNotifications: boolean;
|
||||||
currentFiltersValues = {};
|
currentFiltersValues: { [key: string]: number } = {};
|
||||||
|
|
||||||
private readonly taskFilterCloudService = inject(TaskFilterCloudService);
|
private readonly taskFilterCloudService = inject(TaskFilterCloudService);
|
||||||
private readonly translationService = inject(TranslationService);
|
private readonly translationService = inject(TranslationService);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TaskDetailsCloudModel } from '@alfresco/adf-process-services-cloud';
|
import { TaskDetailsCloudModel } from '../../../task/start-task/models/task-details-cloud.model';
|
||||||
import { assignedTaskDetailsCloudMock } from '../../task-header/mocks/task-details-cloud.mock';
|
import { assignedTaskDetailsCloudMock } from '../../task-header/mocks/task-details-cloud.mock';
|
||||||
import { TaskFilterCloudModel, ServiceTaskFilterCloudModel, AssignmentType, TaskStatusFilter } from '../models/filter-cloud.model';
|
import { TaskFilterCloudModel, ServiceTaskFilterCloudModel, AssignmentType, TaskStatusFilter } from '../models/filter-cloud.model';
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user