Skip to content

Commit

Permalink
Use new APIQuickPick for project filter
Browse files Browse the repository at this point in the history
  • Loading branch information
dbanck committed Jun 7, 2023
1 parent 7a9f48e commit 9f462ae
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 51 deletions.
72 changes: 23 additions & 49 deletions src/providers/tfc/workspaceFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import { apiClient } from '../../terraformCloud';
import { Project } from '../../terraformCloud/project';
import { APIResource } from '../../utils/uiHelpers';

export class ResetProjectItem implements vscode.QuickPickItem {
get label() {
Expand All @@ -29,48 +30,35 @@ class ProjectItem implements vscode.QuickPickItem {
}
}

async function createProjectItems(organization: string, search?: string): Promise<ProjectItem[]> {
const projects = await apiClient.listProjects({
params: {
organization_name: organization,
},
// Include query parameter only if search argument is passed
...(search && {
queries: {
q: search,
},
}),
});

return projects.data.map((project) => new ProjectItem(project));
}
export class ProjectsAPIResource implements APIResource {
name = 'projects';
title = 'Filter Workspaces';
placeholder = 'Select a project (type to search)';

export class ProjectQuickPick {
private quickPick: vscode.QuickPick<vscode.QuickPickItem>;
private fetchTimerKey: NodeJS.Timeout | undefined;
constructor(private organizationName: string) {}

constructor(private organizationName: string) {
this.quickPick = vscode.window.createQuickPick();
this.quickPick.title = 'Filter Workspaces';
this.quickPick.placeholder = 'Select a project (type to search)';
this.quickPick.onDidChangeValue(this.onDidChangeValue, this);
}
private async createProjectItems(organization: string, search?: string): Promise<ProjectItem[]> {
const projects = await apiClient.listProjects({
params: {
organization_name: organization,
},
// Include query parameter only if search argument is passed
...(search && {
queries: {
q: search,
},
}),
});

private onDidChangeValue() {
clearTimeout(this.fetchTimerKey);
// Only starts fetching projects after a user stopped typing for 300ms
this.fetchTimerKey = setTimeout(() => this.fetchProjects.apply(this), 300);
return projects.data.map((project) => new ProjectItem(project));
}

private async fetchProjects() {
// TODO?: To further improve performance, we could consider throttling this function
async fetchItems(query?: string): Promise<vscode.QuickPickItem[]> {
const resetProjectItem = new ResetProjectItem();
const picks: vscode.QuickPickItem[] = [resetProjectItem, { label: '', kind: vscode.QuickPickItemKind.Separator }];
try {
this.quickPick.busy = true;
this.quickPick.show();

picks.push(...(await createProjectItems(this.organizationName, this.quickPick.value)));
try {
picks.push(...(await this.createProjectItems(this.organizationName, query)));
} catch (error) {
let message = 'Failed to fetch projects';
if (error instanceof Error) {
Expand All @@ -81,22 +69,8 @@ export class ProjectQuickPick {

picks.push({ label: `$(error) Error: ${message}`, alwaysShow: true });
console.error(error);
} finally {
this.quickPick.items = picks;
this.quickPick.busy = false;
}
}

async pick() {
await this.fetchProjects();

const project = await new Promise<vscode.QuickPickItem | undefined>((c) => {
this.quickPick.onDidAccept(() => c(this.quickPick.selectedItems[0]));
this.quickPick.onDidHide(() => c(undefined));
this.quickPick.show();
});
this.quickPick.hide();

return project;
return picks;
}
}
6 changes: 4 additions & 2 deletions src/providers/tfc/workspaceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import axios from 'axios';
import { RunTreeDataProvider } from './runProvider';
import { apiClient } from '../../terraformCloud';
import { TerraformCloudAuthenticationProvider } from '../authenticationProvider';
import { ProjectQuickPick, ResetProjectItem } from './workspaceFilters';
import { ProjectsAPIResource, ResetProjectItem } from './workspaceFilters';
import { APIQuickPick } from '../../utils/uiHelpers';

export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<WorkspaceTreeItem>, vscode.Disposable {
private readonly didChangeTreeData = new vscode.EventEmitter<void | WorkspaceTreeItem>();
Expand Down Expand Up @@ -40,7 +41,8 @@ export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<Worksp
async filterByProject(): Promise<void> {
// TODO! only run this if user is logged in
const organization = this.ctx.workspaceState.get('terraform.cloud.organization', '');
const projectQuickPick = new ProjectQuickPick(organization);
const projectAPIResource = new ProjectsAPIResource(organization);
const projectQuickPick = new APIQuickPick(projectAPIResource);
const project = await projectQuickPick.pick();

if (project === undefined || project instanceof ResetProjectItem) {
Expand Down

0 comments on commit 9f462ae

Please sign in to comment.