Autocomplete tag options (#505)
This commit is contained in:
parent
be10ea5239
commit
c0fdf738e4
@ -10,6 +10,9 @@ export type Tags = string[];
|
||||
export type TagsChangeEvent = CustomEvent<{
|
||||
tags: string[];
|
||||
}>;
|
||||
export type TagInputEvent = CustomEvent<{
|
||||
value: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
@ -20,6 +23,7 @@ export type TagsChangeEvent = CustomEvent<{
|
||||
* ></btrix-tag-input>
|
||||
* ```
|
||||
*
|
||||
* @events tag-input
|
||||
* @events tags-change
|
||||
*/
|
||||
@localized()
|
||||
@ -110,6 +114,9 @@ export class TagInput extends LitElement {
|
||||
@property({ type: Array })
|
||||
initialTags?: Tags;
|
||||
|
||||
@property({ type: Array })
|
||||
tagOptions: Tags = [];
|
||||
|
||||
@property({ type: Boolean })
|
||||
disabled = false;
|
||||
|
||||
@ -126,9 +133,6 @@ export class TagInput extends LitElement {
|
||||
@state()
|
||||
private dropdownIsOpen?: boolean;
|
||||
|
||||
@state()
|
||||
private tagOptions: Tags = [];
|
||||
|
||||
@query("#input")
|
||||
private input?: HTMLInputElement;
|
||||
|
||||
@ -300,8 +304,14 @@ export class TagInput extends LitElement {
|
||||
this.inputValue = input.value;
|
||||
if (input.value.length) {
|
||||
this.dropdownIsOpen = true;
|
||||
this.tagOptions = await this.getOptions();
|
||||
} else {
|
||||
this.dropdownIsOpen = false;
|
||||
}
|
||||
this.dispatchEvent(
|
||||
<TagInputEvent>new CustomEvent("tag-input", {
|
||||
detail: { value: input.value },
|
||||
})
|
||||
);
|
||||
}) as any;
|
||||
|
||||
private onKeyup(e: KeyboardEvent) {
|
||||
@ -346,10 +356,4 @@ export class TagInput extends LitElement {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private async getOptions() {
|
||||
// TODO actual API call
|
||||
// https://github.com/webrecorder/browsertrix-cloud/issues/453
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import flow from "lodash/fp/flow";
|
||||
import uniq from "lodash/fp/uniq";
|
||||
import RegexColorize from "regex-colorize";
|
||||
import ISO6391 from "iso-639-1";
|
||||
import Fuse from "fuse.js";
|
||||
|
||||
import LiteElement, { html } from "../../utils/LiteElement";
|
||||
import { regexEscape } from "../../utils/string";
|
||||
@ -35,7 +36,11 @@ import type {
|
||||
ExclusionChangeEvent,
|
||||
} from "../../components/queue-exclusion-table";
|
||||
import type { TimeInputChangeEvent } from "../../components/time-input";
|
||||
import type { Tags, TagsChangeEvent } from "../../components/tag-input";
|
||||
import type {
|
||||
TagInputEvent,
|
||||
Tags,
|
||||
TagsChangeEvent,
|
||||
} from "../../components/tag-input";
|
||||
import type {
|
||||
CrawlConfigParams,
|
||||
Profile,
|
||||
@ -195,6 +200,9 @@ export class CrawlConfigEditor extends LiteElement {
|
||||
@property({ type: Object })
|
||||
initialCrawlConfig?: InitialCrawlConfig;
|
||||
|
||||
@state()
|
||||
private tagOptions: string[] = [];
|
||||
|
||||
@state()
|
||||
private isSubmitting = false;
|
||||
|
||||
@ -210,6 +218,12 @@ export class CrawlConfigEditor extends LiteElement {
|
||||
@state()
|
||||
private serverError?: TemplateResult | string;
|
||||
|
||||
// For fuzzy search:
|
||||
private fuse = new Fuse([], {
|
||||
shouldSort: false,
|
||||
threshold: 0.2, // stricter; default is 0.6
|
||||
});
|
||||
|
||||
private get formHasError() {
|
||||
return (
|
||||
!this.hasRequiredFields() ||
|
||||
@ -305,6 +319,9 @@ export class CrawlConfigEditor extends LiteElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changedProperties.get("orgId") && this.orgId) {
|
||||
this.fetchTags();
|
||||
}
|
||||
}
|
||||
|
||||
async updated(changedProperties: Map<string, any>) {
|
||||
@ -332,6 +349,8 @@ export class CrawlConfigEditor extends LiteElement {
|
||||
"sl-input, sl-textarea, sl-select, sl-radio-group"
|
||||
) as HTMLElement
|
||||
)?.focus();
|
||||
|
||||
this.fetchTags();
|
||||
}
|
||||
|
||||
private initializeEditor() {
|
||||
@ -1317,6 +1336,8 @@ https://example.net`}
|
||||
html`
|
||||
<btrix-tag-input
|
||||
.initialTags=${this.formState.tags}
|
||||
.tagOptions=${this.tagOptions}
|
||||
@tag-input=${this.onTagInput}
|
||||
@tags-change=${(e: TagsChangeEvent) =>
|
||||
this.updateFormState(
|
||||
{
|
||||
@ -1704,6 +1725,28 @@ https://example.net`}
|
||||
`;
|
||||
}
|
||||
|
||||
private onTagInput = (e: TagInputEvent) => {
|
||||
const { value } = e.detail;
|
||||
if (!value) return;
|
||||
this.tagOptions = this.fuse.search(value).map(({ item }) => item);
|
||||
};
|
||||
|
||||
private async fetchTags() {
|
||||
this.tagOptions = [];
|
||||
try {
|
||||
const tags = await this.apiFetch(
|
||||
`/orgs/${this.orgId}/crawlconfigs/tags`,
|
||||
this.authState!
|
||||
);
|
||||
|
||||
// Update search/filter collection
|
||||
this.fuse.setCollection(tags as any);
|
||||
} catch (e) {
|
||||
// Fail silently, since users can still enter tags
|
||||
console.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
private parseConfig(): NewCrawlConfigParams {
|
||||
const config: NewCrawlConfigParams = {
|
||||
jobType: this.jobType || "custom",
|
||||
|
Loading…
Reference in New Issue
Block a user