Merge branch 'feature/restart-instance' into 'develop'

Ability to reboot instance from admin-fe

Closes #84

See merge request pleroma/admin-fe!94
This commit is contained in:
Angelina Filippova 2020-02-18 23:45:35 +00:00
commit 38c1842768
8 changed files with 112 additions and 36 deletions

View file

@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Report notes
- Ability to moderate users on the statuses page
- Ability to moderate user on the user's page
- Ability to restart an application when settings that require instance reboot were changed
- Mobile UI for Settings tab
### Fixed

View file

@ -40,4 +40,13 @@ export async function removeSettings(configs, authHost, token) {
})
}
export async function restartApp(authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/restart`,
method: 'get',
headers: authHeaders(token)
})
}
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

View file

@ -363,7 +363,10 @@ export default {
assets: 'Assets',
emoji: 'Emoji',
markup: 'Markup settings',
corsPlug: 'CORS plug config'
corsPlug: 'CORS plug config',
instanceReboot: 'Instance Reboot',
restartApp: 'You must restart the instance to apply settings',
restartSuccess: 'Instance rebooted successfully!'
},
invites: {
inviteTokens: 'Invite tokens',

View file

@ -1,4 +1,4 @@
import { fetchDescription, fetchSettings, removeSettings, updateSettings } from '@/api/settings'
import { fetchDescription, fetchSettings, removeSettings, restartApp, updateSettings } from '@/api/settings'
import { checkPartialUpdate, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
import _ from 'lodash'
@ -6,11 +6,12 @@ const settings = {
state: {
activeTab: 'instance',
configDisabled: true,
description: [],
settings: {},
updatedSettings: {},
db: {},
loading: true
description: [],
loading: true,
needReboot: false,
settings: {},
updatedSettings: {}
},
mutations: {
CLEAR_UPDATED_SETTINGS: (state) => {
@ -50,6 +51,9 @@ const settings = {
state.settings = newSettings
state.db = newDbSettings
},
TOGGLE_REBOOT: (state, needReboot) => {
state.needReboot = needReboot || false
},
TOGGLE_TABS: (state, status) => {
state.configDisabled = status
},
@ -74,6 +78,7 @@ const settings = {
const description = await fetchDescription(getters.authHost, getters.token)
commit('SET_DESCRIPTION', description.data)
commit('SET_SETTINGS', response.data.configs)
commit('TOGGLE_REBOOT', response.data.need_reboot)
} catch (_e) {
commit('TOGGLE_TABS', true)
commit('SET_ACTIVE_TAB', 'relays')
@ -88,8 +93,13 @@ const settings = {
const response = await fetchSettings(getters.authHost, getters.token)
const { group, key, subkeys } = configs[0]
commit('SET_SETTINGS', response.data.configs)
commit('TOGGLE_REBOOT', response.data.need_reboot)
commit('REMOVE_SETTING_FROM_UPDATED', { group, key, subkeys: subkeys || [] })
},
async RestartApplication({ commit, getters }) {
await restartApp(getters.authHost, getters.token)
commit('TOGGLE_REBOOT', false)
},
SetActiveTab({ commit }, tab) {
commit('SET_ACTIVE_TAB', tab)
},
@ -102,6 +112,7 @@ const settings = {
await updateSettings(configs, getters.authHost, getters.token)
const response = await fetchSettings(getters.authHost, getters.token)
commit('SET_SETTINGS', response.data.configs)
commit('TOGGLE_REBOOT', response.data.need_reboot)
commit('CLEAR_UPDATED_SETTINGS')
},
UpdateSettings({ commit }, { group, key, input, value, type }) {

View file

@ -3,6 +3,10 @@
<el-form ref="httpData" :model="httpData" :label-width="labelWidth">
<setting :setting-group="http" :data="httpData"/>
</el-form>
<el-form ref="teslaAdapter" :model="teslaAdapterData" :label-width="labelWidth">
<setting :setting-group="teslaAdapter" :data="teslaAdapterData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="corsPlugData" :model="corsPlugData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">{{ $t('settings.corsPlug') }}</span>
@ -82,6 +86,12 @@ export default {
loading() {
return this.settings.loading
},
teslaAdapter() {
return this.settings.description.find(setting => setting.group === ':tesla')
},
teslaAdapterData() {
return _.get(this.settings.settings, [':tesla']) || {}
},
webCacheTtl() {
return this.settings.description.find(setting => setting.key === ':web_cache_ttl')
},

View file

@ -1,9 +1,5 @@
<template>
<div v-if="!loading" class="form-container">
<el-form ref="teslaAdapter" :model="teslaAdapterData" :label-width="labelWidth">
<setting :setting-group="teslaAdapter" :data="teslaAdapterData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mimeTypes" :model="mimeTypesData" :label-width="labelWidth">
<setting :setting-group="mimeTypes" :data="mimeTypesData"/>
</el-form>
@ -58,12 +54,6 @@ export default {
},
remoteIpData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Plugs.RemoteIp']) || {}
},
teslaAdapter() {
return this.settings.description.find(setting => setting.group === ':tesla')
},
teslaAdapterData() {
return _.get(this.settings.settings, [':tesla']) || {}
}
},
methods: {

View file

@ -3,17 +3,27 @@
<div v-if="isDesktop">
<div class="settings-header-container">
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
<el-link
:underline="false"
href="https://docs-develop.pleroma.social/backend/administration/CLI_tasks/config/"
target="_blank">
<el-button class="settings-docs-button">
<span>
<i class="el-icon-document"/>
{{ $t('settings.seeDocs') }}
</span>
</el-button>
</el-link>
<div>
<el-tooltip v-if="needReboot" :content="$t('settings.restartApp')" placement="bottom-end">
<el-button type="warning" class="settings-reboot-button" @click="restartApp">
<span>
<i class="el-icon-refresh"/>
{{ $t('settings.instanceReboot') }}
</span>
</el-button>
</el-tooltip>
<el-link
:underline="false"
href="https://docs-develop.pleroma.social/backend/administration/CLI_tasks/config/"
target="_blank">
<el-button class="settings-docs-button">
<span>
<i class="el-icon-document"/>
{{ $t('settings.seeDocs') }}
</span>
</el-button>
</el-link>
</div>
</div>
<el-tabs v-model="activeTab" tab-position="left">
<el-tab-pane :label="$t('settings.activityPub')" :disabled="configDisabled" name="activityPub" lazy>
@ -79,8 +89,16 @@
</el-tabs>
</div>
<div v-if="isMobile || isTablet">
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
<div class="settings-header-container">
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
<el-button v-if="needReboot" class="settings-reboot-button" @click="restartApp">
<span>
<i class="el-icon-refresh"/>
{{ $t('settings.instanceReboot') }}
</span>
</el-button>
</div>
<div class="nav-container">
<el-select v-model="activeTab" class="settings-menu" placeholder="Select">
<el-option
v-for="item in options"
@ -219,10 +237,26 @@ export default {
},
isTablet() {
return this.$store.state.app.device === 'tablet'
},
needReboot() {
return this.$store.state.settings.needReboot
}
},
mounted: function() {
this.$store.dispatch('FetchSettings')
},
methods: {
async restartApp() {
try {
await this.$store.dispatch('RestartApplication')
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.restartSuccess')
})
}
}
}
</script>

View file

@ -247,6 +247,8 @@
margin-bottom: 10px;
}
.settings-container {
max-width: 1824px;
margin: auto;
.el-tabs {
margin-top: 20px
}
@ -269,6 +271,12 @@
align-items: center;
margin: 22px 30px 15px 15px;
}
.settings-reboot-button {
width: 145px;
text-align: left;
padding: 10px;
margin-right: 5px;
}
.single-input {
margin-right: 10px
}
@ -318,10 +326,6 @@
}
@media only screen and (min-width: 1824px) {
.settings-container {
max-width: 1824px;
margin: auto;
}
.submit-button-container {
max-width: 1637px;
margin-left: auto;
@ -425,11 +429,20 @@
justify-content: space-between;
}
.settings-header {
margin: 7px 10px 15px 15px;
width: fit-content;
display: inline-block;
margin: 0;
}
.settings-header-container {
margin: 15px;
}
.nav-container {
display: flex;
height: 36px;
justify-content: space-between;
align-items: center;
margin: 15px;
}
.settings-menu {
width: 163px;
}
@ -508,6 +521,7 @@
}
}
@media only screen and (max-width:801px) and (min-width: 481px) {
.delete-setting-button {
margin: 4px 0 0 10px;
height: 28px;
@ -538,14 +552,18 @@
display: flex;
justify-content: space-between;
}
.nav-container {
display: flex;
height: 36px;
justify-content: space-between;
align-items: center;
margin: 15px 30px 15px 15px;
}
.rate-limit-label-container {
width: 250px;
}
.settings-delete-button {
float: right;
}
.settings-header {
margin: 5px 0 0 15px;
}
}
}