Fixed issue that doesn't trigger an update on search in submission collection dropdown

This commit is contained in:
Giuseppe
2018-11-02 13:33:09 +01:00
parent 5acbfe27ea
commit 69a9e41bed
2 changed files with 81 additions and 48 deletions

View File

@@ -1,12 +1,13 @@
<div> <div>
<div ngbDropdown #collectionControls="ngbDropdown" class="btn-group input-group"> <div ngbDropdown #collectionControls="ngbDropdown" class="btn-group input-group" (openChange)="toggled($event)">
<div class="input-group-prepend"> <div class="input-group-prepend">
<span id="collectionControlsMenuLabel" class="input-group-text">Collection</span> <span id="collectionControlsMenuLabel" class="input-group-text">Collection</span>
</div> </div>
<button aria-describedby="collectionControlsMenuLabel" <button aria-describedby="collectionControlsMenuLabel"
id="collectionControlsMenuButton" id="collectionControlsMenuButton"
class="btn btn-outline-primary" class="btn btn-outline-primary"
(click)="onClose($event)" (blur)="onClose()"
(click)="onClose()"
[disabled]="disabled" [disabled]="disabled"
ngbDropdownToggle> ngbDropdownToggle>
<span *ngIf="disabled"><i class='fa fa-circle-o-notch fa-spin'></i></span> <span *ngIf="disabled"><i class='fa fa-circle-o-notch fa-spin'></i></span>
@@ -24,8 +25,8 @@
</div> </div>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<div class="scrollable-menu" aria-labelledby="dropdownMenuButton" (scroll)="onScroll($event)"> <div class="scrollable-menu" aria-labelledby="dropdownMenuButton" (scroll)="onScroll($event)">
<button class="dropdown-item disabled" *ngIf="searchListCollection.length == 0">No results found</button> <button class="dropdown-item disabled" *ngIf="(searchListCollection$ | async).length == 0">No results found</button>
<button class="dropdown-item collection-item" *ngFor="let listItem of searchListCollection" (click)="onSelect(listItem)" title="{{ listItem.collection.name }}"> <button class="dropdown-item collection-item" *ngFor="let listItem of (searchListCollection$ | async)" (click)="onSelect(listItem)" title="{{ listItem.collection.name }}">
<ul class="list-unstyled mb-0"> <ul class="list-unstyled mb-0">
<li class="list-item text-truncate text-secondary" *ngFor="let item of listItem.communities" >{{ item.name}} <i class="fa fa-level-down" aria-hidden="true"></i></li> <li class="list-item text-truncate text-secondary" *ngFor="let item of listItem.communities" >{{ item.name}} <i class="fa fa-level-down" aria-hidden="true"></i></li>
<li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.collection.name}}</li> <li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.collection.name}}</li>

View File

