diff options
Diffstat (limited to 'client/src/app/+admin')
4 files changed, 61 insertions, 4 deletions
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html index d4501490f..f10b4eb8d 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html | |||
@@ -26,8 +26,11 @@ | |||
26 | <span i18n class="button-label">Homepage</span> | 26 | <span i18n class="button-label">Homepage</span> |
27 | </a> | 27 | </a> |
28 | 28 | ||
29 | <my-edit-button *ngIf="pluginType !== PluginType.THEME" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> | ||
29 | 30 | ||
30 | <my-edit-button [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> | 31 | <my-button class="update-button" *ngIf="!isUpdateAvailable(plugin)" (click)="update(plugin)" [loading]="isUpdating(plugin)" |
32 | [label]="getUpdateLabel(plugin)" icon="refresh" [attr.disabled]="isUpdating(plugin)" | ||
33 | ></my-button> | ||
31 | 34 | ||
32 | <my-delete-button (click)="uninstall(plugin)" label="Uninstall" i18n-label></my-delete-button> | 35 | <my-delete-button (click)="uninstall(plugin)" label="Uninstall" i18n-label></my-delete-button> |
33 | </div> | 36 | </div> |
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss index f250404ed..7641c507b 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss | |||
@@ -35,3 +35,7 @@ | |||
35 | @include peertube-button-link; | 35 | @include peertube-button-link; |
36 | @include button-with-icon(21px, 0, -2px); | 36 | @include button-with-icon(21px, 0, -2px); |
37 | } | 37 | } |
38 | |||
39 | .update-button[disabled="true"] /deep/ .action-button { | ||
40 | cursor: default !important; | ||
41 | } | ||
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts index 26a9a616e..67a11c3a8 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts | |||
@@ -6,6 +6,7 @@ import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pa | |||
6 | import { ConfirmService, Notifier } from '@app/core' | 6 | import { ConfirmService, Notifier } from '@app/core' |
7 | import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' | 7 | import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' |
8 | import { ActivatedRoute, Router } from '@angular/router' | 8 | import { ActivatedRoute, Router } from '@angular/router' |
9 | import { compareSemVer } from '@app/shared/misc/utils' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | selector: 'my-plugin-list-installed', | 12 | selector: 'my-plugin-list-installed', |
@@ -26,6 +27,9 @@ export class PluginListInstalledComponent implements OnInit { | |||
26 | sort = 'name' | 27 | sort = 'name' |
27 | 28 | ||
28 | plugins: PeerTubePlugin[] = [] | 29 | plugins: PeerTubePlugin[] = [] |
30 | updating: { [name: string]: boolean } = {} | ||
31 | |||
32 | PluginType = PluginType | ||
29 | 33 | ||
30 | constructor ( | 34 | constructor ( |
31 | private i18n: I18n, | 35 | private i18n: I18n, |
@@ -49,7 +53,7 @@ export class PluginListInstalledComponent implements OnInit { | |||
49 | this.pagination.currentPage = 1 | 53 | this.pagination.currentPage = 1 |
50 | this.plugins = [] | 54 | this.plugins = [] |
51 | 55 | ||
52 | this.router.navigate([], { queryParams: { pluginType: this.pluginType }}) | 56 | this.router.navigate([], { queryParams: { pluginType: this.pluginType } }) |
53 | 57 | ||
54 | this.loadMorePlugins() | 58 | this.loadMorePlugins() |
55 | } | 59 | } |
@@ -82,6 +86,18 @@ export class PluginListInstalledComponent implements OnInit { | |||
82 | return this.i18n('You don\'t have themes installed yet.') | 86 | return this.i18n('You don\'t have themes installed yet.') |
83 | } | 87 | } |
84 | 88 | ||
89 | isUpdateAvailable (plugin: PeerTubePlugin) { | ||
90 | return plugin.latestVersion && compareSemVer(plugin.latestVersion, plugin.version) > 0 | ||
91 | } | ||
92 | |||
93 | getUpdateLabel (plugin: PeerTubePlugin) { | ||
94 | return this.i18n('Update to {{version}}', { version: plugin.latestVersion }) | ||
95 | } | ||
96 | |||
97 | isUpdating (plugin: PeerTubePlugin) { | ||
98 | return !!this.updating[this.getUpdatingKey(plugin)] | ||
99 | } | ||
100 | |||
85 | async uninstall (plugin: PeerTubePlugin) { | 101 | async uninstall (plugin: PeerTubePlugin) { |
86 | const res = await this.confirmService.confirm( | 102 | const res = await this.confirmService.confirm( |
87 | this.i18n('Do you really want to uninstall {{pluginName}}?', { pluginName: plugin.name }), | 103 | this.i18n('Do you really want to uninstall {{pluginName}}?', { pluginName: plugin.name }), |
@@ -102,7 +118,32 @@ export class PluginListInstalledComponent implements OnInit { | |||
102 | ) | 118 | ) |
103 | } | 119 | } |
104 | 120 | ||
121 | async update (plugin: PeerTubePlugin) { | ||
122 | const updatingKey = this.getUpdatingKey(plugin) | ||
123 | if (this.updating[updatingKey]) return | ||
124 | |||
125 | this.updating[updatingKey] = true | ||
126 | |||
127 | this.pluginService.update(plugin.name, plugin.type) | ||
128 | .pipe() | ||
129 | .subscribe( | ||
130 | res => { | ||
131 | this.updating[updatingKey] = false | ||
132 | |||
133 | this.notifier.success(this.i18n('{{pluginName}} updated.', { pluginName: plugin.name })) | ||
134 | |||
135 | Object.assign(plugin, res) | ||
136 | }, | ||
137 | |||
138 | err => this.notifier.error(err.message) | ||
139 | ) | ||
140 | } | ||
141 | |||
105 | getShowRouterLink (plugin: PeerTubePlugin) { | 142 | getShowRouterLink (plugin: PeerTubePlugin) { |
106 | return [ '/admin', 'plugins', 'show', this.pluginService.nameToNpmName(plugin.name, plugin.type) ] | 143 | return [ '/admin', 'plugins', 'show', this.pluginService.nameToNpmName(plugin.name, plugin.type) ] |
107 | } | 144 | } |
145 | |||
146 | private getUpdatingKey (plugin: PeerTubePlugin) { | ||
147 | return plugin.name + plugin.type | ||
148 | } | ||
108 | } | 149 | } |
diff --git a/client/src/app/+admin/plugins/shared/plugin-api.service.ts b/client/src/app/+admin/plugins/shared/plugin-api.service.ts index 1d33cd179..89f190675 100644 --- a/client/src/app/+admin/plugins/shared/plugin-api.service.ts +++ b/client/src/app/+admin/plugins/shared/plugin-api.service.ts | |||
@@ -9,7 +9,7 @@ import { ComponentPagination } from '@app/shared/rest/component-pagination.model | |||
9 | import { ResultList } from '@shared/models' | 9 | import { ResultList } from '@shared/models' |
10 | import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' | 10 | import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' |
11 | import { ManagePlugin } from '@shared/models/plugins/manage-plugin.model' | 11 | import { ManagePlugin } from '@shared/models/plugins/manage-plugin.model' |
12 | import { InstallPlugin } from '@shared/models/plugins/install-plugin.model' | 12 | import { InstallOrUpdatePlugin } from '@shared/models/plugins/install-plugin.model' |
13 | import { RegisterSettingOptions } from '@shared/models/plugins/register-setting.model' | 13 | import { RegisterSettingOptions } from '@shared/models/plugins/register-setting.model' |
14 | 14 | ||
15 | @Injectable() | 15 | @Injectable() |
@@ -89,8 +89,17 @@ export class PluginApiService { | |||
89 | .pipe(catchError(res => this.restExtractor.handleError(res))) | 89 | .pipe(catchError(res => this.restExtractor.handleError(res))) |
90 | } | 90 | } |
91 | 91 | ||
92 | update (pluginName: string, pluginType: PluginType) { | ||
93 | const body: ManagePlugin = { | ||
94 | npmName: this.nameToNpmName(pluginName, pluginType) | ||
95 | } | ||
96 | |||
97 | return this.authHttp.post(PluginApiService.BASE_APPLICATION_URL + '/update', body) | ||
98 | .pipe(catchError(res => this.restExtractor.handleError(res))) | ||
99 | } | ||
100 | |||
92 | install (npmName: string) { | 101 | install (npmName: string) { |
93 | const body: InstallPlugin = { | 102 | const body: InstallOrUpdatePlugin = { |
94 | npmName | 103 | npmName |
95 | } | 104 | } |
96 | 105 | ||