forked from AkkomaGang/admin-fe
Merge branch 'feature/show-reboot-button' into 'develop'
Show reboot button on every page Closes #98 See merge request pleroma/admin-fe!122
This commit is contained in:
commit
f1e1832c7e
51 changed files with 2032 additions and 964 deletions
|
@ -10,6 +10,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
- Link settings that enable registrations and invites
|
||||
|
||||
### Changed
|
||||
|
||||
- Put Instance Reboot button on all pages of admin-fe
|
||||
- Make Instance Reboot button's positon fixed on Settings page
|
||||
- Update jest and babel-jest
|
||||
|
||||
### Fixed
|
||||
|
||||
- Disable Invites tab when invites are disabled on BE
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"autoprefixer": "8.5.0",
|
||||
"babel-eslint": "8.2.6",
|
||||
"babel-helper-vue-jsx-merge-props": "2.0.3",
|
||||
"babel-jest": "^24.1.0",
|
||||
"babel-jest": "^25.3.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
||||
|
@ -101,7 +101,7 @@
|
|||
"hash-sum": "1.0.2",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"husky": "0.14.3",
|
||||
"jest": "^24.1.0",
|
||||
"jest": "^25.3.0",
|
||||
"jest-transform-stub": "^2.0.0",
|
||||
"lint-staged": "7.2.2",
|
||||
"mini-css-extract-plugin": "0.4.1",
|
||||
|
|
7
src/api/__mocks__/app.js
Normal file
7
src/api/__mocks__/app.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export async function needReboot(authHost, token) {
|
||||
return Promise.resolve({ data: false })
|
||||
}
|
||||
|
||||
export async function restartApp(authHost, token) {
|
||||
return Promise.resolve()
|
||||
}
|
|
@ -28,6 +28,10 @@ export async function fetchUser(id, authHost, token) {
|
|||
return Promise.resolve({ data: userProfile })
|
||||
}
|
||||
|
||||
export async function fetchUserCredentials(nickname, authHost, token) {
|
||||
return Promise.resolve({ data: {}})
|
||||
}
|
||||
|
||||
export async function fetchUsers(filters, authHost, token, page = 1) {
|
||||
const filteredUsers = filterUsers(filters)
|
||||
return Promise.resolve({ data: {
|
||||
|
|
23
src/api/app.js
Normal file
23
src/api/app.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import request from '@/utils/request'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { baseName } from './utils'
|
||||
|
||||
export async function needReboot(authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/pleroma/admin/need_reboot`,
|
||||
method: 'get',
|
||||
headers: authHeaders(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()}` } : {}
|
|
@ -40,13 +40,4 @@ 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()}` } : {}
|
||||
|
|
36
src/components/RebootButton/index.vue
Normal file
36
src/components/RebootButton/index.vue
Normal file
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<el-tooltip v-if="needReboot" :content="$t('settings.restartApp')" placement="bottom-end">
|
||||
<el-button type="warning" class="reboot-button" @click="restartApp">
|
||||
<span>
|
||||
<i class="el-icon-refresh"/>
|
||||
{{ $t('settings.instanceReboot') }}
|
||||
</span>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/lang'
|
||||
|
||||
export default {
|
||||
name: 'RebootButton',
|
||||
computed: {
|
||||
needReboot() {
|
||||
return this.$store.state.app.needReboot
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async restartApp() {
|
||||
try {
|
||||
await this.$store.dispatch('RestartApplication')
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.restartSuccess')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -383,7 +383,7 @@ export default {
|
|||
emoji: 'Emoji',
|
||||
markup: 'Markup settings',
|
||||
corsPlug: 'CORS plug config',
|
||||
instanceReboot: 'Instance Reboot',
|
||||
instanceReboot: 'Reboot Instance',
|
||||
restartApp: 'You must restart the instance to apply settings',
|
||||
restartSuccess: 'Instance rebooted successfully!'
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Cookies from 'js-cookie'
|
||||
import { needReboot, restartApp } from '@/api/app'
|
||||
|
||||
const app = {
|
||||
state: {
|
||||
|
@ -8,6 +9,7 @@ const app = {
|
|||
},
|
||||
device: 'desktop',
|
||||
language: Cookies.get('language') || 'en',
|
||||
needReboot: false,
|
||||
size: Cookies.get('size') || 'medium',
|
||||
invitesEnabled: false
|
||||
},
|
||||
|
@ -36,20 +38,25 @@ const app = {
|
|||
state.language = language
|
||||
Cookies.set('language', language)
|
||||
},
|
||||
TOGGLE_REBOOT: (state, needReboot) => {
|
||||
state.needReboot = needReboot
|
||||
},
|
||||
SET_SIZE: (state, size) => {
|
||||
state.size = size
|
||||
Cookies.set('size', size)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
toggleSideBar({ commit }) {
|
||||
commit('TOGGLE_SIDEBAR')
|
||||
},
|
||||
closeSideBar({ commit }, { withoutAnimation }) {
|
||||
commit('CLOSE_SIDEBAR', withoutAnimation)
|
||||
},
|
||||
toggleDevice({ commit }, device) {
|
||||
commit('TOGGLE_DEVICE', device)
|
||||
async NeedReboot({ commit, getters }) {
|
||||
const response = await needReboot(getters.authHost, getters.token)
|
||||
commit('TOGGLE_REBOOT', response.data['need_reboot'])
|
||||
},
|
||||
async RestartApplication({ commit, getters }) {
|
||||
await restartApp(getters.authHost, getters.token)
|
||||
commit('TOGGLE_REBOOT', false)
|
||||
},
|
||||
SetInvitesEnabled({ commit }, invitesEnabled) {
|
||||
commit('SET_INVITES_ENABLED', invitesEnabled)
|
||||
|
@ -59,6 +66,12 @@ const app = {
|
|||
},
|
||||
setSize({ commit }, size) {
|
||||
commit('SET_SIZE', size)
|
||||
},
|
||||
toggleDevice({ commit }, device) {
|
||||
commit('TOGGLE_DEVICE', device)
|
||||
},
|
||||
toggleSideBar({ commit }) {
|
||||
commit('TOGGLE_SIDEBAR')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { fetchDescription, fetchSettings, removeSettings, restartApp, updateSettings } from '@/api/settings'
|
||||
import { fetchDescription, fetchSettings, removeSettings, updateSettings } from '@/api/settings'
|
||||
import { checkPartialUpdate, formSearchObject, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
|
||||
import _ from 'lodash'
|
||||
|
||||
|
@ -9,7 +9,6 @@ const settings = {
|
|||
db: {},
|
||||
description: [],
|
||||
loading: true,
|
||||
needReboot: false,
|
||||
searchData: {},
|
||||
settings: {},
|
||||
updatedSettings: {}
|
||||
|
@ -55,9 +54,6 @@ const settings = {
|
|||
state.settings = newSettings
|
||||
state.db = newDbSettings
|
||||
},
|
||||
TOGGLE_REBOOT: (state, needReboot) => {
|
||||
state.needReboot = needReboot || false
|
||||
},
|
||||
TOGGLE_TABS: (state, status) => {
|
||||
state.configDisabled = status
|
||||
},
|
||||
|
@ -84,7 +80,6 @@ const settings = {
|
|||
const searchObject = formSearchObject(description.data)
|
||||
commit('SET_SEARCH', searchObject)
|
||||
commit('SET_SETTINGS', response.data.configs)
|
||||
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
||||
} catch (_e) {
|
||||
commit('TOGGLE_TABS', true)
|
||||
commit('SET_ACTIVE_TAB', 'relays')
|
||||
|
@ -102,10 +97,6 @@ const settings = {
|
|||
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)
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
z-index: 5000;
|
||||
overflow: hidden;
|
||||
|
||||
//reset element-ui css
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<div class="emoji-packs">
|
||||
<h1 class="emoji-packs-header">{{ $t('emoji.emojiPacks') }}</h1>
|
||||
<div class="emoji-packs-header">
|
||||
<h1>{{ $t('emoji.emojiPacks') }}</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="emoji-header-container">
|
||||
<div class="emoji-packs-header-button-container">
|
||||
<el-button type="primary" class="reload-emoji-button" @click="reloadEmoji">{{ $t('emoji.reloadEmoji') }}</el-button>
|
||||
<el-tooltip :content="$t('emoji.importEmojiTooltip')" effects="dark" placement="bottom" class="import-pack-button">
|
||||
|
@ -9,6 +13,7 @@
|
|||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider class="divider"/>
|
||||
<el-form :label-width="labelWidth" class="emoji-packs-form">
|
||||
<el-form-item :label="$t('emoji.localPacks')">
|
||||
|
@ -58,9 +63,10 @@
|
|||
import LocalEmojiPack from './components/LocalEmojiPack'
|
||||
import RemoteEmojiPack from './components/RemoteEmojiPack'
|
||||
import i18n from '@/lang'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
components: { LocalEmojiPack, RemoteEmojiPack },
|
||||
components: { LocalEmojiPack, RebootButton, RemoteEmojiPack },
|
||||
data() {
|
||||
return {
|
||||
remoteInstanceAddress: '',
|
||||
|
@ -94,6 +100,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.refreshLocalPacks()
|
||||
},
|
||||
methods: {
|
||||
|
@ -149,9 +157,14 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
.emoji-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 15px 22px 15px;
|
||||
}
|
||||
.emoji-packs-header-button-container {
|
||||
display: flex;
|
||||
margin: 0 0 22px 15px;
|
||||
}
|
||||
.create-pack {
|
||||
display: flex;
|
||||
|
@ -164,17 +177,28 @@ export default {
|
|||
margin: 0 30px;
|
||||
}
|
||||
.emoji-packs-header {
|
||||
margin: 10px 0 20px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.import-pack-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1824px) {
|
||||
.emoji-packs {
|
||||
|
@ -200,6 +224,10 @@ export default {
|
|||
.el-message-box {
|
||||
width: 80%;
|
||||
}
|
||||
.emoji-header-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.emoji-packs-form {
|
||||
margin: 0 7px;
|
||||
label {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<template>
|
||||
<div class="invites-container">
|
||||
<div class="invites-header-container">
|
||||
<h1>{{ $t('invites.inviteTokens') }}</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<el-button class="create-invite-token" @click="createTokenDialogVisible = true">
|
||||
<span>
|
||||
|
@ -140,7 +143,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
components: { RebootButton },
|
||||
data() {
|
||||
return {
|
||||
rules: {
|
||||
|
@ -178,6 +184,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('FetchInviteTokens')
|
||||
},
|
||||
methods: {
|
||||
|
@ -232,7 +240,7 @@ export default {
|
|||
height: 36px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 20px 15px 15px 15px;
|
||||
margin: 15px 15px 15px 15px;
|
||||
}
|
||||
.create-invite-token {
|
||||
text-align: left;
|
||||
|
@ -246,7 +254,7 @@ export default {
|
|||
padding: 5px 20px 0 20px
|
||||
}
|
||||
h1 {
|
||||
margin: 10px 0 0 15px;
|
||||
margin: 0;
|
||||
}
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
|
@ -263,12 +271,23 @@ export default {
|
|||
.invite-via-email-dialog {
|
||||
width: 50%
|
||||
}
|
||||
.invites-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 15px;
|
||||
}
|
||||
.info {
|
||||
color: #666666;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
|
@ -296,7 +315,7 @@ export default {
|
|||
padding: 5px 15px 0 15px
|
||||
}
|
||||
h1 {
|
||||
margin: 7px 10px 15px 10px;
|
||||
margin: 0;
|
||||
}
|
||||
.invite-token-table {
|
||||
width: 100%;
|
||||
|
@ -311,6 +330,9 @@ export default {
|
|||
.invite-via-email-dialog {
|
||||
width: 85%
|
||||
}
|
||||
.invites-header-container {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.info {
|
||||
margin: 0 0 10px 5px;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ export default {
|
|||
|
||||
.right-menu-item {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
padding: 0 15px;
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
color: #5a5e66;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="moderation-log-container">
|
||||
<div class="moderation-log-header-container">
|
||||
<h1>{{ $t('moderationLog.moderationLog') }}</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="moderation-log-nav-container">
|
||||
<el-select
|
||||
v-model="user"
|
||||
|
@ -60,8 +63,10 @@
|
|||
import moment from 'moment'
|
||||
import _ from 'lodash'
|
||||
import debounce from 'lodash.debounce'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
components: { RebootButton },
|
||||
data() {
|
||||
return {
|
||||
dateRange: '',
|
||||
|
@ -103,6 +108,8 @@ export default {
|
|||
}, 500)
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('FetchModerationLog')
|
||||
this.$store.dispatch('FetchAdmins')
|
||||
},
|
||||
|
@ -130,7 +137,7 @@ export default {
|
|||
margin: 0 15px;
|
||||
}
|
||||
h1 {
|
||||
margin: 10px 0 20px 0;
|
||||
margin: 0;
|
||||
}
|
||||
.el-timeline {
|
||||
margin: 25px 45px 0 0;
|
||||
|
@ -139,6 +146,12 @@ h1 {
|
|||
.moderation-log-date-panel {
|
||||
width: 350px;
|
||||
}
|
||||
.moderation-log-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 0 15px 0;
|
||||
}
|
||||
.moderation-log-nav-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -150,6 +163,11 @@ h1 {
|
|||
margin: 0 0 20px;
|
||||
width: 350px;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
.search-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -158,6 +176,9 @@ h1 {
|
|||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
.moderation-log-date-panel {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
placement="top"
|
||||
class="timeline-item-container">
|
||||
<el-card class="report">
|
||||
<div class="header-container">
|
||||
<div class="report-header-container">
|
||||
<div class="title-container">
|
||||
<h3 class="report-title">{{ $t('reports.reportOn') }} {{ report.account.display_name }}</h3>
|
||||
<h5 class="id">{{ $t('reports.id') }}: {{ report.id }}</h5>
|
||||
|
@ -212,7 +212,7 @@ export default {
|
|||
height: 17px;
|
||||
}
|
||||
.report {
|
||||
.header-container {
|
||||
.report-header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
|
@ -285,7 +285,7 @@ export default {
|
|||
|
||||
@media only screen and (max-width:480px) {
|
||||
.report {
|
||||
.header-container {
|
||||
.report-header-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div class="reports-container">
|
||||
<div class="reports-header-container">
|
||||
<h1>
|
||||
{{ $t('reports.reports') }}
|
||||
<span class="report-count">({{ normalizedReportsCount }})</span>
|
||||
</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="reports-filter-container">
|
||||
<reports-filter/>
|
||||
</div>
|
||||
|
@ -20,9 +23,10 @@
|
|||
import numeral from 'numeral'
|
||||
import Report from './components/Report'
|
||||
import ReportsFilter from './components/ReportsFilter'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
components: { Report, ReportsFilter },
|
||||
components: { RebootButton, Report, ReportsFilter },
|
||||
computed: {
|
||||
loading() {
|
||||
return this.$store.state.reports.loading
|
||||
|
@ -35,6 +39,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('FetchReports', 1)
|
||||
}
|
||||
}
|
||||
|
@ -42,15 +48,26 @@ export default {
|
|||
|
||||
<style rel='stylesheet/scss' lang='scss' scoped>
|
||||
.reports-container {
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
.reports-filter-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin: 22px 15px 22px 15px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 15px 45px 22px 15px;
|
||||
padding-bottom: 0
|
||||
}
|
||||
.reports-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 15px;
|
||||
}
|
||||
h1 {
|
||||
margin: 10px 0 0 15px;
|
||||
margin: 0;
|
||||
}
|
||||
.no-reports-message {
|
||||
color: gray;
|
||||
|
@ -67,6 +84,13 @@ export default {
|
|||
h1 {
|
||||
margin: 7px 10px 15px 10px;
|
||||
}
|
||||
.reboot-button {
|
||||
margin: 0 0 5px 10px;
|
||||
width: 145px;
|
||||
}
|
||||
.report-count {
|
||||
font-size: 22px;
|
||||
}
|
||||
.reports-filter-container {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="activitypubData" :model="activitypubData" :label-width="labelWidth" data-search=":activitypub">
|
||||
<setting :setting-group="activitypub" :data="activitypubData"/>
|
||||
</el-form>
|
||||
|
@ -35,6 +35,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="pleromaAuthenticatorData" :model="pleromaAuthenticatorData" :label-width="labelWidth">
|
||||
<setting :setting-group="pleromaAuthenticator" :data="pleromaAuthenticatorData"/>
|
||||
</el-form>
|
||||
|
@ -43,6 +43,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="autoLinker" :model="autoLinkerData" :label-width="labelWidth">
|
||||
<setting :setting-group="autoLinker" :data="autoLinkerData"/>
|
||||
</el-form>
|
||||
|
@ -31,6 +31,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="captchaData" :model="captchaData" :label-width="labelWidth">
|
||||
<setting :setting-group="captcha" :data="captchaData"/>
|
||||
</el-form>
|
||||
|
@ -35,6 +35,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="esshdData" :model="esshdData" :label-width="labelWidth">
|
||||
<setting :setting-group="esshd" :data="esshdData"/>
|
||||
</el-form>
|
||||
|
@ -31,6 +31,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="frontendData" :model="frontendData" :label-width="labelWidth">
|
||||
<setting :setting-group="frontend" :data="frontendData"/>
|
||||
</el-form>
|
||||
|
@ -77,6 +77,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form v-if="!loading" ref="gopher" :model="gopherData" :label-width="labelWidth">
|
||||
<setting :setting-group="gopher" :data="gopherData"/>
|
||||
</el-form>
|
||||
|
@ -31,6 +31,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="httpData" :model="httpData" :label-width="labelWidth">
|
||||
<setting :setting-group="http" :data="httpData"/>
|
||||
</el-form>
|
||||
|
@ -67,6 +67,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="obanQueuesData" :model="obanQueuesData" :label-width="labelWidth">
|
||||
<setting :setting-group="obanQueues" :data="obanQueuesData"/>
|
||||
</el-form>
|
||||
|
@ -37,6 +37,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="loggerData" :model="loggerData" :label-width="labelWidth">
|
||||
<setting :setting-group="logger" :data="loggerData"/>
|
||||
</el-form>
|
||||
|
@ -49,6 +49,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="mrfSimple" :model="mrfSimpleData" :label-width="labelWidth">
|
||||
<setting :setting-group="mrfSimple" :data="mrfSimpleData"/>
|
||||
</el-form>
|
||||
|
@ -59,6 +59,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="mailer" :model="mailerData" :label-width="labelWidth">
|
||||
<setting :setting-group="mailer" :data="mailerData"/>
|
||||
</el-form>
|
||||
|
@ -47,6 +47,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form v-if="!loading" ref="mediaProxy" :model="mediaProxyData" :label-width="labelWidth">
|
||||
<setting :setting-group="mediaProxy" :data="mediaProxyData"/>
|
||||
</el-form>
|
||||
|
@ -25,6 +25,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="metadata" :model="metadataData" :label-width="labelWidth">
|
||||
<setting :setting-group="metadata" :data="metadataData"/>
|
||||
</el-form>
|
||||
|
@ -29,6 +29,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="mimeTypes" :model="mimeTypesData" :label-width="labelWidth">
|
||||
<setting :setting-group="mimeTypes" :data="mimeTypesData"/>
|
||||
</el-form>
|
||||
|
@ -28,6 +28,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form v-if="!loading" ref="rateLimiters" :model="rateLimitersData" :label-width="labelWidth">
|
||||
<setting :setting-group="rateLimiters" :data="rateLimitersData"/>
|
||||
</el-form>
|
||||
|
@ -31,6 +31,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form ref="uploadData" :model="uploadData" :label-width="labelWidth">
|
||||
<setting :setting-group="upload" :data="uploadData"/>
|
||||
</el-form>
|
||||
|
@ -43,6 +43,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="form-container">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form v-if="!loading" ref="vapidDetailsData" :model="vapidDetailsData" :label-width="labelWidth">
|
||||
<setting :setting-group="vapidDetails" :data="vapidDetailsData"/>
|
||||
</el-form>
|
||||
|
@ -25,6 +25,9 @@ export default {
|
|||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'sidebar-opened' : 'sidebar-closed'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
<template>
|
||||
<div class="settings-container">
|
||||
<div :class="rebootIsSidebarOpen" class="settings-container">
|
||||
<div class="reboot-button-container">
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div v-if="isDesktop">
|
||||
<div :class="isSidebarOpen" class="settings-header-container">
|
||||
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
|
||||
<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>
|
||||
<div class="docs-search-container">
|
||||
<el-link
|
||||
:underline="false"
|
||||
href="https://docs-develop.pleroma.social/backend/administration/CLI_tasks/config/"
|
||||
|
@ -49,12 +44,6 @@
|
|||
<div v-if="isMobile || isTablet">
|
||||
<div :class="isSidebarOpen" 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">
|
||||
|
@ -127,6 +116,7 @@ import {
|
|||
Upload,
|
||||
WebPush
|
||||
} from './components'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -148,6 +138,7 @@ export default {
|
|||
Other,
|
||||
RateLimiters,
|
||||
Relays,
|
||||
RebootButton,
|
||||
Upload,
|
||||
WebPush
|
||||
},
|
||||
|
@ -202,8 +193,8 @@ export default {
|
|||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
needReboot() {
|
||||
return this.$store.state.settings.needReboot
|
||||
rebootIsSidebarOpen() {
|
||||
return this.$store.state.app.sidebar.opened ? 'reboot-sidebar-opened' : 'reboot-sidebar-closed'
|
||||
},
|
||||
searchData() {
|
||||
return this.$store.state.settings.searchData
|
||||
|
@ -213,20 +204,11 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
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')
|
||||
})
|
||||
},
|
||||
async handleSearchSelect(selectedValue) {
|
||||
const tab = Object.keys(this.tabs).find(tab => {
|
||||
return this.tabs[tab].settings.includes(selectedValue.group === ':pleroma' ? selectedValue.key : selectedValue.group)
|
||||
|
@ -250,7 +232,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
<style rel='stylesheet/scss' lang='scss' scoped>
|
||||
@import './styles/main';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
.divider.thick-line {
|
||||
height: 2px;
|
||||
}
|
||||
.docs-search-container {
|
||||
float: right;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.editable-keyword-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -230,6 +234,20 @@
|
|||
width: 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.reboot-button {
|
||||
width: 145px;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
float: right;
|
||||
margin: 0 30px 0 0;
|
||||
}
|
||||
.reboot-button-container {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
right: 0;
|
||||
z-index: 2000;
|
||||
}
|
||||
.relays-container {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
@ -262,7 +280,7 @@
|
|||
padding: 10px;
|
||||
}
|
||||
.settings-header {
|
||||
margin: 0;
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.header-sidebar-opened {
|
||||
max-width: 1585px;
|
||||
|
@ -271,17 +289,7 @@
|
|||
max-width: 1728px;
|
||||
}
|
||||
.settings-header-container {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 22px 30px 15px 15px;
|
||||
}
|
||||
.settings-reboot-button {
|
||||
width: 145px;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
margin-right: 5px;
|
||||
height: 87px;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 350px;
|
||||
|
@ -336,6 +344,25 @@
|
|||
}
|
||||
|
||||
@media only screen and (min-width: 1824px) {
|
||||
.header-sidebar-closed {
|
||||
max-width: 1772px;
|
||||
}
|
||||
.header-sidebar-opened {
|
||||
max-width: 1630px;
|
||||
}
|
||||
.reboot-button-container {
|
||||
width: 100%;
|
||||
max-width: inherit;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
right: auto;
|
||||
}
|
||||
.reboot-sidebar-opened {
|
||||
max-width: 1630px;
|
||||
}
|
||||
.reboot-sidebar-closed {
|
||||
max-width: 1772px;
|
||||
}
|
||||
.sidebar-closed {
|
||||
max-width: 1586px;
|
||||
}
|
||||
|
@ -392,6 +419,9 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
.input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
@ -455,6 +485,12 @@
|
|||
.rate-limit-label {
|
||||
float: left;
|
||||
}
|
||||
.reboot-button {
|
||||
margin: 0 15px 0 0;
|
||||
}
|
||||
.reboot-button-container {
|
||||
top: 57px;
|
||||
}
|
||||
.scale-input {
|
||||
width: 45%;
|
||||
}
|
||||
|
@ -465,11 +501,11 @@
|
|||
.settings-header {
|
||||
width: fit-content;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
.settings-header-container {
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.docs-search-container {
|
||||
float: right;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
|
@ -479,6 +515,7 @@
|
|||
}
|
||||
.settings-menu {
|
||||
width: 163px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.socks5-checkbox-container {
|
||||
width: 100%;
|
||||
|
@ -548,6 +585,9 @@
|
|||
margin-left: 4px;
|
||||
margin-right: 5px
|
||||
}
|
||||
.settings-header-container {
|
||||
height: 45px;
|
||||
}
|
||||
.value-input {
|
||||
width: 60%;
|
||||
margin-left: 5px;
|
||||
|
@ -598,6 +638,9 @@
|
|||
.settings-delete-button {
|
||||
float: right;
|
||||
}
|
||||
.settings-header-container {
|
||||
height: 36px;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 250px;
|
||||
margin: 0 0 15px 15px;
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
<template>
|
||||
<div v-if="!loadingPeers" class="statuses-container">
|
||||
<div class="statuses-header">
|
||||
<h1>
|
||||
{{ $t('statuses.statuses') }}
|
||||
</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="statuses-header-container">
|
||||
<el-button-group>
|
||||
<el-button plain>{{ $t('statuses.direct') }}: {{ statusVisibility.direct }}</el-button>
|
||||
<el-button plain>{{ $t('statuses.private') }}: {{ statusVisibility.private }}</el-button>
|
||||
<el-button plain>{{ $t('statuses.public') }}: {{ statusVisibility.public }}</el-button>
|
||||
<el-button plain>{{ $t('statuses.unlisted') }}: {{ statusVisibility.unlisted }}</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="selectedInstance"
|
||||
|
@ -54,11 +59,13 @@
|
|||
<script>
|
||||
import MultipleUsersMenu from '@/views/users/components/MultipleUsersMenu'
|
||||
import Status from '@/components/Status'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'Statuses',
|
||||
components: {
|
||||
MultipleUsersMenu,
|
||||
RebootButton,
|
||||
Status
|
||||
},
|
||||
data() {
|
||||
|
@ -82,6 +89,12 @@ export default {
|
|||
isDesktop() {
|
||||
return this.$store.state.app.device === 'desktop'
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
loadingPeers() {
|
||||
return this.$store.state.peers.loading
|
||||
},
|
||||
|
@ -123,6 +136,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('FetchPeers')
|
||||
this.$store.dispatch('FetchStatusesCount')
|
||||
},
|
||||
|
@ -169,8 +184,23 @@ export default {
|
|||
align-items: center;
|
||||
margin: 22px 0 15px 0;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
.select-instance {
|
||||
width: 350px;
|
||||
width: 396px;
|
||||
}
|
||||
.statuses-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.statuses-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.statuses-pagination {
|
||||
padding: 15px 0;
|
||||
|
@ -194,5 +224,15 @@ export default {
|
|||
.select-instance {
|
||||
width: 100%;
|
||||
}
|
||||
.statuses-header-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
.el-button {
|
||||
padding: 10px 6.5px;
|
||||
}
|
||||
.reboot-button {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -179,4 +179,9 @@ export default {
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
@media only screen and (max-width:480px) {
|
||||
.moderate-user-button {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -68,10 +68,4 @@ export default {
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:801px) and (min-width: 481px) {
|
||||
.select-field {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div class="users-container">
|
||||
<div class="users-header-container">
|
||||
<h1>
|
||||
{{ $t('users.users') }}
|
||||
<span class="user-count">({{ normalizedUsersCount }})</span>
|
||||
</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<users-filter/>
|
||||
<el-input
|
||||
|
@ -111,6 +114,7 @@ import UsersFilter from './components/UsersFilter'
|
|||
import MultipleUsersMenu from './components/MultipleUsersMenu'
|
||||
import NewAccountDialog from './components/NewAccountDialog'
|
||||
import ModerationDropdown from './components/ModerationDropdown'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'Users',
|
||||
|
@ -118,6 +122,7 @@ export default {
|
|||
NewAccountDialog,
|
||||
ModerationDropdown,
|
||||
MultipleUsersMenu,
|
||||
RebootButton,
|
||||
UsersFilter
|
||||
},
|
||||
data() {
|
||||
|
@ -169,6 +174,7 @@ export default {
|
|||
}, 500)
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('FetchUsers', { page: 1 })
|
||||
},
|
||||
methods: {
|
||||
|
@ -222,6 +228,9 @@ export default {
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0 15px 10px 15px;
|
||||
.el-dropdown {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.active-tag {
|
||||
color: #409EFF;
|
||||
|
@ -239,6 +248,11 @@ export default {
|
|||
.create-account > .el-icon-plus {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.users-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.password-reset-token {
|
||||
margin: 0 0 14px 0;
|
||||
}
|
||||
|
@ -251,23 +265,28 @@ export default {
|
|||
.users-container {
|
||||
h1 {
|
||||
margin: 10px 0 0 15px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 25px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reboot-button {
|
||||
margin: 0 15px 0 0;
|
||||
padding: 10px;
|
||||
width: 145px;
|
||||
}
|
||||
.search {
|
||||
width: 350px;
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.filter-container {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 22px 15px 15px 15px
|
||||
margin: 15px
|
||||
}
|
||||
.user-count {
|
||||
color: gray;
|
||||
|
@ -281,7 +300,7 @@ export default {
|
|||
}
|
||||
.users-container {
|
||||
h1 {
|
||||
margin: 7px 10px 15px 10px;
|
||||
margin: 0;
|
||||
}
|
||||
.actions-button {
|
||||
width: 100%;
|
||||
|
@ -296,6 +315,7 @@ export default {
|
|||
}
|
||||
.search {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
.filter-container {
|
||||
display: flex;
|
||||
|
@ -315,6 +335,25 @@ export default {
|
|||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
.reboot-button {
|
||||
margin: 0;
|
||||
}
|
||||
.users-header-container {
|
||||
margin: 7px 10px 12px 10px;
|
||||
}
|
||||
.user-count {
|
||||
color: gray;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:801px) and (min-width: 481px) {
|
||||
.actions-button {
|
||||
width: 49%;
|
||||
}
|
||||
.search {
|
||||
width: 49%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,15 +1,31 @@
|
|||
<template>
|
||||
<main v-if="!userProfileLoading">
|
||||
<header v-if="isDesktop || isTablet" class="user-page-header">
|
||||
<div class="avatar-name-container">
|
||||
<el-avatar :src="user.avatar" size="large" />
|
||||
<h1>{{ user.display_name }}</h1>
|
||||
</div>
|
||||
<div class="left-header-container">
|
||||
<moderation-dropdown
|
||||
:user="user"
|
||||
:page="'userPage'"
|
||||
@open-reset-token-dialog="openResetPasswordDialog"/>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
</header>
|
||||
<div v-if="isMobile" class="user-page-header-container">
|
||||
<header class="user-page-header">
|
||||
<div class="avatar-name-container">
|
||||
<el-avatar :src="user.avatar" size="large" />
|
||||
<h1>{{ user.display_name }}</h1>
|
||||
</div>
|
||||
<reboot-button/>
|
||||
</header>
|
||||
<moderation-dropdown
|
||||
:user="user"
|
||||
:page="'userPage'"
|
||||
@open-reset-token-dialog="openResetPasswordDialog"/>
|
||||
</header>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-loading="loading"
|
||||
:visible.sync="resetPasswordDialogOpen"
|
||||
|
@ -104,10 +120,11 @@
|
|||
import Status from '@/components/Status'
|
||||
import ModerationDropdown from './components/ModerationDropdown'
|
||||
import SecuritySettingsModal from './components/SecuritySettingsModal'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'UsersShow',
|
||||
components: { ModerationDropdown, Status, SecuritySettingsModal },
|
||||
components: { ModerationDropdown, RebootButton, Status, SecuritySettingsModal },
|
||||
data() {
|
||||
return {
|
||||
showPrivate: false,
|
||||
|
@ -116,6 +133,15 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
isDesktop() {
|
||||
return this.$store.state.app.device === 'desktop'
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.users.loading
|
||||
},
|
||||
|
@ -142,6 +168,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('FetchUserProfile', { userId: this.$route.params.id, godmode: false })
|
||||
},
|
||||
methods: {
|
||||
|
@ -189,6 +217,11 @@ table {
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
.left-header-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.no-statuses {
|
||||
margin-left: 28px;
|
||||
color: #606266;
|
||||
|
@ -198,6 +231,10 @@ table {
|
|||
padding: 0;
|
||||
width: 30%;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.recent-statuses-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -229,7 +266,8 @@ table {
|
|||
.user-page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
padding: 0 15px 0 20px;
|
||||
align-items: center;
|
||||
h1 {
|
||||
display: inline
|
||||
}
|
||||
|
@ -264,10 +302,14 @@ table {
|
|||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
.user-page-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
margin: 7px 0 15px 10px;
|
||||
margin: 7px 15px 15px 10px;
|
||||
}
|
||||
.user-page-header-container {
|
||||
.el-dropdown {
|
||||
width: 95%;
|
||||
margin: 0 15px 15px 10px;
|
||||
}
|
||||
}
|
||||
.user-profile-card {
|
||||
margin: 0 10px;
|
||||
|
@ -282,9 +324,6 @@ table {
|
|||
}
|
||||
|
||||
@media only screen and (max-width:801px) and (min-width: 481px) {
|
||||
.avatar-name-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.recent-statuses {
|
||||
margin: 20px 10px 15px 0;
|
||||
}
|
||||
|
@ -296,10 +335,8 @@ table {
|
|||
margin: 0 10px 20px 0;
|
||||
}
|
||||
.user-page-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
margin: 7px 0 20px 20px;
|
||||
margin: 7px 15px 20px 20px;
|
||||
}
|
||||
.user-profile-card {
|
||||
margin: 0 20px;
|
||||
|
|
|
@ -12,7 +12,9 @@ const localVue = createLocalVue()
|
|||
localVue.use(Vuex)
|
||||
localVue.use(Element)
|
||||
|
||||
jest.mock('@/api/app')
|
||||
jest.mock('@/api/invites')
|
||||
jest.mock('@/api/nodeInfo')
|
||||
|
||||
describe('Invite tokens', () => {
|
||||
let store
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import app from '@/store/modules/app'
|
||||
import user from '@/store/modules/user'
|
||||
import invites from '@/store/modules/invites'
|
||||
import settings from '@/store/modules/settings'
|
||||
import getters from '@/store/getters'
|
||||
|
||||
export default {
|
||||
modules: {
|
||||
app,
|
||||
invites,
|
||||
settings,
|
||||
user
|
||||
},
|
||||
getters
|
||||
|
|
|
@ -23,7 +23,9 @@ describe('Log out', () => {
|
|||
store = new Vuex.Store(cloneDeep(storeConfig))
|
||||
router = new VueRouter(cloneDeep(routerConfig))
|
||||
router.beforeEach(beforeEachRoute)
|
||||
window.location.reload = jest.fn()
|
||||
|
||||
delete window.location
|
||||
window.location = { href: '' }
|
||||
})
|
||||
|
||||
it('logs out user', async (done) => {
|
||||
|
|
|
@ -14,6 +14,7 @@ const localVue = createLocalVue()
|
|||
localVue.use(Vuex)
|
||||
localVue.use(Element)
|
||||
|
||||
jest.mock('@/api/app')
|
||||
jest.mock('@/api/reports')
|
||||
|
||||
describe('Reports', () => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import app from '@/store/modules/app'
|
|||
import user from '@/store/modules/user'
|
||||
import users from '@/store/modules/users'
|
||||
import reports from '@/store/modules/reports'
|
||||
import settings from '@/store/modules/settings'
|
||||
import status from '@/store/modules/status'
|
||||
import getters from '@/store/getters'
|
||||
|
||||
|
@ -11,6 +12,7 @@ export default {
|
|||
user,
|
||||
users,
|
||||
reports,
|
||||
settings,
|
||||
status
|
||||
},
|
||||
getters
|
||||
|
|
|
@ -16,12 +16,14 @@ localVue.use(Element)
|
|||
describe('Settings search', () => {
|
||||
let store
|
||||
let actions
|
||||
let appActions
|
||||
|
||||
beforeEach(() => {
|
||||
actions = { ...settings.actions, FetchSettings: jest.fn() }
|
||||
appActions = { ...app.actions, NeedReboot: jest.fn() }
|
||||
actions = { ...settings.actions, FetchSettings: jest.fn(), GetNodeInfo: jest.fn() }
|
||||
store = new Vuex.Store({
|
||||
modules: {
|
||||
app,
|
||||
app: { ...app, actions: appActions },
|
||||
settings: { ...settings, actions }
|
||||
},
|
||||
getters
|
||||
|
|
|
@ -14,6 +14,7 @@ const localVue = createLocalVue()
|
|||
localVue.use(Vuex)
|
||||
localVue.use(Element)
|
||||
|
||||
jest.mock('@/api/app')
|
||||
jest.mock('@/api/nodeInfo')
|
||||
jest.mock('@/api/users')
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import app from '@/store/modules/app'
|
||||
import settings from '@/store/modules/settings'
|
||||
import user from '@/store/modules/user'
|
||||
import userProfile from '@/store/modules/userProfile'
|
||||
import users from '@/store/modules/users'
|
||||
|
@ -7,6 +8,7 @@ import getters from '@/store/getters'
|
|||
export default {
|
||||
modules: {
|
||||
app,
|
||||
settings,
|
||||
user,
|
||||
userProfile,
|
||||
users
|
||||
|
|
Loading…
Reference in a new issue