Skip to content

Commit

Permalink
feat: handle multiple concurrent request (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kout95 authored Jun 18, 2024
1 parent 1cb20b0 commit 2c34b06
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 34 deletions.
51 changes: 22 additions & 29 deletions frontend/src/mixins/suggestions-ctl.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Constructor} from './utils';
import {LitElement} from 'lit';
import {property, state} from 'lit/decorators.js';
import {VersioningMixin, VersioningMixinInterface} from './versioning';

/**
* Type for term options.
Expand All @@ -21,9 +22,10 @@ export type TaxomiesTermsResponse = {
/**
* Interface for the SearchaliciousTaxonomies.
*/
export interface SearchaliciousTaxonomiesInterface {
termsByTaxonomyId: Record<string, TermOption[]>;
loadingByTaxonomyId: Record<string, boolean>;
export interface SearchaliciousTaxonomiesInterface
extends VersioningMixinInterface {
terms: TermOption[];
isTermsLoading: boolean;
taxonomiesBaseUrl: string;
langs: string;

Expand All @@ -48,13 +50,13 @@ export interface SearchaliciousTaxonomiesInterface {
export const SearchaliciousTermsMixin = <T extends Constructor<LitElement>>(
superClass: T
): Constructor<SearchaliciousTaxonomiesInterface> & T => {
class SearchaliciousTermsMixinClass extends superClass {
class SearchaliciousTermsMixinClass extends VersioningMixin(superClass) {
// this olds terms corresponding to current input for each taxonomy
@state()
termsByTaxonomyId: Record<string, TermOption[]> = {};
terms: TermOption[] = [];

@state()
loadingByTaxonomyId = {} as Record<string, boolean>;
isTermsLoading = {} as boolean;

@property({attribute: 'base-url'})
taxonomiesBaseUrl = '/';
Expand All @@ -73,19 +75,6 @@ export const SearchaliciousTermsMixin = <T extends Constructor<LitElement>>(
return `${baseUrl}/autocomplete?q=${q}&lang=${this.langs}&taxonomy_names=${taxonomyNames}&size=5`;
}

/**
* Method to set loading state by taxonomy names.
* We support more than one taxonomy at once,
* as suggest requests can target multiple taxonomies at once
* @param {string[]} taxonomyNames - The taxonomy names.
* @param {boolean} isLoading - The loading state.
*/
_setIsLoadingByTaxonomyNames(taxonomyNames: string[], isLoading: boolean) {
taxonomyNames.forEach((taxonomyName) => {
this.loadingByTaxonomyId[taxonomyName] = isLoading;
});
}

/**
* Method to get taxonomies terms.
* @param {string} q - The query string.
Expand All @@ -96,29 +85,33 @@ export const SearchaliciousTermsMixin = <T extends Constructor<LitElement>>(
q: string,
taxonomyNames: string[]
): Promise<TaxomiesTermsResponse> {
this._setIsLoadingByTaxonomyNames(taxonomyNames, true);
this.isTermsLoading = true;
// get the version of the terms for each taxonomy
const version = this.incrementVersion();

return fetch(this._termsUrl(q, taxonomyNames), {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
this._setIsLoadingByTaxonomyNames(taxonomyNames, false);

if (this.isLatestVersion(version)) {
// this is the legitimate suggestion request, loading finished
this.isTermsLoading = false;
}
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json() as Promise<TaxomiesTermsResponse>;
})
.then((response) => {
this.termsByTaxonomyId = response.options.reduce((acc, option) => {
if (!acc[option.taxonomy_name]) {
acc[option.taxonomy_name] = [];
}
acc[option.taxonomy_name].push(option);
return acc;
}, {} as Record<string, TermOption[]>);
if (!this.isLatestVersion(version)) {
// another suggestion request was launched in the mean time,
// give up
return response;
}
this.terms = response.options;
return response;
});
}
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/mixins/versioning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {Constructor} from './utils';
import {property} from 'lit/decorators.js';
import {LitElement} from 'lit';

export interface VersioningMixinInterface {
version: number;
incrementVersion(): number;
isLatestVersion(version: number): boolean;
}
export const VersioningMixin = <T extends Constructor<LitElement>>(
superClass: T
) => {
/**
* The mixin encapsulate the versioning logic
* It allows to avoid updating the data with older responses
*/
class VersioningMixinClass extends superClass {
/**
* The version of the object
*/
@property({attribute: false})
version = 0;

/**
* Increment the version of the object
*/
incrementVersion() {
this.version++;
return this.version;
}

/**
* Check if the version is the latest
*/
isLatestVersion(version: number) {
return version === this.version;
}
}

return VersioningMixinClass as Constructor<VersioningMixinInterface> & T;
};
8 changes: 4 additions & 4 deletions frontend/src/search-facets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ export class SearchaliciousTermsFacet extends SearchActionMixin(
const value = event.detail.value;
// eslint-disable-next-line @typescript-eslint/no-this-alias
this.debounce(() => {
// update options in termsByTaxonomyId SearchaliciousTermsMixin
// update options in terms SearchaliciousTermsMixin
// which will update the property of the autocomplete component during render
this.getTaxonomiesTerms(value, [taxonomy]);
});
}, 500);
}

/**
Expand All @@ -277,7 +277,7 @@ export class SearchaliciousTermsFacet extends SearchActionMixin(
this.onInputAddTerm(e, taxonomy);
};

const options = (this.termsByTaxonomyId[taxonomy] || []).map((term) => {
const options = (this.terms || []).map((term) => {
return {
value: term.id.replace(/^en:/, ''),
label: term.text,
Expand All @@ -292,7 +292,7 @@ export class SearchaliciousTermsFacet extends SearchActionMixin(
<searchalicious-autocomplete
.inputName=${inputName}
.options=${options}
.isLoading=${this.loadingByTaxonomyId[taxonomy]}
.isLoading=${this.isTermsLoading}
@searchalicious-autocomplete-submit=${this.addTerm}
@searchalicious-autocomplete-input=${onInput}
></searchalicious-autocomplete>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/utils/taxonomies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
* @param taxonomy
*/
export const getTaxonomyName = (taxonomy: string): string => {
return `${taxonomy}`.replace('s_tags', '').replace('ies_tags', 'y');
return `${taxonomy}`.replace('ies_tags', 'y').replace('s_tags', '');
};

0 comments on commit 2c34b06

Please sign in to comment.