diff --git a/package-lock.json b/package-lock.json index 986efb55..2a20e656 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@kubernetes/client-node": "^0.12.2", + "@redhat-developer/alizer": "^0.0.1", "@redhat-developer/vscode-redhat-telemetry": "^0.2.0", "axios": "^0.21.1", "binary-search": "^1.3.5", @@ -18,6 +19,7 @@ "event-stream": "3.3.4", "fs-extra": "^7.0.1", "fuzzysearch": "^1.0.3", + "fuzzysort": "^1.1.4", "git-fetch-pack": "^0.1.1", "git-transport-protocol": "^0.1.0", "hasha": "5.0.0", @@ -413,6 +415,15 @@ "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", "dev": true }, + "node_modules/@redhat-developer/alizer": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@redhat-developer/alizer/-/alizer-0.0.1.tgz", + "integrity": "sha512-yg7zGjNYNt6FPMC5ArRrSpEoh4poF2UtCvLRDlNNULRhmjzMDsB2v+z4GDm2wG79JhmtfG3/P1ZjjBUmjh7n8w==", + "dependencies": { + "glob-gitignore": "^1.0.14", + "js-yaml": "^3.14.0" + } + }, "node_modules/@redhat-developer/vscode-redhat-telemetry": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@redhat-developer/vscode-redhat-telemetry/-/vscode-redhat-telemetry-0.2.0.tgz", @@ -3574,6 +3585,11 @@ "resolved": "https://registry.npmjs.org/fuzzysearch/-/fuzzysearch-1.0.3.tgz", "integrity": "sha1-3/yA9tawQiPyImqnndGUIxCW0Ag=" }, + "node_modules/fuzzysort": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", + "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3721,6 +3737,30 @@ "node": "*" } }, + "node_modules/glob-gitignore": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/glob-gitignore/-/glob-gitignore-1.0.14.tgz", + "integrity": "sha512-YuAEPqL58bOQDqDF2kMv009rIjSAtPs+WPzyGbwRWK+wD0UWQVRoP34Pz6yJ6ivco65C9tZnaIt0I3JCuQ8NZQ==", + "dependencies": { + "glob": "^7.1.3", + "ignore": "^5.0.5", + "lodash.difference": "^4.5.0", + "lodash.union": "^4.6.0", + "make-array": "^1.0.5", + "util.inherits": "^1.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-gitignore/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "engines": { + "node": ">= 4" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -4816,6 +4856,11 @@ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", "dev": true }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, "node_modules/lodash.filter": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", @@ -4875,6 +4920,11 @@ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", "dev": true }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, "node_modules/log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -4974,6 +5024,14 @@ "node": ">=10" } }, + "node_modules/make-array": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/make-array/-/make-array-1.0.5.tgz", + "integrity": "sha512-sgK2SAzxT19rWU+qxKUcn6PAh/swiIiz2F8C2cZjLc1z4iwYIfdoihqFIDQ8BDzAGtWPYJ6Sr13K1j/DXynDLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -7658,6 +7716,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "node_modules/util.inherits": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util.inherits/-/util.inherits-1.0.3.tgz", + "integrity": "sha1-qcYmoNBtNIKdR7pWyrEnjXRfnOY=", + "engines": { + "node": ">=4" + } + }, "node_modules/util.promisify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", @@ -8582,6 +8648,15 @@ "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", "dev": true }, + "@redhat-developer/alizer": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@redhat-developer/alizer/-/alizer-0.0.1.tgz", + "integrity": "sha512-yg7zGjNYNt6FPMC5ArRrSpEoh4poF2UtCvLRDlNNULRhmjzMDsB2v+z4GDm2wG79JhmtfG3/P1ZjjBUmjh7n8w==", + "requires": { + "glob-gitignore": "^1.0.14", + "js-yaml": "^3.14.0" + } + }, "@redhat-developer/vscode-redhat-telemetry": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@redhat-developer/vscode-redhat-telemetry/-/vscode-redhat-telemetry-0.2.0.tgz", @@ -11277,6 +11352,11 @@ "resolved": "https://registry.npmjs.org/fuzzysearch/-/fuzzysearch-1.0.3.tgz", "integrity": "sha1-3/yA9tawQiPyImqnndGUIxCW0Ag=" }, + "fuzzysort": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", + "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -11422,6 +11502,26 @@ "path-is-absolute": "^1.0.0" } }, + "glob-gitignore": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/glob-gitignore/-/glob-gitignore-1.0.14.tgz", + "integrity": "sha512-YuAEPqL58bOQDqDF2kMv009rIjSAtPs+WPzyGbwRWK+wD0UWQVRoP34Pz6yJ6ivco65C9tZnaIt0I3JCuQ8NZQ==", + "requires": { + "glob": "^7.1.3", + "ignore": "^5.0.5", + "lodash.difference": "^4.5.0", + "lodash.union": "^4.6.0", + "make-array": "^1.0.5", + "util.inherits": "^1.0.3" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + } + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -12304,6 +12404,11 @@ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", "dev": true }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, "lodash.filter": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", @@ -12363,6 +12468,11 @@ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", "dev": true }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -12443,6 +12553,11 @@ "yallist": "^4.0.0" } }, + "make-array": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/make-array/-/make-array-1.0.5.tgz", + "integrity": "sha512-sgK2SAzxT19rWU+qxKUcn6PAh/swiIiz2F8C2cZjLc1z4iwYIfdoihqFIDQ8BDzAGtWPYJ6Sr13K1j/DXynDLA==" + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -14660,6 +14775,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "util.inherits": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util.inherits/-/util.inherits-1.0.3.tgz", + "integrity": "sha1-qcYmoNBtNIKdR7pWyrEnjXRfnOY=" + }, "util.promisify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", diff --git a/package.json b/package.json index 66d60c50..72406924 100644 --- a/package.json +++ b/package.json @@ -948,6 +948,7 @@ }, "dependencies": { "@kubernetes/client-node": "^0.12.2", + "@redhat-developer/alizer": "^0.0.1", "@redhat-developer/vscode-redhat-telemetry": "^0.2.0", "axios": "^0.21.1", "binary-search": "^1.3.5", @@ -956,6 +957,7 @@ "event-stream": "3.3.4", "fs-extra": "^7.0.1", "fuzzysearch": "^1.0.3", + "fuzzysort": "^1.1.4", "git-fetch-pack": "^0.1.1", "git-transport-protocol": "^0.1.0", "hasha": "5.0.0", @@ -977,4 +979,4 @@ "validator": "^11.0.0", "vscode-kubernetes-tools-api": "1.3.0" } -} \ No newline at end of file +} diff --git a/src/hub/hub-client.ts b/src/hub/hub-client.ts index 28344c7b..fab6050a 100644 --- a/src/hub/hub-client.ts +++ b/src/hub/hub-client.ts @@ -36,7 +36,7 @@ export async function getTektonHubStatus(): Promise { export async function searchTask(name: string): Promise { try { const resApi = createResourceApi(); - const result = await resApi.resourceQuery(name); + const result = await resApi.resourceQuery(name, undefined, ['task'], undefined, undefined, 'contains'); return result.data.data; } catch (err) { if (err instanceof Error ){ @@ -49,6 +49,12 @@ export async function searchTask(name: string): Promise { } } +export async function listTasks(limit = 1000): Promise { + const restApi = createResourceApi(); + const result = await restApi.resourceList(limit); + return result.data.data; +} + export async function getVersions(id: number): Promise { const restApi = createResourceApi(); const result = await restApi.resourceVersionsByID(id); diff --git a/src/hub/hub-common.ts b/src/hub/hub-common.ts index 4a3e3a24..f3317257 100644 --- a/src/hub/hub-common.ts +++ b/src/hub/hub-common.ts @@ -12,6 +12,7 @@ export interface HubTaskInstallation { minPipelinesVersion?: string; asClusterTask: boolean; taskVersion?: ResourceVersionData; + view: string; } export interface HubTaskUninstall { @@ -24,7 +25,7 @@ export interface InstalledTask extends ResourceData { clusterTask?: boolean; } -export type HubTask = InstalledTask | ResourceData +export type HubTask = (InstalledTask | ResourceData) & { view?: string } export function isInstalledTask(task: HubTask): task is InstalledTask { return (task as InstalledTask).installedVersion !== undefined; diff --git a/src/hub/hub-recommendation.ts b/src/hub/hub-recommendation.ts new file mode 100644 index 00000000..bf98ba48 --- /dev/null +++ b/src/hub/hub-recommendation.ts @@ -0,0 +1,38 @@ +/*----------------------------------------------------------------------------------------------- + * Copyright (c) Red Hat, Inc. All rights reserved. + * Licensed under the MIT License. See LICENSE file in the project root for license information. + *-----------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { getProjectType } from '../project-analizer/language-recongnizer/recognazer' + +const MAX_LANG_AND_TOOLS = 10; +export async function startDetectingLanguage(): Promise { + const folder = vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders[0]; + if (folder) { + try { + const langAndTools = await getProjectType(folder.uri.fsPath); + if (langAndTools && langAndTools.length > 0) { + + const result = []; + for (const element of langAndTools) { + result.push(element.name); + result.push(element.builder); + if (element.frameworks){ + result.push(...element.frameworks); + } + if (result.length >= MAX_LANG_AND_TOOLS) { + break; + } + } + + return result; + } + } catch (err) { + console.error(err); + } + } + + return []; +} + diff --git a/src/hub/hub-view.ts b/src/hub/hub-view.ts index 5628339b..96dc61a7 100644 --- a/src/hub/hub-view.ts +++ b/src/hub/hub-view.ts @@ -4,7 +4,7 @@ *-----------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { Disposable } from '../util/disposable'; -import { getTaskById, getTaskByNameAndVersion, getTektonHubStatus, getTopRatedTasks, searchTask, TektonHubStatusEnum } from './hub-client'; +import { getTaskById, getTaskByNameAndVersion, getTektonHubStatus, getTopRatedTasks, listTasks, searchTask, TektonHubStatusEnum } from './hub-client'; import { ResourceData } from '../tekton-hub-client'; import { taskPageManager } from './task-page-manager'; import { installTask, installEvent } from './install-task'; @@ -12,7 +12,10 @@ import { version } from '../util/tknversion'; import { getRawTasks } from '../yaml-support/tkn-tasks-provider'; import { InstalledTask, isInstalledTask } from './hub-common'; import { uninstallTaskEvent } from './uninstall-task'; +import { startDetectingLanguage } from './hub-recommendation'; +import * as fuzzysort from 'fuzzysort'; +const MAX_RECOMMENDED_TASK = 7; export class TektonHubTasksViewProvider extends Disposable implements vscode.WebviewViewProvider { @@ -21,7 +24,7 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web private installedTasks: InstalledTask[] | undefined; constructor( - private readonly extensionUri: vscode.Uri, + private readonly extensionUri: vscode.Uri, ) { super(); @@ -54,16 +57,16 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web const indexJS = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, 'out', 'webview', 'tekton-hub', 'index.js')); webviewView.webview.html = this.getHmlContent().replace('{{init}}', indexJS.toString()); - + this.register(webviewView.webview.onDidReceiveMessage(e => { switch (e.type) { - case 'ready': + case 'ready': this.handleReady(); break; case 'search': this.doSearch(e.data); break; - case 'openTaskPage': + case 'openTaskPage': this.openTaskPage(e.data); break; case 'installTask': @@ -95,32 +98,37 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web } - private sendMessage(message: {type: string; data?: unknown}): void { + private sendMessage(message: { type: string; data?: unknown }): void { this.webviewView?.webview?.postMessage(message); } private async handleReady(): Promise { - const hubAvailable = await this.doCheckHub(); - if (hubAvailable){ - await this.loadInstalledTasks(); - await this.loadRecommendedTasks(); + try { + const hubAvailable = await this.doCheckHub(); + if (hubAvailable) { + await this.loadInstalledTasks(); + await this.loadRecommendedTasks(); + } + } catch (err) { + console.error(err); } + } private async doCheckHub(): Promise { const status = await getTektonHubStatus(); const tknVersions = await version(); - if (!tknVersions){ - this.sendMessage({type: 'error', data: 'Cannot detect Tekton Pipelines version' }); + if (!tknVersions) { + this.sendMessage({ type: 'error', data: 'Cannot detect Tekton Pipelines version' }); return false; } this.tknVersion = tknVersions.pipeline; - - if (status.status !== TektonHubStatusEnum.Ok){ - this.sendMessage({type: 'error', data: status.error}); + + if (status.status !== TektonHubStatusEnum.Ok) { + this.sendMessage({ type: 'error', data: status.error }); return false; } else { - this.sendMessage({type: 'tknVersion', data: tknVersions.pipeline}); + this.sendMessage({ type: 'tknVersion', data: tknVersions.pipeline }); return true; } } @@ -128,7 +136,7 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web private async doSearch(value: string): Promise { try { const tasks = await searchTask(value); - this.sendMessage({type: 'showTasks', data: tasks}); + this.sendMessage({ type: 'showTasks', data: tasks }); } catch (err) { console.error(err); } @@ -137,8 +145,8 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web private async loadInstalledTasks(): Promise { const rawTasks = await getRawTasks(true); - const installedTasksRaw = rawTasks.filter( task => { - if (!task.metadata?.labels){ + const installedTasksRaw = rawTasks.filter(task => { + if (!task.metadata?.labels) { return false; } return task.metadata?.labels['hub.tekton.dev/catalog'] !== undefined; @@ -159,8 +167,7 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web } } this.installedTasks = installedTasks; - this.sendMessage({type: 'installedTasks', data: installedTasks}); - return; + this.sendMessage({ type: 'installedTasks', data: installedTasks }); } private async openTaskPage(task: ResourceData | InstalledTask): Promise { @@ -175,7 +182,27 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web private async loadRecommendedTasks(): Promise { try { - const recommendedTasks = await getTopRatedTasks(7); + const usedTools = await startDetectingLanguage(); + const recommendedTasks = []; + if (usedTools) { + let taskList = await listTasks(); + taskList = taskList.map(it => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (it as any).displayName = it.latestVersion.displayName; + return it; + }); + for (const toolName of usedTools) { + const sortResult = fuzzysort + .go(toolName, taskList, { keys: ['name', 'displayName'] }) + .map((resource) => resource.obj); + recommendedTasks.push(...sortResult); + if (recommendedTasks.length >= MAX_RECOMMENDED_TASK) { + break; + } + } + } else { + recommendedTasks.push(...await getTopRatedTasks(MAX_RECOMMENDED_TASK)); + } let result = []; if (this.installedTasks) { const installedId = this.installedTasks.map((it) => it.id); @@ -189,8 +216,8 @@ export class TektonHubTasksViewProvider extends Disposable implements vscode.Web result = recommendedTasks; } - this.sendMessage({type: 'recommendedTasks', data: result}); - } catch (err){ + this.sendMessage({ type: 'recommendedTasks', data: result }); + } catch (err) { console.error(err); } diff --git a/src/hub/install-task.ts b/src/hub/install-task.ts index f7261da4..de513127 100644 --- a/src/hub/install-task.ts +++ b/src/hub/install-task.ts @@ -89,8 +89,11 @@ async function doInstallTask(task: HubTaskInstallation): Promise { vscode.window.showWarningMessage(message); } else { message = `Task ${task.name} installed.`; - telemetryLog('tekton.hub.install', message); vscode.window.showInformationMessage(message); + if (task.view && task.view === 'recommendedView'){ + message += ' From recommendation.' + } + telemetryLog('tekton.hub.install', message); installEventEmitter.fire(task); return true; } diff --git a/src/project-analizer/language-recongnizer/recognazer.ts b/src/project-analizer/language-recongnizer/recognazer.ts new file mode 100644 index 00000000..e8c65f57 --- /dev/null +++ b/src/project-analizer/language-recongnizer/recognazer.ts @@ -0,0 +1,12 @@ +/*----------------------------------------------------------------------------------------------- + * Copyright (c) Red Hat, Inc. All rights reserved. + * Licensed under the MIT License. See LICENSE file in the project root for license information. + *-----------------------------------------------------------------------------------------------*/ + +import { ProjectType } from '../project-types'; +import {detectLanguages} from '@redhat-developer/alizer'; + +export async function getProjectType(path: string): Promise { + const result = await detectLanguages(path); + return result; +} diff --git a/src/project-analizer/project-types.ts b/src/project-analizer/project-types.ts new file mode 100644 index 00000000..d9a444e5 --- /dev/null +++ b/src/project-analizer/project-types.ts @@ -0,0 +1,10 @@ +/*----------------------------------------------------------------------------------------------- + * Copyright (c) Red Hat, Inc. All rights reserved. + * Licensed under the MIT License. See LICENSE file in the project root for license information. + *-----------------------------------------------------------------------------------------------*/ + +export interface ProjectType { + name: string; + frameworks?: string[]; + builder?: string; +} diff --git a/src/webview/hub/task-view.ts b/src/webview/hub/task-view.ts index d5fc959d..c4fc4278 100644 --- a/src/webview/hub/task-view.ts +++ b/src/webview/hub/task-view.ts @@ -50,7 +50,7 @@ export class SearchInput { export class TaskItem extends BaseWidget { - constructor(private task: HubTask, private messageSender: VSMessage, private loader: Loader, private tknVersion?: string) { + constructor(private task: HubTask, private messageSender: VSMessage, private loader: Loader, private viewType: string, private tknVersion?: string) { super(); this.element = createDiv('task-list-item'); const iconContainer = createDiv('icon-container'); @@ -62,6 +62,7 @@ export class TaskItem extends BaseWidget { this.createDetails(); this.element.onclick = () => { try { + this.task.view = this.viewType; this.messageSender.postMessage({type: 'openTaskPage', data: this.task}); } catch (err) { console.error(err); @@ -161,7 +162,8 @@ export class TaskItem extends BaseWidget { name: this.task.name, minPipelinesVersion: this.task.latestVersion.minPipelinesVersion, tknVersion: this.tknVersion, - taskVersion: this.task.latestVersion + taskVersion: this.task.latestVersion, + view: this.viewType } as HubTaskInstallation}); } @@ -197,7 +199,7 @@ export class TaskList extends ListWidget { tknVersion: string | undefined; - constructor(element: HTMLElement, private messageSender: VSMessage, private loader: Loader){ + constructor(element: HTMLElement, private messageSender: VSMessage, private loader: Loader, private type: string){ super(element); } @@ -206,7 +208,7 @@ export class TaskList extends ListWidget { } createItemWidget(item: HubTask): Widget { - return new TaskItem(item, this.messageSender, this.loader, this.tknVersion); + return new TaskItem(item, this.messageSender, this.loader, this.type, this.tknVersion); } show(items: HubTask[]): void { @@ -260,7 +262,7 @@ export class TaskView { // const taskListContainer = createDiv(); taskListContainer.id = 'tasksList'; - this.taskList = new TaskList(taskListContainer, this.vscodeAPI, this.loader); + this.taskList = new TaskList(taskListContainer, this.vscodeAPI, this.loader, 'searchView'); this.mainContainer = document.getElementById('mainContainer'); const listContainer = createDiv('collapsibleListContainer'); @@ -325,7 +327,7 @@ export class TaskView { this.installedTasks = new Map(tasks.map(it => [it.name, it])); if (!this.installedList){ const installedElement = createDiv(); - this.installedList = new TaskList(installedElement, this.vscodeAPI, this.loader); + this.installedList = new TaskList(installedElement, this.vscodeAPI, this.loader, 'installedView'); this.welcomeList.addSubList('INSTALLED', this.installedList); this.installedList.tknVersion = this.taskList.tknVersion; } @@ -338,7 +340,7 @@ export class TaskView { setRecommendedTasks(tasks: ResourceData[]): void { if (!this.recommendedList){ const recommendedElement = createDiv(); - this.recommendedList = new TaskList(recommendedElement, this.vscodeAPI, this.loader); + this.recommendedList = new TaskList(recommendedElement, this.vscodeAPI, this.loader, 'recommendedView'); this.welcomeList.addSubList('RECOMMENDED', this.recommendedList); this.recommendedList.tknVersion = this.taskList.tknVersion; } diff --git a/test/hub/install-task.test.ts b/test/hub/install-task.test.ts index 420a9867..1439ee05 100644 --- a/test/hub/install-task.test.ts +++ b/test/hub/install-task.test.ts @@ -50,7 +50,8 @@ suite('Install Task', () => { name: 'foo', url: 'https://some/path/task.yaml', asClusterTask: false, - taskVersion: {version: '1.0'} as ResourceVersionData + taskVersion: {version: '1.0'} as ResourceVersionData, + view: 'test' }); expect(executeStub).calledOnceWith(Command.hubInstall('foo', '1.0')); @@ -66,7 +67,8 @@ suite('Install Task', () => { await installTask({ name: 'foo', url: 'https://some/path/task.yaml', - asClusterTask: true + asClusterTask: true, + view: 'test' }); const tempPath = path.join('/foo','task.yaml'); expect(downloadStub).calledOnceWith('https://some/path/task.yaml', tempPath);