diff --git a/tabby-plugin-manager/src/components/pluginsSettingsTab.component.pug b/tabby-plugin-manager/src/components/pluginsSettingsTab.component.pug index 2c750b05..4759a896 100644 --- a/tabby-plugin-manager/src/components/pluginsSettingsTab.component.pug +++ b/tabby-plugin-manager/src/components/pluginsSettingsTab.component.pug @@ -60,8 +60,19 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav') li(ngbNavItem) a(ngbNavLink, translate) Installed ng-template(ngbNavContent) + .input-group.mb-3.mt-3 + .input-group-prepend + .input-group-text + i.fas.fa-fw.fa-search + input.form-control( + type='text', + [(ngModel)]='_2', + (ngModelChange)='searchInstalled(_2)', + [placeholder]='"Search plugins"|translate' + ) + ngb-accordion.mb-4([closeOthers]='true') - ng-container(*ngFor='let plugin of pluginManager.installedPlugins') + ng-container(*ngFor='let plugin of installedPlugins$') ngb-panel ng-template(ngbPanelTitle) .text-left.mr-auto diff --git a/tabby-plugin-manager/src/components/pluginsSettingsTab.component.ts b/tabby-plugin-manager/src/components/pluginsSettingsTab.component.ts index 68172234..61aa5fa8 100644 --- a/tabby-plugin-manager/src/components/pluginsSettingsTab.component.ts +++ b/tabby-plugin-manager/src/components/pluginsSettingsTab.component.ts @@ -23,6 +23,7 @@ export class PluginsSettingsTabComponent { @Input() availablePlugins$: Observable @Input() availablePluginsQuery$ = new BehaviorSubject('') @Input() availablePluginsReady = false + @Input() installedPluginsQuery$ = new BehaviorSubject('') @Input() knownUpgrades: Record = {} @Input() busy = new Map() @Input() erroredPlugin: string @@ -30,6 +31,8 @@ export class PluginsSettingsTabComponent { @HostBinding('class.content-box') true + installedPlugins$: PluginInfo[] = [] + constructor ( private config: ConfigService, private platform: PlatformService, @@ -58,6 +61,18 @@ export class PluginsSettingsTabComponent { this.knownUpgrades[plugin.name] = available.find(x => x.name === plugin.name && semverGt(x.version, plugin.version)) ?? null } }) + + this.installedPluginsQuery$ + .asObservable() + .pipe( + debounceTime(200), + distinctUntilChanged(), + flatMap(query => { + return this.pluginManager.listInstalled(query) + }) + ).subscribe(plugin => { + this.installedPlugins$ = plugin + }) } openPluginsFolder (): void { @@ -68,6 +83,10 @@ export class PluginsSettingsTabComponent { this.availablePluginsQuery$.next(query) } + searchInstalled (query: string) { + this.installedPluginsQuery$.next(query) + } + isAlreadyInstalled (plugin: PluginInfo): boolean { return this.pluginManager.installedPlugins.some(x => x.name === plugin.name) } diff --git a/tabby-plugin-manager/src/services/pluginManager.service.ts b/tabby-plugin-manager/src/services/pluginManager.service.ts index f9b44c54..b39c41b6 100644 --- a/tabby-plugin-manager/src/services/pluginManager.service.ts +++ b/tabby-plugin-manager/src/services/pluginManager.service.ts @@ -1,6 +1,6 @@ import axios from 'axios' import { compare as semverCompare } from 'semver' -import { Observable, from, forkJoin, map } from 'rxjs' +import { Observable, from, forkJoin, map, of } from 'rxjs' import { Injectable, Inject } from '@angular/core' import { Logger, LogService, PlatformService, BOOTSTRAP_DATA, BootstrapData, PluginInfo } from 'tabby-core' import { PLUGIN_BLACKLIST } from '../../../app/src/pluginBlacklist' @@ -45,6 +45,10 @@ export class PluginManagerService { ) } + listInstalled (query: string): Observable { + return of(this.installedPlugins.filter(x=>x.name.includes(query))) + } + _listAvailableInternal (namePrefix: string, keyword: string, query?: string): Observable { return from( axios.get(`https://api.npms.io/v2/search?q=keywords%3A${keyword}+${encodeURIComponent(query ?? '')}&size=250`)