AAE-26215 Standalone process cloud components (#10553)

This commit is contained in:
Denys Vuika
2025-01-15 08:37:46 -05:00
committed by GitHub
parent 8b5dcf19b9
commit 0a17fb4f4c
39 changed files with 475 additions and 974 deletions

View File

@@ -1,36 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NoTaskDetailsTemplateDirective } from './no-task-detail-template.directive';
import { TaskDetailsComponent } from '../task-details/task-details.component';
describe('NoTaskDetailsTemplateDirective', () => {
let component: NoTaskDetailsTemplateDirective;
let detailsComponent: TaskDetailsComponent;
beforeEach(() => {
detailsComponent = new TaskDetailsComponent(null, null, null, null, null);
component = new NoTaskDetailsTemplateDirective(detailsComponent);
});
it('should set "no task details" template on task details component', () => {
const testTemplate: any = 'test template';
component.template = testTemplate;
component.ngAfterContentInit();
expect(detailsComponent.noTaskDetailsTemplateComponent).toBe(testTemplate);
});
});

View File

@@ -1,39 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
import { TaskDetailsComponent } from '../task-details/task-details.component';
/**
* @deprecated no longer used anywhere, and can be safely removed
* Directive selectors without adf- prefix will be deprecated on 3.0.0
*/
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'adf-no-task-details-template, no-task-details-template',
standalone: true
})
export class NoTaskDetailsTemplateDirective implements AfterContentInit {
@ContentChild(TemplateRef)
template: any;
constructor(private activitiTaskDetails: TaskDetailsComponent) {}
ngAfterContentInit() {
this.activitiTaskDetails.noTaskDetailsTemplateComponent = this.template;
}
}

View File

@@ -1,155 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { TaskListService } from '../../services/tasklist.service';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TaskAuditDirective } from '@alfresco/adf-process-services';
declare let jasmine: any;
describe('TaskAuditDirective', () => {
@Component({
selector: 'adf-basic-button',
standalone: true,
imports: [TaskAuditDirective],
template: ` <button
id="auditButton"
adf-task-audit
[task-id]="currentTaskId"
[download]="download"
[fileName]="fileName"
[format]="format"
(clicked)="onAuditClick($event)"
>
My button
</button>`
})
class BasicButtonComponent {
download: boolean = false;
fileName: string;
format: string;
onAuditClick() {}
}
let fixture: ComponentFixture<BasicButtonComponent>;
let component: BasicButtonComponent;
let service: TaskListService;
const createFakePdfBlob = (): Blob => {
const pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'
);
return new Blob([pdfData], { type: 'application/pdf' });
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessTestingModule, BasicButtonComponent]
});
fixture = TestBed.createComponent(BasicButtonComponent);
component = fixture.componentInstance;
service = TestBed.inject(TaskListService);
jasmine.Ajax.install();
});
afterEach(() => {
jasmine.Ajax.uninstall();
});
it('should fetch the pdf Blob when the format is pdf', fakeAsync(() => {
component.fileName = 'FakeAuditName';
component.format = 'pdf';
const blob = createFakePdfBlob();
spyOn(service, 'fetchTaskAuditPdfById').and.returnValue(of(blob));
spyOn(component, 'onAuditClick').and.callThrough();
fixture.detectChanges();
const button = fixture.nativeElement.querySelector('#auditButton');
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(component.onAuditClick).toHaveBeenCalledWith({ format: 'pdf', value: blob, fileName: 'FakeAuditName' });
});
button.click();
}));
it('should fetch the json info when the format is json', fakeAsync(() => {
component.fileName = 'FakeAuditName';
component.format = 'json';
component.download = true;
const auditJson = {
taskId: '77',
taskName: 'Fake Task Name',
assignee: 'FirstName LastName',
formData: [],
selectedOutcome: null,
comments: []
};
spyOn(service, 'fetchTaskAuditJsonById').and.returnValue(of(auditJson));
spyOn(component, 'onAuditClick').and.callThrough();
fixture.detectChanges();
const button = fixture.nativeElement.querySelector('#auditButton');
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(component.onAuditClick).toHaveBeenCalledWith({ format: 'json', value: auditJson, fileName: 'FakeAuditName' });
});
button.click();
}));
it('should fetch the pdf Blob as default when the format is UNKNOWN', fakeAsync(() => {
component.fileName = 'FakeAuditName';
component.format = 'fakeFormat';
const blob = createFakePdfBlob();
spyOn(service, 'fetchTaskAuditPdfById').and.returnValue(of(blob));
spyOn(component, 'onAuditClick').and.callThrough();
fixture.detectChanges();
const button = fixture.nativeElement.querySelector('#auditButton');
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(component.onAuditClick).toHaveBeenCalledWith({ format: 'pdf', value: blob, fileName: 'FakeAuditName' });
});
button.click();
}));
});

