Refactor admin plugins

pull/4696/head
Chocobozzz 2021-12-29 12:14:06 +01:00
parent 9744bb2ae8
commit 2accfdd8ec
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
18 changed files with 117 additions and 132 deletions

View File

@ -302,11 +302,13 @@
"defaultProject": "PeerTube",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"style": "scss"
"prefix": "my",
"style": "scss",
"skipTests": true,
"flat": true
},
"@schematics/angular:directive": {
"prefix": "app"
"prefix": "my"
}
}
}

View File

@ -1,5 +1,4 @@
import { ChartModule } from 'primeng/chart'
import { SelectButtonModule } from 'primeng/selectbutton'
import { TableModule } from 'primeng/table'
import { NgModule } from '@angular/core'
import { SharedAbuseListModule } from '@app/shared/shared-abuse-list'
@ -45,7 +44,7 @@ import {
PluginApiService,
PluginCardComponent,
PluginListInstalledComponent,
PluginsComponent,
PluginNavigationComponent,
PluginSearchComponent,
PluginShowInstalledComponent
} from './plugins'
@ -70,7 +69,6 @@ import { JobsComponent } from './system/jobs/jobs.component'
SharedTablesModule,
TableModule,
SelectButtonModule,
ChartModule
],
@ -98,11 +96,11 @@ import { JobsComponent } from './system/jobs/jobs.component'
InstanceServerBlocklistComponent,
InstanceAccountBlocklistComponent,
PluginsComponent,
PluginListInstalledComponent,
PluginSearchComponent,
PluginShowInstalledComponent,
PluginCardComponent,
PluginNavigationComponent,
JobsComponent,
LogsComponent,

View File

@ -1,6 +1,4 @@
export * from './plugins.component'
export * from './shared'
export * from './plugin-list-installed'
export * from './plugin-search'
export * from './plugin-show-installed'

View File

@ -1,6 +1,4 @@
<div class="toggle-plugin-type">
<p-selectButton [options]="pluginTypeOptions" [(ngModel)]="pluginType" (ngModelChange)="reloadPlugins()"></p-selectButton>
</div>
<my-plugin-navigation [pluginType]="pluginType"></my-plugin-navigation>
<div class="no-results" *ngIf="pagination.totalItems === 0">
{{ getNoResultMessage() }}

View File

