diff --git a/src/cx/cx.ts b/src/cx/cx.ts index 5ccd4559b..8731dd0e4 100644 --- a/src/cx/cx.ts +++ b/src/cx/cx.ts @@ -175,7 +175,7 @@ export class Cx implements CxPlatform { return []; } const cx = new CxWrapper(config); - const projects = await cx.projectList("limit=10000"); + const projects = await cx.projectList("limit=20"); if (projects.payload) { r = projects.payload; @@ -185,6 +185,25 @@ export class Cx implements CxPlatform { return r; } + async getProjectListWithParams(params: string): Promise { + let r = []; + const config = this.getAstConfiguration(); + if (!config) { + return []; + } + const cx = new CxWrapper(config); + const projects = await cx.projectList(params); + + if (projects.payload) { + r = projects.payload; + } else if (projects.exitCode===0){ + return r; + }else { + throw new Error(projects.status); + } + return r; + } + async getBranches(projectId: string | undefined): Promise { let r = []; const config = this.getAstConfiguration(); @@ -212,7 +231,7 @@ export class Cx implements CxPlatform { if (!config) { return []; } - const filter = `project-id=${projectId},branch=${branch},limit=10000,statuses=Completed`; + const filter = `project-id=${projectId},branch=${branch},limit=20,statuses=Completed`; const cx = new CxWrapper(config); const scans = await cx.scanList(filter); if (scans.payload) { diff --git a/src/cx/cxMock.ts b/src/cx/cxMock.ts index 4afb80a69..56c13d34f 100644 --- a/src/cx/cxMock.ts +++ b/src/cx/cxMock.ts @@ -1053,6 +1053,11 @@ export class CxMock implements CxPlatform { return true; } + async getProjectListWithParams(prefix: string): Promise { + console.log(`Filtering projects by prefix: ${prefix}`); + return this.getProjectList(); + } + async triageShow() { return []; } diff --git a/src/cx/cxPlatform.ts b/src/cx/cxPlatform.ts index bd0b42da6..e78414f9a 100644 --- a/src/cx/cxPlatform.ts +++ b/src/cx/cxPlatform.ts @@ -18,6 +18,8 @@ export interface CxPlatform { * @return List of sca results. */ scaScanCreate(sourcePath: string): Promise; + + getProjectListWithParams(params: string): Promise; /** * Creates a scan in cx one platform diff --git a/src/utils/pickers/pickers.ts b/src/utils/pickers/pickers.ts index 04c112f32..1a50db5cf 100644 --- a/src/utils/pickers/pickers.ts +++ b/src/utils/pickers/pickers.ts @@ -1,42 +1,75 @@ import * as vscode from "vscode"; -import { Logs } from "../../models/logs"; -import { - PROGRESS_HEADER, - getProperty, - getScanLabel, - getFormattedDateTime, - getFormattedId, - formatLabel -} from "../utils"; -import { commands } from "../common/commands"; -import { - constants -} from "../common/constants"; -import { getFromState, updateState, updateStateError } from "../common/globalState"; -import { CxQuickPickItem } from "./multiStepUtils"; -import { messages } from "../common/messages"; -import { cx } from "../../cx"; -// label, funcao p ir buscar os projects/branchse, etc override, onDidChange , funcao de "pre pick" p retornar um bool +import {Logs} from "../../models/logs"; +import {formatLabel, getFormattedDateTime, getFormattedId, getProperty, getScanLabel, PROGRESS_HEADER} from "../utils"; +import {commands} from "../common/commands"; +import {constants} from "../common/constants"; +import {getFromState, updateState, updateStateError} from "../common/globalState"; +import {CxQuickPickItem} from "./multiStepUtils"; +import {messages} from "../common/messages"; +import {cx} from "../../cx"; + +let currentPage = 0; +const pageSize = 20; + +// label, function to search for projects/branchse, etc. override, onDidChange, "pre pick" function to return a bool export async function projectPicker( context: vscode.ExtensionContext, logs: Logs, ) { + const projectCache = new Map(); const quickPick = vscode.window.createQuickPick(); quickPick.placeholder = constants.projectPlaceholder; quickPick.items = await getProjectsPickItems(logs, context); + quickPick.onDidChangeValue(async (value) => { + try{ + const params = `name=${value}`; + quickPick.items = await getProjectsPickItemsWithParams(params, logs, context); + } + catch (error) { + updateStateError(context, constants.errorMessage + error); + vscode.commands.executeCommand(commands.showError); + } + }); quickPick.onDidChangeSelection(async ([item]) => { - updateState(context, constants.projectIdKey, { - id: item.id, - name: `${constants.projectLabel} ${item.label}`, - displayScanId: undefined, - scanDatetime: undefined - }); + if (item.id === 'nextPage') { + currentPage++; + if (projectCache.has(currentPage)) { + // Use cached items + quickPick.items = projectCache.get(currentPage)!; + } else { + // Fetch new items and cache them + const params = `limit=${pageSize},offset=${pageSize * currentPage}`; + const items = await getProjectsPickItemsWithParams(params, logs, context); + projectCache.set(currentPage, items); + quickPick.items = items; + } + } else if (item.id === 'previousPage') { + currentPage--; + if (projectCache.has(currentPage)) { + // Use cached items + quickPick.items = projectCache.get(currentPage)!; + } else { + // Fetch new items and cache them + const params = `limit=${pageSize},offset=${pageSize * currentPage}`; + const items = await getProjectsPickItemsWithParams(params, logs, context); + projectCache.set(currentPage, items); + quickPick.items = items; + } + } else { + updateState(context, constants.projectIdKey, { + id: item.id, + name: `${constants.projectLabel} ${item.label}`, + displayScanId: undefined, + scanDatetime: undefined + }); + + updateState(context, constants.branchIdKey, { id: undefined, name: constants.branchLabel, displayScanId: undefined, scanDatetime: undefined}); updateState(context, constants.scanIdKey, { id: undefined, name: constants.scanLabel, displayScanId: undefined, scanDatetime: undefined}); await vscode.commands.executeCommand(commands.refreshTree); quickPick.hide(); - }); + }}); quickPick.show(); } @@ -161,12 +194,13 @@ export async function getProjectsPickItems( logs: Logs, context: vscode.ExtensionContext ) { - return vscode.window.withProgress( + const items = await vscode.window.withProgress( PROGRESS_HEADER, async (progress, token) => { token.onCancellationRequested(() => logs.info(messages.cancelLoading)); progress.report({ message: messages.loadingProjects }); try { + currentPage = 0; const projectList = await cx.getProjectList(); return projectList ? projectList.map((label) => ({ @@ -181,6 +215,60 @@ export async function getProjectsPickItems( } } ); + if (currentPage > 0) { + items.unshift({ + label: '$(arrow-left) Previous Page', + id: 'previousPage', + }); + } + + items.push({ + label: '$(arrow-right) Next Page', + id: 'nextPage', + }); + return items; +} + +export async function getProjectsPickItemsWithParams( + params: string, + logs: Logs, + context: vscode.ExtensionContext +) { + const items = await vscode.window.withProgress( + PROGRESS_HEADER, + async (progress, token) => { + token.onCancellationRequested(() => { + logs.info(messages.cancelLoading); + currentPage = 0; + }); + progress.report({ message: messages.loadingProjects }); + try { + const projectList = await cx.getProjectListWithParams(params); + return projectList + ? projectList.map((label?) => ({ + label: label.name, + id: label.id, + })) + : []; + } catch (error) { + updateStateError(context, constants.errorMessage + error); + vscode.commands.executeCommand(commands.showError); + return []; + } + } + ); + if (currentPage > 0) { + items.unshift({ + label: '$(arrow-left) Previous Page', + id: 'previousPage', + }); + } + + items.push({ + label: '$(arrow-right) Next Page', + id: 'nextPage', + }); + return items; } export async function getScansPickItems(