diff --git a/package-lock.json b/package-lock.json index e733f35eb4..091459e8a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@microsoft/vscode-azext-azureappservice": "~2.0", "@microsoft/vscode-azext-azureauth": "^1.1.2", "@microsoft/vscode-azext-azureutils": "^2.0.0", - "@microsoft/vscode-azext-utils": "^2.0.0", + "@microsoft/vscode-azext-utils": "file:../vscode-azuretools/utils/microsoft-vscode-azext-utils-2.1.1.tgz", "@microsoft/vscode-container-client": "^0.1.0", "@microsoft/vscode-docker-registries": "file:../vscode-docker-extensibility/packages/vscode-docker-registries/microsoft-vscode-docker-registries-0.1.0.tgz", "dayjs": "^1.11.7", @@ -771,9 +771,10 @@ } }, "node_modules/@microsoft/vscode-azext-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.0.5.tgz", - "integrity": "sha512-DNyORyHfPuohBy7Z0rD6YRa4iNLW2LpA+lAv75E9NQ3c1ZhO27tQ2EHj4sYowAqrKZXlqvPHvgjYFj3Dqu5eOQ==", + "version": "2.1.1", + "resolved": "file:../vscode-azuretools/utils/microsoft-vscode-azext-utils-2.1.1.tgz", + "integrity": "sha512-be22iQu1IyWUjKrB6WhbmtsffZ469xRFqjRQwkBzXdwI15j7W2bRpFsyadPHxuIVjzFTcZpmB7a5R8X93UvhZQ==", + "license": "MIT", "dependencies": { "@microsoft/vscode-azureresources-api": "^2.0.4", "@vscode/extension-telemetry": "^0.6.2", @@ -814,7 +815,7 @@ "node_modules/@microsoft/vscode-docker-registries": { "version": "0.1.0", "resolved": "file:../vscode-docker-extensibility/packages/vscode-docker-registries/microsoft-vscode-docker-registries-0.1.0.tgz", - "integrity": "sha512-hiIKmhq4gHDTrPzrkvj72oKSMfReexwnJzrGUL4COq7r0m8SX6EMRzRaN+DKl7ApsqCMJJXF/y7u17cWq/PWQQ==", + "integrity": "sha512-af963bHhdUX51Rn3rSGSRD1qO/qeUxcoRbTzvA/c8R9GJdDqtRzgyaOu57ETzHyG/fUfd4qaDCMs2FNI9HNk5g==", "license": "See LICENSE in the project root for license information.", "dependencies": { "dayjs": "^1.11.7", diff --git a/package.json b/package.json index af70c2a43f..64fd844a2a 100644 --- a/package.json +++ b/package.json @@ -467,7 +467,7 @@ }, { "command": "vscode-docker.registries.azure.deleteRegistry", - "when": "view == dockerRegistries && viewItem =~ /azureContainerRegistry/i", + "when": "view == dockerRegistries && viewItem =~ /azure;.*commonregistry/i", "group": "regs_reg_2_destructive@1" }, { @@ -477,7 +477,7 @@ }, { "command": "vscode-docker.registries.azure.deleteRepository", - "when": "view == dockerRegistries && viewItem =~ /azureContainerRepository/i", + "when": "view == dockerRegistries && viewItem =~ /azure;.*commonrepository/i", "group": "regs_repo_2_destructive@1" }, { @@ -492,7 +492,7 @@ }, { "command": "vscode-docker.registries.copyImageDigest", - "when": "view == dockerRegistries && viewItem =~ /registryV2Tag/i", + "when": "view == dockerRegistries && viewItem =~ /commontag/i && !(viewItem =~ /commontag;.*dockerhub/i)", "group": "regs_tag_1_general@3" }, { @@ -507,42 +507,42 @@ }, { "command": "vscode-docker.registries.azure.untagImage", - "when": "view == dockerRegistries && viewItem =~ /azureContainerTag/i", + "when": "view == dockerRegistries && viewItem =~ /azure;.*commontag/i", "group": "regs_tag_2_destructive@1" }, { "command": "vscode-docker.registries.deleteImage", - "when": "view == dockerRegistries && viewItem =~ /commontag/i && !(viewItem =~ /(githubRegistryTag|dockerHubTag)/i)", + "when": "view == dockerRegistries && viewItem =~ /commontag/i && !(viewItem =~ /commontag;.*(dockerhub|github)/i)", "group": "regs_tag_2_destructive@2" }, { "command": "vscode-docker.registries.disconnectRegistry", - "when": "view == dockerRegistries && viewItem =~ /commonregistryroot/i && !(viewItem =~ /genericRegistryV2Root/i)", + "when": "view == dockerRegistries && viewItem =~ /commonregistryroot/i && !(viewItem =~ /commonregistryroot;.*generic/i)", "group": "regs_yyy_destructive@1" }, { "command": "vscode-docker.registries.genericV2.removeTrackedRegistry", - "when": "view == dockerRegistries && viewItem =~ /genericRegistryV2Registry/i", + "when": "view == dockerRegistries && viewItem =~ /commonregistry;.*generic/i", "group": "regs_yyy_destructive@1" }, { "command": "vscode-docker.registries.genericV2.addTrackedRegistry", - "when": "view == dockerRegistries && viewItem =~ /genericRegistryV2Root/i", + "when": "view == dockerRegistries && viewItem =~ /commonregistryroot;.*generic/i", "group": "regs_yyy_destructive@1" }, { "command": "vscode-docker.registries.azure.openInPortal", - "when": "view == dockerRegistries && viewItem =~ /(azuresubscription|azureContainerRegistry|azureContainerRepository)/i", + "when": "view == dockerRegistries && viewItem =~ /azuresubscription|azure;.*(commonregistry|commonrepository)/i", "group": "regs_zzz_common@1" }, { "command": "vscode-docker.registries.dockerHub.openInBrowser", - "when": "view == dockerRegistries && viewItem =~ /(dockerHubRegistry|dockerHubRepository|dockerHubTag)/i", + "when": "view == dockerRegistries && viewItem =~ /(commonregistry|commonrepository|commontag);.*dockerhub/i", "group": "regs_zzz_common@1" }, { "command": "vscode-docker.registries.azure.viewProperties", - "when": "view == dockerRegistries && viewItem =~ /azureContainerRegistry/i", + "when": "view == dockerRegistries && viewItem =~ /azure;.*commonregistry/i", "group": "regs_zzz_common@2" }, { @@ -557,12 +557,7 @@ }, { "command": "vscode-docker.registries.refresh", - "when": "view == dockerRegistries && viewItem =~ /.*;.*;(Repository|Registry|RegistryProvider);/", - "group": "regs_zzz_common@9" - }, - { - "command": "vscode-docker.registries.refresh", - "when": "view == dockerRegistries && viewItem =~ /azure(Subscription|Tasks|Task|RunsWithoutTask)$/", + "when": "view == dockerRegistries && viewItem =~ /commonregistry|commonregistryroot|commonrepository/", "group": "regs_zzz_common@9" }, { @@ -3001,7 +2996,7 @@ "@microsoft/vscode-azext-azureappservice": "~2.0", "@microsoft/vscode-azext-azureauth": "^1.1.2", "@microsoft/vscode-azext-azureutils": "^2.0.0", - "@microsoft/vscode-azext-utils": "^2.0.0", + "@microsoft/vscode-azext-utils": "file:../vscode-azuretools/utils/microsoft-vscode-azext-utils-2.1.1.tgz", "@microsoft/vscode-container-client": "^0.1.0", "@microsoft/vscode-docker-registries": "file:../vscode-docker-extensibility/packages/vscode-docker-registries/microsoft-vscode-docker-registries-0.1.0.tgz", "dayjs": "^1.11.7", diff --git a/src/commands/images/pushImage.ts b/src/commands/images/pushImage.ts index badb092890..421e25c1e6 100644 --- a/src/commands/images/pushImage.ts +++ b/src/commands/images/pushImage.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, NoResourceFoundError, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { IActionContext, NoResourceFoundError } from '@microsoft/vscode-azext-utils'; import { parseDockerLikeImageName } from '@microsoft/vscode-container-client'; import { CommonRegistry } from '@microsoft/vscode-docker-registries'; import * as vscode from 'vscode'; @@ -11,6 +11,7 @@ import { ext } from '../../extensionVariables'; import { TaskCommandRunnerFactory } from '../../runtimes/runners/TaskCommandRunnerFactory'; import { ImageTreeItem } from '../../tree/images/ImageTreeItem'; import { UnifiedRegistryItem } from '../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { registryExperience } from '../../utils/registryExperience'; import { addImageTaggingTelemetry, tagImage } from './tagImage'; export async function pushImage(context: IActionContext, node: ImageTreeItem | undefined): Promise { @@ -31,7 +32,7 @@ export async function pushImage(context: IActionContext, node: ImageTreeItem | u // If the prompt setting is true, we'll ask; if not we'll assume Docker Hub. if (prompt) { try { - connectedRegistry = await contextValueExperience(context, ext.registriesTree, { include: ['commonregistry'] }); + connectedRegistry = await registryExperience(context, { contextValueFilter: { include: [/commonregistry/i] } }); } catch (error) { if (error instanceof NoResourceFoundError) { // Do nothing, move on without a selected registry @@ -42,7 +43,14 @@ export async function pushImage(context: IActionContext, node: ImageTreeItem | u } } else { // Try to find a connected Docker Hub registry (primarily for login credentials) - connectedRegistry = await contextValueExperience(context, ext.dockerHubRegistryDataProvider, { include: ['dockerHubRegistry'] }); + connectedRegistry = await registryExperience( + context, + { + registryFilter: { include: [ext.dockerHubRegistryDataProvider.label] }, + contextValueFilter: { include: /commonregistry/i }, + skipIfOne: true + } + ); } } else { // The registry to push to is determinate. If there's a connected registry in the tree view, we'll try to find it, to perform login ahead of time. @@ -84,7 +92,7 @@ async function tryGetConnectedRegistryForPath(context: IActionContext, baseImage let matchedRegistry = allRegistries.find((registry) => registry.wrappedItem.baseUrl.authority === baseImageNameInfo.registry); if (!matchedRegistry) { - matchedRegistry = await contextValueExperience(context, ext.registriesTree, { include: ['commonregistry'] }); + matchedRegistry = await registryExperience(context, { contextValueFilter: { include: [/commonregistry/i] } }); } return matchedRegistry; diff --git a/src/commands/registries/azure/createAzureRegistry.ts b/src/commands/registries/azure/createAzureRegistry.ts index 1c65bd67ea..137be90bb3 100644 --- a/src/commands/registries/azure/createAzureRegistry.ts +++ b/src/commands/registries/azure/createAzureRegistry.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AzureWizard, IActionContext, contextValueExperience, createSubscriptionContext, nonNullProp } from '@microsoft/vscode-azext-utils'; +import { AzureWizard, IActionContext, createSubscriptionContext, nonNullProp } from '@microsoft/vscode-azext-utils'; import { l10n, window } from 'vscode'; import { ext } from '../../../extensionVariables'; import { AzureSubscriptionRegistryItem } from '../../../tree/registries/Azure/AzureRegistryDataProvider'; @@ -11,16 +11,22 @@ import { AzureRegistryCreateStep } from '../../../tree/registries/Azure/createWi import { AzureRegistryNameStep } from '../../../tree/registries/Azure/createWizard/AzureRegistryNameStep'; import { AzureRegistrySkuStep } from '../../../tree/registries/Azure/createWizard/AzureRegistrySkuStep'; import { IAzureRegistryWizardContext } from '../../../tree/registries/Azure/createWizard/IAzureRegistryWizardContext'; -import { UnifiedRegistryItem, isUnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { UnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; import { getAzExtAzureUtils } from '../../../utils/lazyPackages'; +import { registryExperience } from '../../../utils/registryExperience'; export async function createAzureRegistry(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.azureRegistryDataProvider, { include: 'azuresubscription' }); + node = await registryExperience(context, + { + contextValueFilter: { include: /azuresubscription/i }, + registryFilter: { include: [ext.azureRegistryDataProvider.label] } + } + ); } - const registryItem = isUnifiedRegistryItem(node) ? node.wrappedItem : node; + const registryItem = node.wrappedItem; const subscriptionContext = createSubscriptionContext(registryItem.subscription); const wizardContext: IAzureRegistryWizardContext = { diff --git a/src/commands/registries/azure/deleteAzureRegistry.ts b/src/commands/registries/azure/deleteAzureRegistry.ts index 2ef44c8453..3125cecb78 100644 --- a/src/commands/registries/azure/deleteAzureRegistry.ts +++ b/src/commands/registries/azure/deleteAzureRegistry.ts @@ -3,16 +3,20 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DialogResponses, IActionContext, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { DialogResponses, IActionContext } from '@microsoft/vscode-azext-utils'; import { ProgressLocation, l10n, window } from 'vscode'; import { ext } from '../../../extensionVariables'; import { AzureRegistry, AzureRegistryDataProvider } from '../../../tree/registries/Azure/AzureRegistryDataProvider'; import { UnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { registryExperience } from '../../../utils/registryExperience'; export async function deleteAzureRegistry(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { // we can't pass in the azure tree provider because it's not a UnifiedRegistryItem and we need the provider to delete - node = await contextValueExperience(context, ext.registriesTree, { include: 'azureContainerRegistry' }); + node = await registryExperience(context, { + contextValueFilter: { include: /commonregistry/i }, + registryFilter: { include: [ext.azureRegistryDataProvider.label] } + }); } const registryName = node.wrappedItem.label; diff --git a/src/commands/registries/azure/deleteAzureRepository.ts b/src/commands/registries/azure/deleteAzureRepository.ts index 335a2baa60..07d71f707c 100644 --- a/src/commands/registries/azure/deleteAzureRepository.ts +++ b/src/commands/registries/azure/deleteAzureRepository.ts @@ -3,16 +3,20 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DialogResponses, IActionContext, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { DialogResponses, IActionContext } from '@microsoft/vscode-azext-utils'; import { ProgressLocation, l10n, window } from 'vscode'; import { ext } from '../../../extensionVariables'; import { AzureRegistryDataProvider, AzureRepository } from '../../../tree/registries/Azure/AzureRegistryDataProvider'; import { UnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { registryExperience } from '../../../utils/registryExperience'; export async function deleteAzureRepository(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { // we can't pass in the azure tree provider because it's not a UnifiedRegistryItem and we need the provider to delete - node = await contextValueExperience(context, ext.registriesTree, { include: 'azureContainerRepository' }); + node = await registryExperience(context, { + contextValueFilter: { include: /commonrepository/i }, + registryFilter: { include: [ext.azureRegistryDataProvider.label] } + }); } const confirmDelete = l10n.t('Are you sure you want to delete repository "{0}" and its associated images?', node.wrappedItem.label); diff --git a/src/commands/registries/azure/deployImageToAca.ts b/src/commands/registries/azure/deployImageToAca.ts index c84198e975..89b447eff9 100644 --- a/src/commands/registries/azure/deployImageToAca.ts +++ b/src/commands/registries/azure/deployImageToAca.ts @@ -3,16 +3,16 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { contextValueExperience, IActionContext, nonNullProp, UserCancelledError } from '@microsoft/vscode-azext-utils'; +import { IActionContext, nonNullProp, UserCancelledError } from '@microsoft/vscode-azext-utils'; import { parseDockerLikeImageName } from '@microsoft/vscode-container-client'; import { CommonRegistry, CommonTag, isDockerHubRegistry, LoginInformation } from '@microsoft/vscode-docker-registries'; import * as semver from 'semver'; import * as vscode from 'vscode'; -import { ext } from '../../../extensionVariables'; import { isAzureRegistry } from '../../../tree/registries/Azure/AzureRegistryDataProvider'; import { getFullImageNameFromRegistryTagItem } from '../../../tree/registries/registryTreeUtils'; import { UnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; import { installExtension } from '../../../utils/installExtension'; +import { registryExperience } from '../../../utils/registryExperience'; import { addImageTaggingTelemetry } from '../../images/tagImage'; const acaExtensionId = 'ms-azuretools.vscode-azurecontainerapps'; @@ -35,7 +35,7 @@ export async function deployImageToAca(context: IActionContext, node?: UnifiedRe } if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commontag' }); + node = await registryExperience(context, { contextValueFilter: { include: /commontag/i } }); } const commandOptions: Partial = { diff --git a/src/commands/registries/azure/deployImageToAzure.ts b/src/commands/registries/azure/deployImageToAzure.ts index 20dd8c8531..7bba3abb90 100644 --- a/src/commands/registries/azure/deployImageToAzure.ts +++ b/src/commands/registries/azure/deployImageToAzure.ts @@ -5,7 +5,7 @@ import type { Site } from '@azure/arm-appservice'; // These are only dev-time imports so don't need to be lazy import type { IAppServiceWizardContext } from "@microsoft/vscode-azext-azureappservice"; // These are only dev-time imports so don't need to be lazy -import { AzureWizard, AzureWizardExecuteStep, AzureWizardPromptStep, IActionContext, contextValueExperience, createSubscriptionContext, nonNullProp } from "@microsoft/vscode-azext-utils"; +import { AzureWizard, AzureWizardExecuteStep, AzureWizardPromptStep, IActionContext, createSubscriptionContext, nonNullProp } from "@microsoft/vscode-azext-utils"; import { CommonTag } from '@microsoft/vscode-docker-registries'; import { Uri, env, l10n, window } from "vscode"; import { ext } from "../../../extensionVariables"; @@ -24,15 +24,18 @@ export interface IAppServiceContainerWizardContext extends IAppServiceWizardCont export async function deployImageToAzure(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: ['commontag'], }); + node = await registryExperience(context, { contextValueFilter: { include: 'commontag' } }); } const azExtAzureUtils = await getAzExtAzureUtils(); const vscAzureAppService = await getAzExtAppService(); const promptSteps: AzureWizardPromptStep[] = []; - const subscriptionItem = await registryExperience(context, ext.azureRegistryDataProvider, { include: 'azuresubscription' }) as AzureSubscriptionRegistryItem; - const subscriptionContext = createSubscriptionContext(subscriptionItem.subscription); + const subscriptionItem = await registryExperience(context, { + registryFilter: { include: [ext.azureRegistryDataProvider.label] }, + contextValueFilter: { include: /azuresubscription/i }, + }); + const subscriptionContext = createSubscriptionContext(subscriptionItem.wrappedItem.subscription); const wizardContext: IActionContext & Partial = { ...context, ...subscriptionContext, diff --git a/src/commands/registries/azure/openInAzurePortal.ts b/src/commands/registries/azure/openInAzurePortal.ts index 3f66c09504..f72b11b2d2 100644 --- a/src/commands/registries/azure/openInAzurePortal.ts +++ b/src/commands/registries/azure/openInAzurePortal.ts @@ -3,18 +3,22 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience, createSubscriptionContext } from '@microsoft/vscode-azext-utils'; +import { IActionContext, createSubscriptionContext } from '@microsoft/vscode-azext-utils'; import { ext } from '../../../extensionVariables'; import { AzureRegistry, AzureRepository, AzureSubscriptionRegistryItem, isAzureRegistry, isAzureSubscriptionRegistryItem } from '../../../tree/registries/Azure/AzureRegistryDataProvider'; -import { UnifiedRegistryItem, isUnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { UnifiedRegistryItem } from '../../../tree/registries/UnifiedRegistryTreeDataProvider'; import { getAzExtAzureUtils } from '../../../utils/lazyPackages'; +import { registryExperience } from '../../../utils/registryExperience'; export async function openInAzurePortal(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.azureRegistryDataProvider, { include: ['azureContainerRegistry'] }); + node = await registryExperience(context, { + registryFilter: { include: [ext.azureRegistryDataProvider.label] }, + contextValueFilter: { include: [/commonregistry/i] }, + }); } - const azureRegistryItem = isUnifiedRegistryItem(node) ? node.wrappedItem : node; + const azureRegistryItem = node.wrappedItem; const azExtAzureUtils = await getAzExtAzureUtils(); let subscriptionContext = undefined; if (isAzureSubscriptionRegistryItem(azureRegistryItem)) { diff --git a/src/commands/registries/azure/tasks/scheduleRunRequest.ts b/src/commands/registries/azure/tasks/scheduleRunRequest.ts index 4db6aa19c2..02e680aff8 100644 --- a/src/commands/registries/azure/tasks/scheduleRunRequest.ts +++ b/src/commands/registries/azure/tasks/scheduleRunRequest.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { DockerBuildRequest as AcrDockerBuildRequest, FileTaskRunRequest as AcrFileTaskRunRequest, OS as AcrOS, Run as AcrRun, ContainerRegistryManagementClient } from "@azure/arm-containerregistry"; // These are only dev-time imports so don't need to be lazy -import { IActionContext, IAzureQuickPickItem, contextValueExperience, nonNullProp } from '@microsoft/vscode-azext-utils'; +import { IActionContext, IAzureQuickPickItem, nonNullProp } from '@microsoft/vscode-azext-utils'; import * as fse from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; @@ -12,13 +12,14 @@ import * as readline from 'readline'; import * as tar from 'tar'; import * as vscode from 'vscode'; import { ext } from '../../../../extensionVariables'; -import { AzureRegistryItem } from "../../../../tree/registries/Azure/AzureRegistryDataProvider"; -import { UnifiedRegistryItem, isUnifiedRegistryItem } from "../../../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { AzureRegistry, AzureRegistryItem } from "../../../../tree/registries/Azure/AzureRegistryDataProvider"; +import { UnifiedRegistryItem } from "../../../../tree/registries/UnifiedRegistryTreeDataProvider"; import { createAzureContainerRegistryClient, getResourceGroupFromId } from "../../../../utils/azureUtils"; import { getStorageBlob } from '../../../../utils/lazyPackages'; import { delay } from '../../../../utils/promiseUtils'; import { Item, quickPickDockerFileItem, quickPickYamlFileItem } from '../../../../utils/quickPickFile'; import { quickPickWorkspaceFolder } from '../../../../utils/quickPickWorkspaceFolder'; +import { registryExperience } from "../../../../utils/registryExperience"; import { addImageTaggingTelemetry, getTagFromUserInput } from '../../../images/tagImage'; const idPrecision = 6; @@ -46,8 +47,11 @@ export async function scheduleRunRequest(context: IActionContext, requestType: ' throw new Error(vscode.l10n.t('Run Request Type Currently not supported.')); } - const node: UnifiedRegistryItem = await contextValueExperience(context, ext.azureRegistryDataProvider, { include: 'azureContainerRegistry' }); - const registryItem: AzureRegistryItem = isUnifiedRegistryItem(node) ? node.wrappedItem : node; + const node: UnifiedRegistryItem = await registryExperience(context, { + registryFilter: { include: [ext.azureRegistryDataProvider.label] }, + contextValueFilter: { include: /commonregistry/i }, + }); + const registryItem: AzureRegistryItem = node.wrappedItem; const resourceGroup = getResourceGroupFromId(registryItem.id); const osPick = ['Linux', 'Windows'].map(item => >{ label: item, data: item }); diff --git a/src/commands/registries/azure/untagAzureImage.ts b/src/commands/registries/azure/untagAzureImage.ts index 49867042fa..285ab301bb 100644 --- a/src/commands/registries/azure/untagAzureImage.ts +++ b/src/commands/registries/azure/untagAzureImage.ts @@ -3,17 +3,21 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { contextValueExperience, IActionContext } from "@microsoft/vscode-azext-utils"; +import { IActionContext } from "@microsoft/vscode-azext-utils"; import { l10n, ProgressLocation, window } from "vscode"; import { ext } from "../../../extensionVariables"; import { AzureRegistryDataProvider, AzureTag } from "../../../tree/registries/Azure/AzureRegistryDataProvider"; import { getFullImageNameFromRegistryTagItem } from "../../../tree/registries/registryTreeUtils"; import { UnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { registryExperience } from "../../../utils/registryExperience"; export async function untagAzureImage(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { // we can't pass in the azure tree provider because it's not a UnifiedRegistryItem and we need the provider to untag - node = await contextValueExperience(context, ext.registriesTree, { include: 'azureContainerTag' }); + node = await registryExperience(context, { + registryFilter: { include: [ext.azureRegistryDataProvider.label] }, + contextValueFilter: { include: /commontag/i }, + }); } const fullTag = getFullImageNameFromRegistryTagItem(node.wrappedItem); diff --git a/src/commands/registries/azure/viewAzureProperties.ts b/src/commands/registries/azure/viewAzureProperties.ts index e70398edef..298dfdf74e 100644 --- a/src/commands/registries/azure/viewAzureProperties.ts +++ b/src/commands/registries/azure/viewAzureProperties.ts @@ -6,14 +6,17 @@ import { IActionContext, openReadOnlyJson } from "@microsoft/vscode-azext-utils"; import { ext } from "../../../extensionVariables"; import { AzureRegistry } from "../../../tree/registries/Azure/AzureRegistryDataProvider"; -import { UnifiedRegistryItem, isUnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { UnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; import { registryExperience } from "../../../utils/registryExperience"; export async function viewAzureProperties(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await registryExperience(context, ext.azureRegistryDataProvider, { 'include': 'azureContainerRegistry' }, true); + node = await registryExperience(context, { + registryFilter: { include: [ext.azureRegistryDataProvider.label] }, + contextValueFilter: { include: /commonregistry/i }, + }); } - const registryItem = isUnifiedRegistryItem(node) ? node.wrappedItem : node; + const registryItem = node.wrappedItem; await openReadOnlyJson({ label: registryItem.label, fullId: registryItem.id }, registryItem.registryProperties); } diff --git a/src/commands/registries/copyRemoteFullTag.ts b/src/commands/registries/copyRemoteFullTag.ts index 1cf1c7a475..6cb63e1cfd 100644 --- a/src/commands/registries/copyRemoteFullTag.ts +++ b/src/commands/registries/copyRemoteFullTag.ts @@ -3,16 +3,16 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { IActionContext } from '@microsoft/vscode-azext-utils'; import { CommonTag } from '@microsoft/vscode-docker-registries'; import * as vscode from 'vscode'; -import { ext } from '../../extensionVariables'; import { UnifiedRegistryItem } from '../../tree/registries/UnifiedRegistryTreeDataProvider'; import { getFullImageNameFromRegistryTagItem } from '../../tree/registries/registryTreeUtils'; +import { registryExperience } from '../../utils/registryExperience'; export async function copyRemoteFullTag(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commontag' }); + node = await registryExperience(context, { contextValueFilter: { include: /commontag/i } }); } const fullTag = getFullImageNameFromRegistryTagItem(node.wrappedItem); void vscode.env.clipboard.writeText(fullTag); diff --git a/src/commands/registries/copyRemoteImageDigest.ts b/src/commands/registries/copyRemoteImageDigest.ts index 7daad72e76..9411cca1f4 100644 --- a/src/commands/registries/copyRemoteImageDigest.ts +++ b/src/commands/registries/copyRemoteImageDigest.ts @@ -3,15 +3,19 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from "@microsoft/vscode-azext-utils"; -import { RegistryV2DataProvider, V2Tag } from "@microsoft/vscode-docker-registries"; +import { IActionContext } from "@microsoft/vscode-azext-utils"; +import { CommonTag, RegistryV2DataProvider } from "@microsoft/vscode-docker-registries"; import * as vscode from "vscode"; import { ext } from "../../extensionVariables"; import { UnifiedRegistryItem } from "../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { registryExperience } from "../../utils/registryExperience"; -export async function copyRemoteImageDigest(context: IActionContext, node?: UnifiedRegistryItem): Promise { +export async function copyRemoteImageDigest(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: ['registryV2Tag'] }); + node = await registryExperience(context, { + registryFilter: { exclude: [ext.dockerHubRegistryDataProvider.label] }, + contextValueFilter: { include: /commontag/i, }, + }); } const v2DataProvider = node.provider as unknown as RegistryV2DataProvider; diff --git a/src/commands/registries/deleteRemoteImage.ts b/src/commands/registries/deleteRemoteImage.ts index e1e1c5d870..10b430025a 100644 --- a/src/commands/registries/deleteRemoteImage.ts +++ b/src/commands/registries/deleteRemoteImage.ts @@ -13,7 +13,10 @@ import { registryExperience } from '../../utils/registryExperience'; export async function deleteRemoteImage(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await registryExperience(context, ext.registriesTree, { include: 'commontag', exclude: ['githubRegistryTag', 'dockerHubTag'] }, false); + node = await registryExperience(context, { + registryFilter: { exclude: [ext.githubRegistryDataProvider.label, ext.dockerHubRegistryDataProvider.label] }, + contextValueFilter: { include: /commontag/i }, + }); } const provider = node.provider as unknown as CommonRegistryDataProvider; @@ -46,6 +49,5 @@ export async function deleteRemoteImage(context: IActionContext, node?: UnifiedR // Other tags that also matched the image may have been deleted, so refresh the whole repository // don't wait void ext.registriesTree.refresh(); - /* eslint-disable-next-line @typescript-eslint/no-floating-promises */ - window.showInformationMessage(l10n.t('Successfully deleted image "{0}".', tagName)); + void window.showInformationMessage(l10n.t('Successfully deleted image "{0}".', tagName)); } diff --git a/src/commands/registries/disconnectRegistry.ts b/src/commands/registries/disconnectRegistry.ts index e158c6b49d..50a81d50c5 100644 --- a/src/commands/registries/disconnectRegistry.ts +++ b/src/commands/registries/disconnectRegistry.ts @@ -3,13 +3,15 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from "@microsoft/vscode-azext-utils"; +import { IActionContext } from "@microsoft/vscode-azext-utils"; +import { CommonRegistry } from "@microsoft/vscode-docker-registries"; import { ext } from "../../extensionVariables"; import { UnifiedRegistryItem } from "../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { registryExperience } from "../../utils/registryExperience"; export async function disconnectRegistry(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commonregistryroot', exclude: 'genericRegistryV2Root' }); + node = await registryExperience(context, { registryFilter: { exclude: [ext.genericRegistryV2DataProvider.label] } }); } await ext.registriesTree.disconnectRegistryProvider(node); diff --git a/src/commands/registries/dockerHub/openDockerHubInBrowser.ts b/src/commands/registries/dockerHub/openDockerHubInBrowser.ts index 41273d803f..a3cc62af61 100644 --- a/src/commands/registries/dockerHub/openDockerHubInBrowser.ts +++ b/src/commands/registries/dockerHub/openDockerHubInBrowser.ts @@ -8,16 +8,19 @@ import { CommonRegistryItem, isRegistry, isRepository, isTag } from "@microsoft/ import * as vscode from "vscode"; import { dockerHubUrl } from "../../../constants"; import { ext } from "../../../extensionVariables"; -import { UnifiedRegistryItem, isUnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { UnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; import { registryExperience } from "../../../utils/registryExperience"; export async function openDockerHubInBrowser(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await registryExperience(context, ext.dockerHubRegistryDataProvider, { include: ['dockerHubRegistry'] }, true); + node = await registryExperience(context, { + registryFilter: { include: [ext.dockerHubRegistryDataProvider.label] }, + contextValueFilter: { include: [/commonregistry/i] }, + }); } let url = dockerHubUrl; - const dockerHubItem = isUnifiedRegistryItem(node) ? node.wrappedItem : node; + const dockerHubItem = node.wrappedItem; if (isRegistry(dockerHubItem)) { url = `${url}u/${dockerHubItem.label}`; diff --git a/src/commands/registries/genericV2/removeTrackedGenericV2Registry.ts b/src/commands/registries/genericV2/removeTrackedGenericV2Registry.ts index 23e1540c82..9c9815b3a5 100644 --- a/src/commands/registries/genericV2/removeTrackedGenericV2Registry.ts +++ b/src/commands/registries/genericV2/removeTrackedGenericV2Registry.ts @@ -3,14 +3,18 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from "@microsoft/vscode-azext-utils"; -import { GenericV2Registry } from "@microsoft/vscode-docker-registries"; +import { IActionContext } from "@microsoft/vscode-azext-utils"; +import { V2Registry } from "@microsoft/vscode-docker-registries"; import { ext } from "../../../extensionVariables"; import { UnifiedRegistryItem } from "../../../tree/registries/UnifiedRegistryTreeDataProvider"; +import { registryExperience } from "../../../utils/registryExperience"; -export async function removeTrackedGenericV2Registry(context: IActionContext, node?: UnifiedRegistryItem): Promise { +export async function removeTrackedGenericV2Registry(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.genericRegistryV2DataProvider, { include: 'genericRegistryV2Registry' }); + node = await registryExperience(context, { + registryFilter: { include: [ext.genericRegistryV2DataProvider.label] }, + contextValueFilter: { include: /commonregistry/i }, + }); } await ext.genericRegistryV2DataProvider.removeTrackedRegistry(node.wrappedItem); diff --git a/src/commands/registries/logInToDockerCli.ts b/src/commands/registries/logInToDockerCli.ts index 594a822d85..2f30e6f8ef 100644 --- a/src/commands/registries/logInToDockerCli.ts +++ b/src/commands/registries/logInToDockerCli.ts @@ -3,16 +3,17 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience, parseError } from '@microsoft/vscode-azext-utils'; +import { IActionContext, parseError } from '@microsoft/vscode-azext-utils'; import { CommonRegistry } from '@microsoft/vscode-docker-registries'; import * as stream from 'stream'; import * as vscode from 'vscode'; import { ext } from '../../extensionVariables'; import { UnifiedRegistryItem } from '../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { registryExperience } from '../../utils/registryExperience'; export async function logInToDockerCli(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesRoot, { include: 'commonregistry' }); + node = await registryExperience(context, { contextValueFilter: { include: /commonregistry/i } }); } const creds = await node.provider?.getLoginInformation?.(node.wrappedItem); diff --git a/src/commands/registries/logOutOfDockerCli.ts b/src/commands/registries/logOutOfDockerCli.ts index 7c93a4b89d..dd9e774798 100644 --- a/src/commands/registries/logOutOfDockerCli.ts +++ b/src/commands/registries/logOutOfDockerCli.ts @@ -3,16 +3,17 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { IActionContext } from '@microsoft/vscode-azext-utils'; import { CommonRegistry } from '@microsoft/vscode-docker-registries'; import { l10n } from 'vscode'; import { ext } from '../../extensionVariables'; import { TaskCommandRunnerFactory } from '../../runtimes/runners/TaskCommandRunnerFactory'; import { UnifiedRegistryItem } from '../../tree/registries/UnifiedRegistryTreeDataProvider'; +import { registryExperience } from '../../utils/registryExperience'; export async function logOutOfDockerCli(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commonregistry' }); + node = await registryExperience(context, { contextValueFilter: { include: /commonregistry/i } }); } const serverUrl = (await node.provider.getLoginInformation?.(node.wrappedItem))?.server; if (!serverUrl) { diff --git a/src/commands/registries/pullImages.ts b/src/commands/registries/pullImages.ts index 1a9489f214..7e21b5447e 100644 --- a/src/commands/registries/pullImages.ts +++ b/src/commands/registries/pullImages.ts @@ -3,17 +3,18 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext, contextValueExperience } from '@microsoft/vscode-azext-utils'; +import { IActionContext } from '@microsoft/vscode-azext-utils'; import { CommonRegistry, CommonRepository, CommonTag } from '@microsoft/vscode-docker-registries/lib/clients/Common/models'; import { ext } from '../../extensionVariables'; import { TaskCommandRunnerFactory } from '../../runtimes/runners/TaskCommandRunnerFactory'; import { UnifiedRegistryItem } from '../../tree/registries/UnifiedRegistryTreeDataProvider'; import { getFullImageNameFromRegistryTagItem, getFullRepositoryNameFromRepositoryItem } from '../../tree/registries/registryTreeUtils'; +import { registryExperience } from '../../utils/registryExperience'; import { logInToDockerCli } from './logInToDockerCli'; export async function pullRepository(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commonrepository' }); + node = await registryExperience(context, { contextValueFilter: { include: /commonrepository/i } }); } await pullImages(context, node.parent, getFullRepositoryNameFromRepositoryItem(node.wrappedItem), true); @@ -21,7 +22,7 @@ export async function pullRepository(context: IActionContext, node?: UnifiedRegi export async function pullImageFromRepository(context: IActionContext, node?: UnifiedRegistryItem): Promise { if (!node) { - node = await contextValueExperience(context, ext.registriesTree, { include: 'commontag' }); + node = await registryExperience(context, { contextValueFilter: { include: /commontag/i } }); } await pullImages(context, node.parent.parent, getFullImageNameFromRegistryTagItem(node.wrappedItem), false); diff --git a/src/commands/registries/reconnectRegistry.ts b/src/commands/registries/reconnectRegistry.ts index 16abcdecf1..258d5027fb 100644 --- a/src/commands/registries/reconnectRegistry.ts +++ b/src/commands/registries/reconnectRegistry.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IActionContext } from "@microsoft/vscode-azext-utils"; -import { GenericV2Registry, RegistryConnectError, isGenericV2Registry } from "@microsoft/vscode-docker-registries"; +import { RegistryConnectError, V2Registry, isGenericV2Registry } from "@microsoft/vscode-docker-registries"; import { l10n } from 'vscode'; import { ext } from "../../extensionVariables"; import { UnifiedRegistryItem } from "../../tree/registries/UnifiedRegistryTreeDataProvider"; @@ -16,7 +16,7 @@ export async function reconnectRegistry(context: IActionContext, node?: UnifiedR } if (isGenericV2Registry(node.parent.wrappedItem)) { - await ext.genericRegistryV2DataProvider.removeTrackedRegistry(node.parent.wrappedItem as GenericV2Registry); + await ext.genericRegistryV2DataProvider.removeTrackedRegistry(node.parent.wrappedItem as V2Registry); await ext.genericRegistryV2DataProvider.addTrackedRegistry(); } else { await ext.registriesTree.disconnectRegistryProvider(node.parent); diff --git a/src/tree/registries/Azure/AzureRegistryDataProvider.ts b/src/tree/registries/Azure/AzureRegistryDataProvider.ts index a7a75daf88..494eec04c8 100644 --- a/src/tree/registries/Azure/AzureRegistryDataProvider.ts +++ b/src/tree/registries/Azure/AzureRegistryDataProvider.ts @@ -6,7 +6,7 @@ import type { Registry as AcrRegistry, RegistryListCredentialsResult } from '@azure/arm-containerregistry'; import { AzureSubscription, VSCodeAzureSubscriptionProvider } from '@microsoft/vscode-azext-azureauth'; import { RegistryV2DataProvider, V2Registry, V2RegistryItem, V2Repository, V2Tag, getContextValue, registryV2Request } from '@microsoft/vscode-docker-registries'; -import { CommonRegistryItem, isRegistryRoot } from '@microsoft/vscode-docker-registries/lib/clients/Common/models'; +import { CommonRegistryItem, isRegistry, isRegistryRoot, isRepository, isTag } from '@microsoft/vscode-docker-registries/lib/clients/Common/models'; import * as vscode from 'vscode'; import { createAzureContainerRegistryClient, getResourceGroupFromId } from '../../../utils/azureUtils'; import { ACROAuthProvider } from './ACROAuthProvider'; @@ -34,15 +34,15 @@ export function isAzureSubscriptionRegistryItem(item: unknown): item is AzureSub } export function isAzureRegistry(item: unknown): item is AzureRegistry { - return !!item && typeof item === 'object' && (item as AzureRegistryItem).additionalContextValues?.includes('azureContainerRegistry'); + return isRegistry(item) && item.additionalContextValues?.includes('azure'); } export function isAzureRepository(item: unknown): item is AzureRepository { - return !!item && typeof item === 'object' && (item as AzureRepository).additionalContextValues?.includes('azureContainerRepository'); + return isRepository(item) && item.additionalContextValues?.includes('azure'); } export function isAzureTag(item: unknown): item is AzureTag { - return !!item && typeof item === 'object' && (item as AzureTag).additionalContextValues?.includes('azureContainerTag'); + return isTag(item) && item.additionalContextValues?.includes('azure'); } export class AzureRegistryDataProvider extends RegistryV2DataProvider implements vscode.Disposable { @@ -79,13 +79,18 @@ export class AzureRegistryDataProvider extends RegistryV2DataProvider implements } as AzureSubscriptionRegistryItem; }); } else if (isAzureSubscriptionRegistryItem(element)) { - return await this.getRegistries(element); + const registries = await this.getRegistries(element); + registries.forEach(registry => { + registry.additionalContextValues = [...(registry.additionalContextValues || []), 'azure']; + }); + return registries; } else { const children = await super.getChildren(element); if ((element as AzureRegistryItem)?.subscription) { children.forEach(e => { e.subscription = (element as AzureRegistryItem).subscription; + e.additionalContextValues = [...(e.additionalContextValues || []), 'azure']; }); } @@ -124,26 +129,6 @@ export class AzureRegistryDataProvider extends RegistryV2DataProvider implements }); } - public override async getRepositories(registry: AzureRegistry): Promise { - const repositories = await super.getRepositories(registry); - const repositoriesWithAdditionalContext = repositories.map(repository => ({ - ...repository, - additionalContextValues: ['azureContainerRepository'] - })); - - return repositoriesWithAdditionalContext; - } - - public override async getTags(repository: AzureRepository): Promise { - const tags = await super.getTags(repository); - const tagsWithAdditionalContext = tags.map(tag => ({ - ...tag, - additionalContextValues: ['azureContainerTag'] - })); - - return tagsWithAdditionalContext; - } - public override getTreeItem(element: CommonRegistryItem): Promise { if (isAzureSubscriptionRegistryItem(element)) { return Promise.resolve({ diff --git a/src/tree/registries/UnifiedRegistryTreeDataProvider.ts b/src/tree/registries/UnifiedRegistryTreeDataProvider.ts index 95d332496f..d4cb4066d4 100644 --- a/src/tree/registries/UnifiedRegistryTreeDataProvider.ts +++ b/src/tree/registries/UnifiedRegistryTreeDataProvider.ts @@ -9,10 +9,6 @@ export interface UnifiedRegistryItem { parent: UnifiedRegistryItem | undefined; } -export function isUnifiedRegistryItem(item: unknown): item is UnifiedRegistryItem { - return !!item && typeof item === 'object' && 'provider' in item && 'wrappedItem' in item && 'parent' in item; -} - const ConnectedRegistryProvidersKey = 'ConnectedRegistryProviders'; export class UnifiedRegistryTreeDataProvider implements vscode.TreeDataProvider> { diff --git a/src/utils/registryExperience.ts b/src/utils/registryExperience.ts index e4a7eb0700..8bb6092ddf 100644 --- a/src/utils/registryExperience.ts +++ b/src/utils/registryExperience.ts @@ -3,22 +3,81 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AzureWizardPromptStep, ContextValueFilter, IActionContext, QuickPickWizardContext, RecursiveQuickPickStep, runQuickPickWizard } from '@microsoft/vscode-azext-utils'; -import * as vscode from 'vscode'; +import { AzureWizardPromptStep, ContextValueFilterQuickPickOptions, GenericQuickPickStep, IActionContext, PickFilter, QuickPickWizardContext, RecursiveQuickPickStep, runQuickPickWizard } from '@microsoft/vscode-azext-utils'; +import { CommonRegistryItem } from '@microsoft/vscode-docker-registries'; +import { TreeItem } from 'vscode'; +import { ext } from '../extensionVariables'; +import { UnifiedRegistryItem, UnifiedRegistryTreeDataProvider } from '../tree/registries/UnifiedRegistryTreeDataProvider'; -export async function registryExperience(context: IActionContext, tdp: vscode.TreeDataProvider, contextValueFilter: ContextValueFilter, skipIfOne: boolean = true): Promise { +export interface RegistryFilter { + /** + * This filter will include registry labels that you do want to show in the quick pick. + */ + include?: string[]; + + /** + * This filter will exclude registry labels that you don't want to show in the quick pick. If `exclude` is present, `include` will be ignored. + */ + exclude?: string[]; +} + +export interface RegistryExperienceOptions extends Partial { + // if registryFilter is undefined, all registries will be shown in the quick pick + registryFilter?: RegistryFilter; +} + +export async function registryExperience(context: IActionContext, options?: RegistryExperienceOptions): Promise> { + // get the registry provider unified item const promptSteps: AzureWizardPromptStep[] = [ - new RecursiveQuickPickStep( - tdp, - { - contextValueFilter: contextValueFilter, - skipIfOne: skipIfOne - } - ) + new RegistryQuickPickStep(ext.registriesTree, options) ]; - return await runQuickPickWizard(context, { + if (options?.contextValueFilter) { + promptSteps.push(new RecursiveQuickPickStep(ext.registriesTree, options as ContextValueFilterQuickPickOptions)); + } + + const unifiedRegistryItem = await runQuickPickWizard>(context, { hideStepCount: true, promptSteps: promptSteps, }); + + return unifiedRegistryItem; +} + +export class RegistryPickFilter implements PickFilter { + public constructor(private readonly options: RegistryExperienceOptions) { } + + public isFinalPick(treeItem: TreeItem, element: unknown): boolean { + if (this.options.contextValueFilter) { + return false; + } + + return this.matchesFilters(treeItem.label as string); + } + + public isAncestorPick(treeItem: TreeItem, element: unknown): boolean { + return this.matchesFilters(treeItem.label as string); + } + + private matchesFilters(treeItemLabel: string): boolean { + if (this.options.registryFilter?.exclude) { + return !this.options.registryFilter.exclude.includes(treeItemLabel); + } else if (this.options.registryFilter?.include) { + return this.options.registryFilter.include.includes(treeItemLabel); + } else { + return true; + } + } +} + +export class RegistryQuickPickStep extends GenericQuickPickStep { + public readonly pickFilter: PickFilter; + + public constructor( + protected readonly treeDataProvider: UnifiedRegistryTreeDataProvider, + protected readonly pickOptions: RegistryExperienceOptions, + ) { + super(treeDataProvider, pickOptions); + this.pickFilter = new RegistryPickFilter(pickOptions); + } }