mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-5137] Fixed navigation between images (#8534)
* [ACS-5137] fixed navigation between images * [ACS-5137] disable navigation while file is saving * [ACS-5137] moved mocked tested components * [ACS-5137] code improvements * [ACS-5137] small fix * Empty commit * [ACS-5137] linting * Empty commit
This commit is contained in:
committed by
GitHub
parent
4301cb0933
commit
b5d410b75c
@@ -126,7 +126,7 @@ describe('Test Img viewer component ', () => {
|
||||
it('If no url or blob are passed should thrown an error', () => {
|
||||
const change = new SimpleChange(null, null, true);
|
||||
expect(() => {
|
||||
component.ngOnChanges({ blobFile: change });
|
||||
component.ngOnChanges({ blobFile: change, urlFile: change });
|
||||
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
|
||||
});
|
||||
|
||||
@@ -143,6 +143,19 @@ describe('Test Img viewer component ', () => {
|
||||
expect(element.querySelector('#viewer-image').getAttribute('alt')).toEqual('fake-name');
|
||||
});
|
||||
|
||||
it('should call replace on cropper with new url if blobFile is null', () => {
|
||||
component.fileName = 'fake-name';
|
||||
component.urlFile = 'fake-url';
|
||||
spyOn(component.cropper, 'replace').and.stub();
|
||||
const fileName = new SimpleChange('val', 'val2', false);
|
||||
const urlFile = new SimpleChange('fake-url', 'fake-url-2', false);
|
||||
|
||||
fixture.detectChanges();
|
||||
component.ngOnChanges({ fileName, urlFile });
|
||||
|
||||
expect(component.cropper.replace).toHaveBeenCalledWith('fake-url-2');
|
||||
});
|
||||
|
||||
it('If blob is passed should not thrown an error', () => {
|
||||
const blob = createFakeBlob();
|
||||
|
||||
@@ -341,15 +354,21 @@ describe('Test Img viewer component ', () => {
|
||||
component.readOnly = false;
|
||||
component.isEditing = true;
|
||||
|
||||
spyOn(component, 'save');
|
||||
const canvasMock = document.createElement('canvas');
|
||||
spyOn(component.isSaving, 'emit');
|
||||
spyOn(component, 'save').and.callThrough();
|
||||
spyOn(component.cropper, 'getCroppedCanvas').and.returnValue(canvasMock);
|
||||
spyOn(component.cropper.getCroppedCanvas(), 'toBlob').and.callFake(() => component.isSaving.emit(false));
|
||||
|
||||
fixture.detectChanges();
|
||||
const saveButtonElement = fixture.debugElement.query(By.css('#viewer-save-button'));
|
||||
saveButtonElement.triggerEventHandler('click', null);
|
||||
tick();
|
||||
|
||||
expect(component.save).toHaveBeenCalled();
|
||||
expect(component.isSaving.emit).toHaveBeenCalledWith(true);
|
||||
expect(component.isSaving.emit).toHaveBeenCalledWith(false);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -61,6 +61,9 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
||||
@Output()
|
||||
submit = new EventEmitter<any>();
|
||||
|
||||
@Output()
|
||||
isSaving = new EventEmitter<boolean>();
|
||||
|
||||
@ViewChild('image', { static: false})
|
||||
public imageElement: ElementRef;
|
||||
|
||||
@@ -74,7 +77,8 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private appConfigService: AppConfigService,
|
||||
private urlService: UrlService) {
|
||||
private urlService: UrlService
|
||||
) {
|
||||
this.initializeScaling();
|
||||
}
|
||||
|
||||
@@ -143,6 +147,13 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
||||
this.urlFile = this.urlService.createTrustedUrl(this.blobFile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!changes['urlFile'].firstChange && changes['fileName']) {
|
||||
if (changes['fileName'].previousValue !== changes['fileName'].currentValue) {
|
||||
this.cropper.replace(changes['urlFile'].currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.urlFile && !this.blobFile) {
|
||||
throw new Error('Attribute urlFile or blobFile is required');
|
||||
}
|
||||
@@ -172,13 +183,14 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
save() {
|
||||
this.isSaving.emit(true);
|
||||
this.isEditing = false;
|
||||
this.cropper.setDragMode('move');
|
||||
|
||||
this.cropper.getCroppedCanvas().toBlob((blob) => {
|
||||
this.submit.emit(blob);
|
||||
this.cropper.replace(this.cropper.getCroppedCanvas().toDataURL());
|
||||
this.cropper.clear();
|
||||
this.isSaving.emit(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 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';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-more-actions',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-more-actions>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>dialpad</mat-icon>
|
||||
<span>Action One</span>
|
||||
</button>
|
||||
<button mat-menu-item disabled>
|
||||
<mat-icon>voicemail</mat-icon>
|
||||
<span>Action Two</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>notifications_off</mat-icon>
|
||||
<span>Action Three</span>
|
||||
</button>
|
||||
</adf-viewer-more-actions>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
export class ViewerWithCustomMoreActionsComponent {
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 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';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-open-with',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-open-with>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>dialpad</mat-icon>
|
||||
<span>Option 1</span>
|
||||
</button>
|
||||
<button mat-menu-item disabled>
|
||||
<mat-icon>voicemail</mat-icon>
|
||||
<span>Option 2</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>notifications_off</mat-icon>
|
||||
<span>Option 3</span>
|
||||
</button>
|
||||
</adf-viewer-open-with>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
export class ViewerWithCustomOpenWithComponent {
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 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';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-sidebar',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-sidebar>
|
||||
<div class="custom-sidebar"></div>
|
||||
</adf-viewer-sidebar>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
export class ViewerWithCustomSidebarComponent {
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 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';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-toolbar-actions',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-toolbar-actions>
|
||||
<button mat-icon-button id="custom-button">
|
||||
<mat-icon>alarm</mat-icon>
|
||||
</button>
|
||||
</adf-viewer-toolbar-actions>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
export class ViewerWithCustomToolbarActionsComponent {
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 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';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-toolbar',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-toolbar>
|
||||
<div class="custom-toolbar-element"></div>
|
||||
</adf-viewer-toolbar>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
export class ViewerWithCustomToolbarComponent {
|
||||
}
|
@@ -38,7 +38,6 @@
|
||||
[cacheType]="cacheTypeForContent"
|
||||
(close)="onClose()"
|
||||
(error)="onUnsupportedFile()">
|
||||
|
||||
</adf-pdf-viewer>
|
||||
</ng-container>
|
||||
|
||||
@@ -49,6 +48,7 @@
|
||||
[blobFile]="blobFile"
|
||||
(error)="onUnsupportedFile()"
|
||||
(submit)="onSubmitFile($event)"
|
||||
(isSaving)="isSaving.emit($event)"
|
||||
></adf-img-viewer>
|
||||
</ng-container>
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
<ng-container *ngSwitchCase="'text'">
|
||||
<adf-txt-viewer [urlFile]="urlFile"
|
||||
[blobFile]="blobFile">
|
||||
|
||||
</adf-txt-viewer>
|
||||
</ng-container>
|
||||
|
||||
|
@@ -30,6 +30,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-double-viewer',
|
||||
@@ -365,6 +366,18 @@ describe('ViewerComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should emit new value when isSaving emits new event', () => {
|
||||
spyOn(component.isSaving, 'emit');
|
||||
component.urlFile = 'fake-url-file.png';
|
||||
component.ngOnChanges();
|
||||
fixture.detectChanges();
|
||||
|
||||
const imgViewer = fixture.debugElement.query(By.css('adf-img-viewer'));
|
||||
imgViewer.triggerEventHandler('isSaving', true);
|
||||
|
||||
expect(component.isSaving.emit).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
describe('Attribute', () => {
|
||||
|
||||
it('should urlFile present not thrown any error ', () => {
|
||||
|
@@ -90,6 +90,10 @@ export class ViewerRenderComponent implements OnChanges, OnInit, OnDestroy {
|
||||
@Output()
|
||||
close = new EventEmitter<boolean>();
|
||||
|
||||
/** Emitted when the img is saving. */
|
||||
@Output()
|
||||
isSaving = new EventEmitter<boolean>();
|
||||
|
||||
extensionTemplates: { template: TemplateRef<any>; isVisible: boolean }[] = [];
|
||||
extension: string;
|
||||
internalFileName: string;
|
||||
|
@@ -157,6 +157,7 @@
|
||||
[readOnly]="readOnly"
|
||||
(submitFile)="onSubmitFile($event)"
|
||||
[urlFile]="urlFile"
|
||||
(isSaving)="allowNavigate = !$event"
|
||||
[tracks]="tracks">
|
||||
</adf-viewer-render>
|
||||
|
||||
|
@@ -31,49 +31,14 @@ import {
|
||||
DownloadPromptDialogComponent,
|
||||
DownloadPromptActions
|
||||
} from '@alfresco/adf-core';
|
||||
import { Component } from '@angular/core';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-toolbar',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-toolbar>
|
||||
<div class="custom-toolbar-element"></div>
|
||||
</adf-viewer-toolbar>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
class ViewerWithCustomToolbarComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-toolbar-actions',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-toolbar-actions>
|
||||
<button mat-icon-button id="custom-button">
|
||||
<mat-icon>alarm</mat-icon>
|
||||
</button>
|
||||
</adf-viewer-toolbar-actions>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
class ViewerWithCustomToolbarActionsComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-sidebar',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-sidebar>
|
||||
<div class="custom-sidebar"></div>
|
||||
</adf-viewer-sidebar>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
class ViewerWithCustomSidebarComponent {
|
||||
}
|
||||
import { ViewerWithCustomMoreActionsComponent } from './mock/adf-viewer-container-more-actions.component.mock';
|
||||
import { ViewerWithCustomToolbarComponent } from './mock/adf-viewer-container-toolbar.component.mock';
|
||||
import { ViewerWithCustomSidebarComponent } from './mock/adf-viewer-container-sidebar.component.mock';
|
||||
import { ViewerWithCustomOpenWithComponent } from './mock/adf-viewer-container-open-with.component.mock';
|
||||
import { ViewerWithCustomToolbarActionsComponent } from './mock/adf-viewer-container-toolbar-actions.component.mock';
|
||||
import { Component } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-dialog-dummy',
|
||||
@@ -82,55 +47,6 @@ class ViewerWithCustomSidebarComponent {
|
||||
class DummyDialogComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-open-with',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-open-with>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>dialpad</mat-icon>
|
||||
<span>Option 1</span>
|
||||
</button>
|
||||
<button mat-menu-item disabled>
|
||||
<mat-icon>voicemail</mat-icon>
|
||||
<span>Option 2</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>notifications_off</mat-icon>
|
||||
<span>Option 3</span>
|
||||
</button>
|
||||
</adf-viewer-open-with>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
class ViewerWithCustomOpenWithComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-more-actions',
|
||||
template: `
|
||||
<adf-viewer>
|
||||
<adf-viewer-more-actions>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>dialpad</mat-icon>
|
||||
<span>Action One</span>
|
||||
</button>
|
||||
<button mat-menu-item disabled>
|
||||
<mat-icon>voicemail</mat-icon>
|
||||
<span>Action Two</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>notifications_off</mat-icon>
|
||||
<span>Action Three</span>
|
||||
</button>
|
||||
</adf-viewer-more-actions>
|
||||
</adf-viewer>
|
||||
`
|
||||
})
|
||||
class ViewerWithCustomMoreActionsComponent {
|
||||
}
|
||||
|
||||
|
||||
describe('ViewerComponent', () => {
|
||||
|
||||
let component: ViewerComponent<any>;
|
||||
@@ -371,6 +287,18 @@ describe('ViewerComponent', () => {
|
||||
expect(prevButton).toBeNull();
|
||||
});
|
||||
|
||||
it('should not show navigation buttons if file is saving', async () => {
|
||||
component.allowNavigate = true;
|
||||
fixture.detectChanges();
|
||||
const viewerRender = fixture.debugElement.query(By.css('adf-viewer-render'));
|
||||
|
||||
viewerRender.triggerEventHandler('isSaving', true);
|
||||
expect(component.allowNavigate).toBeFalsy();
|
||||
|
||||
viewerRender.triggerEventHandler('isSaving', false);
|
||||
expect(component.allowNavigate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should now show navigation buttons even if navigation enabled', async () => {
|
||||
component.allowNavigate = true;
|
||||
component.canNavigateBefore = false;
|
||||
|
Reference in New Issue
Block a user