зеркало из https://github.com/microsoft/kiota.git
feature/vs code filter tree view (#2561)
* - adds a welcome view for the vscode explorer * - moves the nodes loading to a separate method * - implements get parent function * - temp filtering with ugly copy * - much better filtering implementation with big o one and zero allocs * - code linting * - implements filter box * - removes clear filter button * - remembers the filter between prompts * - adds french translations for the filtering capability
This commit is contained in:
Родитель
2bbc155bff
Коммит
22a80d658a
|
@ -26,5 +26,9 @@
|
|||
"Downloading kiota...": "Téléchargement de Kiota...",
|
||||
"Generating client...": "Génération du client...",
|
||||
"Updating clients...": "Mise à jour des clients...",
|
||||
"Loading...": "Chargement..."
|
||||
"Loading...": "Chargement...",
|
||||
"Pick a lock file": "Sélectionnez un fichier verrou",
|
||||
"Open a lock file": "Ouvrir un fichier verrou",
|
||||
"Filter the API description": "Filtrer la description d'API",
|
||||
"Enter a filter": "Entrez un filtre"
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
"main": "./dist/extension.js",
|
||||
"l10n": "./l10n",
|
||||
"contributes": {
|
||||
"viewsWelcome":[
|
||||
{
|
||||
"view": "kiota.openApiExplorer",
|
||||
"contents": "%kiota.openApiExplorer.welcome%"
|
||||
}
|
||||
],
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
|
@ -77,14 +83,19 @@
|
|||
"group": "navigation@1"
|
||||
},
|
||||
{
|
||||
"command": "kiota.openApiExplorer.generateClient",
|
||||
"command": "kiota.openApiExplorer.filterDescription",
|
||||
"when": "view == kiota.openApiExplorer",
|
||||
"group": "navigation@3"
|
||||
},
|
||||
{
|
||||
"command": "kiota.openApiExplorer.closeDescription",
|
||||
"command": "kiota.openApiExplorer.generateClient",
|
||||
"when": "view == kiota.openApiExplorer",
|
||||
"group": "navigation@4"
|
||||
},
|
||||
{
|
||||
"command": "kiota.openApiExplorer.closeDescription",
|
||||
"when": "view == kiota.openApiExplorer",
|
||||
"group": "navigation@5"
|
||||
}
|
||||
],
|
||||
"view/item/context": [
|
||||
|
@ -139,6 +150,12 @@
|
|||
"title": "%kiota.selectLock.title%",
|
||||
"icon": "$(file-symlink-file)"
|
||||
},
|
||||
{
|
||||
"command": "kiota.searchLock",
|
||||
"category": "Kiota",
|
||||
"title": "%kiota.searchLock.title%",
|
||||
"icon": "$(file-symlink-file)"
|
||||
},
|
||||
{
|
||||
"command": "kiota.updateClients",
|
||||
"category": "Kiota",
|
||||
|
@ -150,6 +167,12 @@
|
|||
"title": "%kiota.openApiExplorer.generateClient.title%",
|
||||
"icon": "$(play)"
|
||||
},
|
||||
{
|
||||
"command": "kiota.openApiExplorer.filterDescription",
|
||||
"category": "Kiota",
|
||||
"title": "%kiota.openApiExplorer.filterDescription.title%",
|
||||
"icon": "$(filter)"
|
||||
},
|
||||
{
|
||||
"command": "kiota.searchApiDescription",
|
||||
"category": "Kiota",
|
||||
|
|
|
@ -14,5 +14,8 @@
|
|||
"kiota.openApiExplorer.addAllToSelectedEndpoints.title": "Tout ajouter",
|
||||
"kiota.openApiExplorer.removeAllFromSelectedEndpoints.title": "Tout supprimer",
|
||||
"kiota.openApiExplorer.closeDescription.title": "Fermer la description d'API",
|
||||
"kiota.openApiExplorer.openDescription.title": "Ouvrir une description d'API"
|
||||
"kiota.openApiExplorer.openDescription.title": "Ouvrir une description d'API",
|
||||
"kiota.openApiExplorer.welcome": "Aucune description sélectionnée.\n[Rechercher](command:kiota.searchApiDescription)\n[Ouvrir](command:kiota.openApiExplorer.openDescription)\n[Sélectionner un fichier verrou](command:kiota.searchLock)",
|
||||
"kiota.searchLock.title": "Rechercher un fichier verrou",
|
||||
"kiota.openApiExplorer.filterDescription.title": "Filtrer la description"
|
||||
}
|
||||
|
|
|
@ -14,5 +14,8 @@
|
|||
"kiota.openApiExplorer.addAllToSelectedEndpoints.title": "Add all",
|
||||
"kiota.openApiExplorer.removeAllFromSelectedEndpoints.title": "Remove all",
|
||||
"kiota.openApiExplorer.closeDescription.title": "Close API description",
|
||||
"kiota.openApiExplorer.openDescription.title": "Open API description"
|
||||
"kiota.openApiExplorer.openDescription.title": "Open API description",
|
||||
"kiota.openApiExplorer.welcome": "No API description selected.\n[Search](command:kiota.searchApiDescription)\n[Open](command:kiota.openApiExplorer.openDescription)\n[Select lock file](command:kiota.searchLock)",
|
||||
"kiota.searchLock.title": "Search for a lock file",
|
||||
"kiota.openApiExplorer.filterDescription.title": "Filter API description"
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
LogLevel,
|
||||
parseGenerationLanguage,
|
||||
} from "./kiotaInterop";
|
||||
import { generateSteps, openSteps, searchSteps } from "./steps";
|
||||
import { filterSteps, generateSteps, openSteps, searchLockSteps, searchSteps } from "./steps";
|
||||
import { getKiotaVersion } from "./getKiotaVersion";
|
||||
import { searchDescription } from "./searchDescription";
|
||||
import { generateClient } from "./generateClient";
|
||||
|
@ -20,6 +20,12 @@ import { updateClients } from "./updateClients";
|
|||
|
||||
let kiotaStatusBarItem: vscode.StatusBarItem;
|
||||
let kiotaOutputChannel: vscode.LogOutputChannel;
|
||||
const extensionId = "kiota";
|
||||
const focusCommandId = ".focus";
|
||||
const statusBarCommandId = `${extensionId}.status`;
|
||||
const treeViewId = `${extensionId}.openApiExplorer`;
|
||||
const dependenciesInfo = `${extensionId}.dependenciesInfo`;
|
||||
export const kiotaLockFile = "kiota-lock.json";
|
||||
|
||||
// This method is called when your extension is activated
|
||||
// Your extension is activated the very first time the command is executed
|
||||
|
@ -29,28 +35,22 @@ export async function activate(
|
|||
kiotaOutputChannel = vscode.window.createOutputChannel("Kiota", {
|
||||
log: true,
|
||||
});
|
||||
const extensionId = "kiota";
|
||||
const focusCommandId = ".focus";
|
||||
const statusBarCommandId = `${extensionId}.status`;
|
||||
const treeViewId = `${extensionId}.openApiExplorer`;
|
||||
const dependenciesInfo = `${extensionId}.dependenciesInfo`;
|
||||
const openApiTreeProvider = new OpenApiTreeProvider(context);
|
||||
const dependenciesInfoProvider = new DependenciesViewProvider(
|
||||
context.extensionUri
|
||||
);
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(
|
||||
`${extensionId}.selectLock`,
|
||||
async (node: { fsPath: string }) => {
|
||||
await vscode.window.withProgress({
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
cancellable: false,
|
||||
title: vscode.l10n.t("Loading...")
|
||||
}, (progress, _) => openApiTreeProvider.loadLockFile(node.fsPath));
|
||||
if (openApiTreeProvider.descriptionUrl) {
|
||||
await vscode.commands.executeCommand(`${treeViewId}${focusCommandId}`);
|
||||
`${extensionId}.searchLock`,
|
||||
async () => {
|
||||
const lockFilePath = await searchLockSteps();
|
||||
if (lockFilePath && lockFilePath.lockFilePath) {
|
||||
await loadLockFile(lockFilePath.lockFilePath, openApiTreeProvider);
|
||||
}
|
||||
}
|
||||
}),
|
||||
vscode.commands.registerCommand(
|
||||
`${extensionId}.selectLock`,
|
||||
(x) => loadLockFile(x, openApiTreeProvider)
|
||||
),
|
||||
vscode.commands.registerCommand(statusBarCommandId, async () => {
|
||||
const yesAnswer = vscode.l10n.t("Yes");
|
||||
|
@ -158,7 +158,7 @@ export async function activate(
|
|||
if (typeof config.outputPath === "string" && !openApiTreeProvider.isLockFileLoaded &&
|
||||
vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0 &&
|
||||
result && getLogEntriesForLevel(result, LogLevel.critical, LogLevel.error).length === 0) {
|
||||
await openApiTreeProvider.loadLockFile(path.join(vscode.workspace.workspaceFolders[0].uri.fsPath, config.outputPath, "kiota-lock.json"));
|
||||
await openApiTreeProvider.loadLockFile(path.join(vscode.workspace.workspaceFolders[0].uri.fsPath, config.outputPath, kiotaLockFile));
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
|
@ -171,7 +171,7 @@ export async function activate(
|
|||
async () => {
|
||||
const config = await searchSteps(x => searchDescription(context, x));
|
||||
if (config.descriptionPath) {
|
||||
openApiTreeProvider.descriptionUrl = config.descriptionPath;
|
||||
await openApiTreeProvider.setDescriptionUrl(config.descriptionPath);
|
||||
await vscode.commands.executeCommand(`${treeViewId}${focusCommandId}`);
|
||||
}
|
||||
}
|
||||
|
@ -179,12 +179,17 @@ export async function activate(
|
|||
vscode.commands.registerCommand(`${treeViewId}.closeDescription`, () =>
|
||||
openApiTreeProvider.closeDescription()
|
||||
),
|
||||
vscode.commands.registerCommand(`${treeViewId}.filterDescription`,
|
||||
async () => {
|
||||
await filterSteps(openApiTreeProvider.filter, x => openApiTreeProvider.filter = x);
|
||||
}
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
`${treeViewId}.openDescription`,
|
||||
async () => {
|
||||
const openState = await openSteps();
|
||||
if (openState.descriptionPath) {
|
||||
openApiTreeProvider.descriptionUrl = openState.descriptionPath;
|
||||
await openApiTreeProvider.setDescriptionUrl(openState.descriptionPath);
|
||||
await vscode.commands.executeCommand(`${treeViewId}${focusCommandId}`);
|
||||
}
|
||||
}
|
||||
|
@ -248,6 +253,17 @@ export async function activate(
|
|||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
async function loadLockFile(node: { fsPath: string }, openApiTreeProvider: OpenApiTreeProvider): Promise<void> {
|
||||
await vscode.window.withProgress({
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
cancellable: false,
|
||||
title: vscode.l10n.t("Loading...")
|
||||
}, (progress, _) => openApiTreeProvider.loadLockFile(node.fsPath));
|
||||
if (openApiTreeProvider.descriptionUrl) {
|
||||
await vscode.commands.executeCommand(`${treeViewId}${focusCommandId}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function exportLogsAndShowErrors(result: KiotaLogEntry[]) : Promise<void> {
|
||||
const informationMessages = result
|
||||
? getLogEntriesForLevel(result, LogLevel.information)
|
||||
|
|
|
@ -25,7 +25,7 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
this._lockFile = JSON.parse(lockFileData.toString()) as LockFile;
|
||||
if (this._lockFile?.descriptionLocation) {
|
||||
this._descriptionUrl = this._lockFile.descriptionLocation;
|
||||
await this.getChildren();
|
||||
await this.loadNodes();
|
||||
if (this.rawRootNode) {
|
||||
if (this._lockFile.includePatterns.length === 0) {
|
||||
this.setAllSelected(this.rawRootNode, true);
|
||||
|
@ -37,7 +37,7 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
}
|
||||
});
|
||||
}
|
||||
this.refresh();
|
||||
this.refreshView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,14 +62,17 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
this.rawRootNode = undefined;
|
||||
this._lockFile = undefined;
|
||||
this._lockFilePath = undefined;
|
||||
this.tokenizedFilter = [];
|
||||
this._filterText = '';
|
||||
if (shouldRefresh) {
|
||||
this.refresh();
|
||||
this.refreshView();
|
||||
}
|
||||
}
|
||||
public set descriptionUrl(descriptionUrl: string) {
|
||||
public async setDescriptionUrl(descriptionUrl: string): Promise<void> {
|
||||
this.closeDescription(false);
|
||||
this._descriptionUrl = descriptionUrl;
|
||||
this.refresh();
|
||||
await this.loadNodes();
|
||||
this.refreshView();
|
||||
}
|
||||
public get descriptionUrl(): string {
|
||||
return this._descriptionUrl || '';
|
||||
|
@ -81,7 +84,7 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
const apiNode = this.findApiNode(this.getPathSegments(item.path), this.rawRootNode);
|
||||
if(apiNode) {
|
||||
this.selectInternal(apiNode, selected, recursive);
|
||||
this.refresh();
|
||||
this.refreshView();
|
||||
}
|
||||
}
|
||||
private selectInternal(apiNode: KiotaOpenApiNode, selected: boolean, recursive: boolean) {
|
||||
|
@ -104,7 +107,7 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
return undefined;
|
||||
}
|
||||
|
||||
refresh(): void {
|
||||
refreshView(): void {
|
||||
this._onDidChangeTreeData.fire();
|
||||
}
|
||||
getTreeItem(element: OpenApiTreeNode): vscode.TreeItem {
|
||||
|
@ -127,75 +130,94 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider<OpenApiTreeN
|
|||
private getPathSegments(path: string): string[] {
|
||||
return path.replace('/', '').split('\\').filter(x => x !== ''); // the root node is always /
|
||||
}
|
||||
private readonly selectedSet: IconSet = new vscode.ThemeIcon('check');
|
||||
private readonly unselectedSet: IconSet = new vscode.ThemeIcon('circle-slash');
|
||||
private getIconSet(selected: boolean): IconSet {
|
||||
return selected ? this.selectedSet : this.unselectedSet;
|
||||
}
|
||||
private rawRootNode: KiotaOpenApiNode | undefined;
|
||||
async getChildren(element?: OpenApiTreeNode): Promise<OpenApiTreeNode[]> {
|
||||
private tokenizedFilter: string[] = [];
|
||||
private _filterText: string = '';
|
||||
public set filter(filterText: string) {
|
||||
this._filterText = filterText;
|
||||
if (!this.rawRootNode) {
|
||||
return;
|
||||
}
|
||||
this.tokenizedFilter = filterText.length === 0 ? [] : filterText.split(' ').filter(x => x !== '').map(x => x.trim().toLowerCase());
|
||||
this.refreshView();
|
||||
}
|
||||
public get filter(): string {
|
||||
return this._filterText;
|
||||
}
|
||||
private async loadNodes(): Promise<void> {
|
||||
if (!this.descriptionUrl || this.descriptionUrl.length === 0) {
|
||||
return;
|
||||
}
|
||||
const result = await connectToKiota(this.context, async (connection) => {
|
||||
const request = new rpc.RequestType<KiotaShowConfiguration, KiotaShowResult, void>('Show');
|
||||
return await connection.sendRequest(request, {
|
||||
includeFilters: this.includeFilters,
|
||||
excludeFilters: this.excludeFilters,
|
||||
descriptionPath: this.descriptionUrl
|
||||
});
|
||||
});
|
||||
if(result && result.rootNode) {
|
||||
this.rawRootNode = result.rootNode;
|
||||
}
|
||||
}
|
||||
getCollapsedState(hasChildren: boolean): vscode.TreeItemCollapsibleState {
|
||||
return !hasChildren ?
|
||||
vscode.TreeItemCollapsibleState.None :
|
||||
(this.tokenizedFilter.length === 0 ?
|
||||
vscode.TreeItemCollapsibleState.Collapsed :
|
||||
vscode.TreeItemCollapsibleState.Expanded);
|
||||
}
|
||||
getTreeNodeFromKiotaNode(node: KiotaOpenApiNode, parent?: OpenApiTreeNode): OpenApiTreeNode {
|
||||
const result = new OpenApiTreeNode(
|
||||
node.path,
|
||||
node.segment,
|
||||
node.selected,
|
||||
this.getCollapsedState(node.children.length > 0)
|
||||
);
|
||||
result.children = node.children.map(x => this.getTreeNodeFromKiotaNode(x, result));
|
||||
return result;
|
||||
}
|
||||
getChildren(element?: OpenApiTreeNode): OpenApiTreeNode[] {
|
||||
if (!this.rawRootNode) {
|
||||
return [];
|
||||
}
|
||||
if (!this.rawRootNode) {
|
||||
const result = await connectToKiota(this.context, async (connection) => {
|
||||
const request = new rpc.RequestType<KiotaShowConfiguration, KiotaShowResult, void>('Show');
|
||||
return await connection.sendRequest(request, {
|
||||
includeFilters: this.includeFilters,
|
||||
excludeFilters: this.excludeFilters,
|
||||
descriptionPath: this.descriptionUrl
|
||||
});
|
||||
});
|
||||
if(result && result.rootNode) {
|
||||
this.rawRootNode = result.rootNode;
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if (element) {
|
||||
return this.findChildren(this.getPathSegments(element.path), this.rawRootNode)
|
||||
.map(x => new OpenApiTreeNode(x.path,
|
||||
x.segment,
|
||||
x.selected,
|
||||
this.getIconSet(x.selected),
|
||||
x.children.length > 0 ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None,
|
||||
));
|
||||
return element.children.filter(x => x.isNodeVisible(this.tokenizedFilter));
|
||||
} else {
|
||||
return [new OpenApiTreeNode(this.rawRootNode.path,
|
||||
this.rawRootNode.segment,
|
||||
this.rawRootNode.selected,
|
||||
this.getIconSet(this.rawRootNode.selected),
|
||||
vscode.TreeItemCollapsibleState.Expanded)];
|
||||
const result = this.getTreeNodeFromKiotaNode(this.rawRootNode);
|
||||
result.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
|
||||
return [result];
|
||||
}
|
||||
}
|
||||
private findChildren(segments: string[], currentNode: KiotaOpenApiNode): KiotaOpenApiNode[] {
|
||||
if(segments.length === 0) {
|
||||
return currentNode.children;
|
||||
} else {
|
||||
const segment = segments.shift();
|
||||
if(segment) {
|
||||
const child = currentNode.children.find(x => x.segment === segment);
|
||||
if(child) {
|
||||
return this.findChildren(segments, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
type IconSet = string | vscode.Uri | { light: string | vscode.Uri; dark: string | vscode.Uri } | vscode.ThemeIcon;
|
||||
export class OpenApiTreeNode extends vscode.TreeItem {
|
||||
private static readonly selectedSet: IconSet = new vscode.ThemeIcon('check');
|
||||
private static readonly unselectedSet: IconSet = new vscode.ThemeIcon('circle-slash');
|
||||
public children: OpenApiTreeNode[];
|
||||
constructor(
|
||||
public readonly path: string,
|
||||
public readonly label: string,
|
||||
public selected: boolean,
|
||||
iconSet: IconSet,
|
||||
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
|
||||
public readonly command?: vscode.Command
|
||||
public readonly selected: boolean,
|
||||
public collapsibleState: vscode.TreeItemCollapsibleState,
|
||||
_children?: OpenApiTreeNode[]
|
||||
) {
|
||||
super(label, collapsibleState);
|
||||
this.iconPath = iconSet;
|
||||
this.iconPath = selected ? OpenApiTreeNode.selectedSet : OpenApiTreeNode.unselectedSet;
|
||||
if (_children) {
|
||||
this.children = _children;
|
||||
} else {
|
||||
this.children = [];
|
||||
}
|
||||
}
|
||||
public isNodeVisible(tokenizedFilter: string[]): boolean {
|
||||
if (tokenizedFilter.length === 0) {
|
||||
return true;
|
||||
}
|
||||
if (this.children.length === 0) {
|
||||
const lowerCaseSegment = this.label.toLowerCase();
|
||||
return tokenizedFilter.some(x => lowerCaseSegment.includes(x.toLowerCase()));
|
||||
}
|
||||
return this.children.some(x => x.isNodeVisible(tokenizedFilter));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { QuickPickItem, window, Disposable, QuickInputButton, QuickInput, QuickInputButtons, workspace, l10n } from 'vscode';
|
||||
import { QuickPickItem, window, Disposable, QuickInputButton, QuickInput, QuickInputButtons, workspace, l10n, Uri } from 'vscode';
|
||||
import { allGenerationLanguages, generationLanguageToString, KiotaSearchResultItem, LanguagesInformation, maturityLevelToString } from './kiotaInterop';
|
||||
import { kiotaLockFile } from './extension';
|
||||
|
||||
|
||||
export async function openSteps() {
|
||||
|
@ -22,6 +23,57 @@ export async function openSteps() {
|
|||
return state;
|
||||
};
|
||||
|
||||
export async function searchLockSteps() {
|
||||
const state = {} as Partial<SearchLockState>;
|
||||
let step = 1;
|
||||
let totalSteps = 1;
|
||||
const title = l10n.t('Open a lock file');
|
||||
async function pickSearchResult(input: MultiStepInput, state: Partial<SearchLockState>) {
|
||||
const searchResults = await workspace.findFiles(`**/${kiotaLockFile}`);
|
||||
const items = searchResults.map(x =>
|
||||
{
|
||||
return {
|
||||
label: x.path.replace(workspace.getWorkspaceFolder(x)?.uri.path || '', ''),
|
||||
} as QuickPickItem;
|
||||
});
|
||||
const pick = await input.showQuickPick({
|
||||
title,
|
||||
step: step++,
|
||||
totalSteps: totalSteps,
|
||||
placeholder: l10n.t('Pick a lock file'),
|
||||
items: items,
|
||||
shouldResume: shouldResume
|
||||
});
|
||||
state.lockFilePath = searchResults.find(x => x.path.replace(workspace.getWorkspaceFolder(x)?.uri.path || '', '') === pick?.label);
|
||||
}
|
||||
await MultiStepInput.run(input => pickSearchResult(input, state), () => step-=2);
|
||||
return state;
|
||||
}
|
||||
|
||||
export async function filterSteps(existingFilter: string, filterCallback: (searchQuery: string) => void) {
|
||||
const state = {} as Partial<BaseStepsState>;
|
||||
const title = l10n.t('Filter the API description');
|
||||
let step = 1;
|
||||
let totalSteps = 1;
|
||||
async function inputFilterQuery(input: MultiStepInput, state: Partial<BaseStepsState>) {
|
||||
await input.showInputBox({
|
||||
title,
|
||||
step: step++,
|
||||
totalSteps: totalSteps,
|
||||
value: existingFilter,
|
||||
prompt: l10n.t('Enter a filter'),
|
||||
validate: x => {
|
||||
filterCallback(x.length === 0 && existingFilter.length > 0 ? existingFilter : x);
|
||||
existingFilter = '';
|
||||
return Promise.resolve(undefined);
|
||||
},
|
||||
shouldResume: shouldResume
|
||||
});
|
||||
}
|
||||
await MultiStepInput.run(input => inputFilterQuery(input, state), () => step-=2);
|
||||
return state;
|
||||
}
|
||||
|
||||
export async function searchSteps(searchCallBack: (searchQuery: string) => Promise<Record<string, KiotaSearchResultItem> | undefined>) {
|
||||
const state = {} as Partial<SearchState>;
|
||||
const title = l10n.t('Search for an API description');
|
||||
|
@ -173,6 +225,9 @@ interface OpenState extends BaseStepsState {
|
|||
descriptionPath: string;
|
||||
}
|
||||
|
||||
interface SearchLockState extends BaseStepsState {
|
||||
lockFilePath: Uri;
|
||||
}
|
||||
|
||||
interface GenerateState extends BaseStepsState {
|
||||
clientClassName: string;
|
||||
|
|
Загрузка…
Ссылка в новой задаче