From ff6650d481e09dce6856d43d0b133b7d9265a76f Mon Sep 17 00:00:00 2001 From: sua yoo Date: Tue, 5 Sep 2023 14:52:17 -0700 Subject: [PATCH] Manage collection from archived item details (#1085) - Lists collections that an archived item belongs to in item detail view - Improves performance of collection add component --------- Co-authored-by: Tessa Walsh --- frontend/src/components/collections-add.ts | 120 +++++++++++------- .../src/components/crawl-metadata-editor.ts | 53 ++++++-- frontend/src/pages/org/crawl-detail.ts | 26 ++++ frontend/src/types/crawler.ts | 1 + 4 files changed, 140 insertions(+), 60 deletions(-) diff --git a/frontend/src/components/collections-add.ts b/frontend/src/components/collections-add.ts index f20d4b20..2d5b55e3 100644 --- a/frontend/src/components/collections-add.ts +++ b/frontend/src/components/collections-add.ts @@ -60,7 +60,7 @@ export class CollectionsAdd extends LiteElement { emptyText?: string; @state() - private collections: CollectionList = []; + private collectionsData: { [id: string]: Collection } = {}; @state() private collectionIds: string[] = []; @@ -78,12 +78,17 @@ export class CollectionsAdd extends LiteElement { @state() private searchResultsOpen = false; - async connectedCallback() { + connectedCallback() { if (this.initialCollections) { this.collectionIds = this.initialCollections; } - await this.initializeCollectionsFromIds(); super.connectedCallback(); + this.initializeCollectionsFromIds(); + } + + disconnectedCallback() { + this.onSearchInput.cancel(); + super.disconnectedCallback(); } render() { @@ -95,12 +100,12 @@ export class CollectionsAdd extends LiteElement { ${this.renderSearch()} - ${when(this.collections, () => - this.collections.length + ${when(this.collectionIds, () => + this.collectionIds.length ? html`
    - ${this.collections.map(this.renderCollectionItem, this)} + ${this.collectionIds.map(this.renderCollectionItem, this)}
` @@ -132,12 +137,17 @@ export class CollectionsAdd extends LiteElement { (collection) => collection.id === collId ); if (coll) { - this.collections.push(coll); - this.collectionIds.push(coll.id); - await this.dispatchChange(); + const { id } = coll; + if (!this.collectionsData[id]) { + this.collectionsData = { + ...this.collectionsData, + [id]: await this.getCollection(id), + }; + } + this.collectionIds = [...this.collectionIds, id]; + this.dispatchChange(); } } - await this.updateComplete; }} > + new RegExp(`^${this.searchByValue}`, "i").test(res.name) + ); + + if (!searchResults.length) { return html` ${msg("No matching Collections found.")} { + ${searchResults.map((item: Collection) => { return html`
@@ -193,40 +208,44 @@ export class CollectionsAdd extends LiteElement { `; } - private renderCollectionItem(collection: Collection) { - return html`
  • -
    -
    ${ - collection.name - }
    -
    - ${msg(str`${collection.crawlCount} Crawls`)} -
    - - - -
  • `; + private renderCollectionItem(id: string) { + const collection = this.collectionsData[id]; + return html`
  • +
    +
    + ${collection?.name} +
    +
    + ${msg(str`${collection?.crawlCount || 0} Crawls`)} +
    + + +
    +
  • `; } - private async removeCollection(event: Event) { + private removeCollection(event: Event) { const target = event.currentTarget as HTMLElement; const collectionId = target.getAttribute("data-key"); if (collectionId) { const collIdIndex = this.collectionIds.indexOf(collectionId); if (collIdIndex > -1) { - this.collectionIds.splice(collIdIndex, 1); - } - const collIndex = this.collections.findIndex( - (collection) => collection.id === collectionId - ); - if (collIndex > -1) { - this.collections.splice(collIndex, 1); + this.collectionIds = [ + ...this.collectionIds.slice(0, collIdIndex), + ...this.collectionIds.slice(collIdIndex + 1), + ]; + this.dispatchChange(); } } - await this.requestUpdate(); } private onSearchInput = debounce(200)(async (e: any) => { @@ -247,9 +266,7 @@ export class CollectionsAdd extends LiteElement { private filterOutSelectedCollections(results: CollectionList) { return results.filter((result) => { - return this.collections.every((coll) => { - return coll.id !== result.id; - }); + return !this.collectionIds.some((id) => id === result.id); }); } @@ -291,18 +308,25 @@ export class CollectionsAdd extends LiteElement { } private async initializeCollectionsFromIds() { - for (let i = 0; i < this.collectionIds?.length; i++) { - const collId = this.collectionIds[i]; - const data: Collection = await this.apiFetch( - `/orgs/${this.orgId}/collections/${collId}`, - this.authState! - ); + if (!this.collectionIds) return; + this.collectionIds.forEach(async (id) => { + const data = await this.getCollection(id); if (data) { - this.collections.push(data); + this.collectionsData = { + ...this.collectionsData, + [id]: data, + }; } - } + }); } + private getCollection = (collId: string): Promise => { + return this.apiFetch( + `/orgs/${this.orgId}/collections/${collId}`, + this.authState! + ); + }; + private async dispatchChange() { await this.updateComplete; this.dispatchEvent( diff --git a/frontend/src/components/crawl-metadata-editor.ts b/frontend/src/components/crawl-metadata-editor.ts index 58fe076b..a6cd2868 100644 --- a/frontend/src/components/crawl-metadata-editor.ts +++ b/frontend/src/components/crawl-metadata-editor.ts @@ -53,6 +53,9 @@ export class CrawlMetadataEditor extends LiteElement { @state() private tagsToSave: Tags = []; + @state() + private collectionsToSave: string[] = []; + // For fuzzy search: private fuse = new Fuse([], { shouldSort: false, @@ -68,6 +71,7 @@ export class CrawlMetadataEditor extends LiteElement { if (changedProperties.has("crawl") && this.crawl) { this.includeName = this.crawl.type === "upload"; this.tagsToSave = this.crawl.tags || []; + this.collectionsToSave = this.crawl.collectionIds || []; } } @@ -121,6 +125,18 @@ export class CrawlMetadataEditor extends LiteElement { @tags-change=${(e: TagsChangeEvent) => (this.tagsToSave = e.detail.tags)} > +
    + + (this.collectionsToSave = e.detail.collections)} + > + +
    html`` )} + + ${when( + this.crawl, + () => + when( + this.crawl!.collections.length, + () => html` +
      + ${this.crawl!.collections.map( + ({ id, name }) => + html`
    • + ${name} +
    • ` + )} +
    + `, + () => noneText + ), + () => html`` + )} +
    `; } diff --git a/frontend/src/types/crawler.ts b/frontend/src/types/crawler.ts index f55e0c9d..39579bb2 100644 --- a/frontend/src/types/crawler.ts +++ b/frontend/src/types/crawler.ts @@ -129,6 +129,7 @@ export type Crawl = CrawlConfig & { seedCount: number; stopping: boolean; collectionIds: string[]; + collections: { id: string; name: string }[]; type?: "crawl" | "upload" | null; };