[AAE-3405] - Optimise attach file widget UI (#6271)

* Optimise attach file widget UI

* Show filter button only when there are custom models
This commit is contained in:
arditdomi 2020-10-21 14:21:37 +01:00 committed by GitHub
parent dc8117711a
commit 2273dd7035
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 130 additions and 13 deletions

View File

@ -21,9 +21,6 @@
</mat-icon> </mat-icon>
</mat-form-field> </mat-form-field>
<adf-search-panel>
</adf-search-panel>
<adf-sites-dropdown <adf-sites-dropdown
*ngIf="showDropdownSiteList" *ngIf="showDropdownSiteList"
class="full-width" class="full-width"
@ -34,7 +31,17 @@
[value]="startSiteGuid" [value]="startSiteGuid"
data-automation-id="content-node-selector-sites-combo"> data-automation-id="content-node-selector-sites-combo">
</adf-sites-dropdown> </adf-sites-dropdown>
<button *ngIf="hasCustomModels()"
data-automation-id="adf-toggle-search-panel-button"
mat-icon-button
(click)="toggleSearchPanel()">
<mat-icon>filter_list</mat-icon>
{{ 'SEARCH.SEARCH_HEADER.TITLE' | translate }}
</button>
<div class="adf-content-node-selector-search-panel-container">
<adf-search-panel *ngIf="searchPanelExpanded">
</adf-search-panel>
<div class="adf-content-node-selector-document-list-container">
<adf-toolbar> <adf-toolbar>
<adf-toolbar-title> <adf-toolbar-title>
<ng-container *ngIf="!showBreadcrumbs()"> <ng-container *ngIf="!showBreadcrumbs()">
@ -106,3 +113,5 @@
</adf-infinite-pagination> </adf-infinite-pagination>
</div> </div>
</div> </div>
</div>
</div>

View File

@ -16,6 +16,14 @@
.adf-content-node-selector { .adf-content-node-selector {
&-search-panel-container {
display: flex;
}
&-document-list-container {
width: 100%;
}
&-content { &-content {
padding-top: 0; padding-top: 0;
@ -86,7 +94,7 @@
} }
&-list { &-list {
height: 200px; height: 300px;
overflow: auto; overflow: auto;
border: 1px solid mat-color($foreground, base, 0.07); border: 1px solid mat-color($foreground, base, 0.07);
border-top: 0; border-top: 0;

View File

@ -32,6 +32,8 @@ import { NodeEntryEvent, ShareDataRow } from '../document-list';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { SearchQueryBuilderService } from '../search'; import { SearchQueryBuilderService } from '../search';
import { mockQueryBody } from '../mock/search-query.mock'; import { mockQueryBody } from '../mock/search-query.mock';
import { ContentNodeSelectorPanelService } from './content-node-selector-panel.service';
import { mockContentModelProperty } from '../mock/content-model.mock';
const fakeResultSetPaging: ResultSetPaging = { const fakeResultSetPaging: ResultSetPaging = {
list: { list: {
@ -62,6 +64,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
const fakeNodeEntry = new Node({ id: 'fakeId' }); const fakeNodeEntry = new Node({ id: 'fakeId' });
const nodeEntryEvent = new NodeEntryEvent(fakeNodeEntry); const nodeEntryEvent = new NodeEntryEvent(fakeNodeEntry);
let searchQueryBuilderService: SearchQueryBuilderService; let searchQueryBuilderService: SearchQueryBuilderService;
let contentNodeSelectorPanelService: ContentNodeSelectorPanelService;
function typeToSearchBox(searchTerm = 'string-to-search') { function typeToSearchBox(searchTerm = 'string-to-search') {
const searchInput = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-input"]')); const searchInput = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-input"]'));
@ -91,6 +94,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
nodeService = TestBed.inject(NodesApiService); nodeService = TestBed.inject(NodesApiService);
sitesService = TestBed.inject(SitesService); sitesService = TestBed.inject(SitesService);
contentNodeSelectorPanelService = TestBed.inject(ContentNodeSelectorPanelService);
searchQueryBuilderService = component.queryBuilderService; searchQueryBuilderService = component.queryBuilderService;
spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node', path: { elements: [{ nodeType: 'st:site', name: 'fake-site'}] } })); spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node', path: { elements: [{ nodeType: 'st:site', name: 'fake-site'}] } }));
@ -1167,5 +1171,53 @@ describe('ContentNodeSelectorPanelComponent', () => {
}); });
}); });
describe('Search panel', () => {
beforeEach(() => {
contentNodeSelectorPanelService.customModels = undefined;
});
it ('should search panel be collapsed by default and expand when clicking the filter button', async() => {
contentNodeSelectorPanelService.customModels = [mockContentModelProperty];
fixture.detectChanges();
expect(component.searchPanelExpanded).toEqual(false);
const toggleFiltersPanelButton = fixture.debugElement.query(By.css('[data-automation-id="adf-toggle-search-panel-button"]'));
toggleFiltersPanelButton.nativeElement.click();
fixture.detectChanges();
await fixture.whenStable();
expect(component.searchPanelExpanded).toEqual(true);
});
it ('should search panel be present when the filter section is expanded', () => {
component.searchPanelExpanded = true;
fixture.detectChanges();
const searchPanelContainer = fixture.debugElement.query(By.css('[data-automation-id="adf-search-panel-container"]'));
expect(searchPanelContainer).not.toBe(null);
});
it('should filter button be present only when there are custom models', () => {
contentNodeSelectorPanelService.customModels = [mockContentModelProperty];
fixture.detectChanges();
const toggleFiltersPanelButton = fixture.debugElement.query(By.css('[data-automation-id="adf-toggle-search-panel-button"]'));
expect(toggleFiltersPanelButton).not.toEqual(null);
});
it('should filter button not be present when there are no custom models', () => {
fixture.detectChanges();
const toggleFiltersPanelButton = fixture.debugElement.query(By.css('[data-automation-id="adf-toggle-search-panel-button"]'));
expect(toggleFiltersPanelButton).toEqual(null);
});
});
}); });
}); });

