Skip to content

Commit

Permalink
Load relation target suggestions in chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
tkleinke committed Jul 31, 2023
1 parent 06028de commit 59d70cd
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ import { Constraint, Query, Datastore, Relation, Constraints, CHILDOF_CONTAIN, D
/**
* @author Thomas Kleinke
*/
export async function getSuggestions(datastore: Datastore, resource: Resource,
relationDefinition: Relation): Promise<Array<Document>> {
export async function getSuggestions(datastore: Datastore, resource: Resource, relationDefinition: Relation,
searchTerm: string, offset: number, limit: number): Promise<Array<Document>> {

return (await datastore.find(
makeQuery(resource, relationDefinition)
makeQuery(resource, relationDefinition, searchTerm, offset, limit)
)).documents;
}


function makeQuery(resource: Resource, relationDefinition: Relation): Query {
function makeQuery(resource: Resource, relationDefinition: Relation, searchTerm: string, offset: number,
limit: number): Query {

return {
q: '',
q: searchTerm,
categories: relationDefinition.range,
constraints: makeConstraints(resource, relationDefinition)
constraints: makeConstraints(resource, relationDefinition),
offset,
limit
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Component, ElementRef, Input, OnChanges } from '@angular/core';
import { isUndefinedOrEmpty, to } from 'tsfun';
import { Component, Input, OnChanges } from '@angular/core';
import { isUndefinedOrEmpty } from 'tsfun';
import { Document, Datastore, Resource, Relation } from 'idai-field-core';
import { getSuggestions } from './get-suggestions';


const SUGGESTIONS_CHUNK_SIZE: number = 20;


@Component({
selector: 'relation-picker',
templateUrl: './relation-picker.html'
Expand All @@ -23,9 +26,11 @@ export class RelationPickerComponent implements OnChanges {
public selectedTarget: Document|undefined;
public disabled: boolean = false;

private searchTerm: string = '';
private offset: number = 0;

constructor(private element: ElementRef,
private datastore: Datastore) {}

constructor(private datastore: Datastore) {}


public getAvailableTargetIds = () => this.availableTargets?.map(target => target.resource.id);
Expand All @@ -43,9 +48,10 @@ export class RelationPickerComponent implements OnChanges {
console.error(err);
}

if (!this.selectedTarget) {
this.availableTargets = await this.fetchAvailableTargets();
}
this.searchTerm = '';
this.offset = 0;

if (!this.selectedTarget) await this.loadNextChunk();
}


Expand All @@ -70,6 +76,27 @@ export class RelationPickerComponent implements OnChanges {
}


public async search(term: string) {

this.availableTargets = [];
this.offset = 0;
this.searchTerm = term;

await this.loadNextChunk();
}


public async loadNextChunk() {

const newTargets: Array<Document> = await this.fetchAvailableTargets();

if (!this.availableTargets) this.availableTargets = [];
this.availableTargets = this.availableTargets.concat(newTargets);

this.offset += SUGGESTIONS_CHUNK_SIZE;
}


public async editTarget() {

this.selectedTarget = undefined;
Expand Down Expand Up @@ -119,7 +146,10 @@ export class RelationPickerComponent implements OnChanges {
private async fetchAvailableTargets(): Promise<Array<Document>> {

try {
return await getSuggestions(this.datastore, this.resource, this.relationDefinition);
return await getSuggestions(
this.datastore, this.resource, this.relationDefinition, this.searchTerm, this.offset,
SUGGESTIONS_CHUNK_SIZE
);
} catch (err) {
console.error(err);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
[getLabel]="getTargetLabel"
[initiallyOpened]="true"
(onValueSelected)="onTargetSelected($event)"
(onBlur)="onBlur()"></searchable-select>
(onBlur)="onBlur()"
(onScrollToEnd)="loadNextChunk()"
(onSearchTermChanged)="search($event)"></searchable-select>
</div>
<div *ngIf="selectedTarget">
<button class="btn btn-default" type="button" (click)="editTarget()">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export class SearchableSelectComponent implements OnInit, OnDestroy {

@Output() onValueSelected: EventEmitter<string> = new EventEmitter<string>();
@Output() onBlur: EventEmitter<void> = new EventEmitter<void>();
@Output() onScrollToEnd: EventEmitter<void> = new EventEmitter<void>();
@Output() onSearchTermChanged: EventEmitter<string> = new EventEmitter<string>();

@ViewChild('selectElement', { static: false }) private selectElement: NgSelectComponent;

Expand Down
4 changes: 3 additions & 1 deletion desktop/src/app/components/widgets/searchable-select.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
(close)="stopListeningToScrollEvents()"
(change)="onValueSelected.emit(selectedValue)"
(clear)="onValueSelected.emit(selectedValue)"
(blur)="onBlur.emit()">
(blur)="onBlur.emit()"
(scrollToEnd)="onScrollToEnd.emit()"
(search)="onSearchTermChanged.emit($event.term)">
<ng-option *ngFor="let value of values" [value]="value">{{getLabel(value)}}</ng-option>
</ng-select>
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ describe('getSuggestions', () => {
inputType: 'relation'
};

await getSuggestions(datastore, document.resource, relationDefinition);
await getSuggestions(datastore, document.resource, relationDefinition, '', 0, 10);

expect(datastore.find).toHaveBeenCalledWith({
q: '',
offset: 0,
limit: 10,
categories: ['RangeCategory1', 'RangeCategory2'],
constraints: {
'id:match': {
Expand Down Expand Up @@ -66,10 +68,12 @@ describe('getSuggestions', () => {
inputType: 'relation'
};

await getSuggestions(datastore, document.resource, relationDefinition);
await getSuggestions(datastore, document.resource, relationDefinition, '', 0, 10);

expect(datastore.find).toHaveBeenCalledWith({
q: '',
offset: 0,
limit: 10,
categories: ['RangeCategory'],
constraints: {
'id:match': {
Expand Down Expand Up @@ -101,10 +105,12 @@ describe('getSuggestions', () => {
inputType: 'relation'
};

await getSuggestions(datastore, document.resource, relationDefinition);
await getSuggestions(datastore, document.resource, relationDefinition, '', 0, 10);

expect(datastore.find).toHaveBeenCalledWith({
q: '',
offset: 0,
limit: 10,
categories: ['RangeCategory'],
constraints: {
'id:match': {
Expand Down Expand Up @@ -136,13 +142,15 @@ describe('getSuggestions', () => {
};

try {
await getSuggestions(datastore, document.resource, relationDefinition);
await getSuggestions(datastore, document.resource, relationDefinition, '', 0, 10);
} catch (err) {
fail();
}

expect(datastore.find).toHaveBeenCalledWith({
q: '',
offset: 0,
limit: 10,
categories: ['RangeCategory'],
constraints: {
'id:match': {
Expand Down

0 comments on commit 59d70cd

Please sign in to comment.