mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-3637] Attach file - Upload button is not disabled when the user is in search mode (#6193)
* [AAE-3637] Attach file - Upload button is not disabled when the user is in search mode * Add missing documentation for Input on the search filters * * Added warning message * * Added Unit tests to the recent changes * * Fixed css error * * Updated string Co-authored-by: adomi <ardit.domi@alfresco.com>
This commit is contained in:
@@ -26,9 +26,15 @@ Represents a main container component for custom search and faceted search setti
|
|||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<adf-search-filter #settings></adf-search-filter>
|
<adf-search-filter #settings [showContextFacets]=true></adf-search-filter>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
| Name | Type | Default value | Description |
|
||||||
|
| ---- | ---- | ------------- | ----------- |
|
||||||
|
| showContextFacets | `boolean` | true | Toggles whether to show or not the context facet filters |
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
The component UI uses dynamically created widgets to specify the search query and its
|
The component UI uses dynamically created widgets to specify the search query and its
|
||||||
|
@@ -359,6 +359,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
|||||||
|
|
||||||
describe('Search functionality', () => {
|
describe('Search functionality', () => {
|
||||||
let getCorrespondingNodeIdsSpy;
|
let getCorrespondingNodeIdsSpy;
|
||||||
|
let customResourcesService: CustomResourcesService;
|
||||||
const entry: Node = <Node> { id: 'fakeid'};
|
const entry: Node = <Node> { id: 'fakeid'};
|
||||||
|
|
||||||
const defaultSearchOptions = (searchTerm, rootNodeId = undefined, skipCount = 0, showFiles = false) => {
|
const defaultSearchOptions = (searchTerm, rootNodeId = undefined, skipCount = 0, showFiles = false) => {
|
||||||
@@ -402,7 +403,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
|||||||
|
|
||||||
spyOn(sitesService, 'getSites').and.returnValue(of({ list: { entries: [] } }));
|
spyOn(sitesService, 'getSites').and.returnValue(of({ list: { entries: [] } }));
|
||||||
|
|
||||||
const customResourcesService = TestBed.inject(CustomResourcesService);
|
customResourcesService = TestBed.inject(CustomResourcesService);
|
||||||
getCorrespondingNodeIdsSpy = spyOn(customResourcesService, 'getCorrespondingNodeIds').and
|
getCorrespondingNodeIdsSpy = spyOn(customResourcesService, 'getCorrespondingNodeIds').and
|
||||||
.callFake((id) => {
|
.callFake((id) => {
|
||||||
if (id === '-sites-') {
|
if (id === '-sites-') {
|
||||||
@@ -609,6 +610,60 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
|||||||
expect(cnSearchSpy).toHaveBeenCalledWith('search', 'my-root-id', 0, 25, [], false);
|
expect(cnSearchSpy).toHaveBeenCalledWith('search', 'my-root-id', 0, 25, [], false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should emit showingSearch event with true while searching', async () => {
|
||||||
|
spyOn(customResourcesService, 'hasCorrespondingNodeIds').and.returnValue(true);
|
||||||
|
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||||
|
component.search('search');
|
||||||
|
|
||||||
|
triggerSearchResults(fakeResultSetPaging);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
expect(component.showingSearchResults).toBe(true);
|
||||||
|
expect(showingSearchSpy).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit showingSearch event with false if you remove search term without clicking on X (icon) icon', async () => {
|
||||||
|
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||||
|
component.search('');
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
expect(component.showingSearchResults).toBe(false);
|
||||||
|
expect(showingSearchSpy).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit showingResults event with false when clicking on the X (clear) icon', () => {
|
||||||
|
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||||
|
component.chosenNode = [entry];
|
||||||
|
|
||||||
|
component.nodePaging = {
|
||||||
|
list: {
|
||||||
|
entries: [{ entry }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
component.searchTerm = 'piccolo';
|
||||||
|
component.showingSearchResults = true;
|
||||||
|
|
||||||
|
component.clear();
|
||||||
|
|
||||||
|
expect(component.showingSearchResults).toBe(false);
|
||||||
|
expect(showingSearchSpy).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit showingResults event with false if search api fails', async () => {
|
||||||
|
getCorrespondingNodeIdsSpy.and.throwError('Failed');
|
||||||
|
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||||
|
component.search('search');
|
||||||
|
|
||||||
|
triggerSearchResults(fakeResultSetPaging);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
expect(component.showingSearchResults).toBe(true);
|
||||||
|
expect(showingSearchSpy).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('should the query restrict the search to the site and not to the currentFolderId in case is changed', () => {
|
it('should the query restrict the search to the site and not to the currentFolderId in case is changed', () => {
|
||||||
component.currentFolderId = 'my-root-id';
|
component.currentFolderId = 'my-root-id';
|
||||||
component.restrictRootToCurrentFolderId = true;
|
component.restrictRootToCurrentFolderId = true;
|
||||||
|
@@ -212,6 +212,10 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
siteChange: EventEmitter<string> = new EventEmitter<string>();
|
siteChange: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
|
||||||
|
/** Emitted on search input. */
|
||||||
|
@Output()
|
||||||
|
showingSearch: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ViewChild('documentList', { static: true })
|
@ViewChild('documentList', { static: true })
|
||||||
documentList: DocumentListComponent;
|
documentList: DocumentListComponent;
|
||||||
|
|
||||||
@@ -406,6 +410,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
|||||||
this.pagination.maxItems = this.pageSize;
|
this.pagination.maxItems = this.pageSize;
|
||||||
this.resetChosenNode();
|
this.resetChosenNode();
|
||||||
this.showingSearchResults = false;
|
this.showingSearchResults = false;
|
||||||
|
this.showingSearch.emit(this.showingSearchResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -464,6 +469,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
|||||||
private showSearchResults(nodePaging: NodePaging): void {
|
private showSearchResults(nodePaging: NodePaging): void {
|
||||||
this.showingSearchResults = true;
|
this.showingSearchResults = true;
|
||||||
this.loadingSearchResults = false;
|
this.loadingSearchResults = false;
|
||||||
|
this.showingSearch.emit(this.showingSearchResults);
|
||||||
|
|
||||||
this.nodePaging = nodePaging;
|
this.nodePaging = nodePaging;
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
[showDropdownSiteList]="data?.showDropdownSiteList"
|
[showDropdownSiteList]="data?.showDropdownSiteList"
|
||||||
[showFilesInResult]="data?.showFilesInResult"
|
[showFilesInResult]="data?.showFilesInResult"
|
||||||
(select)="onSelect($event)"
|
(select)="onSelect($event)"
|
||||||
|
(showingSearch)="onShowingSearch($event)"
|
||||||
(siteChange)="onSiteChange($event)"
|
(siteChange)="onSiteChange($event)"
|
||||||
(navigationChange)="onNavigationChange($event)">
|
(navigationChange)="onNavigationChange($event)">
|
||||||
</adf-content-node-selector-panel>
|
</adf-content-node-selector-panel>
|
||||||
@@ -33,8 +34,15 @@
|
|||||||
[staticTitle]="'FORM.FIELD.UPLOAD' | translate "
|
[staticTitle]="'FORM.FIELD.UPLOAD' | translate "
|
||||||
[multipleFiles]="isMultipleSelection()"
|
[multipleFiles]="isMultipleSelection()"
|
||||||
[rootFolderId]="currentDirectoryId"
|
[rootFolderId]="currentDirectoryId"
|
||||||
|
[disabled]="disableUploadButton"
|
||||||
(error)="onError($event)">
|
(error)="onError($event)">
|
||||||
</adf-upload-button>
|
</adf-upload-button>
|
||||||
|
<ng-container *ngIf="data?.showLocalUploadButton && disableUploadButton">
|
||||||
|
<div class="adf-content-node-upload-button-warning-message">
|
||||||
|
<mat-icon>warning</mat-icon>
|
||||||
|
<span>{{ 'NODE_SELECTOR.UPLOAD_BUTTON_WARNING_MESSAGE' | translate }}</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
@@ -57,4 +57,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.adf-content-node-upload-button-warning-message {
|
||||||
|
margin-left: 20px;
|
||||||
|
display: flex;
|
||||||
|
font-size: 12px;
|
||||||
|
mat-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -202,6 +202,50 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
expect(adfUploadButton.nativeElement.innerText).toEqual('file_uploadFORM.FIELD.UPLOAD');
|
expect(adfUploadButton.nativeElement.innerText).toEqual('file_uploadFORM.FIELD.UPLOAD');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to disable UploadButton if disableUploadButton set to true', () => {
|
||||||
|
component.disableUploadButton = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||||
|
|
||||||
|
expect(adfUploadButton).not.toBeNull();
|
||||||
|
expect(adfUploadButton.nativeElement.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to enable UploadButton if disableUploadButton set to false', () => {
|
||||||
|
component.disableUploadButton = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||||
|
|
||||||
|
expect(adfUploadButton).not.toBeNull();
|
||||||
|
expect(adfUploadButton.nativeElement.disabled).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to show warning message if showLocalUploadButton and disableUploadButton set to true', () => {
|
||||||
|
component.disableUploadButton = true;
|
||||||
|
component.data.showLocalUploadButton = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
const warnningMessage = fixture.debugElement.query(By.css('.adf-content-node-upload-button-warning-message span'));
|
||||||
|
|
||||||
|
expect(warnningMessage).not.toBeNull();
|
||||||
|
expect(warnningMessage.nativeElement.innerText).toEqual('NODE_SELECTOR.UPLOAD_BUTTON_WARNING_MESSAGE');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be able to show warning message if showLocalUploadButton set to false', () => {
|
||||||
|
component.data.showLocalUploadButton = false;
|
||||||
|
component.disableUploadButton = false;
|
||||||
|
const warnningMessage = fixture.debugElement.query(By.css('.adf-content-node-upload-button-warning-message'));
|
||||||
|
|
||||||
|
expect(warnningMessage).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be able to show warning message if disableUploadButton set to false', () => {
|
||||||
|
component.data.showLocalUploadButton = true;
|
||||||
|
component.disableUploadButton = false;
|
||||||
|
const warnningMessage = fixture.debugElement.query(By.css('.adf-content-node-upload-button-warning-message'));
|
||||||
|
|
||||||
|
expect(warnningMessage).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
it('should not be able to show upload button if showLocalUploadButton set to false', () => {
|
it('should not be able to show upload button if showLocalUploadButton set to false', () => {
|
||||||
component.data.showLocalUploadButton = false;
|
component.data.showLocalUploadButton = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@@ -34,6 +34,7 @@ export class ContentNodeSelectorComponent {
|
|||||||
buttonActionName: string;
|
buttonActionName: string;
|
||||||
chosenNode: Node[];
|
chosenNode: Node[];
|
||||||
currentDirectoryId: string;
|
currentDirectoryId: string;
|
||||||
|
disableUploadButton = false;
|
||||||
|
|
||||||
constructor(private translation: TranslationService,
|
constructor(private translation: TranslationService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
@@ -86,4 +87,8 @@ export class ContentNodeSelectorComponent {
|
|||||||
hasNodeSelected(): boolean {
|
hasNodeSelected(): boolean {
|
||||||
return this.chosenNode?.length > 0;
|
return this.chosenNode?.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onShowingSearch(value: boolean) {
|
||||||
|
this.disableUploadButton = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -89,7 +89,8 @@
|
|||||||
"NO_RESULTS": "No results found",
|
"NO_RESULTS": "No results found",
|
||||||
"SEARCH": "Search",
|
"SEARCH": "Search",
|
||||||
"SEARCH_RESULTS": "Search results",
|
"SEARCH_RESULTS": "Search results",
|
||||||
"SELECT_LOCATION": "Select Location"
|
"SELECT_LOCATION": "Select Location",
|
||||||
|
"UPLOAD_BUTTON_WARNING_MESSAGE": "You can't upload a file whilst a search is still running"
|
||||||
},
|
},
|
||||||
"OPERATION": {
|
"OPERATION": {
|
||||||
"SUCCESS": {
|
"SUCCESS": {
|
||||||
|
Reference in New Issue
Block a user