View File

@ -47,6 +47,7 @@ import { NodeEntryEvent, ShareDataRow } from '../document-list';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { SEARCH_QUERY_SERVICE_TOKEN } from '../search/search-query-service.token'; import { SEARCH_QUERY_SERVICE_TOKEN } from '../search/search-query-service.token';
import { SearchQueryBuilderService } from '../search/search-query-builder.service'; import { SearchQueryBuilderService } from '../search/search-query-builder.service';
import { ContentNodeSelectorPanelService } from './content-node-selector-panel.service';
export type ValidationFunction = (entry: Node) => boolean; export type ValidationFunction = (entry: Node) => boolean;
@ -240,6 +241,8 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
target: PaginatedComponent; target: PaginatedComponent;
preselectNodes: NodeEntry[] = []; preselectNodes: NodeEntry[] = [];
searchPanelExpanded: boolean = false;
private onDestroy$ = new Subject<boolean>(); private onDestroy$ = new Subject<boolean>();
constructor(private customResourcesService: CustomResourcesService, constructor(private customResourcesService: CustomResourcesService,
@ -247,7 +250,8 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
private userPreferencesService: UserPreferencesService, private userPreferencesService: UserPreferencesService,
private nodesApiService: NodesApiService, private nodesApiService: NodesApiService,
private uploadService: UploadService, private uploadService: UploadService,
private sitesService: SitesService) { private sitesService: SitesService,
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService) {
} }
set chosenNode(value: Node[]) { set chosenNode(value: Node[]) {
@ -317,6 +321,14 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
this.onDestroy$.complete(); this.onDestroy$.complete();
} }
toggleSearchPanel() {
this.searchPanelExpanded = !this.searchPanelExpanded;
}
hasCustomModels(): boolean {
return this.contentNodeSelectorPanelService?.customModels?.length > 0;
}
private onFileUploadEvent() { private onFileUploadEvent() {
this.uploadService.fileUploadComplete this.uploadService.fileUploadComplete
.pipe( .pipe(

View File

@ -0,0 +1,32 @@
/*!
* @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.
*/
export const mockContentModelProperty = {
name: 'name',
prefixedName: 'account:name',
title: 'name',
description: '',
dataType: 'd:text',
multiValued: false,
mandatory: false,
defaultValue: '',
mandatoryEnforced: false,
indexed: false,
facetable: 'FALSE',
indexTokenisationMode: '',
constraints: []
};

View File

@ -1,5 +1,5 @@
<div class="adf-search-panel-scrollable"> <div class="adf-search-panel-scrollable" data-automation-id="adf-search-panel-container">
<adf-search-filter *ngIf="contentNodeSelectorSearchPanelService?.customModels?.length > 0" <adf-search-filter *ngIf="hasCustomModels()"
class="app-search-settings" class="app-search-settings"
[showContextFacets]="false"> [showContextFacets]="false">
</adf-search-filter> </adf-search-filter>

View File

@ -1,4 +1,4 @@
.adf-search-panel-scrollable { .adf-search-panel-scrollable {
overflow: scroll; overflow: scroll;
max-height: 200px; max-height: 300px;
} }

View File

@ -30,11 +30,15 @@ import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
}) })
export class SearchPanelComponent implements OnInit { export class SearchPanelComponent implements OnInit {
constructor(public contentNodeSelectorSearchPanelService: ContentNodeSelectorPanelService, constructor(private contentNodeSelectorPanelService: ContentNodeSelectorPanelService,
@Inject(SEARCH_QUERY_SERVICE_TOKEN) private queryBuilderService: SearchQueryBuilderService) { @Inject(SEARCH_QUERY_SERVICE_TOKEN) private queryBuilderService: SearchQueryBuilderService) {
} }
ngOnInit(): void { ngOnInit(): void {
this.queryBuilderService.categories = this.contentNodeSelectorSearchPanelService.convertCustomModelPropertiesToSearchCategories(); this.queryBuilderService.categories = this.contentNodeSelectorPanelService.convertCustomModelPropertiesToSearchCategories();
}
hasCustomModels(): boolean {
return this.contentNodeSelectorPanelService?.customModels?.length > 0;
} }
} }

View File

@ -49,7 +49,7 @@ export class ContentCloudNodeSelectorService {
showDropdownSiteList: false, showDropdownSiteList: false,
showLocalUploadButton: isAllFileSources showLocalUploadButton: isAllFileSources
}; };
this.openContentNodeDialog(data, 'adf-content-node-selector-dialog', '630px'); this.openContentNodeDialog(data, 'adf-content-node-selector-dialog', '66%');
return select; return select;
} }