[MNT-24950] Fix process file preview button state (#10790)

* [MNT-24950] Fix process file preview button state

* [MNT-24950] cr fix

* [MNT-24950] fix unit tests error
This commit is contained in:
Mykyta Maliarchuk 2025-04-15 10:05:55 +02:00 committed by GitHub
parent c8f9bd21ea
commit a426338f94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 140 additions and 27 deletions

View File

@ -83,7 +83,7 @@
<mat-menu #fileActionMenu="matMenu" xPosition="before"> <mat-menu #fileActionMenu="matMenu" xPosition="before">
<button <button
id="{{ 'file-' + file.id + '-show-file' }}" id="{{ 'file-' + file.id + '-show-file' }}"
[disabled]="file.isExternal || !file.contentAvailable || !file.mimeType" [disabled]="file.isExternal || !file.mimeType || (!file.sourceId && (isStartProcessPage || !file.contentAvailable))"
mat-menu-item mat-menu-item
(click)="onAttachFileClicked(file)" (click)="onAttachFileClicked(file)"
> >

View File

@ -26,7 +26,8 @@ import {
FormFieldMetadata, FormFieldMetadata,
DownloadService, DownloadService,
AppConfigService, AppConfigService,
AppConfigValues AppConfigValues,
UnitTestingUtils
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { ContentNodeDialogService } from '@alfresco/adf-content-services'; import { ContentNodeDialogService } from '@alfresco/adf-content-services';
import { of } from 'rxjs'; import { of } from 'rxjs';
@ -37,6 +38,9 @@ import { ActivitiContentService } from '../../services/activiti-alfresco.service
import { ProcessContentService } from '../../services/process-content.service'; import { ProcessContentService } from '../../services/process-content.service';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatMenuHarness } from '@angular/material/menu/testing';
const fakeRepositoryListAnswer = [ const fakeRepositoryListAnswer = [
{ {
@ -145,6 +149,8 @@ const fakePngAnswer: any = {
describe('AttachFileWidgetComponent', () => { describe('AttachFileWidgetComponent', () => {
let widget: AttachFileWidgetComponent; let widget: AttachFileWidgetComponent;
let fixture: ComponentFixture<AttachFileWidgetComponent>; let fixture: ComponentFixture<AttachFileWidgetComponent>;
let loader: HarnessLoader;
let unitTestingUtils: UnitTestingUtils;
let element: HTMLInputElement; let element: HTMLInputElement;
let activitiContentService: ActivitiContentService; let activitiContentService: ActivitiContentService;
let router: Router; let router: Router;
@ -173,6 +179,8 @@ describe('AttachFileWidgetComponent', () => {
}); });
fixture = TestBed.createComponent(AttachFileWidgetComponent); fixture = TestBed.createComponent(AttachFileWidgetComponent);
widget = fixture.componentInstance; widget = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
unitTestingUtils = new UnitTestingUtils(fixture.debugElement);
element = fixture.nativeElement; element = fixture.nativeElement;
router = TestBed.inject(Router); router = TestBed.inject(Router);
activatedRoute = TestBed.inject(ActivatedRoute); activatedRoute = TestBed.inject(ActivatedRoute);
@ -189,6 +197,16 @@ describe('AttachFileWidgetComponent', () => {
fixture.destroy(); fixture.destroy();
}); });
const isPreviewButtonDisabled = async (fileId: string): Promise<boolean> => {
const menu = await loader.getHarness(MatMenuHarness);
unitTestingUtils.clickByCSS(`#file-${fileId}-option-menu`);
fixture.detectChanges();
await fixture.whenStable();
const items = await menu.getItems();
const showFileButton = items[0];
return showFileButton.isDisabled();
};
it('should add file to tempFilesList when form has value and file source is configured', () => { it('should add file to tempFilesList when form has value and file source is configured', () => {
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(of(fakeRepositoryListAnswer)); spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(of(fakeRepositoryListAnswer));
spyOn(widget, 'isFileSourceConfigured').and.returnValue(true); spyOn(widget, 'isFileSourceConfigured').and.returnValue(true);
@ -608,6 +626,115 @@ describe('AttachFileWidgetComponent', () => {
const showOption = fixture.debugElement.query(By.css('#file-1155-show-file')).nativeElement as HTMLButtonElement; const showOption = fixture.debugElement.query(By.css('#file-1155-show-file')).nativeElement as HTMLButtonElement;
expect(showOption.disabled).toBeTruthy(); expect(showOption.disabled).toBeTruthy();
}); });
it('should set isStartProcessPage to true when URL contains start-process', () => {
spyOnProperty(router, 'url', 'get').and.returnValue('/start-process?foo=bar');
widget.ngOnInit();
expect(widget.isStartProcessPage).toBeTrue();
});
it('should set isStartProcessPage to false when URL does not contain start-process', () => {
spyOnProperty(router, 'url', 'get').and.returnValue('/other-page?foo=start-process');
widget.ngOnInit();
expect(widget.isStartProcessPage).toBeFalse();
});
it('should disable preview button when file is external', async () => {
const testFile = {
id: '123',
isExternal: true,
mimeType: 'application/pdf',
contentAvailable: true
};
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
expect(await isPreviewButtonDisabled('123')).toBeTrue();
});
it('should disable preview button when file has no mime type', async () => {
const testFile = {
id: '123',
isExternal: false,
mimeType: null,
contentAvailable: true
};
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
expect(await isPreviewButtonDisabled('123')).toBeTrue();
});
it('should disable preview button when content is not available and is start process page', async () => {
const testFile = {
id: '123',
isExternal: false,
mimeType: 'application/pdf',
contentAvailable: false,
sourceId: null
};
widget.isStartProcessPage = true;
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
expect(await isPreviewButtonDisabled('123')).toBeTrue();
});
it('should enable preview button when all conditions are met', async () => {
const testFile = {
id: '123',
isExternal: false,
mimeType: 'application/pdf',
contentAvailable: true,
sourceId: '456'
};
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
expect(await isPreviewButtonDisabled('123')).toBeFalse();
});
it('should enable preview button and ignore start process page check when content is available', async () => {
const testFile = {
id: '123',
isExternal: false,
mimeType: 'application/pdf',
contentAvailable: true,
sourceId: '1234'
};
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
widget.isStartProcessPage = true;
fixture.detectChanges();
expect(await isPreviewButtonDisabled('123')).toBeFalse();
});
it('should enable preview button when sourceId exists even if content is not available', async () => {
const testFile = {
id: '123',
isExternal: false,
mimeType: 'application/pdf',
contentAvailable: false,
sourceId: '456'
};
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [testFile]
});
expect(await isPreviewButtonDisabled('123')).toBeFalse();
});
}); });
it('should be able to upload files when a defined folder from external content service', async () => { it('should be able to upload files when a defined folder from external content service', async () => {

View File

@ -18,21 +18,9 @@
/* eslint-disable @angular-eslint/component-selector */ /* eslint-disable @angular-eslint/component-selector */
import { Component, DestroyRef, inject, isDevMode, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, DestroyRef, inject, isDevMode, OnInit, ViewEncapsulation } from '@angular/core';
import { import { AppConfigService, AppConfigValues, DownloadService, ErrorWidgetComponent, FormService, ThumbnailService } from '@alfresco/adf-core';
AppConfigService,
AppConfigValues,
DownloadService,
ErrorWidgetComponent,
FormService,
ThumbnailService
} from '@alfresco/adf-core';
import { AlfrescoIconComponent, ContentNodeDialogService, ContentService } from '@alfresco/adf-content-services'; import { AlfrescoIconComponent, ContentNodeDialogService, ContentService } from '@alfresco/adf-content-services';
import { import { AlfrescoEndpointRepresentation, Node, NodeChildAssociation, RelatedContentRepresentation } from '@alfresco/js-api';
AlfrescoEndpointRepresentation,
Node,
NodeChildAssociation,
RelatedContentRepresentation
} from '@alfresco/js-api';
import { from, of, zip } from 'rxjs'; import { from, of, zip } from 'rxjs';
import { mergeMap } from 'rxjs/operators'; import { mergeMap } from 'rxjs/operators';
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service'; import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
@ -79,6 +67,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit { export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit {
typeId = 'AttachFileWidgetComponent'; typeId = 'AttachFileWidgetComponent';
repositoryList: AlfrescoEndpointRepresentation[] = []; repositoryList: AlfrescoEndpointRepresentation[] = [];
isStartProcessPage = false;
private tempFilesList = []; private tempFilesList = [];
private readonly destroyRef = inject(DestroyRef); private readonly destroyRef = inject(DestroyRef);
@ -101,7 +91,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
ngOnInit() { ngOnInit() {
super.ngOnInit(); super.ngOnInit();
this.isStartProcessPage = this.router.url.split('?')[0].includes('start-process');
if (Array.isArray(this.field.value) && this.isFileSourceConfigured()) { if (Array.isArray(this.field.value) && this.isFileSourceConfigured()) {
this.tempFilesList.push(...this.field.value); this.tempFilesList.push(...this.field.value);
} }
@ -185,7 +175,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
} }
onAttachFileClicked(file: any) { onAttachFileClicked(file: any) {
if (file.isExternal || !file.contentAvailable) { if (file.isExternal || (!file.sourceId && (this.isStartProcessPage || !file.contentAvailable))) {
return; return;
} }
if (this.isTemporaryFile(file)) { if (this.isTemporaryFile(file)) {
@ -292,16 +282,12 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
); );
} }
private updateNodesParams(): void { private updateNodesParams(): void {
this.router.navigate( this.router.navigate([], {
[], relativeTo: this.activatedRoute,
{ queryParams: { nodes: this.tempFilesList.map((file) => file.id).join(',') },
relativeTo: this.activatedRoute, queryParamsHandling: 'merge'
queryParams: { nodes: this.tempFilesList.map(file => file.id).join(',') }, });
queryParamsHandling: 'merge'
}
);
} }
private getDomainHost(urlToCheck: string): string { private getDomainHost(urlToCheck: string): string {