[ACA-1379] Search Results Actions and Bulk Actions (#406)

* download actions and effects

* download multiple search results

* remove inline toolbar

* base page and toolbar for the Search results

* toolbar actions

* update search settings

* toggle favorites from search results

* manage versions dialog

* folder navigation

* sidebar integration

* remove obsolete style
This commit is contained in:
Denys Vuika
2018-06-13 14:21:09 +01:00
committed by GitHub
parent 6620600550
commit a849a215bb
9 changed files with 365 additions and 77 deletions

View File

@@ -2,6 +2,65 @@
<div class="inner-layout__header">
<adf-breadcrumb root="APP.BROWSE.SEARCH.TITLE">
</adf-breadcrumb>
<adf-toolbar class="inline" *ngIf="hasSelection">
<button
color="primary"
mat-icon-button
*ngIf="selectedFile"
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
(click)="showPreview(selectedFile)">
<mat-icon>open_in_browser</mat-icon>
</button>
<button
color="primary"
mat-icon-button
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
[acaDownloadNodes]="selectedNodes">
<mat-icon>get_app</mat-icon>
</button>
<button mat-icon-button
[color]="infoDrawerOpened ? 'accent' : 'primary'"
title="{{ 'APP.ACTIONS.DETAILS' | translate }}"
(click)="toggleSidebar()">
<mat-icon>info_outline</mat-icon>
</button>
<button
color="primary"
mat-icon-button
title="{{ 'APP.ACTIONS.MORE' | translate }}"
[matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu" [overlapTrigger]="false">
<button
mat-menu-item
#selection="adfFavorite"
[adf-node-favorite]="selectedNodes">
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
</button>
<button
mat-menu-item
[acaCopyNode]="selectedNodes">
<mat-icon>content_copy</mat-icon>
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
</button>
<button
mat-menu-item
*ngIf="selectedFile"
[acaNodeVersions]="selectedFile">
<mat-icon>history</mat-icon>
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
</button>
</mat-menu>
</adf-toolbar>
</div>
<div class="adf-search-results__facets">
@@ -11,77 +70,87 @@
<div class="inner-layout__content">
<adf-search
#search
[searchTerm]="searchedWord"
[maxResults]="maxItems"
[skipResults]="skipCount"
(resultLoaded)="onSearchResultLoaded($event)">
</adf-search>
<div class="adf-search-results">
<adf-search-filter #searchFilter></adf-search-filter>
<div class="inner-layout__panel">
<div class="adf-search-results">
<adf-search-filter #searchFilter></adf-search-filter>
<div class="adf-search-results__content">
<div class="adf-search-results__content-header" *ngIf="data?.list.entries.length">
<div class="adf-search-results--info-text">{{ 'APP.BROWSE.SEARCH.FOUND_RESULTS' | translate: { number: totalResults } }}</div>
<adf-search-sorting-picker></adf-search-sorting-picker>
<div class="adf-search-results__content">
<div class="adf-search-results__content-header" *ngIf="data?.list.entries.length">
<div class="adf-search-results--info-text">{{ 'APP.BROWSE.SEARCH.FOUND_RESULTS' | translate: { number: totalResults } }}</div>
<adf-search-sorting-picker></adf-search-sorting-picker>
</div>
<adf-document-list
#documentList
[showHeader]="false"
[selectionMode]="'multiple'"
[sortingMode]="'server'"
[sorting]="sorting"
[node]="data"
(node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)"
(ready)="onDocumentListReady($event, documentList)"
(node-select)="onNodeSelect($event, documentList)"
(node-unselect)="onNodeUnselect($event, documentList)">
<data-columns>
<data-column
[key]="'$thumbnail'"
[type]="'image'"
[sr-title]="'ADF-DOCUMENT-LIST.LAYOUT.THUMBNAIL'"
[sortable]="false">
</data-column>
<data-column
[key]="'name'"
[type]="'text'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.NAME'"
[class]="'full-width ellipsis-cell'"
[sortable]="false">
</data-column>
<data-column
[key]="'content.sizeInBytes'"
[type]="'fileSize'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.SIZE'"
[sortable]="false">
</data-column>
<data-column
[key]="'modifiedAt'"
[type]="'date'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.MODIFIED_ON'"
[format]="'timeAgo'"
[sortable]="false">
</data-column>
<data-column
[key]="'modifiedByUser.displayName'"
[type]="'text'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.MODIFIED_BY'"
[sortable]="false">
</data-column>
</data-columns>
<empty-folder-content>
<ng-template>
<div class="empty-search__block">
<p class="empty-search__text">Your search returned 0 results</p>
</div>
</ng-template>
</empty-folder-content>
</adf-document-list>
<adf-pagination *ngIf="!documentList.isEmpty()"
[target]="documentList"
(change)="onPaginationChanged($event)">
</adf-pagination>
</div>
<adf-document-list
#documentList
[showHeader]="false"
[sortingMode]="'server'"
[sorting]="sorting"
[node]="data"
(node-dblclick)="onNodeDoubleClick($event.detail?.node?.entry)">
<data-columns>
<data-column
[key]="'$thumbnail'"
[type]="'image'"
[sr-title]="'ADF-DOCUMENT-LIST.LAYOUT.THUMBNAIL'"
[sortable]="false">
</data-column>
<data-column
[key]="'name'"
[type]="'text'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.NAME'"
[class]="'full-width ellipsis-cell'"
[sortable]="false">
</data-column>
<data-column
[key]="'content.sizeInBytes'"
[type]="'fileSize'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.SIZE'"
[sortable]="false">
</data-column>
<data-column
[key]="'modifiedAt'"
[type]="'date'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.MODIFIED_ON'"
[format]="'timeAgo'"
[sortable]="false">
</data-column>
<data-column
[key]="'modifiedByUser.displayName'"
[type]="'text'"
[title]="'ADF-DOCUMENT-LIST.LAYOUT.MODIFIED_BY'"
[sortable]="false">
</data-column>
</data-columns>
<empty-folder-content>
<ng-template>
<div class="empty-search__block">
<p class="empty-search__text">Your search returned 0 results</p>
</div>
</ng-template>
</empty-folder-content>
</adf-document-list>
<adf-pagination *ngIf="!documentList.isEmpty()"
[target]="documentList"
(change)="onPaginationChanged($event)">
</adf-pagination>
</div>
</div>
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
</div>
</div>
</div>

View File

@@ -23,23 +23,28 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, OnInit, Optional, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MinimalNodeEntryEntity, NodePaging, Pagination } from 'alfresco-js-api';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { SearchQueryBuilderService, SearchComponent as AdfSearchComponent } from '@alfresco/adf-content-services';
import { SearchConfigurationService } from '@alfresco/adf-core';
import { SearchQueryBuilderService, SearchComponent as AdfSearchComponent, NodePermissionService } from '@alfresco/adf-content-services';
import { SearchConfigurationService, UserPreferencesService, SearchService } from '@alfresco/adf-core';
import { PageComponent } from '../page.component';
import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state';
import { NavigateToLocationAction } from '../../store/actions';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
styleUrls: ['./search.component.scss'],
providers: [SearchService]
})
export class SearchComponent implements OnInit {
export class SearchComponent extends PageComponent implements OnInit {
@ViewChild('search')
search: AdfSearchComponent;
searchedWord: string;
queryParamName = 'q';
data: NodePaging;
totalResults = 0;
@@ -48,10 +53,15 @@ export class SearchComponent implements OnInit {
sorting = ['name', 'asc'];
constructor(
public router: Router,
public permission: NodePermissionService,
private queryBuilder: SearchQueryBuilderService,
private searchConfiguration: SearchConfigurationService,
@Optional() private route: ActivatedRoute) {
store: Store<AppStore>,
router: Router,
preferences: UserPreferencesService,
route: ActivatedRoute) {
super(preferences, router, route, store);
queryBuilder.paging = {
skipCount: 0,
maxItems: 25
@@ -59,6 +69,8 @@ export class SearchComponent implements OnInit {
}
ngOnInit() {
super.ngOnInit();
this.sorting = this.getSorting();
this.queryBuilder.updated.subscribe(() => {
@@ -67,9 +79,9 @@ export class SearchComponent implements OnInit {
if (this.route) {
this.route.params.forEach((params: Params) => {
const searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
if (searchedWord) {
const queryBody = this.searchConfiguration.generateQueryBody(searchedWord, 0, 100);
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
if (this.searchedWord) {
const queryBody = this.searchConfiguration.generateQueryBody(this.searchedWord, 0, 100);
this.queryBuilder.userQuery = queryBody.query.query;
this.queryBuilder.update();
@@ -112,6 +124,10 @@ export class SearchComponent implements OnInit {
}
onNodeDoubleClick(node: MinimalNodeEntryEntity) {
if (node && node.isFolder) {
this.store.dispatch(new NavigateToLocationAction(node));
}
if (node && PageComponent.isLockedNode(node)) {
event.preventDefault();