sync latest features and bug fixes (#34)

* [ACA-968] Language Picker

* [ACA-9380] fix Incorrect behavior when doing a multiple selection Copy or Move and only some of the items fail to be copied (#31)

* [ACA-938] Incorrect behavior when doing a multiple selection Copy or Move and only some of the items fail to be copied

* [ACA-938] Incorrect behavior when doing a multiple selection Copy or Move and only some of the items fail to be copied

unit tests changes according to partial action changes

* [ACA-919] style fixes for search and toolbar (#27)

* style fixes for search and toolbar

* inherited font family

* [ACA-937] fix trashcan tooltip

* tab title translation (#33)

* fix logo image reference

* minor code formatting
This commit is contained in:
Denys Vuika
2017-11-03 14:35:40 +00:00
committed by GitHub
parent bfbc7d354a
commit a16885a856
23 changed files with 235 additions and 87 deletions
+44 -1
View File
@@ -4,6 +4,7 @@
"name": "Alfresco Example Content Application",
"build": "1234"
},
"languagePicker": false,
"document-list": {
"supportedPageSizes": [
25,
@@ -18,5 +19,47 @@
"thumbs.db",
".git"
]
}
},
"languages": [
{
"key": "de",
"label": "German"
},
{
"key": "en",
"label": "English"
},
{
"key": "es",
"label": "Spanish"
},
{
"key": "fr",
"label": "French"
},
{
"key": "it",
"label": "Italian"
},
{
"key": "ja",
"label": "Japanese"
},
{
"key": "nb",
"label": "Norwegian"
},
{
"key": "nl",
"label": "Dutch"
},
{
"key": "pt-BR",
"label": "Brazilian Portuguese"
},
{
"key": "ru",
"label": "Russian"
}
]
}
+4 -3
View File
@@ -49,9 +49,10 @@ export class AppComponent implements OnInit {
const data: any = snapshot.data || {};
if (data.i18nTitle) {
translateService.get(data.i18nTitle).subscribe(title => {
pageTitle.setTitle(title);
});
this.translateService.translate
.stream(data.i18nTitle)
.subscribe((title) => pageTitle.setTitle(title));
} else {
pageTitle.setTitle(data.title || '');
}
+1 -2
View File
@@ -112,8 +112,7 @@ export const APP_ROUTES: Routes = [
data: {
i18nTitle: 'APP.BROWSE.TRASHCAN.TITLE'
}
}
,
},
{
path: '**',
component: GenericErrorComponent
@@ -116,6 +116,82 @@ describe('NodeCopyDirective', () => {
);
});
it('notifies partially copy of one node out of a multiple selection of nodes', () => {
spyOn(service, 'copyNodes').and.returnValue(Observable.of('OPERATION.SUCCES.CONTENT.COPY'));
component.selection = [
{ entry: { id: 'node-to-copy-1', name: 'name1' } },
{ entry: { id: 'node-to-copy-2', name: 'name2' } }];
const createdItems = [
{ entry: { id: 'copy-of-node-1', name: 'name1' } }];
fixture.detectChanges();
element.triggerEventHandler('click', null);
service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction).toHaveBeenCalledWith(
'APP.MESSAGES.INFO.NODE_COPY.PARTIAL_SINGULAR', 'Undo', 10000
);
});
it('notifies partially copy of more nodes out of a multiple selection of nodes', () => {
spyOn(service, 'copyNodes').and.returnValue(Observable.of('OPERATION.SUCCES.CONTENT.COPY'));
component.selection = [
{ entry: { id: 'node-to-copy-0', name: 'name0' } },
{ entry: { id: 'node-to-copy-1', name: 'name1' } },
{ entry: { id: 'node-to-copy-2', name: 'name2' } }];
const createdItems = [
{ entry: { id: 'copy-of-node-0', name: 'name0' } },
{ entry: { id: 'copy-of-node-1', name: 'name1' } }];
fixture.detectChanges();
element.triggerEventHandler('click', null);
service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction).toHaveBeenCalledWith(
'APP.MESSAGES.INFO.NODE_COPY.PARTIAL_PLURAL', 'Undo', 10000
);
});
it('notifies of failed copy of multiple nodes', () => {
spyOn(service, 'copyNodes').and.returnValue(Observable.of('OPERATION.SUCCES.CONTENT.COPY'));
component.selection = [
{ entry: { id: 'node-to-copy-0', name: 'name0' } },
{ entry: { id: 'node-to-copy-1', name: 'name1' } },
{ entry: { id: 'node-to-copy-2', name: 'name2' } }];
const createdItems = [];
fixture.detectChanges();
element.triggerEventHandler('click', null);
service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction).toHaveBeenCalledWith(
'APP.MESSAGES.INFO.NODE_COPY.FAIL_PLURAL', '', 3000
);
});
it('notifies of failed copy of one node', () => {
spyOn(service, 'copyNodes').and.returnValue(Observable.of('OPERATION.SUCCES.CONTENT.COPY'));
component.selection = [
{ entry: { id: 'node-to-copy', name: 'name' } }];
const createdItems = [];
fixture.detectChanges();
element.triggerEventHandler('click', null);
service.contentCopied.next(<any>createdItems);
expect(service.copyNodes).toHaveBeenCalled();
expect(notificationService.openSnackMessageAction).toHaveBeenCalledWith(
'APP.MESSAGES.INFO.NODE_COPY.FAIL_SINGULAR', '', 3000
);
});
it('notifies error if success message was not emitted', () => {
spyOn(service, 'copyNodes').and.returnValue(Observable.of(''));
@@ -60,14 +60,27 @@ export class NodeCopyDirective {
}
private toastMessage(info: any, newItems?: MinimalNodeEntity[]) {
const numberOfCopiedItems = newItems ? newItems.length : '';
const numberOfCopiedItems = newItems ? newItems.length : 0;
const failedItems = this.selection.length - numberOfCopiedItems;
let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC';
if (typeof info === 'string') {
if (info.toLowerCase().indexOf('succes') !== -1) {
let i18MessageSuffix;
if (failedItems) {
if (numberOfCopiedItems) {
i18MessageSuffix = ( numberOfCopiedItems === 1 ) ? 'PARTIAL_SINGULAR' : 'PARTIAL_PLURAL';
} else {
i18MessageSuffix = ( failedItems === 1 ) ? 'FAIL_SINGULAR' : 'FAIL_PLURAL';
}
} else {
i18MessageSuffix = ( numberOfCopiedItems === 1 ) ? 'SINGULAR' : 'PLURAL';
}
const i18MessageSuffix = ( numberOfCopiedItems === 1 ) ? 'SINGULAR' : 'PLURAL';
i18nMessageString = `APP.MESSAGES.INFO.NODE_COPY.${i18MessageSuffix}`;
}
@@ -86,7 +99,7 @@ export class NodeCopyDirective {
const undo = (numberOfCopiedItems > 0) ? 'Undo' : '';
const withUndo = (numberOfCopiedItems > 0) ? '_WITH_UNDO' : '';
this.translation.get(i18nMessageString, { number: numberOfCopiedItems }).subscribe(message => {
this.translation.get(i18nMessageString, { success: numberOfCopiedItems, failed: failedItems }).subscribe(message => {
this.notification.openSnackMessageAction(message, undo, NodeActionsService[`SNACK_MESSAGE_DURATION${withUndo}`])
.onAction()
.subscribe(() => this.deleteCopy(newItems));
@@ -369,8 +369,8 @@ describe('NodeActionsService', () => {
spyOnSuccess.calls.reset();
spyOnError.calls.reset();
copyObservable.toPromise().then(
() => {
spyOnSuccess();
(response) => {
spyOnSuccess(response);
},
() => {
spyOnError();
@@ -382,8 +382,9 @@ describe('NodeActionsService', () => {
{ targetParentId: folderDestination.entry.id, name: undefined }
);
}).then(() => {
expect(spyOnSuccess.calls.count()).toEqual(0);
expect(spyOnError.calls.count()).toEqual(1);
expect(spyOnSuccess.calls.count()).toEqual(1);
expect(spyOnSuccess).toHaveBeenCalledWith(permissionError);
expect(spyOnError.calls.count()).toEqual(0);
});
}));
@@ -401,16 +402,16 @@ describe('NodeActionsService', () => {
spyOnError.calls.reset();
copyObservable.toPromise()
.then(
() => {
spyOnSuccess();
(response) => {
spyOnSuccess(response);
},
() => {
spyOnError();
})
.then(
() => {
expect(spyOnSuccess).not.toHaveBeenCalled();
expect(spyOnError).toHaveBeenCalled();
expect(spyOnSuccess).toHaveBeenCalledWith(permissionError);
expect(spyOnError).not.toHaveBeenCalled();
expect(spyContentAction).toHaveBeenCalled();
expect(spyFolderAction).not.toHaveBeenCalled();
@@ -694,7 +695,7 @@ describe('NodeActionsService', () => {
});
}));
it('should throw permission error in case it occurs', async(() => {
it('should not throw permission error, to be able to show message in case of partial move of files', async(() => {
spyOnDocumentListServiceAction = spyOn(documentListService, 'moveNode').and
.returnValue(Observable.throw(permissionError));
@@ -711,8 +712,8 @@ describe('NodeActionsService', () => {
.then(() => {
expect(spyOnDocumentListServiceAction).toHaveBeenCalled();
expect(spyOnSuccess).not.toHaveBeenCalledWith(permissionError);
expect(spyOnError).toHaveBeenCalledWith(permissionError);
expect(spyOnSuccess).toHaveBeenCalledWith(permissionError);
expect(spyOnError).not.toHaveBeenCalledWith(permissionError);
});
}));
@@ -750,15 +751,15 @@ describe('NodeActionsService', () => {
spyOnError.calls.reset();
});
it('should throw permission error in case it occurs on folder move', async(() => {
it('should not throw permission error in case it occurs on folder move', async(() => {
spyOnDocumentListServiceAction = spyOn(documentListService, 'moveNode').and
.returnValue(Observable.throw(permissionError));
const moveFolderActionObservable = service.moveFolderAction(folderToMove.entry, folderDestinationId);
moveFolderActionObservable.toPromise()
.then(
() => {
spyOnSuccess();
(value) => {
spyOnSuccess(value);
},
(error) => {
spyOnError(error);
@@ -766,8 +767,8 @@ describe('NodeActionsService', () => {
.then(() => {
expect(spyOnDocumentListServiceAction).toHaveBeenCalled();
expect(spyOnSuccess).not.toHaveBeenCalled();
expect(spyOnError).toHaveBeenCalledWith(permissionError);
expect(spyOnSuccess).toHaveBeenCalledWith(permissionError);
expect(spyOnError).not.toHaveBeenCalled();
});
}));
+11 -19
View File
@@ -103,11 +103,11 @@ export class NodeActionsService {
(newContent) => {
observable.next(`OPERATION.SUCCES.${type.toUpperCase()}.${action.toUpperCase()}`);
const processedData = this.processResponse(newContent);
if (action === 'copy') {
this.contentCopied.next(newContent);
this.contentCopied.next(processedData.succeeded);
} else if (action === 'move') {
const processedData = this.processResponse(newContent);
this.contentMoved.next(processedData);
}
@@ -219,7 +219,8 @@ export class NodeActionsService {
if (errStatusCode && errStatusCode === 409) {
return this.copyContentAction(contentEntry, selectionId, this.getNewNameFrom(_oldName, contentEntry.name));
} else {
return Observable.throw(err || 'Server error');
// do not throw error, to be able to show message in case of partial copy of files
return Observable.of(err || 'Server error');
}
});
}
@@ -268,7 +269,8 @@ export class NodeActionsService {
});
} else {
return Observable.throw(err || 'Server error');
// do not throw error, to be able to show message in case of partial copy of files
return Observable.of(err || 'Server error');
}
});
}
@@ -367,7 +369,8 @@ export class NodeActionsService {
return Observable.zip(...batch);
});
} else {
return Observable.throw(err);
// do not throw error, to be able to show message in case of partial move of files
return Observable.of(err);
}
});
}
@@ -382,19 +385,8 @@ export class NodeActionsService {
return { itemMoved, initialParentId };
})
.catch((err) => {
let errStatusCode;
try {
const {error: {statusCode}} = JSON.parse(err.message);
errStatusCode = statusCode;
} catch (e) { //
}
if (errStatusCode && errStatusCode === 409) {
// do not throw error, to be able to show message in case of partial move of files
return Observable.of(err);
} else {
return Observable.throw(err);
}
// do not throw error, to be able to show message in case of partial move of files
return Observable.of(err);
});
}
@@ -413,7 +405,7 @@ export class NodeActionsService {
}
},
(err) => {
return Observable.throw(err || 'Server error');
return Observable.of(err || 'Server error');
});
return matchedNodes;
}
@@ -11,8 +11,17 @@
</div>
<mat-menu #userMenu="matMenu" [overlapTrigger]="false">
<button *ngIf="showLanguagePicker"
mat-menu-item [matMenuTriggerFor]="langMenu">
{{ 'APP.LANGUAGE' | translate }}
</button>
<button mat-menu-item adf-logout>
{{ 'APP.SIGN_OUT' | translate }}
</button>
</mat-menu>
<mat-menu #langMenu="matMenu">
<adf-language-menu></adf-language-menu>
</mat-menu>
</div>
@@ -16,7 +16,7 @@
*/
import { Component, OnInit, OnDestroy } from '@angular/core';
import { PeopleContentService } from 'ng2-alfresco-core';
import { PeopleContentService, AppConfigService } from 'ng2-alfresco-core';
import { Subscription } from 'rxjs/Rx';
@Component({
@@ -29,7 +29,10 @@ export class CurrentUserComponent implements OnInit, OnDestroy {
user: any = null;
constructor(private peopleApi: PeopleContentService) {}
constructor(
private peopleApi: PeopleContentService,
private appConfig: AppConfigService
) {}
ngOnInit() {
this.personSubscription = this.peopleApi.getCurrentPerson()
@@ -61,4 +64,8 @@ export class CurrentUserComponent implements OnInit, OnDestroy {
const { userFirstName: first, userLastName: last } = this;
return [ first[0], last[0] ].join('');
}
get showLanguagePicker() {
return this.appConfig.get('languagePicker') || false;
}
}
@@ -5,7 +5,7 @@
&.adf-toolbar {
.mat-toolbar {
background-color: #00bcd4;
font-family: 'Muli',"Roboto","Helvetica","Arial",sans-serif !important;
font-family: inherit;
min-height: $app-menu-height;
height: $app-menu-height;
@@ -18,8 +18,13 @@
}
}
.adf-toolbar-divider > div {
background-color: $alfresco-white !important;
.adf-toolbar-divider {
margin-left: 5px;
margin-right: 5px;
& > div {
background-color: $alfresco-white !important;
}
}
}
@@ -33,7 +38,7 @@
color: inherit;
background: url('../../../assets/images/alfresco-logo-white.svg') no-repeat 0 50%;
background: url('/assets/images/alfresco-logo-white.svg') no-repeat 0 50%;
background-size: 100% auto;
display: block;
@@ -3,7 +3,3 @@
adf-search-control {
color: $alfresco-white;
}
:host {
height: $app-menu-height;
}
@@ -9,7 +9,7 @@
[app-permanent-delete-node]="documentList.selection"
(selection-node-deleted)="refresh()"
*ngIf="documentList.selection.length"
title="{{ 'APP.ACTIONS.DELETE' | translate }}">
title="{{ 'APP.ACTIONS.DELETE_PERMANENT' | translate }}">
<mat-icon>delete_forever</mat-icon>
</button>
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "{{ success }} Elemente gelöscht, {{ failed }} konnte(n) nicht gelöscht werden"
},
"NODE_COPY": {
"SINGULAR": "{{ number }} Element kopiert.",
"PLURAL": "{{ number }} Elemente kopiert."
"SINGULAR": "{{ success }} Element kopiert.",
"PLURAL": "{{ success }} Elemente kopiert."
},
"NODE_MOVE": {
"SINGULAR": "{{ success }} Element verschoben.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+8 -2
View File
@@ -1,5 +1,6 @@
{
"APP": {
"LANGUAGE": "Language",
"SIGN_IN": "Sign in",
"SIGN_OUT": "Sign out",
"NEW_MENU": {
@@ -90,6 +91,7 @@
"COPY": "Copy",
"MOVE": "Move",
"DELETE": "Delete",
"DELETE_PERMANENT": "Permanently delete",
"MORE": "More actions",
"UNDO": "Undo",
"RESTORE": "Restore",
@@ -204,8 +206,12 @@
"PARTIAL_PLURAL": "Deleted {{ success }} items, {{ failed }} couldn't be deleted"
},
"NODE_COPY": {
"SINGULAR": "Copied {{ number }} item",
"PLURAL": "Copied {{ number }} items"
"SINGULAR": "Copied {{ success }} item",
"PLURAL": "Copied {{ success }} items",
"PARTIAL_SINGULAR": "Copied {{ success }} item, {{ failed }} couldn't be copied.",
"PARTIAL_PLURAL": "Copied {{ success }} items, {{ failed }} couldn't be copied.",
"FAIL_SINGULAR": "{{ failed }} item couldn't be copied.",
"FAIL_PLURAL": "{{ failed }} items couldn't be copied."
},
"NODE_MOVE": {
"SINGULAR": "Moved {{ success }} item.",
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "Se han eliminado {{ success }} elementos, {{ failed }} no se han podido eliminar"
},
"NODE_COPY": {
"SINGULAR": "Se ha copiado {{ number }} elemento",
"PLURAL": "Se han copiado {{ number }} elementos"
"SINGULAR": "Se ha copiado {{ success }} elemento",
"PLURAL": "Se han copiado {{ success }} elementos"
},
"NODE_MOVE": {
"SINGULAR": "Se ha movido {{ success }} elemento.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "{{ success }} éléments supprimés, {{ failed }} n'a/n'ont pas pu être supprimé(s)"
},
"NODE_COPY": {
"SINGULAR": "{{ number }} élément copié",
"PLURAL": "{{ number }} éléments copiés"
"SINGULAR": "{{ success }} élément copié",
"PLURAL": "{{ success }} éléments copiés"
},
"NODE_MOVE": {
"SINGULAR": "{{ success }} élément déplacé.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "Elementi {{ success }} eliminati, impossibile eliminare {{ failed }}"
},
"NODE_COPY": {
"SINGULAR": "Copiato {{ number }} elemento",
"PLURAL": "Copiati {{ number }} elementi"
"SINGULAR": "Copiato {{ success }} elemento",
"PLURAL": "Copiati {{ success }} elementi"
},
"NODE_MOVE": {
"SINGULAR": "Spostato {{ success }} elemento.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "{{ success }} 件のアイテムを削除しましたが、{{ failed }} 件は削除できませんでした"
},
"NODE_COPY": {
"SINGULAR": "{{ number }} 件のアイテムをコピーしました",
"PLURAL": "{{ number }} 件のアイテムをコピーしました"
"SINGULAR": "{{ success }} 件のアイテムをコピーしました",
"PLURAL": "{{ success }} 件のアイテムをコピーしました"
},
"NODE_MOVE": {
"SINGULAR": "{{ success }} 件のアイテムを移動しました。",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "Slettet {{ success }} elementer, {{ failed }} kunne ikke slettes"
},
"NODE_COPY": {
"SINGULAR": "Kopierte {{ number }} element",
"PLURAL": "Kopierte {{ number }} elementer"
"SINGULAR": "Kopierte {{ success }} element",
"PLURAL": "Kopierte {{ success }} elementer"
},
"NODE_MOVE": {
"SINGULAR": "Flyttet {{ success }} element.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "{{ success }} items verwijderd, kan {{ failed }} niet verwijderen"
},
"NODE_COPY": {
"SINGULAR": "{{ number }} item gekopieerd",
"PLURAL": "{{ number }} items gekopieerd"
"SINGULAR": "{{ success }} item gekopieerd",
"PLURAL": "{{ success }} items gekopieerd"
},
"NODE_MOVE": {
"SINGULAR": "{{ success }} item verplaatst.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "Itens {{ success }} excluídos, não foi possível excluir {{ failed }}"
},
"NODE_COPY": {
"SINGULAR": "Item {{ number }} copiado",
"PLURAL": "Itens {{ number }} copiados"
"SINGULAR": "Item {{ success }} copiado",
"PLURAL": "Itens {{ success }} copiados"
},
"NODE_MOVE": {
"SINGULAR": "Item {{ success }} movido.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "Удалено элементов: {{ success }}, не удалось удалить: {{ failed }}"
},
"NODE_COPY": {
"SINGULAR": "Скопирован {{ number }} элемент",
"PLURAL": "Скопировано элементов: {{ number }}"
"SINGULAR": "Скопирован {{ success }} элемент",
"PLURAL": "Скопировано элементов: {{ success }}"
},
"NODE_MOVE": {
"SINGULAR": "Перемещен {{ success }} элемент.",
@@ -199,4 +199,4 @@
}
}
}
}
}
+3 -3
View File
@@ -184,8 +184,8 @@
"PARTIAL_PLURAL": "已删除 {{ success }} 项目,{{ failed }} 无法删除"
},
"NODE_COPY": {
"SINGULAR": "已复制 {{ number }} 个项目",
"PLURAL": "已复制 {{ number }} 个项目"
"SINGULAR": "已复制 {{ success }} 个项目",
"PLURAL": "已复制 {{ success }} 个项目"
},
"NODE_MOVE": {
"SINGULAR": "已移动 {{ success }} 项目。",
@@ -199,4 +199,4 @@
}
}
}
}
}