mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[AAE-6242] upload a new version of a file attached in a form (#7651)
* [AAE-6242] Create upload new version dialog to handle the upload of the new file version * [AAE-6242] Create version manager service to open version manager dialog * [AAE-6242] Export service and dialog * [AAE-6242] add adf-upload button to the show the upload new file button * [AAE-6242] open upload new version dialog * [AAE-6242] Removed console log * [AAE-8798] display update option name to newVersion * [AAE-8799] Emit version manager data when new file version is uploaded * [AAE-8799] When a new file version is uploaded open new version dialog and update current file version with the new file version * [AAE-8799] Rename UploadNewVersionDialogComponent to VersionManagerDialogComponent and UploadNewVersionDialogData to VersionManagerDialogData * [AAE-8799] Use default root folder id * [AAE-8799] Add #uploadSingleFile ViewChild in order get the input reference * [AAE-8799] Trigger adf-upload-button by clicking on the button in order to open the file chooser and upload a new file version * [AAE-8799] Version manager dialog emits file upload error * [AAE-8799] Format version manager dialog code * [AAE-8799] Reject upload and permission errors * [AAE-8799] Catch upload new version errors * [AAE-8799] Update allowable operation type * [AAE-8799] Rename VersionManagerDialogComponent into NewVersionUploaderDialogComponent and VersionManagerService into NewVersionUploaderService, create specific folder for new version uploader component and service * Restore previous UploadButtonComponent version * [AAE-8799] Use [adf-upload] directive to upload new file version * [AAE-8799] Add mock file for new version uploader unit tests * [AAE-8799] Override mat dialog configuration * [AAE-8799] Add unit test related to event emitted from Dialog * [AAE-8799] Create model to handle New Version Uploader data * [AAE-8799] Return data on dialog close * [AAE-8799] Add showVersionsOnly property to dialog to show only file version list * [AAE-8799] Add dialogAction to emit dialog actions * [AAE-8799] Return observable instead of promise * [AAE-8799] Update new file version type * [AAE-8799] Subscribe dialog because return an Observable * [AAE-8799] Add license header * [AAE-8799] Add i18n new version uploader translations * [AAE-8799] If data.title is not provided, add a default title * [AAE-8799] Change panelClass for manage versions visualizations, add dialog styles * [AAE-8799] Add upload new version dialog unit test * [AAE-8799] Add upload new version dialog unit test related to manage versions section * [AAE-8799] Add onUploadNewFileVersion unit tests * [AAE-8799] Test new dialog panelClass * [AAE-8799] Create a method to set dialog title, if title isn't provided from parent component, a default title is set * [AAE-8799] Add doc to new-version-uploader-dilog component and service * [AAE-8799] Add new-version-uploader.dialog.service documentation
This commit is contained in:
parent
95fd3e822a
commit
4457aed5b4
@ -0,0 +1,89 @@
|
||||
---
|
||||
Title: New Version Uploader service
|
||||
Added: v1.0.0
|
||||
Status: Active
|
||||
Last reviewed: 2022-05-26
|
||||
---
|
||||
|
||||
# [New Version Uploader service](../../../lib/content-services/src/lib/new-version-uploader/new-version-uploader.service.ts "Defined in new-version-uploader.service.ts")
|
||||
|
||||
Display a dialog that allows to upload new file version or to manage the current node versions.
|
||||
|
||||
## Class members
|
||||
|
||||
### Methods
|
||||
|
||||
- **openUploadNewVersionDialog**(data: [NewVersionUploaderDialogData](../../../lib/content-services/src/lib/new-version-uploader/models/new-version-uploader.model.ts), config: `MatDialogConfig`): `Observable`<br/>
|
||||
Opens a dialog to upload new file version or to manage current node versions
|
||||
- _data:_ [NewVersionUploaderDialogData](../../../lib/content-services/src/lib/new-version-uploader/models/new-version-uploader.model.ts) - The data to pass to the dialog
|
||||
- _config:_ `MatDialogConfig` - A configuration object that allows to override default dialog configuration
|
||||
- **Returns** `Observable` - [`Observable`](http://reactivex.io/documentation/observable.html) which you can subscribe in order to get information about the dialog actions or error notification in case of error condition.
|
||||
## Details
|
||||
|
||||
You can open dialog in two different ways:
|
||||
|
||||
- [Upload new file version](#upload-new-version)
|
||||
- [Manage node versions](#manage-versions)
|
||||
|
||||
### Upload New Version
|
||||
|
||||
The dialog shows
|
||||
|
||||
- a side by side comparison between the current target node (type, name, icon) and the new file that should update it's version
|
||||
- the new version's minor/major changes
|
||||
- the optional comment
|
||||
- a button to upload a new file version
|
||||

|
||||
|
||||
Usage example:
|
||||
```ts
|
||||
import { NewVersionUploaderService } from '@alfresco/adf-content-services'
|
||||
|
||||
constructor(private newVersionUploaderService: NewVersionUploaderService){}
|
||||
|
||||
yourFunctionToOpenDialog(){
|
||||
const newVersionUploaderDialogData: NewVersionUploaderDialogData = {
|
||||
file,
|
||||
node
|
||||
};
|
||||
this.newVersionUploaderService.openUploadNewVersionDialog(newVersionUploaderDialogData).subscribe(
|
||||
(data: NewVersionUploaderData) => {
|
||||
// place your action here on operation success!
|
||||
},
|
||||
(error) => {
|
||||
// place your action here on operation error!
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Manage Versions
|
||||
|
||||
Setting `showVersionsOnly` to `true` the dialog displays the version history of a node, with the ability to restore, delete and view version of the current node
|
||||

|
||||
|
||||
Usage example:
|
||||
```ts
|
||||
import { NewVersionUploaderService } from '@alfresco/adf-content-services'
|
||||
|
||||
constructor(private newVersionUploaderService: NewVersionUploaderService){}
|
||||
|
||||
yourFunctionToOpenDialog(){
|
||||
const newVersionUploaderDialogData: NewVersionUploaderDialogData = {
|
||||
file,
|
||||
node,
|
||||
showVersionsOnly: true
|
||||
};
|
||||
this.newVersionUploaderService.openUploadNewVersionDialog(newVersionUploaderDialogData).subscribe(
|
||||
(data: NewVersionUploaderData) => {
|
||||
// place your action here on operation success!
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [Version list component](../components/docs/content-services/components/version-list.component.md)
|
||||
- [Version Comparison Component](../components/docs/content-services/components/version-comparison.component.md)
|
||||
- [Version Upload Component](../components/docs/content-services/components/version-upload.component.md)
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
docs/docassets/images/adf-new-version-uploader_upload.png
Normal file
BIN
docs/docassets/images/adf-new-version-uploader_upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -22,6 +22,17 @@
|
||||
"NO_LABEL": "No"
|
||||
}
|
||||
},
|
||||
"ADF-NEW-VERSION-UPLOADER": {
|
||||
"DIALOG_LIST": {
|
||||
"TITLE": "Manage Versions",
|
||||
"CLOSE": "Close"
|
||||
},
|
||||
"DIALOG_UPLOAD": {
|
||||
"TITLE": "Upload New Version",
|
||||
"CANCEL": "Cancel",
|
||||
"UPLOAD": "Upload"
|
||||
}
|
||||
},
|
||||
"ADF_VERSION_COMPARISON": {
|
||||
"CURRENT_VERSION": "Current",
|
||||
"NEW_VERSION": "New",
|
||||
|
@ -0,0 +1,182 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const mockNode: any = ({
|
||||
isFile: true,
|
||||
createdByUser: { id: 'admin', displayName: 'Administrator' },
|
||||
modifiedAt: '2017-05-24T15:08:55.640Z',
|
||||
nodeType: 'cm:content',
|
||||
content: {
|
||||
mimeType: 'application/rtf',
|
||||
mimeTypeName: 'Rich Text Format',
|
||||
sizeInBytes: 14530,
|
||||
encoding: 'UTF-8'
|
||||
},
|
||||
parentId: 'd124de26-6ba0-4f40-8d98-4907da2d337a',
|
||||
createdAt: '2017-05-24T15:08:55.640Z',
|
||||
path: {
|
||||
name: '/Company Home/Guest Home',
|
||||
isComplete: true,
|
||||
elements: [{
|
||||
id: '94acfc73-7014-4475-9bd9-93a2162f0f8c',
|
||||
name: 'Company Home'
|
||||
}, { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' }]
|
||||
},
|
||||
isFolder: false,
|
||||
modifiedByUser: { id: 'admin', displayName: 'Administrator' },
|
||||
name: 'b_txt_file.rtf',
|
||||
id: '70e1cc6a-6918-468a-b84a-1048093b06fd',
|
||||
properties: { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' },
|
||||
allowableOperations: ['delete', 'update']
|
||||
});
|
||||
|
||||
export const mockFile = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
|
||||
|
||||
export const mockNewVersionUploaderData: any = {
|
||||
action: 'upload',
|
||||
newVersion: {
|
||||
value: {
|
||||
entry: {
|
||||
isFile: true,
|
||||
createdByUser: {
|
||||
id: 'hruser',
|
||||
displayName: 'hruser'
|
||||
},
|
||||
modifiedAt: '2022-05-24T10:19:43.544Z',
|
||||
nodeType: 'cm:content',
|
||||
content: {
|
||||
mimeType:
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
mimeTypeName: 'Microsoft Word 2007',
|
||||
sizeInBytes: 11887,
|
||||
encoding: 'UTF-8'
|
||||
},
|
||||
parentId: '422538ca-ea4b-4086-83f9-b36e4521ec7f',
|
||||
aspectNames: [
|
||||
'rn:renditioned',
|
||||
'cm:versionable',
|
||||
'cm:titled',
|
||||
'cm:auditable',
|
||||
'cm:author',
|
||||
'cm:thumbnailModification'
|
||||
],
|
||||
createdAt: '2022-05-24T07:26:44.429Z',
|
||||
isFolder: false,
|
||||
modifiedByUser: {
|
||||
id: 'hruser',
|
||||
displayName: 'hruser'
|
||||
},
|
||||
name: 'Test3.docx',
|
||||
id: '42ddb84d-fc96-4b45-aa3c-f24ca997d602',
|
||||
properties: {
|
||||
'cm:versionType': 'MINOR',
|
||||
'cm:versionLabel': '1.1',
|
||||
'cm:author': 'Amedeo Lepore',
|
||||
'cm:lastThumbnailModification': ['doclib:1653377205499']
|
||||
},
|
||||
allowableOperations: ['delete', 'update', 'updatePermissions']
|
||||
}
|
||||
}
|
||||
},
|
||||
currentVersion: {
|
||||
isFile: true,
|
||||
createdByUser: {
|
||||
id: 'hruser',
|
||||
displayName: 'hruser'
|
||||
},
|
||||
modifiedAt: '2022-05-24T07:26:45.337Z',
|
||||
nodeType: 'cm:content',
|
||||
content: {
|
||||
mimeType:
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
mimeTypeName: 'Microsoft Word 2007',
|
||||
sizeInBytes: 11949,
|
||||
encoding: 'UTF-8'
|
||||
},
|
||||
parentId: '422538ca-ea4b-4086-83f9-b36e4521ec7f',
|
||||
aspectNames: [
|
||||
'rn:renditioned',
|
||||
'cm:versionable',
|
||||
'cm:titled',
|
||||
'cm:auditable',
|
||||
'cm:author',
|
||||
'cm:thumbnailModification'
|
||||
],
|
||||
createdAt: '2022-05-24T07:26:44.429Z',
|
||||
path: {
|
||||
name: '/Company Home/User Homes/hruser',
|
||||
isComplete: true,
|
||||
elements: [
|
||||
{
|
||||
id: '4e2284fd-9457-4914-a612-ea844e87f53f',
|
||||
name: 'Company Home',
|
||||
nodeType: 'cm:folder',
|
||||
aspectNames: ['cm:titled', 'cm:auditable', 'app:uifacets']
|
||||
},
|
||||
{
|
||||
id: '75a5d2d2-6edb-40b6-822e-499f5e8beffb',
|
||||
name: 'User Homes',
|
||||
nodeType: 'cm:folder',
|
||||
aspectNames: ['cm:titled', 'cm:auditable', 'app:uifacets']
|
||||
},
|
||||
{
|
||||
id: '422538ca-ea4b-4086-83f9-b36e4521ec7f',
|
||||
name: 'hruser',
|
||||
nodeType: 'cm:folder',
|
||||
aspectNames: ['cm:ownable', 'cm:auditable']
|
||||
}
|
||||
]
|
||||
},
|
||||
isFolder: false,
|
||||
permissions: {
|
||||
inherited: [
|
||||
{
|
||||
authorityId: 'ROLE_OWNER',
|
||||
name: 'All',
|
||||
accessStatus: 'ALLOWED'
|
||||
},
|
||||
{
|
||||
authorityId: 'hruser',
|
||||
name: 'All',
|
||||
accessStatus: 'ALLOWED'
|
||||
}
|
||||
],
|
||||
settable: [
|
||||
'Contributor',
|
||||
'Collaborator',
|
||||
'Coordinator',
|
||||
'Editor',
|
||||
'Consumer'
|
||||
],
|
||||
isInheritanceEnabled: true
|
||||
},
|
||||
modifiedByUser: {
|
||||
id: 'hruser',
|
||||
displayName: 'hruser'
|
||||
},
|
||||
name: 'Test2.docx',
|
||||
id: '42ddb84d-fc96-4b45-aa3c-f24ca997d602',
|
||||
properties: {
|
||||
'cm:versionType': 'MAJOR',
|
||||
'cm:versionLabel': '1.0',
|
||||
'cm:author': 'Amedeo Lepore',
|
||||
'cm:lastThumbnailModification': ['doclib:1653377205499']
|
||||
},
|
||||
allowableOperations: ['delete', 'update', 'updatePermissions'],
|
||||
isExternal: true
|
||||
}
|
||||
};
|
@ -22,3 +22,4 @@ export * from './search.service.mock';
|
||||
export * from './search-filter-mock';
|
||||
export * from './sites-dropdown.component.mock';
|
||||
export * from './search-query.mock';
|
||||
export * from './new-version-uploader.service.mock';
|
||||
|
18
lib/content-services/src/lib/new-version-uploader/index.ts
Normal file
18
lib/content-services/src/lib/new-version-uploader/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './public-api';
|
@ -0,0 +1,17 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export * from './new-version-uploader.model';
|
@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { MinimalNodeEntryEntity, Version, NodeChildAssociation, Node } from '@alfresco/js-api';
|
||||
import { NodeEntityEvent } from '../../document-list';
|
||||
|
||||
export interface NewVersionUploaderDialogData {
|
||||
title?: string;
|
||||
node: MinimalNodeEntryEntity;
|
||||
file?: File;
|
||||
currentVersion?: Version;
|
||||
showVersionsOnly?: boolean;
|
||||
}
|
||||
|
||||
export type NewVersionUploaderData = VersionManagerUploadData | ViewVersion | RefreshData;
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
export enum NewVersionUploaderDataAction {
|
||||
refresh = 'refresh',
|
||||
upload = 'upload',
|
||||
view = 'view'
|
||||
}
|
||||
|
||||
interface BaseData {
|
||||
action: NewVersionUploaderDataAction;
|
||||
}
|
||||
|
||||
export interface VersionManagerUploadData extends BaseData {
|
||||
action: NewVersionUploaderDataAction.upload;
|
||||
newVersion: NodeEntityEvent;
|
||||
currentVersion: NodeChildAssociation;
|
||||
}
|
||||
|
||||
export interface ViewVersion extends BaseData {
|
||||
action: NewVersionUploaderDataAction.view;
|
||||
versionId: string;
|
||||
}
|
||||
|
||||
export interface RefreshData extends BaseData {
|
||||
action: NewVersionUploaderDataAction.refresh;
|
||||
node: Node;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<header mat-dialog-title>{{ title | translate }}</header>
|
||||
<section mat-dialog-content *ngIf="!data.showVersionsOnly">
|
||||
<adf-version-comparison id="adf-version-comparison" [newFileVersion]="data.file" [node]="data.node"></adf-version-comparison>
|
||||
<adf-version-upload
|
||||
id="adf-version-upload-button"
|
||||
[node]="data.node"
|
||||
[newFileVersion]="data.file"
|
||||
[currentVersion]="data.currentVersion"
|
||||
(success)="handleUpload($event)"
|
||||
(cancel)="handleCancel()"
|
||||
(error)="onUploadError($event)"
|
||||
>
|
||||
</adf-version-upload>
|
||||
</section>
|
||||
<ng-container *ngIf="data.showVersionsOnly">
|
||||
<section mat-dialog-content>
|
||||
<div class="adf-version-list-container">
|
||||
<div class="adf-version-list-table">
|
||||
<adf-version-list
|
||||
[node]="data.node"
|
||||
[showComments]="'adf-version-manager.allowComments' | adfAppConfig: true"
|
||||
[allowDownload]="'adf-version-manager.allowDownload' | adfAppConfig: true"
|
||||
(deleted)="refresh($event)"
|
||||
(restored)="refresh($event)"
|
||||
(viewVersion)="onViewingVersion($event)"
|
||||
></adf-version-list>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer mat-dialog-actions>
|
||||
<button mat-button color="primary" [mat-dialog-close]="true">{{ 'ADF-NEW-VERSION-UPLOADER.DIALOG_LIST.CLOSE' | translate }}</button>
|
||||
</footer>
|
||||
</ng-container>
|
@ -0,0 +1,79 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.adf-new-version-uploader-dialog {
|
||||
&-list {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
&-upload {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.mat-dialog {
|
||||
&-title {
|
||||
flex: 0 0 auto;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
letter-spacing: -0.5px;
|
||||
color: var(--theme-text-bold-color);
|
||||
}
|
||||
|
||||
&-content {
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
max-height: 100vh;
|
||||
overflow: hidden;
|
||||
padding: 2px 26px;
|
||||
}
|
||||
|
||||
&-actions {
|
||||
/* stylelint-disable-next-line shorthand-property-no-redundant-values */
|
||||
padding: 8px 8px 24px 8px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
color: var(--theme-text-color);
|
||||
|
||||
button {
|
||||
text-transform: uppercase;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-list-item-content {
|
||||
padding: 0;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.adf-version-list-container {
|
||||
.adf-version-list {
|
||||
height: 250px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mat-list.adf-version-list {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { setupTestBed } from 'core';
|
||||
import { mockFile, mockNode } from '../mock';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
import { UploadVersionButtonComponent } from '../upload';
|
||||
import { VersionComparisonComponent, VersionListComponent, VersionUploadComponent } from '../version-manager';
|
||||
import { NewVersionUploaderDataAction } from './models';
|
||||
import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog';
|
||||
|
||||
describe('NewVersionUploaderDialog', () => {
|
||||
let component: NewVersionUploaderDialogComponent;
|
||||
let fixture: ComponentFixture<NewVersionUploaderDialogComponent>;
|
||||
let nativeElement;
|
||||
|
||||
const cssSelectors = {
|
||||
adfVersionUploadButton: '#adf-version-upload-button',
|
||||
adfVersionComparison: '#adf-version-comparison',
|
||||
adfVersionList: '.adf-version-list',
|
||||
matDialogTitle: '.mat-dialog-title'
|
||||
};
|
||||
|
||||
const mockDialogRef = {
|
||||
close: jasmine.createSpy('close'),
|
||||
open: jasmine.createSpy('open')
|
||||
};
|
||||
const showVersionsOnly = true;
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
declarations: [
|
||||
NewVersionUploaderDialogComponent,
|
||||
VersionListComponent,
|
||||
VersionUploadComponent,
|
||||
UploadVersionButtonComponent,
|
||||
VersionComparisonComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: MAT_DIALOG_DATA, useValue: { node: mockNode, showVersionsOnly, file: mockFile } },
|
||||
{
|
||||
provide: MatDialogRef, useValue: mockDialogRef
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NewVersionUploaderDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
nativeElement = fixture.debugElement.nativeElement;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('Upload New Version', () => {
|
||||
|
||||
const expectedUploadNewVersionTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_UPLOAD.TITLE';
|
||||
|
||||
it('should display adf version upload button if showVersionsOnly is passed as false from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
const adfVersionComponent = nativeElement.querySelector(cssSelectors.adfVersionUploadButton);
|
||||
expect(adfVersionComponent).not.toEqual(null);
|
||||
});
|
||||
|
||||
it('should display adf version comparison if showVersionsOnly is passed as false from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
const adfVersionComparisonComponent = nativeElement.querySelector(cssSelectors.adfVersionComparison);
|
||||
expect(adfVersionComparisonComponent).not.toEqual(null);
|
||||
});
|
||||
|
||||
it('should not display adf version list if showVersionsOnly is passed as false from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
const adfVersionComparisonComponent = nativeElement.querySelector(cssSelectors.adfVersionList);
|
||||
expect(adfVersionComparisonComponent).toEqual(null);
|
||||
});
|
||||
|
||||
it('should show default title if title is not provided from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
|
||||
});
|
||||
|
||||
it('should show default title if title is provided as empty from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
component.data.title = '';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
|
||||
});
|
||||
|
||||
it('should not show Upload New Version default title if title is provided from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
component.data.title = 'TEST_TITLE';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
|
||||
});
|
||||
|
||||
it('should emit dialog action when upload a new file', () => {
|
||||
const spyOnDialogAction = spyOn(component.dialogAction, 'emit');
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
component.handleUpload(mockNode);
|
||||
const expectedEmittedValue = {
|
||||
action: NewVersionUploaderDataAction.upload,
|
||||
currentVersion: component.data.node,
|
||||
newVersion: mockNode
|
||||
};
|
||||
expect(spyOnDialogAction).toHaveBeenCalledWith(expectedEmittedValue);
|
||||
});
|
||||
|
||||
it('should close dialog after file is uploaded', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
component.handleUpload(mockFile);
|
||||
expect(mockDialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close dialog after click on dialog cancel', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
component.handleCancel();
|
||||
expect(mockDialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Manage Versions', () => {
|
||||
|
||||
const expectedManageVersionsTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_LIST.TITLE';
|
||||
|
||||
it('should display adf version list if showVersionsOnly is passed as true from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
fixture.detectChanges();
|
||||
const adfVersionListComponent = document.querySelector(cssSelectors.adfVersionList);
|
||||
expect(adfVersionListComponent).not.toEqual(null);
|
||||
});
|
||||
|
||||
it('should not display adf version upload button if showVersionsOnly is passed as true from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
fixture.detectChanges();
|
||||
const adfVersionComponent = nativeElement.querySelector(cssSelectors.adfVersionUploadButton);
|
||||
expect(adfVersionComponent).toEqual(null);
|
||||
});
|
||||
|
||||
it('should not display adf version comparison if showVersionsOnly is passed as true from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
fixture.detectChanges();
|
||||
const adfVersionComponent = nativeElement.querySelector(cssSelectors.adfVersionComparison);
|
||||
expect(adfVersionComponent).toEqual(null);
|
||||
});
|
||||
|
||||
it('should show Manage Versions default title if title is not provided from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = undefined;
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
|
||||
});
|
||||
|
||||
it('should show Manage Versions default title if title is provided as empty from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = '';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
|
||||
});
|
||||
|
||||
it('should not show Manage Versions default title if title is provided from parent component', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = 'TEST_TITLE';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,83 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { Node } from '@alfresco/js-api';
|
||||
import { Component, EventEmitter, Inject, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { NewVersionUploaderDialogData, NewVersionUploaderData, NewVersionUploaderDataAction } from './models';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-new-version-uploader-dialog',
|
||||
templateUrl: './new-version-uploader.dialog.html',
|
||||
styleUrls: ['./new-version-uploader.dialog.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class NewVersionUploaderDialogComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* Dialog title to show into the header.
|
||||
* If data.title is not provided, a default title is set
|
||||
* */
|
||||
title: string;
|
||||
|
||||
/** Emitted when an action is done. */
|
||||
@Output()
|
||||
dialogAction = new EventEmitter<NewVersionUploaderData>();
|
||||
|
||||
/** Emitted when an error occurs. */
|
||||
@Output()
|
||||
uploadError = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: NewVersionUploaderDialogData,
|
||||
private dialogRef: MatDialogRef<NewVersionUploaderDialogComponent>
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setDialogTitle();
|
||||
}
|
||||
|
||||
private setDialogTitle() {
|
||||
if (!this.data.title) {
|
||||
this.title = this.data.showVersionsOnly ? 'ADF-NEW-VERSION-UPLOADER.DIALOG_LIST.TITLE' : 'ADF-NEW-VERSION-UPLOADER.DIALOG_UPLOAD.TITLE';
|
||||
} else {
|
||||
this.title = this.data.title;
|
||||
}
|
||||
}
|
||||
|
||||
handleUpload(newFileVersion) {
|
||||
this.dialogAction.emit({ action: NewVersionUploaderDataAction.upload, newVersion: newFileVersion, currentVersion: this.data.node });
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onUploadError(error) {
|
||||
this.uploadError.emit(error);
|
||||
}
|
||||
|
||||
onViewingVersion(versionId: string) {
|
||||
this.dialogAction.emit({ action: NewVersionUploaderDataAction.view, versionId });
|
||||
}
|
||||
|
||||
refresh(node: Node) {
|
||||
this.dialogAction.emit({ action: NewVersionUploaderDataAction.refresh, node });
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MaterialModule } from '../material.module';
|
||||
|
||||
import { UploadModule } from '../upload/upload.module';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { VersionManagerModule } from '../version-manager';
|
||||
import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MaterialModule,
|
||||
CoreModule,
|
||||
UploadModule,
|
||||
FormsModule,
|
||||
VersionManagerModule
|
||||
],
|
||||
declarations: [
|
||||
NewVersionUploaderDialogComponent
|
||||
],
|
||||
exports: [
|
||||
NewVersionUploaderDialogComponent,
|
||||
FormsModule
|
||||
]
|
||||
})
|
||||
export class NewVersionUploaderModule { }
|
@ -0,0 +1,242 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { ContentService } from '@alfresco/adf-core';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, of, Subject } from 'rxjs';
|
||||
import { mockFile, mockNewVersionUploaderData, mockNode } from '../mock';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
import { NewVersionUploaderData, NewVersionUploaderDataAction, NewVersionUploaderDialogData, RefreshData, VersionManagerUploadData, ViewVersion } from './models';
|
||||
import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog';
|
||||
import { NewVersionUploaderService } from './new-version-uploader.service';
|
||||
|
||||
@Component({
|
||||
template: ''
|
||||
})
|
||||
class TestDialogComponent {
|
||||
@Output()
|
||||
dialogAction = new EventEmitter<NewVersionUploaderData>();
|
||||
|
||||
@Output()
|
||||
uploadError = new EventEmitter<any>();
|
||||
|
||||
afterClosed = () => of({ action: 'refresh', node: mockNode });
|
||||
|
||||
}
|
||||
|
||||
describe('NewVersionUploaderService', () => {
|
||||
let fixture: ComponentFixture<TestDialogComponent>;
|
||||
let service: NewVersionUploaderService;
|
||||
let contentService: ContentService;
|
||||
let dialog: MatDialog;
|
||||
let spyOnDialogOpen: jasmine.Spy;
|
||||
let dialogRefSpyObj;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
declarations: [TestDialogComponent]
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(NewVersionUploaderService);
|
||||
contentService = TestBed.inject(ContentService);
|
||||
dialog = TestBed.inject(MatDialog);
|
||||
fixture = TestBed.createComponent(TestDialogComponent);
|
||||
|
||||
dialogRefSpyObj = jasmine.createSpyObj({ afterClosed: null });
|
||||
dialogRefSpyObj.componentInstance = fixture.componentInstance;
|
||||
dialogRefSpyObj.afterClosed = fixture.componentInstance.afterClosed;
|
||||
spyOnDialogOpen = spyOn(dialog, 'open').and.returnValue(dialogRefSpyObj);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('openUploadNewVersionDialog', () => {
|
||||
it('Should not open dialog if update operation is not allowed', () => {
|
||||
spyOn(contentService, 'hasAllowableOperations').and.returnValue(false);
|
||||
expect(spyOnDialogOpen).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should return error if update operation is not allowed', async () => {
|
||||
spyOn(contentService, 'hasAllowableOperations').and.returnValue(false);
|
||||
const mockNewVersionUploaderDialogData: NewVersionUploaderDialogData = {
|
||||
node: mockNode,
|
||||
file: mockFile
|
||||
};
|
||||
try {
|
||||
await service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).toPromise();
|
||||
fail('An error should have been thrown');
|
||||
} catch (error) {
|
||||
expect(error).toEqual({ value: 'OPERATION.ERROR.PERMISSION' });
|
||||
}
|
||||
});
|
||||
|
||||
describe('Mat Dialog configuration', () => {
|
||||
let mockNewVersionUploaderDialogData: NewVersionUploaderDialogData;
|
||||
beforeEach(() => {
|
||||
spyOn(contentService, 'hasAllowableOperations').and.returnValue(true);
|
||||
spyOn(service.versionsApi, 'listVersionHistory').and.returnValue(Promise.resolve({
|
||||
list: { entries: [{ entry: '2' }] }
|
||||
}));
|
||||
mockNewVersionUploaderDialogData = {
|
||||
node: mockNode,
|
||||
file: mockFile
|
||||
};
|
||||
});
|
||||
|
||||
it('Should open dialog with default configuration', fakeAsync(() => {
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).toPromise();
|
||||
tick();
|
||||
expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, {
|
||||
data: { file: mockFile, node: mockNode, currentVersion: '2', showComments: true, allowDownload: true, showVersionsOnly: undefined },
|
||||
panelClass: ['adf-new-version-uploader-dialog', 'adf-new-version-uploader-dialog-upload'],
|
||||
width: '630px'
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should override default dialog panelClass', fakeAsync(() => {
|
||||
const mockDialogConfiguration: MatDialogConfig = {
|
||||
panelClass: 'adf-custom-class',
|
||||
width: '500px'
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise();
|
||||
tick();
|
||||
expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, {
|
||||
data: { file: mockFile, node: mockNode, currentVersion: '2', showComments: true, allowDownload: true, showVersionsOnly: undefined },
|
||||
panelClass: 'adf-custom-class',
|
||||
width: '500px'
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should set dialog height', fakeAsync(() => {
|
||||
const mockDialogConfiguration: MatDialogConfig = {
|
||||
height: '600px'
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise();
|
||||
tick();
|
||||
expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, {
|
||||
data: { file: mockFile, node: mockNode, currentVersion: '2', showComments: true, allowDownload: true, showVersionsOnly: undefined },
|
||||
panelClass: ['adf-new-version-uploader-dialog', 'adf-new-version-uploader-dialog-upload'],
|
||||
width: '630px',
|
||||
height: '600px'
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should not override dialog configuration, if dialog configuration is empty', fakeAsync(() => {
|
||||
const mockDialogConfiguration: MatDialogConfig = {};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise();
|
||||
tick();
|
||||
expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, {
|
||||
data: { file: mockFile, node: mockNode, currentVersion: '2', showComments: true, allowDownload: true, showVersionsOnly: undefined },
|
||||
panelClass: ['adf-new-version-uploader-dialog', 'adf-new-version-uploader-dialog-upload'],
|
||||
width: '630px'
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should dialog add list css class if showVersionsOnly is true', fakeAsync(() => {
|
||||
const mockNewVersionUploaderDialogDataWithVersionsOnly = {
|
||||
node: mockNode,
|
||||
file: mockFile,
|
||||
showVersionsOnly: true
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogDataWithVersionsOnly).toPromise();
|
||||
tick();
|
||||
expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, {
|
||||
data: { file: mockFile, node: mockNode, currentVersion: '2', showComments: true, allowDownload: true, showVersionsOnly: true },
|
||||
panelClass: ['adf-new-version-uploader-dialog', 'adf-new-version-uploader-dialog-list'],
|
||||
width: '630px'
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('Subscribe events from Dialog', () => {
|
||||
let mockNewVersionUploaderDialogData: NewVersionUploaderDialogData;
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(contentService, 'hasAllowableOperations').and.returnValue(true);
|
||||
spyOn(service.versionsApi, 'listVersionHistory').and.returnValue(Promise.resolve({
|
||||
list: { entries: [{ entry: '2' }] }
|
||||
}));
|
||||
mockNewVersionUploaderDialogData = {
|
||||
node: mockNode,
|
||||
file: mockFile
|
||||
};
|
||||
});
|
||||
|
||||
it('Should return Refresh action', (done) => {
|
||||
dialogRefSpyObj.componentInstance = {
|
||||
dialogAction: new BehaviorSubject<RefreshData>({ action: NewVersionUploaderDataAction.refresh, node: mockNode }),
|
||||
uploadError: new Subject()
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).subscribe((res) => {
|
||||
expect(res).toEqual({ action: NewVersionUploaderDataAction.refresh, node: mockNode });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Should return Upload action', (done) => {
|
||||
dialogRefSpyObj.componentInstance = {
|
||||
dialogAction: new BehaviorSubject<VersionManagerUploadData>(mockNewVersionUploaderData),
|
||||
uploadError: new Subject()
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).subscribe((res) => {
|
||||
expect(res).toEqual(mockNewVersionUploaderData);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Should return View Version action', (done) => {
|
||||
dialogRefSpyObj.componentInstance = {
|
||||
dialogAction: new BehaviorSubject<ViewVersion>({ action: NewVersionUploaderDataAction.view, versionId: '2' }),
|
||||
uploadError: new Subject()
|
||||
};
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).subscribe((res) => {
|
||||
expect(res).toEqual({ action: NewVersionUploaderDataAction.view, versionId: '2' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Should return upload error', (done) => {
|
||||
dialogRefSpyObj.componentInstance = {
|
||||
dialogAction: new Subject(),
|
||||
uploadError: new BehaviorSubject<any>({ value: 'Upload error' })
|
||||
};
|
||||
spyOnDialogOpen.and.returnValue(dialogRefSpyObj);
|
||||
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).subscribe(() => {
|
||||
fail('An error should have been thrown');
|
||||
},
|
||||
error => {
|
||||
expect(error).toEqual({ value: 'Upload error' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
@ -0,0 +1,86 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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 { Injectable } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
|
||||
import { AlfrescoApiService, ContentService } from '@alfresco/adf-core';
|
||||
|
||||
import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog';
|
||||
import { VersionPaging, VersionsApi } from '@alfresco/js-api';
|
||||
import { NewVersionUploaderData, NewVersionUploaderDialogData } from './models';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class NewVersionUploaderService {
|
||||
|
||||
_versionsApi: VersionsApi;
|
||||
get versionsApi(): VersionsApi {
|
||||
this._versionsApi = this._versionsApi ?? new VersionsApi(this.apiService.getInstance());
|
||||
return this._versionsApi;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private contentService: ContentService,
|
||||
private apiService: AlfrescoApiService,
|
||||
private dialog: MatDialog
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Open a dialog NewVersionUploaderDialogComponent to display:
|
||||
* - a side by side comparison between the current target node (type, name, icon) and the new file that should update it's version
|
||||
* - the new version's minor/major changes and the optional comment of a node and the ability to upload a new file version
|
||||
* - if data.showVersionsOnly is set to true, displays the version history of a node, with the ability to restore, delete and view version of the current node
|
||||
* @param data data to pass to MatDialog
|
||||
* @param config allow to override default MatDialogConfig
|
||||
* @returns an Observable represents the triggered dialog action or an error in case of an error condition
|
||||
*/
|
||||
openUploadNewVersionDialog(data: NewVersionUploaderDialogData, config?: MatDialogConfig) {
|
||||
const { file, node, showVersionsOnly } = data;
|
||||
const showComments = true;
|
||||
const allowDownload = true;
|
||||
|
||||
return new Observable((observer) => {
|
||||
if (this.contentService.hasAllowableOperations(node, 'update')) {
|
||||
this.versionsApi.listVersionHistory(node.id).then((versionPaging: VersionPaging) => {
|
||||
const dialogRef = this.dialog.open(NewVersionUploaderDialogComponent, {
|
||||
data: { file, node, currentVersion: versionPaging.list.entries[0].entry, showComments, allowDownload, showVersionsOnly },
|
||||
panelClass: this.composePanelClass(showVersionsOnly),
|
||||
width: '630px',
|
||||
...(config && Object.keys(config).length > 0 && config)
|
||||
});
|
||||
dialogRef.componentInstance.dialogAction.asObservable()
|
||||
.subscribe((newVersionUploaderData: NewVersionUploaderData) => {
|
||||
observer.next(newVersionUploaderData);
|
||||
});
|
||||
dialogRef.componentInstance.uploadError.asObservable().subscribe(error => {
|
||||
observer.error(error);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
observer.error({ value: 'OPERATION.ERROR.PERMISSION' });
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private composePanelClass(showVersionsOnly: boolean): string | string[] {
|
||||
const dialogCssClass = 'adf-new-version-uploader-dialog';
|
||||
return [dialogCssClass, `${dialogCssClass}-${showVersionsOnly ? 'list' : 'upload'}`];
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './new-version-uploader.dialog';
|
||||
export * from './new-version-uploader.module';
|
||||
export * from './new-version-uploader.service';
|
||||
export * from './models';
|
@ -35,5 +35,6 @@ export * from './lib/tree-view/index';
|
||||
export * from './lib/group/index';
|
||||
export * from './lib/aspect-list/index';
|
||||
export * from './lib/content-type/index';
|
||||
export * from './lib/new-version-uploader';
|
||||
|
||||
export * from './lib/content.module';
|
||||
|
@ -26,6 +26,7 @@
|
||||
(rowClick)="onRowClicked($event)"
|
||||
(attachFileClick)="onAttachFileClicked($event)"
|
||||
(downloadFile)="downloadContent($event)"
|
||||
(uploadNewFileVersion)="onUploadNewFileVersion($event)"
|
||||
(contentModelFileHandler)="contentModelFormFileHandler($event)"
|
||||
(removeAttachFile)="onRemoveAttachFile($event)"
|
||||
></adf-cloud-file-properties-table>
|
||||
|
@ -29,7 +29,8 @@ import {
|
||||
DownloadService,
|
||||
AppConfigService,
|
||||
UploadWidgetContentLinkModel,
|
||||
LocalizedDatePipe
|
||||
LocalizedDatePipe,
|
||||
NotificationService
|
||||
} from '@alfresco/adf-core';
|
||||
import {
|
||||
allSourceParams,
|
||||
@ -60,11 +61,12 @@ import {
|
||||
} from '../../../mocks/attach-file-cloud-widget.mock';
|
||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ContentModule, ContentNodeSelectorPanelService } from '@alfresco/adf-content-services';
|
||||
import { ContentModule, ContentNodeSelectorPanelService, NewVersionUploaderDataAction, NewVersionUploaderService } from '@alfresco/adf-content-services';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { FormCloudModule } from '../../../form-cloud.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { mockNode } from 'content-services/src/lib/mock';
|
||||
|
||||
describe('AttachFileCloudWidgetComponent', () => {
|
||||
let widget: AttachFileCloudWidgetComponent;
|
||||
@ -82,6 +84,8 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
let contentClickedSpy: jasmine.Spy;
|
||||
let openUploadFileDialogSpy: jasmine.Spy;
|
||||
let localizedDataPipe: LocalizedDatePipe;
|
||||
let newVersionUploaderService: NewVersionUploaderService;
|
||||
let notificationService: NotificationService;
|
||||
|
||||
const createUploadWidgetField = (form: FormModel, fieldId: string, value?: any, params?: any, multiple?: boolean, name?: string, readOnly?: boolean) => {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
@ -204,7 +208,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
describe('when is required', () => {
|
||||
|
||||
it('should be able to display label with asterisk', async () => {
|
||||
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
|
||||
type: FormFieldTypes.UPLOAD,
|
||||
required: true
|
||||
});
|
||||
@ -298,7 +302,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
it('should be able to use mapped string variable value if the destinationFolderPath set to string type variable', async () => {
|
||||
const getNodeIdFromPathSpy = spyOn(contentCloudNodeSelectorService, 'getNodeIdFromPath').and.returnValue(mockNodeIdBasedOnStringVariableValue);
|
||||
|
||||
const form = new FormModel({ formVariables, processVariables});
|
||||
const form = new FormModel({ formVariables, processVariables });
|
||||
createUploadWidgetField(form, 'attach-file-alfresco', [], mockAllFileSourceWithStringVariablePathType);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@ -504,7 +508,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
|
||||
describe('when a file is uploaded', () => {
|
||||
beforeEach(async () => {
|
||||
apiServiceSpy = spyOn(widget['nodesApi'], 'getNode').and.returnValue(new Promise(resolve => resolve({entry: fakeNodeWithProperties})));
|
||||
apiServiceSpy = spyOn(widget['nodesApi'], 'getNode').and.returnValue(new Promise(resolve => resolve({ entry: fakeNodeWithProperties })));
|
||||
spyOn(contentCloudNodeSelectorService, 'getNodeIdFromPath').and.returnValue(new Promise(resolve => resolve('fake-properties')));
|
||||
openUploadFileDialogSpy.and.returnValue(of([fakeNodeWithProperties]));
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
@ -846,4 +850,48 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
expect(getProcessVariableValueSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onUploadNewFileVersion', () => {
|
||||
let spyOnOpenUploadNewVersionDialog: jasmine.Spy;
|
||||
let spyOnReplaceOldFileVersionWithNew: jasmine.Spy;
|
||||
let spyOnShowError: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
newVersionUploaderService = TestBed.inject(NewVersionUploaderService);
|
||||
spyOnOpenUploadNewVersionDialog = spyOn(newVersionUploaderService, 'openUploadNewVersionDialog')
|
||||
.and.returnValue(of({ action: NewVersionUploaderDataAction.refresh }));
|
||||
spyOnReplaceOldFileVersionWithNew = spyOn(widget, 'replaceOldFileVersionWithNew');
|
||||
spyOnShowError = spyOn(notificationService, 'showError');
|
||||
});
|
||||
|
||||
it('Should open new version uploader dialog', async () => {
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnOpenUploadNewVersionDialog).toHaveBeenCalledWith(mockNode);
|
||||
});
|
||||
|
||||
it('Should not replace old file version with the new one if dialog returned action is not upload', async () => {
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should replace old file version with the new one if dialog returned action is upload', async () => {
|
||||
spyOnOpenUploadNewVersionDialog.and.returnValue(of({ action: NewVersionUploaderDataAction.upload }));
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('Should show notification error if new version uploader dialog return error', async () => {
|
||||
const mockError = {value: 'Upload error'};
|
||||
spyOnOpenUploadNewVersionDialog.and.returnValue(throwError(mockError));
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).not.toHaveBeenCalled();
|
||||
expect(spyOnShowError).toHaveBeenCalledWith(mockError.value);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ import { ContentCloudNodeSelectorService } from '../../../services/content-cloud
|
||||
import { ProcessCloudContentService } from '../../../services/process-cloud-content.service';
|
||||
import { UploadCloudWidgetComponent } from './upload-cloud.widget';
|
||||
import { DestinationFolderPathModel, DestinationFolderPathType } from '../../../models/form-cloud-representation.model';
|
||||
import { ContentNodeSelectorPanelService } from '@alfresco/adf-content-services';
|
||||
import { ContentNodeSelectorPanelService, NewVersionUploaderData, NewVersionUploaderDataAction, NewVersionUploaderDialogData, NewVersionUploaderService, VersionManagerUploadData } from '@alfresco/adf-content-services';
|
||||
|
||||
export const RETRIEVE_METADATA_OPTION = 'retrieveMetadata';
|
||||
export const ALIAS_ROOT_FOLDER = '-root-';
|
||||
@ -81,7 +81,8 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent i
|
||||
private contentNodeSelectorService: ContentCloudNodeSelectorService,
|
||||
private appConfigService: AppConfigService,
|
||||
private apiService: AlfrescoApiService,
|
||||
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService
|
||||
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService,
|
||||
private newVersionUploaderService: NewVersionUploaderService
|
||||
) {
|
||||
super(formService, thumbnails, processCloudContentService, notificationService, logger);
|
||||
}
|
||||
@ -211,6 +212,16 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent i
|
||||
this.processCloudContentService.downloadFile(file.id);
|
||||
}
|
||||
|
||||
onUploadNewFileVersion(node: NewVersionUploaderDialogData): void {
|
||||
this.newVersionUploaderService.openUploadNewVersionDialog(node).subscribe((newVersionUploaderData: NewVersionUploaderData) => {
|
||||
if (newVersionUploaderData.action === NewVersionUploaderDataAction.upload) {
|
||||
this.replaceOldFileVersionWithNew(newVersionUploaderData as VersionManagerUploadData);
|
||||
}
|
||||
},
|
||||
error => this.notificationService.showError(error.value)
|
||||
);
|
||||
}
|
||||
|
||||
onAttachFileClicked(nodeSelector: any) {
|
||||
nodeSelector.nodeId = nodeSelector.id;
|
||||
this.fileClicked(new ContentLinkModel(nodeSelector));
|
||||
|
@ -62,6 +62,14 @@
|
||||
<mat-icon class="mat-24">highlight_off</mat-icon>
|
||||
<span>{{ 'FORM.FIELD.REMOVE_FILE' | translate }}</span>
|
||||
</button>
|
||||
<div *ngIf="displayMenuOption('newVersion')">
|
||||
<button [adf-upload]="true" [mode]="['click']"
|
||||
(upload-files)="onUploadNewFileVersion($event, element);"
|
||||
id="{{'file-'+ element?.id +'-upload-new-version'}}" mat-menu-item>
|
||||
<mat-icon class="mat-24">file_upload</mat-icon>
|
||||
<span>{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TITLE' | translate }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
@ -20,6 +20,7 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { LocalizedDatePipe, ThumbnailService } from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { NewVersionUploaderDialogData } from '@alfresco/adf-content-services';
|
||||
|
||||
export const RETRIEVE_METADATA_OPTION = 'retrieveMetadata';
|
||||
|
||||
@ -56,6 +57,9 @@ export class FilePropertiesTableCloudComponent {
|
||||
@Output()
|
||||
downloadFile: EventEmitter<Node> = new EventEmitter<Node>();
|
||||
|
||||
@Output()
|
||||
uploadNewFileVersion: EventEmitter<NewVersionUploaderDialogData> = new EventEmitter<NewVersionUploaderDialogData>();
|
||||
|
||||
@Output()
|
||||
contentModelFileHandler: EventEmitter<any> = new EventEmitter<Node>();
|
||||
|
||||
@ -76,6 +80,14 @@ export class FilePropertiesTableCloudComponent {
|
||||
this.downloadFile.emit(file);
|
||||
}
|
||||
|
||||
onUploadNewFileVersion(customEvent: any, node: Node){
|
||||
const newVersionUploaderDialogData: NewVersionUploaderDialogData = {
|
||||
file: customEvent.detail.files[0].file,
|
||||
node
|
||||
};
|
||||
this.uploadNewFileVersion.emit(newVersionUploaderDialogData);
|
||||
}
|
||||
|
||||
contentModelFormFileHandler(file?: any) {
|
||||
this.contentModelFileHandler.emit(file);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import { mergeMap } from 'rxjs/operators';
|
||||
import { WidgetComponent, LogService, FormService, ThumbnailService, NotificationService } from '@alfresco/adf-core';
|
||||
import { ProcessCloudContentService } from '../../../services/process-cloud-content.service';
|
||||
import { FileSourceTypes, DestinationFolderPathType } from '../../../models/form-cloud-representation.model';
|
||||
import { VersionManagerUploadData } from '@alfresco/adf-content-services';
|
||||
|
||||
@Component({
|
||||
selector: 'upload-cloud-widget',
|
||||
@ -78,6 +79,13 @@ export class UploadCloudWidgetComponent extends WidgetComponent implements OnIni
|
||||
}
|
||||
}
|
||||
|
||||
replaceOldFileVersionWithNew(versionManagerData: VersionManagerUploadData) {
|
||||
const currentUploadedFileIndex = this.uploadedFiles.findIndex(file => file.name === versionManagerData.currentVersion.name);
|
||||
this.uploadedFiles[currentUploadedFileIndex] = { ...versionManagerData.newVersion.value.entry};
|
||||
this.field.value = [...this.uploadedFiles];
|
||||
this.field.form.values[this.field.id] = [...this.uploadedFiles];
|
||||
}
|
||||
|
||||
onFileChanged(event: any) {
|
||||
const files: File[] = [];
|
||||
const filesSaved: Node[] = [];
|
||||
|
@ -24,7 +24,7 @@ import { MaterialModule } from '../material.module';
|
||||
import { FormCloudComponent } from './components/form-cloud.component';
|
||||
import { FormDefinitionSelectorCloudComponent } from './components/form-definition-selector-cloud.component';
|
||||
import { FormCustomOutcomesComponent } from './components/form-cloud-custom-outcomes.component';
|
||||
import { ContentMetadataModule, ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||
import { ContentMetadataModule, ContentNodeSelectorModule, UploadModule } from '@alfresco/adf-content-services';
|
||||
|
||||
import { DateCloudWidgetComponent } from './components/widgets/date/date-cloud.widget';
|
||||
import { DropdownCloudWidgetComponent } from './components/widgets/dropdown/dropdown-cloud.widget';
|
||||
@ -51,7 +51,8 @@ import { FilePropertiesTableCloudComponent } from './components/widgets/attach-f
|
||||
ContentNodeSelectorModule,
|
||||
PeopleCloudModule,
|
||||
GroupCloudModule,
|
||||
ContentMetadataModule
|
||||
ContentMetadataModule,
|
||||
UploadModule
|
||||
],
|
||||
declarations: [
|
||||
FormCloudComponent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user