plugin settings updates

上级 8a0a9700
.d-flex.mb-3
h3 Plugins
button.btn.btn-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
i.fas.fa-folder
span Plugins folder
.alert.alert-danger(*ngIf='errorMessage')
strong Error in {{erroredPlugin}}:
pre {{errorMessage}}
.d-flex
h3.mb-1 Installed
button.btn.btn-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
i.fas.fa-folder
span Plugins folder
ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) Available
ng-template(ngbNavContent)
.input-group.mb-3.mt-3
.input-group-prepend
.input-group-text
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='!availablePluginsReady')
i.fas.fa-fw.fa-search(*ngIf='availablePluginsReady')
input.form-control(
type='text',
[(ngModel)]='_1',
(ngModelChange)='searchAvailable(_1)',
placeholder='Search plugins'
)
.list-group.list-group-flush.mt-2
.list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins')
toggle(
[ngModel]='isPluginEnabled(plugin)',
(ngModelChange)='togglePlugin(plugin)',
[disabled]='!canDisablePlugin(plugin)'
)
ngb-accordion.mb-4(*ngIf='availablePlugins$', type='dark', [closeOthers]='true')
ng-container(*ngFor='let plugin of (availablePlugins$|async)')
ngb-panel(*ngIf='!isAlreadyInstalled(plugin)', cardClass='bg-dark')
ng-template(ngbPanelTitle)
.text-left
strong.d-block {{plugin.name}}
small.d-block.text-muted {{plugin.description}}
ng-template(ngbPanelContent)
.row
.col-4
button.btn.btn-primary.btn-block.justify-content-center(
(click)='installPlugin(plugin)',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-cloud-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span.ml-2 Get
.mr-auto.d-flex.flex-column
div
strong {{plugin.name}}
small.text-muted.ml-1(*ngIf='!plugin.isBuiltin') {{plugin.version}} / {{plugin.author}}
small.text-muted.ml-1(*ngIf='plugin.isBuiltin') Built-in
small.text-warning.ml-1(*ngIf='!isPluginEnabled(plugin)') Disabled
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
button.btn.btn-secondary.btn-block.justify-content-center(
*ngIf='plugin.homepage',
(click)='showPluginHomepage(plugin)'
)
i.fas.fa-fw.fa-external-link-alt
span.ml-2 Homepage
button.btn.btn-primary.ml-2(
*ngIf='knownUpgrades[plugin.name]',
(click)='upgradePlugin(plugin)',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-arrow-up(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}})
.col-8
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
button.btn.btn-link.text-danger.ml-2(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
.mt-2 {{plugin.description}}
div
h3.mt-4 Available
li(ngbNavItem)
a(ngbNavLink) Installed
ng-template(ngbNavContent)
ngb-accordion.mb-4(type='dark', [closeOthers]='true')
ng-container(*ngFor='let plugin of pluginManager.installedPlugins')
ngb-panel(cardClass='bg-dark')
ng-template(ngbPanelTitle)
.text-left.mr-auto
div
strong {{plugin.name}}
small.text-muted.ml-2(*ngIf='plugin.isBuiltin') Built-in
small.text-warning.ml-2(*ngIf='!isPluginEnabled(plugin)') Disabled
small.d-block.text-muted {{plugin.description}}
.input-group.mb-3
.input-group-prepend
.input-group-text
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='!availablePluginsReady')
i.fas.fa-fw.fa-search(*ngIf='availablePluginsReady')
input.form-control(
type='text',
[(ngModel)]='_1',
(ngModelChange)='searchAvailable(_1)',
placeholder='Search plugins'
)
button.btn.btn-primary.ml-2(
*ngIf='knownUpgrades[plugin.name]',
(click)='upgradePlugin(plugin)',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-arrow-up(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span Upgrade to {{knownUpgrades[plugin.name].version}}
.list-group.list-group-flush.mb-4(*ngIf='availablePlugins$')
ng-container(*ngFor='let plugin of (availablePlugins$|async)')
.list-group-item.d-flex.align-items-center(*ngIf='!isAlreadyInstalled(plugin)')
button.btn.btn-primary.mr-3(
(click)='installPlugin(plugin)',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
ng-template(ngbPanelContent)
.row
.col-4
button.btn.btn-warning.btn-block.justify-content-center(
(click)='togglePlugin(plugin)',
*ngIf='isPluginEnabled(plugin)',
[disabled]='!canDisablePlugin(plugin)'
) Disable
button.btn.btn-success.btn-block.justify-content-center(
(click)='togglePlugin(plugin)',
*ngIf='canDisablePlugin(plugin) && !isPluginEnabled(plugin)'
) Enable
button.btn.btn-danger.btn-block.justify-content-center(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin',
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
span Uninstall
.col-8
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
.mt-2 {{plugin.description}}
ng-template(#pluginInfo, let-plugin='plugin')
.row.align-items-center
.col-4
strong Version
.col-8
span {{plugin.version}}
.row.align-items-center
.col-4
strong Author
.col-8
.badge.badge-success(*ngIf='plugin.isOfficial')
i.fas.fa-check
span.ml-1 Official
a.btn.btn-link.px-0.w-auto((click)='showPluginInfo(plugin)', *ngIf='!plugin.isOfficial')
span {{plugin.author}}
i.fas.fa-fw.fa-external-link-alt.ml-2
div((click)='showPluginInfo(plugin)')
div
strong {{plugin.name}}
small.text-muted.ml-1 {{plugin.version}}
small.text-muted.ml-1(*ngIf='!plugin.isOfficial') by {{plugin.author}}
small.text-success.ml-1(*ngIf='plugin.isOfficial')
i.fas.fa-check
span.ml-1 Official
small.text-muted {{plugin.description}}
.mb-4([ngbNavOutlet]='nav')
.appearance-preview {
padding: 10px 20px;
margin: 0 0 10px;
overflow: hidden;
span {
white-space: pre;
::ng-deep .card-header {
padding: 0;
> button {
width: 100%;
}
}
......@@ -105,6 +105,10 @@ export class PluginsSettingsTabComponent {
this.platform.openExternal('https://www.npmjs.com/package/' + plugin.packageName)
}
showPluginHomepage (plugin: PluginInfo) {
this.platform.openExternal(plugin.homepage ?? '')
}
isPluginEnabled (plugin: PluginInfo) {
return !this.config.store.pluginBlacklist.includes(plugin.name)
}
......
......@@ -32,7 +32,20 @@ export class PluginManagerService {
return forkJoin(
this._listAvailableInternal('tabby-', 'tabby-plugin', query),
this._listAvailableInternal('terminus-', 'terminus-plugin', query),
).pipe(map(x => x.reduce((a, b) => a.concat(b), [])))
).pipe(
map(x => x.reduce((a, b) => a.concat(b), [])),
map(x => {
const names = new Set<string>()
return x.filter(item => {
if (names.has(item.name)) {
return false
}
names.add(item.name)
return true
})
}),
map(x => x.sort((a, b) => a.name.localeCompare(b.name))),
)
}
_listAvailableInternal (namePrefix: string, keyword: string, query?: string): Observable<PluginInfo[]> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册