@@ -26,6 +26,29 @@ import { JsonPatchOperationsService } from '../../../core/json-patch/json-patch-
import { SubmitDataResponseDefinitionObject } from '../../../core/shared/submit-data-response-definition.model'; import { SubmitDataResponseDefinitionObject } from '../../../core/shared/submit-data-response-definition.model';
import { SubmissionService } from '../../submission.service'; import { SubmissionService } from '../../submission.service';
import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; import { SubmissionObject } from '../../../core/submission/models/submission-object.model';
import { Observable } from 'rxjs/Observable';
import {
debounceTime,
distinctUntilChanged,
filter,
first,
flatMap,
map,
mergeMap,
reduce,
startWith,
tap
} from 'rxjs/operators';
interface CollectionListEntryItem {
id: string;
name: string;
}
interface CollectionListEntry {
communities: CollectionListEntryItem[],
collection: CollectionListEntryItem
}
@Component({ @Component({
selector: 'ds-submission-form-collection', selector: 'ds-submission-form-collection',
@@ -44,10 +67,9 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
@Output() collectionChange: EventEmitter<Workspaceitem> = new EventEmitter<Workspaceitem>(); @Output() collectionChange: EventEmitter<Workspaceitem> = new EventEmitter<Workspaceitem>();
public disabled = true; public disabled = true;
public listCollection = [];
public model: any; public model: any;
public searchField: FormControl; public searchField: FormControl = new FormControl();
public searchListCollection = []; public searchListCollection$: Observable<CollectionListEntry[]>;
public selectedCollectionId: string; public selectedCollectionId: string;
public selectedCollectionName: string; public selectedCollectionName: string;
@@ -81,68 +103,71 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if (hasValue(changes.currentCollectionId) if (hasValue(changes.currentCollectionId)
&& hasValue(changes.currentCollectionId.currentValue) && hasValue(changes.currentCollectionId.currentValue)) {
&& !isNotEmpty(this.listCollection)) {
this.selectedCollectionId = this.currentCollectionId; this.selectedCollectionId = this.currentCollectionId;
// @TODO replace with search/top browse endpoint // @TODO replace with search/top browse endpoint
// @TODO implement community/subcommunity hierarchy // @TODO implement community/subcommunity hierarchy
this.subs.push(this.communityDataService.findAll() const listCollection$ = this.communityDataService.findAll().pipe(
.filter((communities: RemoteData<PaginatedList<Community>>) => isNotEmpty(communities.payload)) filter((communities: RemoteData<PaginatedList<Community>>) => isNotEmpty(communities.payload)),
.first() first(),
.switchMap((communities: RemoteData<PaginatedList<Community>>) => communities.payload.page) mergeMap((communities: RemoteData<PaginatedList<Community>>) => communities.payload.page),
.subscribe((communityData: Community) => { flatMap((communityData: Community) => {
return communityData.collections.pipe(
this.subs.push(communityData.collections filter((collections: RemoteData<PaginatedList<Collection>>) => !collections.isResponsePending && collections.hasSucceeded),
.filter((collections: RemoteData<PaginatedList<Collection>>) => !collections.isResponsePending && collections.hasSucceeded) first(),
.first() mergeMap((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.page),
.switchMap((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.page) filter((collectionData: Collection) => isNotEmpty(collectionData)),
.filter((collectionData: Collection) => isNotEmpty(collectionData)) tap((collectionData: Collection) => {
.subscribe((collectionData: Collection) => {
if (collectionData.id === this.selectedCollectionId) { if (collectionData.id === this.selectedCollectionId) {
this.selectedCollectionName = collectionData.name; this.selectedCollectionName = collectionData.name;
} }
const collectionEntry = { }),
communities: [{id: communityData.id, name: communityData.name}], map((collectionData: Collection) => ({
collection: {id: collectionData.id, name: collectionData.name} communities: [{id: communityData.id, name: communityData.name}],
}; collection: {id: collectionData.id, name: collectionData.name}
this.listCollection.push(collectionEntry);
this.searchListCollection.push(collectionEntry);
this.disabled = false;
this.cdr.detectChanges();
})) }))
})); );
}),
reduce((acc: any, value: any) => [...acc, ...value], []),
tap((list: CollectionListEntry[]) => {
if (isNotEmpty(list)) {
this.disabled = false;
}
}),
startWith([])
);
const searchTerm$ = this.searchField.valueChanges.pipe(
debounceTime(200),
distinctUntilChanged(),
startWith('')
);
this.searchListCollection$ = Observable.combineLatest(searchTerm$, listCollection$)
.map(([searchTerm, listCollection]) => {
if (searchTerm === '' || isNullOrUndefined(searchTerm)) {
return listCollection;
} else {
return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5)
}
});
} }
} }
ngOnInit() { ngOnInit() {
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', 'collection'); this.pathCombiner = new JsonPatchOperationPathCombiner('sections', 'collection');
this.searchField = new FormControl();
this.searchField.valueChanges
.debounceTime(200)
.distinctUntilChanged()
.subscribe((term) => {
this.search(term);
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe()); this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
} }
search(text: string) {
if (text === '' || isNullOrUndefined(text)) {
this.searchListCollection = this.listCollection;
} else {
this.searchListCollection = this.listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(text.toLowerCase()) > -1).slice(0, 5);
}
}
onSelect(event) { onSelect(event) {
this.searchField.reset(); this.searchField.reset();
this.searchListCollection = this.listCollection;
this.disabled = true; this.disabled = true;
this.operationsBuilder.replace(this.pathCombiner.getPath(), event.collection.id, true); this.operationsBuilder.replace(this.pathCombiner.getPath(), event.collection.id, true);
this.operationsService.jsonPatchByResourceID( this.subs.push(this.operationsService.jsonPatchByResourceID(
this.submissionService.getSubmissionObjectLinkName(), this.submissionService.getSubmissionObjectLinkName(),
this.submissionId, this.submissionId,
'sections', 'sections',
@@ -155,9 +180,16 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
this.disabled = false; this.disabled = false;
this.cdr.detectChanges(); this.cdr.detectChanges();
}) })
);
} }
onClose(event) { onClose() {
this.searchField.reset(); this.searchField.reset();
} }
toggled(isOpen: boolean) {
if (!isOpen) {
this.searchField.reset();
}
}
} }