@ -10,14 +10,10 @@ import { PeerTubePlugin, PluginType } from '@shared/models'
@Component({
selector: 'my-plugin-list-installed',
templateUrl: './plugin-list-installed.component.html',
styleUrls: [
'../shared/toggle-plugin-type.scss',
'./plugin-list-installed.component.scss'
]
styleUrls: [ './plugin-list-installed.component.scss' ]
})
export class PluginListInstalledComponent implements OnInit {
pluginTypeOptions: { label: string, value: PluginType }[] = []
pluginType: PluginType = PluginType.PLUGIN
pluginType: PluginType
pagination: ComponentPagination = {
currentPage: 1,
@ -39,22 +35,28 @@ export class PluginListInstalledComponent implements OnInit {
private router: Router,
private route: ActivatedRoute
) {
this.pluginTypeOptions = this.pluginApiService.getPluginTypeOptions()
}
ngOnInit () {
const query = this.route.snapshot.queryParams
if (query['pluginType']) this.pluginType = parseInt(query['pluginType'], 10)
if (!this.route.snapshot.queryParams['pluginType']) {
const queryParams = { pluginType: PluginType.PLUGIN }
this.reloadPlugins()
this.router.navigate([], { queryParams })
}
this.route.queryParams.subscribe(query => {
if (!query['pluginType']) return
this.pluginType = parseInt(query['pluginType'], 10)
this.reloadPlugins()
})
}
reloadPlugins () {
this.pagination.currentPage = 1
this.plugins = []
this.router.navigate([], { queryParams: { pluginType: this.pluginType } })
this.loadMorePlugins()
}

View File

@ -1,28 +1,27 @@
<div class="toggle-plugin-type">
<p-selectButton [options]="pluginTypeOptions" [(ngModel)]="pluginType" (ngModelChange)="reloadPlugins()"></p-selectButton>
</div>
<div class="search-bar">
<input type="text" (input)="onSearchChange($event)" i18n-placeholder placeholder="Search..." myAutofocus />
</div>
<my-plugin-navigation [pluginType]="pluginType"></my-plugin-navigation>
<div class="alert alert-info" i18n *ngIf="pluginInstalled">
To load your new installed plugins or themes, refresh the page.
</div>
<div class="result-title" *ngIf="!isSearching">
<div class="result-and-search">
<ng-container *ngIf="!search">
<my-global-icon iconName="trending" aria-hidden="true"></my-global-icon>
<ng-container i18n>Popular</ng-container>
<ng-container *ngIf="!isThemeSearch()" i18n>Popular plugins</ng-container>
<ng-container *ngIf="isThemeSearch()" i18n>Popular themes</ng-container>
</ng-container>
<ng-container *ngIf="!!search">
<ng-container *ngIf="search && !isSearching">
<my-global-icon iconName="search"></my-global-icon>
<ng-container i18n>
{{ pagination.totalItems }} {pagination.totalItems, plural, =1 {result} other {results}} for "{{ search }}"
</ng-container>
</ng-container>
<div class="search-bar">
<input type="text" (input)="onSearchChange($event)" i18n-placeholder placeholder="Search..." myAutofocus />
</div>
</div>
<div class="no-results" i18n *ngIf="pagination.totalItems === 0">

View File

@ -1,27 +1,27 @@
@use '_variables' as *;
@use '_mixins' as *;
.search-bar {
display: flex;
justify-content: center;
margin: 30px 0;
input {
@include peertube-input-text(60%);
height: 35px;
}
}
.result-title {
.result-and-search {
font-size: 22px;
font-weight: 600;
margin-bottom: 15px;
margin: 30px 0 15px;
display: flex;
my-global-icon {
@include margin-right(5px);
}
}
.search-bar {
margin-left: auto;
input {
@include peertube-input-text(500px);
height: 35px;
}
}
.badge {
@include margin-left(15px);

View File

@ -9,14 +9,10 @@ import { PeerTubePluginIndex, PluginType } from '@shared/models'
@Component({
selector: 'my-plugin-search',
templateUrl: './plugin-search.component.html',
styleUrls: [
'../shared/toggle-plugin-type.scss',
'./plugin-search.component.scss'
]
styleUrls: [ './plugin-search.component.scss' ]
})
export class PluginSearchComponent implements OnInit {
pluginTypeOptions: { label: string, value: PluginType }[] = []
pluginType: PluginType = PluginType.PLUGIN
pluginType: PluginType
pagination: ComponentPagination = {
currentPage: 1,
@ -44,24 +40,30 @@ export class PluginSearchComponent implements OnInit {
private router: Router,
private route: ActivatedRoute
) {
this.pluginTypeOptions = this.pluginApiService.getPluginTypeOptions()
}
ngOnInit () {
const query = this.route.snapshot.queryParams
if (query['pluginType']) this.pluginType = parseInt(query['pluginType'], 10)
if (!this.route.snapshot.queryParams['pluginType']) {
const queryParams = { pluginType: PluginType.PLUGIN }
this.router.navigate([], { queryParams })
}
this.route.queryParams.subscribe(query => {
if (!query['pluginType']) return
this.pluginType = parseInt(query['pluginType'], 10)
this.search = query['search'] || ''
this.reloadPlugins()
})
this.searchSubject.asObservable()
.pipe(
debounceTime(400),
distinctUntilChanged()
)
.subscribe(search => {
this.search = search
this.reloadPlugins()
})
this.reloadPlugins()
.subscribe(search => this.router.navigate([], { queryParams: { search }, queryParamsHandling: 'merge' }))
}
onSearchChange (event: Event) {
@ -74,8 +76,6 @@ export class PluginSearchComponent implements OnInit {
this.pagination.currentPage = 1
this.plugins = []
this.router.navigate([], { queryParams: { pluginType: this.pluginType } })
this.loadMorePlugins()
}

View File

@ -1,9 +0,0 @@
<div class="admin-sub-header">
<div class="admin-sub-nav">
<a i18n routerLink="list-installed" routerLinkActive="active">Installed</a>
<a i18n routerLink="search" routerLinkActive="active">Search</a>
</div>
</div>
<router-outlet></router-outlet>

View File

@ -1,7 +0,0 @@
import { Component } from '@angular/core'
@Component({
templateUrl: './plugins.component.html'
})
export class PluginsComponent {
}

View File

@ -2,14 +2,12 @@ import { Routes } from '@angular/router'
import { PluginListInstalledComponent } from '@app/+admin/plugins/plugin-list-installed/plugin-list-installed.component'
import { PluginSearchComponent } from '@app/+admin/plugins/plugin-search/plugin-search.component'
import { PluginShowInstalledComponent } from '@app/+admin/plugins/plugin-show-installed/plugin-show-installed.component'
import { PluginsComponent } from '@app/+admin/plugins/plugins.component'
import { UserRightGuard } from '@app/core'
import { UserRight } from '@shared/models'
export const PluginsRoutes: Routes = [
{
path: 'plugins',
component: PluginsComponent,
canActivate: [ UserRightGuard ],
data: {
userRight: UserRight.MANAGE_PLUGINS

View File

@ -1,2 +1,3 @@
export * from './plugin-api.service'
export * from './plugin-card.component'
export * from './plugin-navigation.component'

View File

@ -25,19 +25,6 @@ export class PluginApiService {
private pluginService: PluginService
) { }
getPluginTypeOptions () {
return [
{
label: $localize`Plugins`,
value: PluginType.PLUGIN
},
{
label: $localize`Themes`,
value: PluginType.THEME
}
]
}
getPluginTypeLabel (type: PluginType) {
if (type === PluginType.PLUGIN) {
return $localize`plugin`

View File

@ -0,0 +1,11 @@
<div class="root">
<div class="btn-group" role="group" i18n-aria-label aria-label="Navigate between installed plugins and themes or find new ones">
<a i18n routerLink="/admin/plugins/list-installed" [queryParams]="{ pluginType: pluginType }" routerLinkActive="active">Installed</a>
<a i18n routerLink="/admin/plugins/search" [queryParams]="{ pluginType: pluginType }" routerLinkActive="active">Search</a>
</div>
<div class="btn-group" role="group" i18n-aria-label aria-label="Navigate between plugins and themes">
<a [ngClass]="{ active: pluginType === 1 }" routerLink="." [queryParams]="{ pluginType: 1 }" queryParamsHandling="merge" class="">Plugins</a>
<a [ngClass]="{ active: pluginType === 2 }" routerLink="." [queryParams]="{ pluginType: 2 }" queryParamsHandling="merge" class="">Themes</a>
</div>
</div>

View File

@ -1,8 +1,11 @@
@use '_variables' as *;
@use '_mixins' as *;
.toggle-plugin-type {
.root {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
.btn-group:not(:last-child) {
@include margin-right(15px);
}

View File

@ -0,0 +1,11 @@
import { Component, Input } from '@angular/core'
import { PluginType } from '@shared/models/plugins'
@Component({
selector: 'my-plugin-navigation',
templateUrl: './plugin-navigation.component.html',
styleUrls: [ './plugin-navigation.component.scss' ]
})
export class PluginNavigationComponent {
@Input() pluginType: PluginType
}

View File

@ -261,28 +261,6 @@ my-input-toggle-hidden ::ng-deep input {
display: flex;
align-items: center;
margin-bottom: 30px;
.admin-sub-nav a {
@include disable-default-a-behaviour;
font-size: 16px;
color: pvar(--mainForegroundColor);
padding: 5px 15px;
border-radius: 0.25rem;
font-weight: $font-semibold;
opacity: 0.6;
&.active {
background-color: pvar(--submenuBackgroundColor);
}
&.active,
&:hover,
&:active,
&:focus {
opacity: 1;
}
}
}
// In tables, don't have a hover different background
@ -402,19 +380,6 @@ ngx-loading-bar {
.admin-sub-header {
flex-direction: column;
.admin-sub-nav {
display: block;
overflow-x: auto;
white-space: nowrap;
height: 50px;
padding: 10px 0;
width: 100%;
a {
@include margin-left(5px);
}
}
}
my-markdown-textarea {

View File

@ -334,6 +334,34 @@ ngb-tooltip-window {
}
}
.btn-group {
font-weight: $font-semibold;
.active {
@include orange-button;
}
:not(.active) {
@include grey-button;
}
> * {
@include peertube-button-link;
box-shadow: none !important;
&:not(:first-child) {
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
&:not(:last-child) {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
}
}
// input box-shadow on focus
.form-control {
font-size: 15px;