From 10cda1c0051ed218571b180243498941977ddadf Mon Sep 17 00:00:00 2001 From: Sergei Shmakov Date: Tue, 29 Oct 2024 21:13:47 +0100 Subject: [PATCH] Simplifies search by URL by removing merging of results (#3543) --- src/plus/launchpad/launchpad.ts | 65 ++++++++++--------------- src/plus/launchpad/launchpadProvider.ts | 38 --------------- 2 files changed, 26 insertions(+), 77 deletions(-) diff --git a/src/plus/launchpad/launchpad.ts b/src/plus/launchpad/launchpad.ts index 2126b844dbe84..74892d5ab638a 100644 --- a/src/plus/launchpad/launchpad.ts +++ b/src/plus/launchpad/launchpad.ts @@ -422,6 +422,7 @@ export class LaunchpadCommand extends QuickCommand { i: LaunchpadItem, ui: LaunchpadGroup, topItem: LaunchpadItem | undefined, + alwaysShow: boolean | undefined, ): LaunchpadItemQuickPickItem => { const buttons = []; @@ -452,6 +453,7 @@ export class LaunchpadCommand extends QuickCommand { i.actionableCategory === 'other' ? '' : `${actionGroupMap.get(i.actionableCategory)![0]} \u2022 ` }${fromNow(i.updatedDate)} by @${i.author!.username}`, + alwaysShow: alwaysShow, buttons: buttons, iconPath: i.author?.avatarUrl != null ? Uri.parse(i.author.avatarUrl) : undefined, item: i, @@ -460,7 +462,7 @@ export class LaunchpadCommand extends QuickCommand { }; }; - const getItems = (result: LaunchpadCategorizedResult, treatAllGroupAsExpanded?: boolean) => { + const getItems = (result: LaunchpadCategorizedResult, isSearching?: boolean) => { const items: (LaunchpadItemQuickPickItem | DirectiveQuickPickItem | ConnectMoreIntegrationsItem)[] = []; if (result.items?.length) { @@ -475,18 +477,21 @@ export class LaunchpadCommand extends QuickCommand { for (const [ui, groupItems] of uiGroups) { if (!groupItems.length) continue; - items.push(...buildGroupHeading(ui, groupItems.length)); - - if (!treatAllGroupAsExpanded && context.collapsed.get(ui)) continue; + if (!isSearching) { + items.push(...buildGroupHeading(ui, groupItems.length)); + if (context.collapsed.get(ui)) { + continue; + } + } - items.push(...groupItems.map(i => buildLaunchpadQuickPickItem(i, ui, topItem))); + items.push(...groupItems.map(i => buildLaunchpadQuickPickItem(i, ui, topItem, isSearching))); } } return items; }; - function getItemsAndPlaceholder(treatAllGroupAsExpanded?: boolean) { + function getItemsAndPlaceholder(isSearching?: boolean) { if (context.result.error != null) { return { placeholder: `Unable to load items (${ @@ -509,7 +514,7 @@ export class LaunchpadCommand extends QuickCommand { return { placeholder: 'Choose an item to focus on', - items: getItems(context.result, treatAllGroupAsExpanded), + items: getItems(context.result, isSearching), }; } @@ -539,8 +544,7 @@ export class LaunchpadCommand extends QuickCommand { }; const { items, placeholder } = getItemsAndPlaceholder(); - - let groupsHidden = false; + const nonGroupedItems = items.filter(i => !isDirectiveQuickPickItem(i)); const step = createPickStep({ title: context.title, @@ -556,32 +560,27 @@ export class LaunchpadCommand extends QuickCommand { RefreshQuickInputButton, ], onDidChangeValue: async quickpick => { - const hideGroups = Boolean(quickpick.value?.length); - - if (groupsHidden !== hideGroups) { - groupsHidden = hideGroups; - quickpick.items = hideGroups ? items.filter(i => !isDirectiveQuickPickItem(i)) : items; - } const { value } = quickpick; - const activeLaunchpadItems = quickpick.activeItems.filter( - (i): i is LaunchpadItemQuickPickItem => 'item' in i && !i.alwaysShow, - ); + const hideGroups = Boolean(value?.length); + const consideredItems = hideGroups ? nonGroupedItems : items; let updated = false; - for (const item of quickpick.items) { + for (const item of consideredItems) { if (item.alwaysShow) { item.alwaysShow = false; updated = true; } - if ('item' in item && item.item?.isSearched) { - updated = true; - } - } - if (updated) { - // Force quickpick to update by changing the items object: - quickpick.items = [...quickpick.items.filter(i => !('item' in i && i.item?.isSearched))]; } + // By doing the following we make sure we operate with the PRs that belong to Launchpad initially. + // Also, when we re-create the array, we make sure that `alwaysShow` updates are applied. + quickpick.items = + updated && quickpick.items === consideredItems ? [...consideredItems] : consideredItems; + + const activeLaunchpadItems = quickpick.activeItems.filter( + (i): i is LaunchpadItemQuickPickItem => 'item' in i, + ); + if (!value?.length || activeLaunchpadItems.length) { // Nothing to search or use items that have been found locally this.updateItemsDebouncer.cancel(); @@ -622,13 +621,6 @@ export class LaunchpadCommand extends QuickCommand { } // Nothing is found above, so let's perform search in the API: await updateItems(quickpick, value); - quickpick.items.forEach(i => { - if ('item' in i && doesPullRequestSatisfyRepositoryURLIdentity(i.item, prUrlIdentity)) { - i.alwaysShow = true; - } - }); - quickpick.items = quickpick.items.filter((i): i is LaunchpadItemQuickPickItem => 'item' in i); - groupsHidden = true; return true; }, onDidClickButton: async (quickpick, button) => { @@ -1369,12 +1361,7 @@ async function updateContextItems( options?: { force?: boolean; search?: string }, cancellation?: CancellationToken, ) { - const result = await container.launchpad.getCategorizedItems(options, cancellation); - if (options?.search) { - context.result = container.launchpad.mergeSearchedCategorizedItems(context.result, result); - } else { - context.result = result; - } + context.result = await container.launchpad.getCategorizedItems(options, cancellation); if (container.telemetry.enabled) { updateTelemetryContext(context); } diff --git a/src/plus/launchpad/launchpadProvider.ts b/src/plus/launchpad/launchpadProvider.ts index fada1f8cb5641..d84bcc80a9689 100644 --- a/src/plus/launchpad/launchpadProvider.ts +++ b/src/plus/launchpad/launchpadProvider.ts @@ -193,7 +193,6 @@ export type LaunchpadItem = LaunchpadPullRequest & { actionableCategory: LaunchpadActionCategory; suggestedActions: LaunchpadAction[]; openRepository?: OpenRepository; - isSearched?: boolean; underlyingPullRequest: PullRequest; }; @@ -644,43 +643,6 @@ export class LaunchpadProvider implements Disposable { return repoRemotes; } - mergeSearchedCategorizedItems( - prsOfTheLaunchpad: LaunchpadCategorizedResult, - prsOfSearch: LaunchpadCategorizedResult | undefined, - ): LaunchpadCategorizedResult { - if (prsOfSearch == null || prsOfSearch?.error) { - if (prsOfTheLaunchpad.items == null) { - return prsOfTheLaunchpad; - } - return { - items: prsOfTheLaunchpad.items.filter(i => !i.isSearched), - timings: prsOfTheLaunchpad.timings, - }; - } - - const result = []; - const idsOfLaunchpadPrs = new Set(); - if (prsOfTheLaunchpad.items) { - for (const item of prsOfTheLaunchpad.items) { - if (!item.isSearched) { - idsOfLaunchpadPrs.add(item.id); - result.push(item); - } - } - } - for (const item of prsOfSearch.items) { - if (!idsOfLaunchpadPrs.has(item.id)) { - item.isSearched = true; - result.push(item); - } - } - - return { - items: result, - timings: prsOfSearch.timings, - }; - } - @gate(o => `${o?.force ?? false}`) @log({ args: { 0: o => `force=${o?.force}`, 1: false } }) async getCategorizedItems(