View File

@@ -1,121 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @angular-eslint/no-input-rename */
import { DownloadService } from '@alfresco/adf-core';
import { Directive, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { TaskListService } from '../../services/tasklist.service';
const JSON_FORMAT: string = 'json';
const PDF_FORMAT: string = 'pdf';
/** @deprecated no longer used anywhere, and can be safely removed */
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'button[adf-task-audit]',
standalone: true,
host: {
role: 'button',
'(click)': 'onClickAudit()'
}
})
export class TaskAuditDirective implements OnChanges {
/** (**required**) The id of the task. */
@Input('task-id')
taskId: string;
/** Name of the downloaded file (for PDF downloads). */
@Input()
fileName: string = 'Audit';
/** Format of the audit information. Can be "pdf" or "json". */
@Input()
format: string = 'pdf';
/** Enables downloading of the audit when the decorated element is clicked. */
@Input()
download: boolean = true;
/** Emitted when the decorated element is clicked. */
@Output()
clicked: EventEmitter<any> = new EventEmitter<any>();
/** Emitted when an error occurs. */
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
public audit: any;
constructor(private downloadService: DownloadService, private taskListService: TaskListService) {}
ngOnChanges(): void {
if (!this.isValidType()) {
this.setDefaultFormatType();
}
}
isValidType(): boolean {
return this.format && (this.isJsonFormat() || this.isPdfFormat());
}
setDefaultFormatType(): void {
this.format = PDF_FORMAT;
}
/**
* fetch the audit information in the requested format
*/
fetchAuditInfo(): void {
if (this.isPdfFormat()) {
this.taskListService.fetchTaskAuditPdfById(this.taskId).subscribe(
(blob: Blob) => {
this.audit = blob;
if (this.download) {
this.downloadService.downloadBlob(this.audit, this.fileName + '.pdf');
}
this.clicked.emit({ format: this.format, value: this.audit, fileName: this.fileName });
},
(err) => {
this.error.emit(err);
}
);
} else {
this.taskListService.fetchTaskAuditJsonById(this.taskId).subscribe(
(res) => {
this.audit = res;
this.clicked.emit({ format: this.format, value: this.audit, fileName: this.fileName });
},
(err) => {
this.error.emit(err);
}
);
}
}
onClickAudit() {
this.fetchAuditInfo();
}
isJsonFormat() {
return this.format === JSON_FORMAT;
}
isPdfFormat() {
return this.format === PDF_FORMAT;
}
}

View File

@@ -20,8 +20,6 @@ import { UnclaimTaskDirective } from './components/task-form/unclaim-task.direct
import { TaskFormComponent } from './components/task-form/task-form.component';
import { AttachFormComponent } from './components/attach-form/attach-form.component';
import { ChecklistComponent } from './components/checklist/checklist.component';
import { NoTaskDetailsTemplateDirective } from './components/no-task-details/no-task-detail-template.directive';
import { TaskAuditDirective } from './components/task-audit/task-audit.directive';
import { TaskFiltersComponent } from './components/task-filters/task-filters.component';
import { TaskListComponent } from './components/task-list/task-list.component';
import { TaskDetailsComponent } from './components/task-details/task-details.component';
@@ -32,13 +30,11 @@ import { TaskStandaloneComponent } from './components/task-standalone/task-stand
export * from './components/task-list/task-list.component';
export * from './components/checklist/checklist.component';
export * from './components/task-header/task-header.component';
export * from './components/no-task-details/no-task-detail-template.directive';
export * from './components/task-filters/task-filters.component';
export * from './components/task-form/task-form.component';
export * from './components/task-form/claim-task.directive';
export * from './components/task-form/unclaim-task.directive';
export * from './components/task-details/task-details.component';
export * from './components/task-audit/task-audit.directive';
export * from './components/start-task/start-task.component';
export * from './components/task-standalone/task-standalone.component';
export * from './components/attach-form/attach-form.component';
@@ -64,7 +60,5 @@ export const TASK_LIST_DIRECTIVES = [
StartTaskComponent,
TaskStandaloneComponent,
ClaimTaskDirective,
UnclaimTaskDirective,
NoTaskDetailsTemplateDirective,
TaskAuditDirective
UnclaimTaskDirective
] as const;