mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-31 17:38:28 +00:00
[ACA-19] Library Search Results (#783)
* [ACA-19] libraries results page * [ACA-19] libraries search query builder service + trigger action on search option select * [ACA-19] remove sorting * [ACA-19] extension - set custom columns for search libraries results * [ACA-19] add role column * [ACA-19] adapt text * [ACA-19] reformat with Prettier * [ACA-19] fix unit tests * [ACA-19] reformat with Prettier * [ACA-19] some unit tests & code cleanup * [ACA-19] fix navigation * [ACA-19] remove duplicates * [ACA-19] unit test
This commit is contained in:
committed by
Denys Vuika
parent
cb3754e29d
commit
1e3136332e
@@ -26,8 +26,10 @@
|
||||
</app-search-input-control>
|
||||
<div id="search-options">
|
||||
<mat-checkbox *ngFor="let option of searchOptions"
|
||||
id="{{ option.id }}"
|
||||
[(ngModel)]="option.value"
|
||||
[disabled]="option.shouldDisable()"
|
||||
(change)="onOptionChange()"
|
||||
(click)="$event.stopPropagation()">
|
||||
{{ option.key | translate }}
|
||||
</mat-checkbox>
|
||||
|
@@ -37,6 +37,8 @@ import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { Actions, ofType } from '@ngrx/effects';
|
||||
import { SEARCH_BY_TERM, SearchByTermAction } from '../../../store/actions';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service';
|
||||
|
||||
describe('SearchInputComponent', () => {
|
||||
let fixture: ComponentFixture<SearchInputComponent>;
|
||||
@@ -47,7 +49,8 @@ describe('SearchInputComponent', () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [AppTestingModule],
|
||||
declarations: [SearchInputComponent],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
providers: [SearchQueryBuilderService, SearchLibrariesQueryBuilderService]
|
||||
})
|
||||
.compileComponents()
|
||||
.then(() => {
|
||||
|
@@ -38,6 +38,14 @@ import { Store } from '@ngrx/store';
|
||||
import { AppStore } from '../../../store/states/app.state';
|
||||
import { SearchByTermAction } from '../../../store/actions';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service';
|
||||
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
|
||||
export enum SearchOptionIds {
|
||||
Files = 'files',
|
||||
Folders = 'folders',
|
||||
Libraries = 'libraries'
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'aca-search-input',
|
||||
@@ -51,18 +59,21 @@ export class SearchInputComponent implements OnInit {
|
||||
navigationTimer: any;
|
||||
|
||||
searchedWord = null;
|
||||
searchOptions: any = [
|
||||
searchOptions: Array<any> = [
|
||||
{
|
||||
id: SearchOptionIds.Files,
|
||||
key: 'SEARCH.INPUT.FILES',
|
||||
value: false,
|
||||
shouldDisable: this.isLibrariesChecked.bind(this)
|
||||
},
|
||||
{
|
||||
id: SearchOptionIds.Folders,
|
||||
key: 'SEARCH.INPUT.FOLDERS',
|
||||
value: false,
|
||||
shouldDisable: this.isLibrariesChecked.bind(this)
|
||||
},
|
||||
{
|
||||
id: SearchOptionIds.Libraries,
|
||||
key: 'SEARCH.INPUT.LIBRARIES',
|
||||
value: false,
|
||||
shouldDisable: this.isContentChecked.bind(this)
|
||||
@@ -72,7 +83,12 @@ export class SearchInputComponent implements OnInit {
|
||||
@ViewChild('searchInputControl')
|
||||
searchInputControl: SearchInputControlComponent;
|
||||
|
||||
constructor(private router: Router, private store: Store<AppStore>) {}
|
||||
constructor(
|
||||
private librariesQueryBuilder: SearchLibrariesQueryBuilderService,
|
||||
private queryBuilder: SearchQueryBuilderService,
|
||||
private router: Router,
|
||||
private store: Store<AppStore>
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.showInputValue();
|
||||
@@ -89,7 +105,7 @@ export class SearchInputComponent implements OnInit {
|
||||
showInputValue() {
|
||||
this.searchedWord = '';
|
||||
|
||||
if (this.onSearchResults) {
|
||||
if (this.onSearchResults || this.onLibrariesSearchResults) {
|
||||
const urlTree: UrlTree = this.router.parseUrl(this.router.url);
|
||||
const urlSegmentGroup: UrlSegmentGroup =
|
||||
urlTree.root.children[PRIMARY_OUTLET];
|
||||
@@ -141,14 +157,57 @@ export class SearchInputComponent implements OnInit {
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
onOptionChange() {
|
||||
if (this.searchedWord) {
|
||||
if (this.isLibrariesChecked()) {
|
||||
if (this.onLibrariesSearchResults) {
|
||||
this.librariesQueryBuilder.update();
|
||||
} else {
|
||||
this.store.dispatch(
|
||||
new SearchByTermAction(this.searchedWord, this.searchOptions)
|
||||
);
|
||||
}
|
||||
} else if (this.isContentChecked()) {
|
||||
if (this.onSearchResults) {
|
||||
// TODO: send here data to this.queryBuilder to be able to search for files/folders
|
||||
this.queryBuilder.update();
|
||||
} else {
|
||||
this.store.dispatch(
|
||||
new SearchByTermAction(this.searchedWord, this.searchOptions)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get onLibrariesSearchResults() {
|
||||
return this.router.url.indexOf('/search-libraries') === 0;
|
||||
}
|
||||
|
||||
get onSearchResults() {
|
||||
return this.router.url.indexOf('/search') === 0;
|
||||
return (
|
||||
!this.onLibrariesSearchResults && this.router.url.indexOf('/search') === 0
|
||||
);
|
||||
}
|
||||
|
||||
isFilesChecked(): boolean {
|
||||
return this.isOptionChecked(SearchOptionIds.Files);
|
||||
}
|
||||
|
||||
isFoldersChecked(): boolean {
|
||||
return this.isOptionChecked(SearchOptionIds.Folders);
|
||||
}
|
||||
|
||||
isLibrariesChecked(): boolean {
|
||||
return this.searchOptions[2].value;
|
||||
return this.isOptionChecked(SearchOptionIds.Libraries);
|
||||
}
|
||||
|
||||
isOptionChecked(optionId: string): boolean {
|
||||
const libItem = this.searchOptions.find(item => item.id === optionId);
|
||||
return !!libItem && libItem.value;
|
||||
}
|
||||
|
||||
isContentChecked(): boolean {
|
||||
return this.searchOptions[0].value || this.searchOptions[1].value;
|
||||
return this.isFilesChecked() || this.isFoldersChecked();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 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 { TestBed } from '@angular/core/testing';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { SearchLibrariesQueryBuilderService } from './search-libraries-query-builder.service';
|
||||
|
||||
describe('SearchLibrariesQueryBuilderService', () => {
|
||||
let apiService: AlfrescoApiService;
|
||||
let builder: SearchLibrariesQueryBuilderService;
|
||||
let queriesApi;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [AppTestingModule]
|
||||
});
|
||||
|
||||
apiService = TestBed.get(AlfrescoApiService);
|
||||
apiService.reset();
|
||||
queriesApi = apiService.getInstance().core.queriesApi;
|
||||
builder = new SearchLibrariesQueryBuilderService(apiService);
|
||||
});
|
||||
|
||||
it('should have empty user query by default', () => {
|
||||
expect(builder.userQuery).toBe('');
|
||||
});
|
||||
|
||||
it('should trim user query value', () => {
|
||||
builder.userQuery = ' something ';
|
||||
expect(builder.userQuery).toEqual('something');
|
||||
});
|
||||
|
||||
it('should build query and raise an event on update', async () => {
|
||||
const query = {};
|
||||
spyOn(builder, 'buildQuery').and.returnValue(query);
|
||||
|
||||
let eventArgs = null;
|
||||
builder.updated.subscribe(args => (eventArgs = args));
|
||||
|
||||
await builder.update();
|
||||
expect(eventArgs).toBe(query);
|
||||
});
|
||||
|
||||
it('should build query and raise an event on execute', async () => {
|
||||
const data = {};
|
||||
spyOn(queriesApi, 'findSites').and.returnValue(Promise.resolve(data));
|
||||
|
||||
const query = {};
|
||||
spyOn(builder, 'buildQuery').and.returnValue(query);
|
||||
|
||||
let eventArgs = null;
|
||||
builder.executed.subscribe(args => (eventArgs = args));
|
||||
|
||||
await builder.execute();
|
||||
expect(eventArgs).toBe(data);
|
||||
});
|
||||
|
||||
it('should require a query fragment to build query', () => {
|
||||
const compiled = builder.buildQuery();
|
||||
expect(compiled).toBeNull();
|
||||
});
|
||||
|
||||
it('should build query when there is a useQuery value', () => {
|
||||
const searchedTerm = 'test';
|
||||
|
||||
builder.userQuery = searchedTerm;
|
||||
|
||||
const compiled = builder.buildQuery();
|
||||
expect(compiled.term).toBe(searchedTerm);
|
||||
});
|
||||
|
||||
it('should use pagination settings', () => {
|
||||
const searchedTerm = 'test';
|
||||
|
||||
builder.paging = { maxItems: 5, skipCount: 5 };
|
||||
builder.userQuery = searchedTerm;
|
||||
|
||||
const compiled = builder.buildQuery();
|
||||
expect(compiled.opts).toEqual({ maxItems: 5, skipCount: 5 });
|
||||
});
|
||||
});
|
@@ -0,0 +1,86 @@
|
||||
/*!
|
||||
* @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 { AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SitePaging } from 'alfresco-js-api';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SearchLibrariesQueryBuilderService {
|
||||
private _userQuery = '';
|
||||
|
||||
updated: Subject<any> = new Subject();
|
||||
executed: Subject<any> = new Subject();
|
||||
|
||||
paging: { maxItems?: number; skipCount?: number } = null;
|
||||
|
||||
get userQuery(): string {
|
||||
return this._userQuery;
|
||||
}
|
||||
|
||||
set userQuery(value: string) {
|
||||
this._userQuery = value ? value.trim() : '';
|
||||
}
|
||||
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {}
|
||||
|
||||
update(): void {
|
||||
const query = this.buildQuery();
|
||||
this.updated.next(query);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
const query = this.buildQuery();
|
||||
if (query) {
|
||||
const data = await this.findLibraries(query);
|
||||
this.executed.next(data);
|
||||
}
|
||||
}
|
||||
|
||||
buildQuery(): any {
|
||||
const query = this.userQuery;
|
||||
if (query) {
|
||||
const resultQuery = {
|
||||
term: query,
|
||||
opts: {
|
||||
skipCount: this.paging && this.paging.skipCount,
|
||||
maxItems: this.paging && this.paging.maxItems
|
||||
}
|
||||
};
|
||||
return resultQuery;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private findLibraries(libraryQuery: { term; opts }): Promise<SitePaging> {
|
||||
return this.alfrescoApiService
|
||||
.getInstance()
|
||||
.core.queriesApi.findSites(libraryQuery.term, libraryQuery.opts)
|
||||
.catch(() => ({ list: { pagination: { totalItems: 0 }, entries: [] } }));
|
||||
}
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
<app-page-layout>
|
||||
|
||||
<app-page-layout-header>
|
||||
<adf-breadcrumb root="APP.BROWSE.SEARCH_LIBRARIES.TITLE">
|
||||
</adf-breadcrumb>
|
||||
<adf-toolbar class="inline">
|
||||
<ng-container *ngFor="let entry of actions; trackBy: trackByActionId">
|
||||
<aca-toolbar-action [actionRef]="entry"></aca-toolbar-action>
|
||||
</ng-container>
|
||||
</adf-toolbar>
|
||||
</app-page-layout-header>
|
||||
|
||||
<app-page-layout-content>
|
||||
<div class="main-content">
|
||||
<div class="adf-search-results">
|
||||
<div class="adf-search-results__content">
|
||||
<mat-progress-bar
|
||||
*ngIf="isLoading"
|
||||
color="primary"
|
||||
mode="indeterminate">
|
||||
</mat-progress-bar>
|
||||
<div class="adf-search-results__content-header content" *ngIf="data?.list.entries.length">
|
||||
<div class="content__side--left">
|
||||
<div class="adf-search-results--info-text">{{ 'APP.BROWSE.SEARCH_LIBRARIES.FOUND_RESULTS' | translate: { number: totalResults } }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<adf-document-list
|
||||
#documentList
|
||||
acaDocumentList
|
||||
[showHeader]="true"
|
||||
[selectionMode]="'single'"
|
||||
[sorting]="[ 'name', 'asc' ]"
|
||||
[node]="data"
|
||||
(node-dblclick)="navigateTo($event.detail?.node)"
|
||||
(name-click)="navigateTo($event.detail?.node)">
|
||||
|
||||
<data-columns>
|
||||
<ng-container *ngFor="let column of columns; trackBy: trackById">
|
||||
|
||||
<ng-container *ngIf="column.template && !(column.desktopOnly && isSmallScreen)">
|
||||
<data-column
|
||||
[key]="column.key"
|
||||
[title]="column.title"
|
||||
[type]="column.type"
|
||||
[format]="column.format"
|
||||
[class]="column.class"
|
||||
[sortable]="column.sortable">
|
||||
<ng-template let-context>
|
||||
<app-dynamic-column
|
||||
[id]="column.template"
|
||||
[context]="context">
|
||||
</app-dynamic-column>
|
||||
</ng-template>
|
||||
</data-column>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!column.template && !(column.desktopOnly && isSmallScreen)">
|
||||
<data-column
|
||||
[key]="column.key"
|
||||
[title]="column.title"
|
||||
[type]="column.type"
|
||||
[format]="column.format"
|
||||
[class]="column.class"
|
||||
[sortable]="column.sortable">
|
||||
</data-column>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
</data-columns>
|
||||
|
||||
|
||||
<empty-folder-content>
|
||||
<ng-template>
|
||||
<ng-container *ngIf="data">
|
||||
<div class="empty-search__block">
|
||||
<p class="empty-search__text">
|
||||
{{ 'APP.BROWSE.SEARCH.NO_RESULTS' | translate }}
|
||||
</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</empty-folder-content>
|
||||
</adf-document-list>
|
||||
|
||||
<adf-pagination *ngIf="!documentList.isEmpty()"
|
||||
acaPagination
|
||||
[target]="documentList"
|
||||
(change)="onPaginationChanged($event)">
|
||||
</adf-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar" *ngIf="infoDrawerOpened$ | async">
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</app-page-layout-content>
|
||||
|
||||
</app-page-layout>
|
@@ -0,0 +1,42 @@
|
||||
@import 'mixins';
|
||||
|
||||
.adf-search-results {
|
||||
@include flex-row;
|
||||
|
||||
&__content {
|
||||
@include flex-column;
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
|
||||
&__content-header {
|
||||
display: flex;
|
||||
padding: 0 25px 0 25px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
&--info-text {
|
||||
flex: 1;
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.text--bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.content {
|
||||
@include flex-row;
|
||||
flex: unset;
|
||||
height: unset;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__side--left {
|
||||
@include flex-column;
|
||||
height: unset;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { AppConfigPipe, DataTableComponent } from '@alfresco/adf-core';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { SearchLibrariesResultsComponent } from './search-libraries-results.component';
|
||||
import { SearchLibrariesQueryBuilderService } from './search-libraries-query-builder.service';
|
||||
import { DocumentListComponent } from '@alfresco/adf-content-services';
|
||||
|
||||
describe('SearchLibrariesResultsComponent', () => {
|
||||
let component: SearchLibrariesResultsComponent;
|
||||
let fixture: ComponentFixture<SearchLibrariesResultsComponent>;
|
||||
|
||||
const emptyPage = { list: { pagination: { totalItems: 0 }, entries: [] } };
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [AppTestingModule],
|
||||
declarations: [
|
||||
DataTableComponent,
|
||||
DocumentListComponent,
|
||||
SearchLibrariesResultsComponent,
|
||||
AppConfigPipe
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
providers: [SearchLibrariesQueryBuilderService]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(SearchLibrariesResultsComponent);
|
||||
component = fixture.componentInstance;
|
||||
});
|
||||
|
||||
it('should show empty page by default', async () => {
|
||||
spyOn(component, 'onSearchResultLoaded').and.callThrough();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.onSearchResultLoaded).toHaveBeenCalledWith(emptyPage);
|
||||
});
|
||||
});
|
@@ -0,0 +1,148 @@
|
||||
/*!
|
||||
* @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 { Component, OnInit } from '@angular/core';
|
||||
import { NodePaging, Pagination, SiteEntry } from 'alfresco-js-api';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { PageComponent } from '../../page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppStore } from '../../../store/states/app.state';
|
||||
import { NavigateLibraryAction } from '../../../store/actions';
|
||||
import { AppExtensionService } from '../../../extensions/extension.service';
|
||||
import { ContentManagementService } from '../../../services/content-management.service';
|
||||
import { SearchLibrariesQueryBuilderService } from './search-libraries-query-builder.service';
|
||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||
|
||||
@Component({
|
||||
selector: 'aca-search-results',
|
||||
templateUrl: './search-libraries-results.component.html',
|
||||
styleUrls: ['./search-libraries-results.component.scss'],
|
||||
providers: [SearchLibrariesQueryBuilderService]
|
||||
})
|
||||
export class SearchLibrariesResultsComponent extends PageComponent
|
||||
implements OnInit {
|
||||
isSmallScreen = false;
|
||||
searchedWord: string;
|
||||
queryParamName = 'q';
|
||||
data: NodePaging;
|
||||
totalResults = 0;
|
||||
isLoading = false;
|
||||
columns: any[] = [];
|
||||
|
||||
constructor(
|
||||
private breakpointObserver: BreakpointObserver,
|
||||
private librariesQueryBuilder: SearchLibrariesQueryBuilderService,
|
||||
private route: ActivatedRoute,
|
||||
store: Store<AppStore>,
|
||||
extensions: AppExtensionService,
|
||||
content: ContentManagementService
|
||||
) {
|
||||
super(store, extensions, content);
|
||||
|
||||
librariesQueryBuilder.paging = {
|
||||
skipCount: 0,
|
||||
maxItems: 25
|
||||
};
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
|
||||
this.columns = this.extensions.documentListPresets.searchLibraries || [];
|
||||
|
||||
this.subscriptions.push(
|
||||
this.librariesQueryBuilder.updated.subscribe(() => {
|
||||
this.isLoading = true;
|
||||
|
||||
this.librariesQueryBuilder.execute();
|
||||
}),
|
||||
|
||||
this.librariesQueryBuilder.executed.subscribe(data => {
|
||||
this.librariesQueryBuilder.paging.skipCount = 0;
|
||||
|
||||
this.onSearchResultLoaded(data);
|
||||
this.isLoading = false;
|
||||
}),
|
||||
|
||||
this.breakpointObserver
|
||||
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
|
||||
.subscribe(result => {
|
||||
this.isSmallScreen = result.matches;
|
||||
})
|
||||
);
|
||||
|
||||
if (this.route) {
|
||||
this.route.params.forEach((params: Params) => {
|
||||
this.searchedWord = params.hasOwnProperty(this.queryParamName)
|
||||
? params[this.queryParamName]
|
||||
: null;
|
||||
const query = this.formatSearchQuery(this.searchedWord);
|
||||
|
||||
if (query && query.length > 1) {
|
||||
this.librariesQueryBuilder.userQuery = query;
|
||||
this.librariesQueryBuilder.update();
|
||||
} else {
|
||||
this.librariesQueryBuilder.userQuery = null;
|
||||
this.librariesQueryBuilder.executed.next({
|
||||
list: { pagination: { totalItems: 0 }, entries: [] }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private formatSearchQuery(userInput: string) {
|
||||
if (!userInput) {
|
||||
return null;
|
||||
}
|
||||
return userInput.trim();
|
||||
}
|
||||
|
||||
onSearchResultLoaded(nodePaging: NodePaging) {
|
||||
this.data = nodePaging;
|
||||
this.totalResults = this.getNumberOfResults();
|
||||
}
|
||||
|
||||
getNumberOfResults() {
|
||||
if (this.data && this.data.list && this.data.list.pagination) {
|
||||
return this.data.list.pagination.totalItems;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
onPaginationChanged(pagination: Pagination) {
|
||||
this.librariesQueryBuilder.paging = {
|
||||
maxItems: pagination.maxItems,
|
||||
skipCount: pagination.skipCount
|
||||
};
|
||||
this.librariesQueryBuilder.update();
|
||||
}
|
||||
|
||||
navigateTo(node: SiteEntry) {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
this.store.dispatch(new NavigateLibraryAction(node.entry.guid));
|
||||
}
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@ import { CoreModule } from '@alfresco/adf-core';
|
||||
import { ContentModule } from '@alfresco/adf-content-services';
|
||||
import { SearchResultsComponent } from './search-results/search-results.component';
|
||||
import { SearchResultsRowComponent } from './search-results-row/search-results-row.component';
|
||||
import { SearchLibrariesResultsComponent } from './search-libraries-results/search-libraries-results.component';
|
||||
import { AppInfoDrawerModule } from '../info-drawer/info.drawer.module';
|
||||
import { AppToolbarModule } from '../toolbar/toolbar.module';
|
||||
import { AppCommonModule } from '../common/common.module';
|
||||
@@ -46,7 +47,15 @@ import { AppLayoutModule } from '../layout/layout.module';
|
||||
DirectivesModule,
|
||||
AppLayoutModule
|
||||
],
|
||||
declarations: [SearchResultsComponent, SearchResultsRowComponent],
|
||||
exports: [SearchResultsComponent, SearchResultsRowComponent]
|
||||
declarations: [
|
||||
SearchResultsComponent,
|
||||
SearchLibrariesResultsComponent,
|
||||
SearchResultsRowComponent
|
||||
],
|
||||
exports: [
|
||||
SearchResultsComponent,
|
||||
SearchLibrariesResultsComponent,
|
||||
SearchResultsRowComponent
|
||||
]
|
||||
})
|
||||
export class AppSearchResultsModule {}
|
||||
|
Reference in New Issue
Block a user