imporove sorting management and reduce repetitive code (#381)

* rework sorting management

* remove fdescribe

* test fixes

* unified desctructor

* unified page reload

* test fixes

* code fixes

* test fixes

* test fixes
This commit is contained in:
Denys Vuika
2018-06-02 16:35:55 +01:00
committed by Cilibiu Bogdan
parent 0ac33f820b
commit 7bb0905045
23 changed files with 195 additions and 486 deletions

View File

@@ -69,6 +69,7 @@ import { MatMenuModule, MatIconModule, MatButtonModule, MatDialogModule, MatInpu
import { SearchComponent } from './components/search/search.component'; import { SearchComponent } from './components/search/search.component';
import { SettingsComponent } from './components/settings/settings.component'; import { SettingsComponent } from './components/settings/settings.component';
import { HybridAppConfigService } from './common/services/hybrid-app-config.service'; import { HybridAppConfigService } from './common/services/hybrid-app-config.service';
import { SortingPreferenceKeyDirective } from './directives/sorting-preference-key.directive';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -118,7 +119,8 @@ import { HybridAppConfigService } from './common/services/hybrid-app-config.serv
NodeVersionsDirective, NodeVersionsDirective,
VersionManagerDialogAdapterComponent, VersionManagerDialogAdapterComponent,
SearchComponent, SearchComponent,
SettingsComponent SettingsComponent,
SortingPreferenceKeyDirective
], ],
providers: [ providers: [
{ provide: AppConfigService, useClass: HybridAppConfigService }, { provide: AppConfigService, useClass: HybridAppConfigService },

View File

@@ -69,7 +69,7 @@ export const APP_ROUTES: Routes = [
{ {
path: 'favorites', path: 'favorites',
data: { data: {
preferencePrefix: 'favorites' sortingPreferenceKey: 'favorites'
}, },
children: [ children: [
{ {
@@ -93,7 +93,7 @@ export const APP_ROUTES: Routes = [
{ {
path: 'libraries', path: 'libraries',
data: { data: {
preferencePrefix: 'libraries' sortingPreferenceKey: 'libraries'
}, },
children: [{ children: [{
path: '', path: '',
@@ -106,7 +106,7 @@ export const APP_ROUTES: Routes = [
component: FilesComponent, component: FilesComponent,
data: { data: {
title: 'APP.BROWSE.LIBRARIES.TITLE', title: 'APP.BROWSE.LIBRARIES.TITLE',
preferencePrefix: 'libraries-files' sortingPreferenceKey: 'libraries-files'
} }
}, },
{ {
@@ -123,7 +123,7 @@ export const APP_ROUTES: Routes = [
{ {
path: 'personal-files', path: 'personal-files',
data: { data: {
preferencePrefix: 'personal-files' sortingPreferenceKey: 'personal-files'
}, },
children: [ children: [
{ {
@@ -164,7 +164,7 @@ export const APP_ROUTES: Routes = [
{ {
path: 'recent-files', path: 'recent-files',
data: { data: {
preferencePrefix: 'recent-files' sortingPreferenceKey: 'recent-files'
}, },
children: [ children: [
{ {
@@ -188,7 +188,7 @@ export const APP_ROUTES: Routes = [
{ {
path: 'shared', path: 'shared',
data: { data: {
preferencePrefix: 'shared-files' sortingPreferenceKey: 'shared-files'
}, },
children: [ children: [
{ {
@@ -214,7 +214,7 @@ export const APP_ROUTES: Routes = [
component: TrashcanComponent, component: TrashcanComponent,
data: { data: {
title: 'APP.BROWSE.TRASHCAN.TITLE', title: 'APP.BROWSE.TRASHCAN.TITLE',
preferencePrefix: 'trashcan' sortingPreferenceKey: 'trashcan'
} }
}, },
{ {

View File

@@ -54,7 +54,7 @@
<button <button
mat-menu-item mat-menu-item
#selection="adfFavorite" #selection="adfFavorite"
(toggle)="refresh()" (toggle)="reload()"
[adf-node-favorite]="documentList.selection"> [adf-node-favorite]="documentList.selection">
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon> <mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon> <mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
@@ -98,8 +98,8 @@
currentFolderId="-favorites-" currentFolderId="-favorites-"
selectionMode="multiple" selectionMode="multiple"
[navigate]="false" [navigate]="false"
[sorting]="sorting" [sorting]="[ 'modifiedAt', 'desc' ]"
(sorting-changed)="onSortingChanged($event)" [acaSortingPreferenceKey]="sortingPreferenceKey"
(node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)"> (node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)">
<empty-folder-content> <empty-folder-content>

View File

@@ -25,10 +25,10 @@
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { TestBed, async } from '@angular/core/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { import {
NotificationService, TranslationService, TranslationMock, NotificationService, TranslationService, TranslationMock,
NodesApiService, AlfrescoApiService, ContentService, NodesApiService, AlfrescoApiService, ContentService,
@@ -50,13 +50,12 @@ import { NodePermissionService } from '../../common/services/node-permission.ser
import { FavoritesComponent } from './favorites.component'; import { FavoritesComponent } from './favorites.component';
describe('Favorites Routed Component', () => { describe('Favorites Routed Component', () => {
let fixture; let fixture: ComponentFixture<FavoritesComponent>;
let component: FavoritesComponent; let component: FavoritesComponent;
let nodesApi: NodesApiService; let nodesApi: NodesApiService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let alfrescoContentService: ContentService; let alfrescoContentService: ContentService;
let contentService: ContentManagementService; let contentService: ContentManagementService;
let preferenceService: UserPreferencesService;
let notificationService: NotificationService; let notificationService: NotificationService;
let router: Router; let router: Router;
let page; let page;
@@ -109,9 +108,6 @@ describe('Favorites Routed Component', () => {
AppConfigPipe AppConfigPipe
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: {
snapshot: { data: { preferencePrefix: 'prefix' } }
} } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
UserPreferencesService, UserPreferencesService,
@@ -139,7 +135,6 @@ describe('Favorites Routed Component', () => {
alfrescoApi.reset(); alfrescoApi.reset();
alfrescoContentService = TestBed.get(ContentService); alfrescoContentService = TestBed.get(ContentService);
contentService = TestBed.get(ContentManagementService); contentService = TestBed.get(ContentManagementService);
preferenceService = TestBed.get(UserPreferencesService);
router = TestBed.get(Router); router = TestBed.get(Router);
}); });
})); }));
@@ -150,32 +145,32 @@ describe('Favorites Routed Component', () => {
describe('Events', () => { describe('Events', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'refresh'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should refresh on editing folder event', () => { it('should refresh on editing folder event', () => {
alfrescoContentService.folderEdit.next(null); alfrescoContentService.folderEdit.next(null);
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should refresh on move node event', () => { it('should refresh on move node event', () => {
contentService.nodeMoved.next(null); contentService.nodeMoved.next(null);
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should refresh on node deleted event', () => { it('should refresh on node deleted event', () => {
contentService.nodeDeleted.next(null); contentService.nodeDeleted.next(null);
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should refresh on node restore event', () => { it('should refresh on node restore event', () => {
contentService.nodeRestored.next(null); contentService.nodeRestored.next(null);
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
@@ -292,43 +287,12 @@ describe('Favorites Routed Component', () => {
spyOn(component.documentList, 'reload'); spyOn(component.documentList, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.refresh(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.documentList.reload).toHaveBeenCalled();
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
describe('openSnackMessage', () => { describe('openSnackMessage', () => {
it('should call notification service', () => { it('should call notification service', () => {
const message = 'notification message'; const message = 'notification message';

View File

@@ -23,13 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx';
import { MinimalNodeEntryEntity, MinimalNodeEntity, PathElementEntity, PathInfo } from 'alfresco-js-api'; import { MinimalNodeEntryEntity, MinimalNodeEntity, PathElementEntity, PathInfo } from 'alfresco-js-api';
import { ContentService, NodesApiService, UserPreferencesService, NotificationService } from '@alfresco/adf-core'; import { ContentService, NodesApiService, UserPreferencesService, NotificationService } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
@@ -38,44 +35,28 @@ import { PageComponent } from '../page.component';
@Component({ @Component({
templateUrl: './favorites.component.html' templateUrl: './favorites.component.html'
}) })
export class FavoritesComponent extends PageComponent implements OnInit, OnDestroy { export class FavoritesComponent extends PageComponent implements OnInit {
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
private subscriptions: Subscription[] = [];
sorting = [ 'modifiedAt', 'desc' ];
constructor(private router: Router, constructor(private router: Router,
private route: ActivatedRoute, route: ActivatedRoute,
private nodesApi: NodesApiService, private nodesApi: NodesApiService,
private contentService: ContentService, private contentService: ContentService,
private content: ContentManagementService, private content: ContentManagementService,
private notificationService: NotificationService, private notificationService: NotificationService,
public permission: NodePermissionService, public permission: NodePermissionService,
preferences: UserPreferencesService) { preferences: UserPreferencesService) {
super(preferences); super(preferences, route);
const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt';
const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
ngOnInit() { ngOnInit() {
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodeDeleted.subscribe(() => this.refresh()), this.content.nodeDeleted.subscribe(() => this.reload()),
this.content.nodeRestored.subscribe(() => this.refresh()), this.content.nodeRestored.subscribe(() => this.reload()),
this.contentService.folderEdit.subscribe(() => this.refresh()), this.contentService.folderEdit.subscribe(() => this.reload()),
this.content.nodeMoved.subscribe(() => this.refresh()) this.content.nodeMoved.subscribe(() => this.reload())
]); ]);
} }
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
}
navigate(favorite: MinimalNodeEntryEntity) { navigate(favorite: MinimalNodeEntryEntity) {
const { isFolder, id } = favorite; const { isFolder, id } = favorite;
@@ -110,25 +91,10 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr
return selection && selection.length === 1 && selection[0].entry.isFolder; return selection && selection.length === 1 && selection[0].entry.isFolder;
} }
refresh(): void {
if (this.documentList) {
this.documentList.reload();
}
}
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
openSnackMessage(event: any) { openSnackMessage(event: any) {
this.notificationService.openSnackMessage( this.notificationService.openSnackMessage(
event, event,
4000 4000
); );
} }
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -109,14 +109,13 @@
[disabled]="!permission.check(node, ['create'])"> [disabled]="!permission.check(node, ['create'])">
<adf-document-list #documentList <adf-document-list #documentList
[sorting]="[ 'modifiedAt', 'desc' ]"
[acaSortingPreferenceKey]="sortingPreferenceKey"
selectionMode="multiple" selectionMode="multiple"
[currentFolderId]="node?.id" [currentFolderId]="node?.id"
[sorting]="sorting"
[allowDropFiles]="true" [allowDropFiles]="true"
[navigate]="false" [navigate]="false"
[imageResolver]="imageResolver" [imageResolver]="imageResolver"
(sorting-changed)="onSortingChanged($event)"
(node-dblclick)="onNodeDoubleClick($event)" (node-dblclick)="onNodeDoubleClick($event)"
(node-select)="onNodeSelect($event, documentList)"> (node-select)="onNodeSelect($event, documentList)">

View File

@@ -62,7 +62,6 @@ describe('FilesComponent', () => {
let router: Router; let router: Router;
let browsingFilesService: BrowsingFilesService; let browsingFilesService: BrowsingFilesService;
let nodeActionsService: NodeActionsService; let nodeActionsService: NodeActionsService;
let preferenceService: UserPreferencesService;
let notificationService: NotificationService; let notificationService: NotificationService;
beforeEach(async(() => { beforeEach(async(() => {
@@ -89,8 +88,8 @@ describe('FilesComponent', () => {
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: { { provide: ActivatedRoute, useValue: {
params: Observable.of({ folderId: 'someId' }), snapshot: { data: { preferencePrefix: 'prefix' } },
snapshot: { data: { preferencePrefix: 'prefix' } } params: Observable.of({ folderId: 'someId' })
} } , } } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
@@ -125,7 +124,6 @@ describe('FilesComponent', () => {
browsingFilesService = TestBed.get(BrowsingFilesService); browsingFilesService = TestBed.get(BrowsingFilesService);
notificationService = TestBed.get(NotificationService); notificationService = TestBed.get(NotificationService);
nodeActionsService = TestBed.get(NodeActionsService); nodeActionsService = TestBed.get(NodeActionsService);
preferenceService = TestBed.get(UserPreferencesService);
}); });
})); }));
@@ -454,37 +452,6 @@ describe('FilesComponent', () => {
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
describe('openSnackMessage', () => { describe('openSnackMessage', () => {
it('should call notification service', () => { it('should call notification service', () => {
const message = 'notification message'; const message = 'notification message';

View File

@@ -23,8 +23,8 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Observable, Subscription } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router'; import { Router, ActivatedRoute, Params } from '@angular/router';
import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElementEntity, NodePaging, PathElement } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElementEntity, NodePaging, PathElement } from 'alfresco-js-api';
import { import {
@@ -32,8 +32,6 @@ import {
ContentService, AlfrescoApiService, UserPreferencesService, NotificationService ContentService, AlfrescoApiService, UserPreferencesService, NotificationService
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { BrowsingFilesService } from '../../common/services/browsing-files.service';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { NodeActionsService } from '../../common/services/node-actions.service'; import { NodeActionsService } from '../../common/services/node-actions.service';
@@ -45,17 +43,13 @@ import { PageComponent } from '../page.component';
templateUrl: './files.component.html' templateUrl: './files.component.html'
}) })
export class FilesComponent extends PageComponent implements OnInit, OnDestroy { export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
@ViewChild(DocumentListComponent) documentList: DocumentListComponent;
isValidPath = true; isValidPath = true;
private nodePath: PathElement[]; private nodePath: PathElement[];
private subscriptions: Subscription[] = [];
sorting = [ 'modifiedAt', 'desc' ];
constructor(private router: Router, constructor(private router: Router,
private route: ActivatedRoute, route: ActivatedRoute,
private nodesApi: NodesApiService, private nodesApi: NodesApiService,
private nodeActionsService: NodeActionsService, private nodeActionsService: NodeActionsService,
private uploadService: UploadService, private uploadService: UploadService,
@@ -66,12 +60,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
private notificationService: NotificationService, private notificationService: NotificationService,
public permission: NodePermissionService, public permission: NodePermissionService,
preferences: UserPreferencesService) { preferences: UserPreferencesService) {
super(preferences); super(preferences, route);
const sortingKey = this.preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt';
const sortingDirection = this.preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
ngOnInit() { ngOnInit() {
@@ -116,8 +105,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
} }
ngOnDestroy() { ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe()); super.ngOnDestroy();
this.browsingFilesService.onChangeParent.next(null); this.browsingFilesService.onChangeParent.next(null);
} }
@@ -269,19 +257,10 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
return false; return false;
} }
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
openSnackMessage(event: any) { openSnackMessage(event: any) {
this.notificationService.openSnackMessage( this.notificationService.openSnackMessage(
event, event,
4000 4000
); );
} }
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -12,8 +12,8 @@
currentFolderId="-mysites-" currentFolderId="-mysites-"
selectionMode="none" selectionMode="none"
[navigate]="false" [navigate]="false"
[sorting]="sorting" [sorting]="[ 'title', 'asc' ]"
(sorting-changed)="onSortingChanged($event)" [acaSortingPreferenceKey]="sortingPreferenceKey"
(node-dblclick)="onNodeDoubleClick($event)"> (node-dblclick)="onNodeDoubleClick($event)">
<empty-folder-content> <empty-folder-content>

View File

@@ -23,10 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { TestBed, async } from '@angular/core/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { import {
@@ -46,12 +46,11 @@ import { ShareDataTableAdapter } from '@alfresco/adf-content-services';
import { LibrariesComponent } from './libraries.component'; import { LibrariesComponent } from './libraries.component';
describe('Libraries Routed Component', () => { describe('Libraries Routed Component', () => {
let fixture; let fixture: ComponentFixture<LibrariesComponent>;
let component: LibrariesComponent; let component: LibrariesComponent;
let nodesApi: NodesApiService; let nodesApi: NodesApiService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let router: Router; let router: Router;
let preferenceService: UserPreferencesService;
let page; let page;
let node; let node;
@@ -91,9 +90,6 @@ describe('Libraries Routed Component', () => {
AppConfigPipe AppConfigPipe
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: {
snapshot: { data: { preferencePrefix: 'prefix' } }
} } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
UserPreferencesService, UserPreferencesService,
@@ -117,7 +113,6 @@ describe('Libraries Routed Component', () => {
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
router = TestBed.get(Router); router = TestBed.get(Router);
preferenceService = TestBed.get(UserPreferencesService);
}); });
})); }));
@@ -230,35 +225,4 @@ describe('Libraries Routed Component', () => {
expect(component.navigate).not.toHaveBeenCalled(); expect(component.navigate).not.toHaveBeenCalled();
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
}); });

View File

@@ -23,10 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Component, ViewChild } from '@angular/core'; import { Component } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { NodesApiService, UserPreferencesService } from '@alfresco/adf-core'; import { NodesApiService, UserPreferencesService } from '@alfresco/adf-core';
import { DocumentListComponent, ShareDataRow } from '@alfresco/adf-content-services'; import { ShareDataRow } from '@alfresco/adf-content-services';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
@@ -35,21 +35,11 @@ import { PageComponent } from '../page.component';
}) })
export class LibrariesComponent extends PageComponent { export class LibrariesComponent extends PageComponent {
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
sorting = [ 'title', 'asc' ];
constructor(private nodesApi: NodesApiService, constructor(private nodesApi: NodesApiService,
private route: ActivatedRoute, route: ActivatedRoute,
private router: Router, private router: Router,
preferences: UserPreferencesService) { preferences: UserPreferencesService) {
super(preferences); super(preferences, route);
const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'title';
const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
makeLibraryTooltip(library: any): string { makeLibraryTooltip(library: any): string {
@@ -92,13 +82,4 @@ export class LibrariesComponent extends PageComponent {
}); });
} }
} }
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -29,7 +29,7 @@ class TestClass extends PageComponent {
node: any; node: any;
constructor() { constructor() {
super(null); super(null, null);
} }
} }

View File

@@ -25,18 +25,36 @@
import { MinimalNodeEntity, MinimalNodeEntryEntity, Pagination } from 'alfresco-js-api'; import { MinimalNodeEntity, MinimalNodeEntryEntity, Pagination } from 'alfresco-js-api';
import { UserPreferencesService } from '@alfresco/adf-core'; import { UserPreferencesService } from '@alfresco/adf-core';
import { ShareDataRow } from '@alfresco/adf-content-services'; import { ShareDataRow, DocumentListComponent } from '@alfresco/adf-content-services';
import { ActivatedRoute } from '@angular/router';
import { OnDestroy, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs/Rx';
export abstract class PageComponent implements OnDestroy {
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
export abstract class PageComponent {
title = 'Page'; title = 'Page';
infoDrawerOpened = false; infoDrawerOpened = false;
node: MinimalNodeEntryEntity; node: MinimalNodeEntryEntity;
protected subscriptions: Subscription[] = [];
get sortingPreferenceKey(): string {
return this.route.snapshot.data.sortingPreferenceKey;
}
static isLockedNode(node) { static isLockedNode(node) {
return node.isLocked || (node.properties && node.properties['cm:lockType'] === 'READ_ONLY_LOCK'); return node.isLocked || (node.properties && node.properties['cm:lockType'] === 'READ_ONLY_LOCK');
} }
constructor(protected preferences: UserPreferencesService) { constructor(protected preferences: UserPreferencesService, protected route: ActivatedRoute) {
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
} }
getParentNodeId(): string { getParentNodeId(): string {
@@ -121,4 +139,11 @@ export abstract class PageComponent {
this.infoDrawerOpened = !this.infoDrawerOpened; this.infoDrawerOpened = !this.infoDrawerOpened;
} }
reload(): void {
if (this.documentList) {
this.documentList.resetSelection();
this.documentList.reload();
}
}
} }

View File

@@ -91,9 +91,9 @@
currentFolderId="-recent-" currentFolderId="-recent-"
selectionMode="multiple" selectionMode="multiple"
[navigate]="false" [navigate]="false"
[sorting]="sorting" [sorting]="[ 'modifiedAt', 'desc' ]"
[acaSortingPreferenceKey]="sortingPreferenceKey"
[imageResolver]="imageResolver" [imageResolver]="imageResolver"
(sorting-changed)="onSortingChanged($event)"
(node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)" (node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)"
(node-select)="onNodeSelect($event, documentList)"> (node-select)="onNodeSelect($event, documentList)">

View File

@@ -23,9 +23,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { TestBed, async } from '@angular/core/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { import {
@@ -47,12 +47,11 @@ import { NodePermissionService } from '../../common/services/node-permission.ser
import { RecentFilesComponent } from './recent-files.component'; import { RecentFilesComponent } from './recent-files.component';
describe('RecentFiles Routed Component', () => { describe('RecentFiles Routed Component', () => {
let fixture; let fixture: ComponentFixture<RecentFilesComponent>;
let component; let component: RecentFilesComponent;
let router: Router; let router: Router;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService; let contentService: ContentManagementService;
let preferenceService: UserPreferencesService;
let page; let page;
beforeEach(() => { beforeEach(() => {
@@ -85,9 +84,6 @@ describe('RecentFiles Routed Component', () => {
AppConfigPipe AppConfigPipe
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: {
snapshot: { data: { preferencePrefix: 'prefix' } }
} } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
UserPreferencesService, UserPreferencesService,
@@ -111,7 +107,6 @@ describe('RecentFiles Routed Component', () => {
router = TestBed.get(Router); router = TestBed.get(Router);
contentService = TestBed.get(ContentManagementService); contentService = TestBed.get(ContentManagementService);
preferenceService = TestBed.get(UserPreferencesService);
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
}); });
@@ -127,7 +122,7 @@ describe('RecentFiles Routed Component', () => {
describe('OnInit()', () => { describe('OnInit()', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'refresh').and.stub(); spyOn(component, 'reload').and.stub();
}); });
it('should reload nodes on onDeleteNode event', () => { it('should reload nodes on onDeleteNode event', () => {
@@ -135,7 +130,7 @@ describe('RecentFiles Routed Component', () => {
contentService.nodeDeleted.next(); contentService.nodeDeleted.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should reload on onRestoreNode event', () => { it('should reload on onRestoreNode event', () => {
@@ -143,7 +138,7 @@ describe('RecentFiles Routed Component', () => {
contentService.nodeRestored.next(); contentService.nodeRestored.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should reload on move node event', () => { it('should reload on move node event', () => {
@@ -151,7 +146,7 @@ describe('RecentFiles Routed Component', () => {
contentService.nodeMoved.next(); contentService.nodeMoved.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
@@ -182,40 +177,9 @@ describe('RecentFiles Routed Component', () => {
spyOn(component.documentList, 'reload'); spyOn(component.documentList, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.refresh(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.documentList.reload).toHaveBeenCalled();
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
}); });

View File

@@ -23,12 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Subscription } from 'rxjs/Rx'; import { Component, OnInit } from '@angular/core';
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { MinimalNodeEntryEntity } from 'alfresco-js-api'; import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { UserPreferencesService } from '@alfresco/adf-core'; import { UserPreferencesService } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { PageComponent } from '../page.component'; import { PageComponent } from '../page.component';
@@ -37,41 +35,25 @@ import { NodePermissionService } from '../../common/services/node-permission.ser
@Component({ @Component({
templateUrl: './recent-files.component.html' templateUrl: './recent-files.component.html'
}) })
export class RecentFilesComponent extends PageComponent implements OnInit, OnDestroy { export class RecentFilesComponent extends PageComponent implements OnInit {
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
private subscriptions: Subscription[] = [];
sorting = [ 'modifiedAt', 'desc' ];
constructor( constructor(
private router: Router, private router: Router,
private route: ActivatedRoute, route: ActivatedRoute,
private content: ContentManagementService, private content: ContentManagementService,
public permission: NodePermissionService, public permission: NodePermissionService,
preferences: UserPreferencesService) { preferences: UserPreferencesService) {
super(preferences); super(preferences, route);
const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt';
const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
ngOnInit() { ngOnInit() {
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodeDeleted.subscribe(() => this.refresh()), this.content.nodeDeleted.subscribe(() => this.reload()),
this.content.nodeMoved.subscribe(() => this.refresh()), this.content.nodeMoved.subscribe(() => this.reload()),
this.content.nodeRestored.subscribe(() => this.refresh()) this.content.nodeRestored.subscribe(() => this.reload())
]); ]);
} }
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
}
onNodeDoubleClick(node: MinimalNodeEntryEntity) { onNodeDoubleClick(node: MinimalNodeEntryEntity) {
if (node && PageComponent.isLockedNode(node)) { if (node && PageComponent.isLockedNode(node)) {
event.preventDefault(); event.preventDefault();
@@ -80,19 +62,4 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes
this.router.navigate(['./preview', node.id], { relativeTo: this.route }); this.router.navigate(['./preview', node.id], { relativeTo: this.route });
} }
} }
refresh(): void {
if (this.documentList) {
this.documentList.reload();
}
}
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -98,8 +98,8 @@
<adf-document-list #documentList <adf-document-list #documentList
currentFolderId="-sharedlinks-" currentFolderId="-sharedlinks-"
selectionMode="multiple" selectionMode="multiple"
[sorting]="sorting" [sorting]="[ 'modifiedAt', 'desc' ]"
(sorting-changed)="onSortingChanged($event)" [acaSortingPreferenceKey]="sortingPreferenceKey"
(node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)"> (node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)">
<empty-folder-content> <empty-folder-content>

View File

@@ -23,9 +23,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { TestBed, async, fakeAsync, tick } from '@angular/core/testing'; import { TestBed, async, fakeAsync, tick, ComponentFixture } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { import {
@@ -47,12 +47,11 @@ import { NodePermissionService } from '../../common/services/node-permission.ser
import { SharedFilesComponent } from './shared-files.component'; import { SharedFilesComponent } from './shared-files.component';
describe('SharedFilesComponent', () => { describe('SharedFilesComponent', () => {
let fixture; let fixture: ComponentFixture<SharedFilesComponent>;
let component: SharedFilesComponent; let component: SharedFilesComponent;
let contentService: ContentManagementService; let contentService: ContentManagementService;
let nodeService; let nodeService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let preferenceService: UserPreferencesService;
let router: Router; let router: Router;
let page; let page;
@@ -87,9 +86,6 @@ describe('SharedFilesComponent', () => {
AppConfigPipe AppConfigPipe
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: {
snapshot: { data: { preferencePrefix: 'prefix' } }
} } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
UserPreferencesService, UserPreferencesService,
@@ -116,7 +112,6 @@ describe('SharedFilesComponent', () => {
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
nodeService = alfrescoApi.getInstance().nodes; nodeService = alfrescoApi.getInstance().nodes;
preferenceService = TestBed.get(UserPreferencesService);
router = TestBed.get(Router); router = TestBed.get(Router);
}); });
@@ -128,7 +123,7 @@ describe('SharedFilesComponent', () => {
describe('OnInit', () => { describe('OnInit', () => {
beforeEach(() => { beforeEach(() => {
spyOn(component, 'refresh').and.callFake(val => val); spyOn(component, 'reload').and.callFake(val => val);
}); });
it('should refresh on deleteNode event', () => { it('should refresh on deleteNode event', () => {
@@ -136,7 +131,7 @@ describe('SharedFilesComponent', () => {
contentService.nodeDeleted.next(); contentService.nodeDeleted.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should refresh on restoreNode event', () => { it('should refresh on restoreNode event', () => {
@@ -144,7 +139,7 @@ describe('SharedFilesComponent', () => {
contentService.nodeRestored.next(); contentService.nodeRestored.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should reload on move node event', () => { it('should reload on move node event', () => {
@@ -152,7 +147,7 @@ describe('SharedFilesComponent', () => {
contentService.nodeMoved.next(); contentService.nodeMoved.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
@@ -199,40 +194,9 @@ describe('SharedFilesComponent', () => {
spyOn(component.documentList, 'reload'); spyOn(component.documentList, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.refresh(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.documentList.reload).toHaveBeenCalled();
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
}); });

View File

@@ -23,12 +23,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { NodePermissionService } from '../../common/services/node-permission.service'; import { NodePermissionService } from '../../common/services/node-permission.service';
@@ -37,41 +35,25 @@ import { PageComponent } from '../page.component';
@Component({ @Component({
templateUrl: './shared-files.component.html' templateUrl: './shared-files.component.html'
}) })
export class SharedFilesComponent extends PageComponent implements OnInit, OnDestroy { export class SharedFilesComponent extends PageComponent implements OnInit {
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
private subscriptions: Subscription[] = [];
sorting = [ 'modifiedAt', 'desc' ];
constructor(private router: Router, constructor(private router: Router,
private route: ActivatedRoute, route: ActivatedRoute,
private content: ContentManagementService, private content: ContentManagementService,
private apiService: AlfrescoApiService, private apiService: AlfrescoApiService,
public permission: NodePermissionService, public permission: NodePermissionService,
preferences: UserPreferencesService) { preferences: UserPreferencesService) {
super(preferences); super(preferences, route);
const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt';
const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
ngOnInit() { ngOnInit() {
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodeDeleted.subscribe(() => this.refresh()), this.content.nodeDeleted.subscribe(() => this.reload()),
this.content.nodeMoved.subscribe(() => this.refresh()), this.content.nodeMoved.subscribe(() => this.reload()),
this.content.nodeRestored.subscribe(() => this.refresh()) this.content.nodeRestored.subscribe(() => this.reload())
]); ]);
} }
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
}
onNodeDoubleClick(link: { nodeId?: string }) { onNodeDoubleClick(link: { nodeId?: string }) {
if (link && link.nodeId) { if (link && link.nodeId) {
this.apiService.nodesApi.getNode(link.nodeId).then( this.apiService.nodesApi.getNode(link.nodeId).then(
@@ -88,20 +70,4 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes
isFileSelected(selection: Array<MinimalNodeEntity>): boolean { isFileSelected(selection: Array<MinimalNodeEntity>): boolean {
return selection && selection.length === 1; return selection && selection.length === 1;
} }
refresh(): void {
if (this.documentList) {
this.documentList.resetSelection();
this.documentList.reload();
}
}
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -32,8 +32,8 @@
currentFolderId="-trashcan-" currentFolderId="-trashcan-"
selectionMode="multiple" selectionMode="multiple"
[navigate]="false" [navigate]="false"
[sorting]="sorting" [sorting]="[ 'archivedAt', 'desc' ]"
(sorting-changed)="onSortingChanged($event)"> [acaSortingPreferenceKey]="sortingPreferenceKey">
<empty-folder-content> <empty-folder-content>
<ng-template> <ng-template>

View File

@@ -23,10 +23,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { TestBed, async } from '@angular/core/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { import {
NotificationService, TranslationService, TranslationMock, NotificationService, TranslationService, TranslationMock,
NodesApiService, AlfrescoApiService, ContentService, NodesApiService, AlfrescoApiService, ContentService,
@@ -46,11 +45,10 @@ import { NodeInfoDirective } from '../../common/directives/node-info.directive';
import { TrashcanComponent } from './trashcan.component'; import { TrashcanComponent } from './trashcan.component';
describe('TrashcanComponent', () => { describe('TrashcanComponent', () => {
let fixture; let fixture: ComponentFixture<TrashcanComponent>;
let component; let component: TrashcanComponent;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService; let contentService: ContentManagementService;
let preferenceService: UserPreferencesService;
let page; let page;
beforeEach(() => { beforeEach(() => {
@@ -83,9 +81,6 @@ describe('TrashcanComponent', () => {
AppConfigPipe AppConfigPipe
], ],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: {
snapshot: { data: { preferencePrefix: 'prefix' } }
} } ,
{ provide: TranslationService, useClass: TranslationMock }, { provide: TranslationService, useClass: TranslationMock },
AuthenticationService, AuthenticationService,
UserPreferencesService, UserPreferencesService,
@@ -110,9 +105,8 @@ describe('TrashcanComponent', () => {
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
contentService = TestBed.get(ContentManagementService); contentService = TestBed.get(ContentManagementService);
preferenceService = TestBed.get(UserPreferencesService);
component.documentList = { component.documentList = <any> {
reload: jasmine.createSpy('reload'), reload: jasmine.createSpy('reload'),
resetSelection: jasmine.createSpy('resetSelection') resetSelection: jasmine.createSpy('resetSelection')
}; };
@@ -125,55 +119,24 @@ describe('TrashcanComponent', () => {
describe('onRestoreNode()', () => { describe('onRestoreNode()', () => {
it('should call refresh()', () => { it('should call refresh()', () => {
spyOn(component, 'refresh'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
contentService.nodeRestored.next(); contentService.nodeRestored.next();
expect(component.refresh).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
describe('refresh()', () => { describe('refresh()', () => {
it('calls child component to reload', () => { it('calls child component to reload', () => {
component.refresh(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.documentList.reload).toHaveBeenCalled();
}); });
it('calls child component to reset selection', () => { it('calls child component to reset selection', () => {
component.refresh(); component.reload();
expect(component.documentList.resetSelection).toHaveBeenCalled(); expect(component.documentList.resetSelection).toHaveBeenCalled();
}); });
}); });
describe('onSortingChanged', () => {
it('should save sorting input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {
key: 'some-name',
direction: 'some-direction'
}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction');
});
it('should save default sorting when no input', () => {
spyOn(preferenceService, 'set');
const event = <any>{
detail: {}
};
component.onSortingChanged(event);
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'archivedAt');
expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc');
});
});
}); });

View File

@@ -23,57 +23,31 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx';
import { Pagination } from 'alfresco-js-api'; import { Pagination } from 'alfresco-js-api';
import { UserPreferencesService } from '@alfresco/adf-core'; import { UserPreferencesService } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../common/services/content-management.service'; import { ContentManagementService } from '../../common/services/content-management.service';
import { PageComponent } from '../page.component';
@Component({ @Component({
templateUrl: './trashcan.component.html' templateUrl: './trashcan.component.html'
}) })
export class TrashcanComponent implements OnInit, OnDestroy { export class TrashcanComponent extends PageComponent implements OnInit {
private subscriptions: Subscription[] = [];
@ViewChild(DocumentListComponent) documentList;
sorting = [ 'archivedAt', 'desc' ];
constructor(private contentManagementService: ContentManagementService, constructor(private contentManagementService: ContentManagementService,
private preferences: UserPreferencesService, preferences: UserPreferencesService,
private route: ActivatedRoute) { route: ActivatedRoute) {
super(preferences, route);
const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'archivedAt';
const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc';
this.sorting = [sortingKey, sortingDirection];
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.contentManagementService.nodeRestored.subscribe(() => this.refresh())); this.subscriptions.push(
} this.contentManagementService.nodeRestored.subscribe(() => this.reload())
);
refresh(): void {
this.documentList.reload();
this.documentList.resetSelection();
}
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
} }
onChangePageSize(event: Pagination): void { onChangePageSize(event: Pagination): void {
this.preferences.paginationSize = event.maxItems; this.preferences.paginationSize = event.maxItems;
} }
onSortingChanged(event: CustomEvent) {
this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'archivedAt');
this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc');
}
private get prefix() {
return this.route.snapshot.data.preferencePrefix;
}
} }

View File

@@ -0,0 +1,64 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2018 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, Input, OnInit, HostListener } from '@angular/core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { UserPreferencesService } from '@alfresco/adf-core';
@Directive({
selector: '[acaSortingPreferenceKey]',
})
export class SortingPreferenceKeyDirective implements OnInit {
// tslint:disable-next-line:no-input-rename
@Input('acaSortingPreferenceKey')
preferenceKey: string;
constructor(
private documentList: DocumentListComponent,
private userPreferencesService: UserPreferencesService) {
}
@HostListener('sorting-changed', ['$event'])
onSortingChanged(event: CustomEvent) {
if (this.preferenceKey) {
this.userPreferencesService.set(`${this.preferenceKey}.sorting.key`, event.detail.key);
this.userPreferencesService.set(`${this.preferenceKey}.sorting.direction`, event.detail.direction);
}
}
ngOnInit() {
if (this.preferenceKey) {
const current = this.documentList.sorting;
const key = this.userPreferencesService.get(`${this.preferenceKey}.sorting.key`, current[0]);
const direction = this.userPreferencesService.get(`${this.preferenceKey}.sorting.direction`, current[1]);
this.documentList.sorting = [key, direction];
// TODO: bug in ADF, the `sorting` binding is not updated when changed from code
this.documentList.data.setSorting({ key, direction });
}
}
}