From 6702a1b2ccd666285dee9c72b5bace641d2fce8b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Jul 2019 11:33:22 +0200 Subject: Add ability to search available plugins --- .../plugin-search/plugin-search.component.html | 55 ++++++++++ .../plugin-search/plugin-search.component.scss | 21 ++++ .../plugin-search/plugin-search.component.ts | 116 +++++++++++++++++++-- 3 files changed, 184 insertions(+), 8 deletions(-) (limited to 'client/src/app/+admin/plugins/plugin-search') diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html index e69de29bb..7dd103979 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html @@ -0,0 +1,55 @@ +
+ +
+ + + +
+ + + Popular + + + + + + + {{ pagination.totalItems }} {pagination.totalItems, plural, =1 {result} other {results}} for "{{ search }}" + + +
+ +
+ No results. +
+ +
+
+
+
+ {{ plugin.name }} + + {{ plugin.latestVersion }} +
+ +
+
{{ plugin.description }}
+ + +
+
+
+
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss index 5e6774739..ad6ff89da 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.scss @@ -1,2 +1,23 @@ @import '_variables'; @import '_mixins'; + +.search-bar { + display: flex; + justify-content: center; + margin: 30px 0; + + input { + @include peertube-input-text(60%); + height: 35px; + } +} + +.result-title { + font-size: 22px; + font-weight: 600; + margin-bottom: 15px; + + my-global-icon { + margin-right: 5px; + } +} diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts index 787be2c8c..935e11362 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts @@ -1,33 +1,133 @@ -import { Component, OnInit, ViewChild } from '@angular/core' +import { Component, OnInit } from '@angular/core' import { Notifier } from '@app/core' -import { SortMeta } from 'primeng/components/common/sortmeta' -import { ConfirmService, ServerService } from '../../../core' -import { RestPagination, RestTable, UserService } from '../../../shared' +import { ConfirmService } from '../../../core' import { I18n } from '@ngx-translate/i18n-polyfill' -import { User } from '../../../../../../shared' -import { UserBanModalComponent } from '@app/shared/moderation' -import { DropdownAction } from '@app/shared/buttons/action-dropdown.component' import { PluginType } from '@shared/models/plugins/plugin.type' import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service' +import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' +import { ActivatedRoute, Router } from '@angular/router' +import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' +import { Subject } from 'rxjs' +import { debounceTime, distinctUntilChanged } from 'rxjs/operators' @Component({ selector: 'my-plugin-search', templateUrl: './plugin-search.component.html', styleUrls: [ '../shared/toggle-plugin-type.scss', + '../shared/plugin-list.component.scss', './plugin-search.component.scss' ] }) export class PluginSearchComponent implements OnInit { pluginTypeOptions: { label: string, value: PluginType }[] = [] + pluginType: PluginType = PluginType.PLUGIN + + pagination: ComponentPagination = { + currentPage: 1, + itemsPerPage: 10 + } + sort = '-popularity' + + search = '' + isSearching = false + + plugins: PeerTubePluginIndex[] = [] + installing: { [name: string]: boolean } = {} + + private searchSubject = new Subject() constructor ( private i18n: I18n, - private pluginService: PluginApiService + private pluginService: PluginApiService, + private notifier: Notifier, + private confirmService: ConfirmService, + private router: Router, + private route: ActivatedRoute ) { this.pluginTypeOptions = this.pluginService.getPluginTypeOptions() } ngOnInit () { + const query = this.route.snapshot.queryParams + if (query['pluginType']) this.pluginType = parseInt(query['pluginType'], 10) + + this.searchSubject.asObservable() + .pipe( + debounceTime(400), + distinctUntilChanged() + ) + .subscribe(search => { + this.search = search + this.reloadPlugins() + }) + + this.reloadPlugins() + } + + onSearchChange (search: string) { + this.searchSubject.next(search) + } + + reloadPlugins () { + this.pagination.currentPage = 1 + this.plugins = [] + + this.router.navigate([], { queryParams: { pluginType: this.pluginType } }) + + this.loadMorePlugins() + } + + loadMorePlugins () { + this.isSearching = true + + this.pluginService.searchAvailablePlugins(this.pluginType, this.pagination, this.sort, this.search) + .subscribe( + res => { + this.isSearching = false + + this.plugins = this.plugins.concat(res.data) + this.pagination.totalItems = res.total + }, + + err => this.notifier.error(err.message) + ) + } + + onNearOfBottom () { + if (!hasMoreItems(this.pagination)) return + + this.pagination.currentPage += 1 + + this.loadMorePlugins() + } + + isInstalling (plugin: PeerTubePluginIndex) { + return !!this.installing[plugin.npmName] + } + + async install (plugin: PeerTubePluginIndex) { + if (this.installing[plugin.npmName]) return + + const res = await this.confirmService.confirm( + this.i18n('Please only install plugins or themes you trust, since they can execute any code on your instance.'), + this.i18n('Install {{pluginName}}?', { pluginName: plugin.name }) + ) + if (res === false) return + + this.installing[plugin.npmName] = true + + this.pluginService.install(plugin.npmName) + .subscribe( + () => { + this.installing[plugin.npmName] = false + + this.notifier.success(this.i18n('{{pluginName}} installed.', { pluginName: plugin.name })) + + plugin.installed = true + }, + + err => this.notifier.error(err.message) + ) } } -- cgit v1.2.3