mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
ACA-3426 - Search Headers for Document List (#5800)
* [ACA-3426] Move filter-menu inside search and renamed as search-header * [ACA-3426] adf-search-header removed from document-list and implemented in app-files * [ACA-3426] Allow custom header filters inside document-list * [ACA-3426] Decouple search from the document-list * [ACA-3409] NodePaging ouputed to the DL * [ACA-3426] - fixed injection for service * Dev baptiste aca 3430 (#5773) * [ACA-3430] Add style to filter and hide action buttons from facet widgets * [ACA-3430] Update eventEmitter created in the DL and create unit tests for the search-header Co-authored-by: BaptisteMahe <mahe.baptiste.19@gmail.com> * [ACA-3426] - added parent for service * [ACA-3426] - added parent for service - fixed method * [ACA-3426] Revert update EventEmitter inside DL * [ACA-3436] Use of the node input instead of nodeUpdate mehtod * [ACA-3426] Add clear behaviour to search-header * [ACA-3426] Remove useless update exposition * [ACA-3426] Update filter button styles and padding inside the filter menu * [ACA-3443] Propagate filters states through DL and datatable to avoid hiding the header * [ACA-3426] Refactor showHeader logic and use it for the filters * [ACA-3426] - fixed pagination for filter result * [ACA-3426] - fixed messed files after rebase * [ACA-3426] - added simplified config version * [ACA-3426] - enabling created by filter * [ACA-3426] Fix search-date-range apply method * [ACA-3426] Fix loading style and default showHeaderMode * [ACA-3426] Changed showHedaer default to always * [ACA-3426] - stabilised the feature and added injection token * [ACA-3426] Add unit test for showHeader new behaviour * [ACA-3426] Add documentation to search-header * [ACA-3426] - added parent filtering for special folders * [ACA-3426] - added unit test for search header * [ACA-3426] - fixed search fitler behavour * [ACA-3426] - fixed search result inject service * [ACA-3426] - fixed search result inject service for search sorting * [ACA-3426] - fixed title for matching selector * [ACA-3426] - fixed app config with missing search widget * Update search-header.component.md Co-authored-by: BaptisteMahe <mahe.baptiste.19@gmail.com> Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
This commit is contained in:
@@ -434,6 +434,176 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"search-headers": {
|
||||
"app:fields": [
|
||||
"cm:name",
|
||||
"cm:title",
|
||||
"cm:description",
|
||||
"ia:whatEvent",
|
||||
"ia:descriptionEvent",
|
||||
"lnk:title",
|
||||
"lnk:description",
|
||||
"TEXT",
|
||||
"TAG"
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"id": "queryName",
|
||||
"name": "Name",
|
||||
"columnKey": "name",
|
||||
"enabled": true,
|
||||
"expanded": true,
|
||||
"component": {
|
||||
"selector": "text",
|
||||
"settings": {
|
||||
"pattern": "cm:name:'(.*?)'",
|
||||
"field": "cm:name",
|
||||
"placeholder": "Enter the name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "checkList",
|
||||
"name": "Check List",
|
||||
"columnKey":"$thumbnail",
|
||||
"enabled": true,
|
||||
"component": {
|
||||
"selector": "check-list",
|
||||
"settings": {
|
||||
"pageSize": 5,
|
||||
"operator": "OR",
|
||||
"options": [
|
||||
{
|
||||
"name": "Folder",
|
||||
"value": "TYPE:'cm:folder'"
|
||||
},
|
||||
{
|
||||
"name": "Document",
|
||||
"value": "TYPE:'cm:content'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "contentSizeRange",
|
||||
"name": "Content Size (range)",
|
||||
"enabled": true,
|
||||
"component": {
|
||||
"selector": "number-range",
|
||||
"settings": {
|
||||
"field": "cm:content.size",
|
||||
"format": "[{FROM} TO {TO}]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "contentSize",
|
||||
"name": "SEARCH.CATEGORIES.SIZE",
|
||||
"columnKey":"content.sizeInBytes",
|
||||
"enabled": true,
|
||||
"component": {
|
||||
"selector": "check-list",
|
||||
"settings": {
|
||||
"options": [
|
||||
{
|
||||
"name": "Small",
|
||||
"value": "content.size:[0 TO 1048576>"
|
||||
},
|
||||
{
|
||||
"name": "Medium",
|
||||
"value": "content.size:[1048576 TO 52428800]"
|
||||
},
|
||||
{
|
||||
"name": "Large",
|
||||
"value": "content.size:<52428800 TO 524288000]"
|
||||
},
|
||||
{
|
||||
"name": "Huge",
|
||||
"value": "content.size:<524288000 TO MAX]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "createdDateRange",
|
||||
"name": "Created Date (range)",
|
||||
"columnKey": "createdAt",
|
||||
"enabled": true,
|
||||
"component": {
|
||||
"selector": "date-range",
|
||||
"settings": {
|
||||
"field": "cm:created",
|
||||
"dateFormat": "DD-MMM-YY",
|
||||
"maxDate": "today"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"highlight": {
|
||||
"prefix": " ",
|
||||
"postfix": " ",
|
||||
"mergeContiguous": true,
|
||||
"fields": [
|
||||
{
|
||||
"field": "cm:title"
|
||||
},
|
||||
{
|
||||
"field": "description",
|
||||
"prefix": "(",
|
||||
"postfix": ")"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sorting": {
|
||||
"options": [
|
||||
{
|
||||
"key": "name",
|
||||
"label": "Name",
|
||||
"type": "FIELD",
|
||||
"field": "cm:name",
|
||||
"ascending": true
|
||||
},
|
||||
{
|
||||
"key": "content.sizeInBytes",
|
||||
"label": "Size",
|
||||
"type": "FIELD",
|
||||
"field": "content.size",
|
||||
"ascending": true
|
||||
},
|
||||
{
|
||||
"key": "createdByUser",
|
||||
"label": "Author",
|
||||
"type": "FIELD",
|
||||
"field": "cm:creator",
|
||||
"ascending": true
|
||||
},
|
||||
{
|
||||
"key": "createdAt",
|
||||
"label": "Created",
|
||||
"type": "FIELD",
|
||||
"field": "cm:created",
|
||||
"ascending": true
|
||||
},
|
||||
{
|
||||
"key": "score",
|
||||
"label": "Relevance",
|
||||
"type": "FIELD",
|
||||
"field": "score",
|
||||
"ascending": false
|
||||
}
|
||||
],
|
||||
"defaults": [
|
||||
{
|
||||
"key": "score",
|
||||
"type": "FIELD",
|
||||
"field": "score",
|
||||
"ascending": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"size": 20,
|
||||
"supportedPageSizes": [
|
||||
|
@@ -102,6 +102,7 @@ import localePl from '@angular/common/locales/pl';
|
||||
import localeFi from '@angular/common/locales/fi';
|
||||
import localeDa from '@angular/common/locales/da';
|
||||
import localeSv from '@angular/common/locales/sv';
|
||||
import { FilteredSearchComponent } from './components/files/filtered-search.component';
|
||||
|
||||
registerLocaleData(localeFr);
|
||||
registerLocaleData(localeDe);
|
||||
@@ -158,6 +159,7 @@ registerLocaleData(localeSv);
|
||||
FormNodeViewerComponent,
|
||||
AppsViewComponent,
|
||||
FilesComponent,
|
||||
FilteredSearchComponent,
|
||||
FormComponent,
|
||||
FormListComponent,
|
||||
VersionManagerDialogAdapterComponent,
|
||||
|
@@ -59,6 +59,7 @@ import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/
|
||||
import { ConfirmDialogExampleComponent } from './components/confirm-dialog/confirm-dialog-example.component';
|
||||
import { DemoErrorComponent } from './components/error/demo-error.component';
|
||||
import { TaskHeaderCloudDemoComponent } from './components/cloud/task-header-cloud-demo.component';
|
||||
import { FilteredSearchComponent } from './components/files/filtered-search.component';
|
||||
export const appRoutes: Routes = [
|
||||
{ path: 'login', loadChildren: 'app/components/login/login.module#AppLoginModule' },
|
||||
{ path: 'logout', component: LogoutComponent },
|
||||
@@ -251,6 +252,21 @@ export const appRoutes: Routes = [
|
||||
component: FilesComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'filtered-search',
|
||||
component: FilteredSearchComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'filtered-search/:id',
|
||||
component: FilteredSearchComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'filtered-search/:id/display/:mode',
|
||||
component: FilteredSearchComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'extensions/document-list/presets',
|
||||
canActivate: [AuthGuardEcm],
|
||||
|
@@ -40,6 +40,7 @@ export class AppLayoutComponent implements OnInit, OnDestroy {
|
||||
]
|
||||
},
|
||||
{ href: '/files', icon: 'folder_open', title: 'APP_LAYOUT.CONTENT_SERVICES' },
|
||||
{ href: '/filtered-search', icon: 'rowing', title: 'APP_LAYOUT.FILTERED_SEARCH' },
|
||||
{ href: '/breadcrumb', icon: 'label', title: 'APP_LAYOUT.BREADCRUMB' },
|
||||
{ href: '/notifications', icon: 'alarm', title: 'APP_LAYOUT.NOTIFICATIONS' },
|
||||
{ href: '/card-view', icon: 'view_headline', title: 'APP_LAYOUT.CARD_VIEW' },
|
||||
|
@@ -244,6 +244,17 @@
|
||||
(folderChange)="onFolderChange($event)"
|
||||
(permissionError)="handlePermissionError($event)"
|
||||
(name-click)="documentList.onNodeDblClick($event.detail?.node)">
|
||||
<adf-custom-header-filter-template *ngIf="enableCustomHeaderFilter">
|
||||
<ng-template let-col>
|
||||
<adf-search-header [col]="col"
|
||||
[currentFolderNodeId]="currentFolderId"
|
||||
[maxItems]="pagination?.maxItems"
|
||||
[skipCount]="pagination?.skipCount"
|
||||
(update)="onFilterUpdate($event)"
|
||||
(clear)="onAllFilterCleared()">
|
||||
</adf-search-header>
|
||||
</ng-template>
|
||||
</adf-custom-header-filter-template>
|
||||
<adf-custom-no-permission-template *ngIf="enableCustomPermissionMessage">
|
||||
<h1>You don't have permissions</h1>
|
||||
</adf-custom-no-permission-template>
|
||||
|
@@ -28,7 +28,7 @@ import {
|
||||
AlfrescoApiService, AuthenticationService, AppConfigService, AppConfigValues, ContentService, TranslationService,
|
||||
FileUploadEvent, FolderCreatedEvent, LogService, NotificationService,
|
||||
UploadService, DataRow, UserPreferencesService,
|
||||
PaginationComponent, FormValues, DisplayMode, InfinitePaginationComponent, HighlightDirective,
|
||||
PaginationComponent, FormValues, DisplayMode, ShowHeaderMode, InfinitePaginationComponent, HighlightDirective,
|
||||
SharedLinksApiService
|
||||
} from '@alfresco/adf-core';
|
||||
|
||||
@@ -104,7 +104,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
showSettingsPanel = true;
|
||||
|
||||
@Input()
|
||||
showHeader = true;
|
||||
showHeader: string = ShowHeaderMode.Always;
|
||||
|
||||
@Input()
|
||||
selectionMode = 'multiple';
|
||||
@@ -157,6 +157,12 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input()
|
||||
searchTerm = '';
|
||||
|
||||
@Input()
|
||||
navigationRoute = '/files';
|
||||
|
||||
@Input()
|
||||
enableCustomHeaderFilter = false;
|
||||
|
||||
@Output()
|
||||
documentListReady: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@@ -195,10 +201,12 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
stickyHeader: boolean;
|
||||
warnOnMultipleUploads = false;
|
||||
thumbnails = false;
|
||||
|
||||
enableCustomPermissionMessage = false;
|
||||
enableMediumTimeFormat = false;
|
||||
displayEmptyMetadata = false;
|
||||
hyperlinkNavigation = false;
|
||||
filtersStates: any[] = [];
|
||||
|
||||
constructor(private notificationService: NotificationService,
|
||||
private uploadService: UploadService,
|
||||
@@ -361,7 +369,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
onFolderChange($event) {
|
||||
this.router.navigate(['/files', $event.value.id, 'display', this.displayMode]);
|
||||
this.router.navigate([this.navigationRoute, $event.value.id, 'display', this.displayMode]);
|
||||
}
|
||||
|
||||
handlePermissionError(event: any) {
|
||||
@@ -519,22 +527,32 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
onChangePageSize(event: Pagination): void {
|
||||
this.preference.paginationSize = event.maxItems;
|
||||
this.pagination.maxItems = event.maxItems;
|
||||
this.pagination.skipCount = event.skipCount;
|
||||
this.changedPageSize.emit(event);
|
||||
}
|
||||
|
||||
onChangePageNumber(event: Pagination): void {
|
||||
this.pagination.maxItems = event.maxItems;
|
||||
this.pagination.skipCount = event.skipCount;
|
||||
this.changedPageNumber.emit(event);
|
||||
}
|
||||
|
||||
onNextPage(event: Pagination): void {
|
||||
this.pagination.maxItems = event.maxItems;
|
||||
this.pagination.skipCount = event.skipCount;
|
||||
this.turnedNextPage.emit(event);
|
||||
}
|
||||
|
||||
loadNextBatch(event: Pagination): void {
|
||||
this.pagination.maxItems = event.maxItems;
|
||||
this.pagination.skipCount = event.skipCount;
|
||||
this.loadNext.emit(event);
|
||||
}
|
||||
|
||||
onPrevPage(event: Pagination): void {
|
||||
this.pagination.maxItems = event.maxItems;
|
||||
this.pagination.skipCount = event.skipCount;
|
||||
this.turnedPreviousPage.emit(event);
|
||||
}
|
||||
|
||||
@@ -630,4 +648,14 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
onFilterUpdate(newNodePaging: NodePaging) {
|
||||
this.nodeResult = newNodePaging;
|
||||
}
|
||||
|
||||
onAllFilterCleared() {
|
||||
this.documentList.node = null;
|
||||
this.documentList.reload();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
<app-files-component [sortingMode]="'server'"
|
||||
[showRecentFiles]="false"
|
||||
[showSitePicker]="true"
|
||||
[showSettingsPanel]="false"
|
||||
[navigationRoute]="navigationRoute"
|
||||
[currentFolderId]="currentFolderId"
|
||||
[enableCustomHeaderFilter]="true">
|
||||
</app-files-component>
|
@@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Optional } from '@angular/core';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN, SearchHeaderQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filtered-search-component',
|
||||
templateUrl: './filtered-search.component.html',
|
||||
providers: [{ provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchHeaderQueryBuilderService}]
|
||||
})
|
||||
export class FilteredSearchComponent {
|
||||
|
||||
navigationRoute = '/filtered-search';
|
||||
currentFolderId = '-my-';
|
||||
|
||||
constructor(@Optional() private route: ActivatedRoute) {
|
||||
if (this.route) {
|
||||
this.route.params.forEach((params: Params) => {
|
||||
if (params['id'] && this.currentFolderId !== params['id']) {
|
||||
this.currentFolderId = params['id'];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -15,10 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Optional, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, Optional, OnDestroy, Inject } from '@angular/core';
|
||||
import { Router, ActivatedRoute, Params } from '@angular/router';
|
||||
import { Pagination, ResultSetPaging } from '@alfresco/js-api';
|
||||
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { SearchQueryBuilderService, SEARCH_QUERY_SERVICE_TOKEN } from '@alfresco/adf-content-services';
|
||||
import { UserPreferencesService, SearchService, AppConfigService } from '@alfresco/adf-core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
@@ -27,7 +27,7 @@ import { takeUntil } from 'rxjs/operators';
|
||||
selector: 'app-search-result-component',
|
||||
templateUrl: './search-result.component.html',
|
||||
styleUrls: ['./search-result.component.scss'],
|
||||
providers: [SearchService, SearchQueryBuilderService]
|
||||
providers: [SearchService, { provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchQueryBuilderService}]
|
||||
})
|
||||
export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
|
||||
@@ -44,7 +44,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
constructor(public router: Router,
|
||||
private config: AppConfigService,
|
||||
private preferences: UserPreferencesService,
|
||||
private queryBuilder: SearchQueryBuilderService,
|
||||
@Inject(SEARCH_QUERY_SERVICE_TOKEN) private queryBuilder: SearchQueryBuilderService,
|
||||
@Optional() private route: ActivatedRoute) {
|
||||
queryBuilder.paging = {
|
||||
maxItems: this.preferences.paginationSize,
|
||||
|
Reference in New Issue
Block a user