forked from AkkomaGang/admin-fe
Merge branch 'feature/reduce-nav-sidebars' into develop
This commit is contained in:
commit
b1ce85fd33
64 changed files with 782 additions and 419 deletions
|
@ -28,6 +28,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Replace regular inputs with textareas for setting welcome messages in the Settings section
|
||||
- Update rendering Moderation Log Messages so that all usernames are links to the pages of the corresponding users in Admin-FE
|
||||
- Remove Websocket based federation settings
|
||||
- Move Settings tab navigation from the tabbed menu to the main sidebar menu. A separate route is created for each tab.
|
||||
- Move Emoji packs configuration to the Emoji tab in the Settings section
|
||||
- 401 and 404 error pages updated
|
||||
- Remove unused components
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"vue": "^2.6.8",
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-i18n": "^8.9.0",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-router": "^3.5.1",
|
||||
"vue-splitpane": "1.0.2",
|
||||
"vuedraggable": "^2.16.0",
|
||||
"vuex": "3.0.1",
|
||||
|
|
|
@ -15,7 +15,16 @@ export async function deleteInstanceDocument(name, authHost, token) {
|
|||
export async function fetchDescription(authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/pleroma/admin/config/descriptions`,
|
||||
url: `/api/v1/pleroma/admin/config/descriptions`,
|
||||
method: 'get',
|
||||
headers: authHeaders(token)
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchDescription2(authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/v2/pleroma/admin/config/descriptions`,
|
||||
method: 'get',
|
||||
headers: authHeaders(token)
|
||||
})
|
||||
|
|
|
@ -70,6 +70,7 @@ export default {
|
|||
chats: 'Chats',
|
||||
settings: 'Settings',
|
||||
moderationLog: 'Moderation Log',
|
||||
relays: 'Relays',
|
||||
mediaProxyCache: 'MediaProxy Cache',
|
||||
'emoji-packs': 'Emoji packs'
|
||||
},
|
||||
|
@ -426,6 +427,7 @@ export default {
|
|||
activityPub: 'ActivityPub',
|
||||
auth: 'Authentication',
|
||||
captcha: 'Captcha',
|
||||
emoji: 'Emoji',
|
||||
frontend: 'Frontend',
|
||||
http: 'HTTP',
|
||||
mrf: 'MRF',
|
||||
|
@ -437,11 +439,6 @@ export default {
|
|||
esshd: 'BBS / SSH access',
|
||||
rateLimiters: 'Rate limiters',
|
||||
other: 'Other',
|
||||
relays: 'Relays',
|
||||
follow: 'Follow',
|
||||
followRelay: 'Follow new relay',
|
||||
followedBack: 'Followed Back',
|
||||
instanceUrl: 'Instance URL',
|
||||
success: 'Settings changed successfully!',
|
||||
description: 'Description',
|
||||
removeFromDB: 'Remove setting from the DB',
|
||||
|
@ -483,6 +480,13 @@ export default {
|
|||
frontendStartedInstallation: 'Installation started',
|
||||
inProcess: 'In process'
|
||||
},
|
||||
relays: {
|
||||
relays: 'Relays',
|
||||
follow: 'Follow',
|
||||
followRelay: 'Follow new relay',
|
||||
followedBack: 'Followed Back',
|
||||
instanceUrl: 'Instance URL'
|
||||
},
|
||||
invites: {
|
||||
inviteTokens: 'Invite tokens',
|
||||
createInviteToken: 'Generate invite token',
|
||||
|
|
|
@ -28,7 +28,7 @@ export const beforeEachRoute = (to, from, next) => {
|
|||
store.dispatch('GetUserInfo').then(res => {
|
||||
const roles = res.data.pleroma.is_admin ? ['admin'] : []
|
||||
store.dispatch('GenerateRoutes', { roles }).then(() => {
|
||||
router.addRoutes(store.getters.addRouters)
|
||||
store.getters.addRouters.forEach(route => router.addRoute(route))
|
||||
next({ ...to, replace: true })
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
|
|
@ -21,19 +21,26 @@ import Layout from '@/views/layout/Layout'
|
|||
|
||||
const disabledFeatures = process.env.DISABLED_FEATURES || []
|
||||
const settingsDisabled = disabledFeatures.includes('settings')
|
||||
const settingsChildren = () => {
|
||||
return localStorage.getItem('settingsTabs')
|
||||
? JSON.parse(localStorage.getItem('settingsTabs')).map(({ label, path }) => {
|
||||
return {
|
||||
path,
|
||||
component: () => import(`@/views/settings`),
|
||||
name: label,
|
||||
meta: { title: label }
|
||||
}
|
||||
})
|
||||
: []
|
||||
}
|
||||
const settings = {
|
||||
path: '/settings',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/settings/index'),
|
||||
name: 'Settings',
|
||||
meta: { title: 'settings', icon: 'settings', noCache: true }
|
||||
}
|
||||
]
|
||||
hasSubmenu: true,
|
||||
meta: { title: 'settings', icon: 'el-icon-setting', noCache: true },
|
||||
children: settingsChildren()
|
||||
}
|
||||
|
||||
const statusesDisabled = disabledFeatures.includes('statuses')
|
||||
const statuses = {
|
||||
path: '/statuses',
|
||||
|
@ -43,7 +50,7 @@ const statuses = {
|
|||
path: 'index',
|
||||
component: () => import('@/views/statuses/index'),
|
||||
name: 'Statuses',
|
||||
meta: { title: 'statuses', icon: 'form', noCache: true }
|
||||
meta: { title: 'statuses', icon: 'el-icon-chat-line-square', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -57,7 +64,7 @@ const reports = {
|
|||
path: 'index',
|
||||
component: () => import('@/views/reports/index'),
|
||||
name: 'Reports',
|
||||
meta: { title: 'reports', icon: 'documentation', noCache: true }
|
||||
meta: { title: 'reports', icon: 'el-icon-receiving', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -71,21 +78,21 @@ const invites = {
|
|||
path: 'index',
|
||||
component: () => import('@/views/invites/index'),
|
||||
name: 'Invites',
|
||||
meta: { title: 'invites', icon: 'guide', noCache: true }
|
||||
meta: { title: 'invites', icon: 'el-icon-postcard', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const emojiPacksDisabled = disabledFeatures.includes('emoji-packs')
|
||||
const emojiPacks = {
|
||||
path: '/emoji_packs',
|
||||
const relaysDisabled = disabledFeatures.includes('relays')
|
||||
const relays = {
|
||||
path: '/relays',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/emojiPacks/index'),
|
||||
name: 'Emoji Packs',
|
||||
meta: { title: 'emoji-packs', icon: 'eye-open', noCache: true }
|
||||
component: () => import('@/views/relays/index'),
|
||||
name: 'Relays',
|
||||
meta: { title: 'relays', icon: 'el-icon-connection', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -99,7 +106,7 @@ const moderationLog = {
|
|||
path: 'index',
|
||||
component: () => import('@/views/moderationLog/index'),
|
||||
name: 'Moderation Log',
|
||||
meta: { title: 'moderationLog', icon: 'list', noCache: true }
|
||||
meta: { title: 'moderationLog', icon: 'el-icon-notebook-2', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -113,7 +120,7 @@ const mediaProxyCache = {
|
|||
path: 'index',
|
||||
component: () => import('@/views/mediaProxyCache/index'),
|
||||
name: 'MediaProxy Cache',
|
||||
meta: { title: 'mediaProxyCache', icon: 'example', noCache: true }
|
||||
meta: { title: 'mediaProxyCache', icon: 'el-icon-coin', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -158,7 +165,8 @@ export const constantRouterMap = [
|
|||
{
|
||||
path: '',
|
||||
component: Layout,
|
||||
redirect: '/users/index'
|
||||
redirect: '/users/index',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -177,15 +185,15 @@ export const asyncRouterMap = [
|
|||
path: 'index',
|
||||
component: () => import('@/views/users/index'),
|
||||
name: 'Users',
|
||||
meta: { title: 'users', icon: 'peoples', noCache: true }
|
||||
meta: { title: 'users', icon: 'el-icon-user', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
...(statusesDisabled ? [] : [statuses]),
|
||||
...(reportsDisabled ? [] : [reports]),
|
||||
...(invitesDisabled ? [] : [invites]),
|
||||
...(emojiPacksDisabled ? [] : [emojiPacks]),
|
||||
...(moderationLogDisabled ? [] : [moderationLog]),
|
||||
...(relaysDisabled ? [] : [relays]),
|
||||
...(mediaProxyCacheDisabled ? [] : [mediaProxyCache]),
|
||||
...(settingsDisabled ? [] : [settings]),
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ const getters = {
|
|||
errorLogs: state => state.errorLog.logs,
|
||||
users: state => state.users.fetchedUsers,
|
||||
authHost: state => state.user.authHost,
|
||||
settings: state => state.settings
|
||||
settings: state => state.settings,
|
||||
tabs: state => state.settings.tabs
|
||||
}
|
||||
export default getters
|
||||
|
|
|
@ -46,15 +46,10 @@ const permission = {
|
|||
}
|
||||
},
|
||||
actions: {
|
||||
GenerateRoutes({ commit }, data) {
|
||||
GenerateRoutes({ commit }, { roles, _routesWithSettings }) {
|
||||
return new Promise(resolve => {
|
||||
const { roles } = data
|
||||
let accessedRouters
|
||||
if (roles.includes('admin')) {
|
||||
accessedRouters = asyncRouterMap
|
||||
} else {
|
||||
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
|
||||
}
|
||||
const routes = _routesWithSettings || asyncRouterMap
|
||||
const accessedRouters = roles.includes('admin') ? routes : filterAsyncRouter(asyncRouterMap, roles)
|
||||
commit('SET_ROUTERS', accessedRouters)
|
||||
resolve()
|
||||
})
|
||||
|
|
|
@ -9,11 +9,11 @@ import {
|
|||
updateInstanceDocument,
|
||||
updateSettings } from '@/api/settings'
|
||||
import { formSearchObject, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
|
||||
import { tabs } from '../../utils/tabs'
|
||||
import _ from 'lodash'
|
||||
|
||||
const settings = {
|
||||
state: {
|
||||
activeTab: 'instance',
|
||||
configDisabled: true,
|
||||
frontends: [],
|
||||
db: {},
|
||||
|
@ -21,7 +21,9 @@ const settings = {
|
|||
instancePanel: '',
|
||||
loading: true,
|
||||
searchData: {},
|
||||
searchQuery: '',
|
||||
settings: {},
|
||||
tabs: [],
|
||||
termsOfServices: '',
|
||||
updatedSettings: {}
|
||||
},
|
||||
|
@ -38,9 +40,6 @@ const settings = {
|
|||
state.updatedSettings = updatedSettings
|
||||
}
|
||||
},
|
||||
SET_ACTIVE_TAB: (state, tab) => {
|
||||
state.activeTab = tab
|
||||
},
|
||||
SET_DESCRIPTION: (state, data) => {
|
||||
state.description = data
|
||||
},
|
||||
|
@ -53,6 +52,9 @@ const settings = {
|
|||
SET_SEARCH: (state, searchObject) => {
|
||||
state.searchData = searchObject
|
||||
},
|
||||
SET_SEARCH_QUERY: (state, query) => {
|
||||
state.searchQuery = query
|
||||
},
|
||||
SET_SETTINGS: (state, data) => {
|
||||
const newSettings = data.reduce((acc, { group, key, value }) => {
|
||||
const parsedValue = valueHasTuples(key, value)
|
||||
|
@ -72,6 +74,9 @@ const settings = {
|
|||
state.settings = newSettings
|
||||
state.db = newDbSettings
|
||||
},
|
||||
SET_TABS: (state, tabs) => {
|
||||
state.tabs = tabs
|
||||
},
|
||||
SET_TERMS_OF_SERVICES: (state, data) => {
|
||||
state.termsOfServices = data
|
||||
},
|
||||
|
@ -107,15 +112,16 @@ const settings = {
|
|||
async FetchSettings({ commit, getters }) {
|
||||
commit('SET_LOADING', true)
|
||||
try {
|
||||
const response = await fetchSettings(getters.authHost, getters.token)
|
||||
const description = await fetchDescription(getters.authHost, getters.token)
|
||||
commit('SET_DESCRIPTION', description.data)
|
||||
const searchObject = formSearchObject(description.data)
|
||||
const settings = await fetchSettings(getters.authHost, getters.token)
|
||||
commit('SET_SETTINGS', settings.data.configs)
|
||||
|
||||
const { data } = await fetchDescription(getters.authHost, getters.token)
|
||||
commit('SET_DESCRIPTION', data)
|
||||
const searchObject = formSearchObject(data)
|
||||
commit('SET_SEARCH', searchObject)
|
||||
commit('SET_SETTINGS', response.data.configs)
|
||||
commit('SET_TABS', tabs)
|
||||
} catch (_e) {
|
||||
commit('TOGGLE_TABS', true)
|
||||
commit('SET_ACTIVE_TAB', 'relays')
|
||||
commit('SET_LOADING', false)
|
||||
return
|
||||
}
|
||||
|
@ -138,8 +144,8 @@ const settings = {
|
|||
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
||||
commit('REMOVE_SETTING_FROM_UPDATED', { group, key, subkeys: subkeys || [] })
|
||||
},
|
||||
SetActiveTab({ commit }, tab) {
|
||||
commit('SET_ACTIVE_TAB', tab)
|
||||
SetSearchQuery({ commit }, query) {
|
||||
commit('SET_SEARCH_QUERY', query)
|
||||
},
|
||||
async SubmitChanges({ getters, commit, state }) {
|
||||
const configs = Object.keys(state.updatedSettings).reduce((acc, group) => {
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
}
|
||||
|
||||
.submenu-title-noDropdown {
|
||||
padding-left: 10px !important;
|
||||
padding-left: 8px !important;
|
||||
position: relative;
|
||||
|
||||
.el-tooltip {
|
||||
|
|
|
@ -19,7 +19,7 @@ $menuHover:#263445;
|
|||
$subMenuBg:#1f2d3d;
|
||||
$subMenuHover:#001528;
|
||||
|
||||
$sideBarWidth: 180px;
|
||||
$sideBarWidth: 205px;
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
:export {
|
||||
|
|
22
src/utils/tabs.js
Normal file
22
src/utils/tabs.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
export const tabs = [
|
||||
{ label: 'ActivityPub', path: 'activity-pub', tab: ':activity_pub' },
|
||||
{ label: 'Authentication', path: 'authentication', tab: ':authentication' },
|
||||
{ label: 'Captcha', path: 'captcha', tab: ':captcha' },
|
||||
{ label: 'BBS / SSH access', path: 'esshd', tab: ':esshd' },
|
||||
{ label: 'Emoji', path: 'emoji', tab: ':emoji' },
|
||||
{ label: 'Frontend', path: 'frontend', tab: ':frontend' },
|
||||
{ label: 'Gopher', path: 'gopher', tab: ':gopher' },
|
||||
{ label: 'HTTP', path: 'http', tab: ':http' },
|
||||
{ label: 'Instance', path: 'instance', tab: ':instance' },
|
||||
{ label: 'Job queue', path: 'job-queue', tab: ':job_queue' },
|
||||
{ label: 'Link Formatter', path: 'link-formatter', tab: ':link_formatter' },
|
||||
{ label: 'Logger', path: 'logger', tab: ':logger' },
|
||||
{ label: 'Mailer', path: 'mailer', tab: ':mailer' },
|
||||
{ label: 'Media Proxy', path: 'media-proxy', tab: ':media_proxy' },
|
||||
{ label: 'Metadata', path: 'metadata', tab: ':metadata' },
|
||||
{ label: 'MRF', path: 'mrf', tab: ':mrf' },
|
||||
{ label: 'Rate limiters', path: 'rate-limiters', tab: ':rate_limiters' },
|
||||
{ label: 'Web push encryption', path: 'web-push', tab: ':web_push' },
|
||||
{ label: 'Upload', path: 'upload', tab: ':upload' },
|
||||
{ label: 'Other', path: 'other', tab: ':other' }
|
||||
]
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<span>
|
||||
<svg-icon :icon-class="icon"/>
|
||||
<div>
|
||||
<i v-if="icon" :class="icon" class="menu-item-icon"/>
|
||||
<span slot="title">{{ title }}</span>
|
||||
<el-badge :value="count" type="primary" class="count-badge" />
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -31,4 +31,11 @@ export default {
|
|||
margin-left: 5px;
|
||||
height: 48px;
|
||||
}
|
||||
.menu-item-icon {
|
||||
margin-right: 5px;
|
||||
width: 18px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div v-if="!item.hidden && item.children && invitesEnabled" class="menu-wrapper">
|
||||
|
||||
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
||||
<div v-if="!item.hidden && invitesEnabled" class="menu-wrapper">
|
||||
<template
|
||||
v-if="item.children && hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
|
||||
<app-link :to="resolvePath(onlyOneChild.path)">
|
||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
||||
<item
|
||||
|
@ -12,7 +12,7 @@
|
|||
</el-menu-item>
|
||||
</app-link>
|
||||
</template>
|
||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)">
|
||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" :id="item.meta.title">
|
||||
<template slot="title">
|
||||
<item
|
||||
v-if="item.meta"
|
||||
|
@ -32,7 +32,7 @@
|
|||
class="nest-menu" />
|
||||
|
||||
<app-link v-else :to="resolvePath(child.path)" :key="child.name">
|
||||
<el-menu-item :index="resolvePath(child.path)">
|
||||
<el-menu-item :index="resolvePath(child.path)" class="submenu-item">
|
||||
<item
|
||||
v-if="child.meta"
|
||||
:count="showCount(item) ? normalizedReportsCount : null"
|
||||
|
@ -90,14 +90,14 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
hasOneShowingChild(children, parent) {
|
||||
const showingChildren = children.filter(item => {
|
||||
if (item.hidden) {
|
||||
if (parent.hasSubmenu) {
|
||||
return false
|
||||
} else {
|
||||
}
|
||||
|
||||
const showingChildren = children.filter(item => {
|
||||
// Temp set(will be used if only has one showing child)
|
||||
this.onlyOneChild = item
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
// When there is only one child router, the child router is displayed by default
|
||||
|
@ -129,3 +129,9 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.submenu-item {
|
||||
padding-left: 54px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
mode="vertical"
|
||||
@open="handleOpen"
|
||||
>
|
||||
<sidebar-item v-for="route in permission_routers" :key="route.path" :item="route" :base-path="route.path"/>
|
||||
</el-menu>
|
||||
|
@ -17,13 +18,17 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import SidebarItem from './SidebarItem'
|
||||
import variables from '@/styles/variables.scss'
|
||||
import router from '@/router'
|
||||
import { asyncRouterMap } from '@/router'
|
||||
|
||||
export default {
|
||||
components: { SidebarItem },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'permission_routers',
|
||||
'sidebar'
|
||||
'roles',
|
||||
'sidebar',
|
||||
'tabs'
|
||||
]),
|
||||
variables() {
|
||||
return variables
|
||||
|
@ -34,6 +39,49 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('FetchOpenReportsCount')
|
||||
},
|
||||
methods: {
|
||||
getMergedRoutes() {
|
||||
const routes = router.getRoutes().filter(item => !item.hidden)
|
||||
return routes.reduce((acc, element) => {
|
||||
if (!element.parent || element.parent.path !== '/settings') {
|
||||
return acc
|
||||
} else {
|
||||
const index = acc.findIndex(route => route.path === '/settings')
|
||||
acc[index] = { ...acc[index], children: [...acc[index].children, element] }
|
||||
return acc
|
||||
}
|
||||
}, [...asyncRouterMap])
|
||||
},
|
||||
async handleOpen($event) {
|
||||
if ($event === '/settings') {
|
||||
if (!localStorage.getItem('settingsTabs')) {
|
||||
await this.$store.dispatch('FetchSettings')
|
||||
const menuItems = this.tabs
|
||||
localStorage.setItem('settingsTabs', JSON.stringify(menuItems))
|
||||
|
||||
menuItems.forEach(({ label, path }) => {
|
||||
router.addRoute('Settings', {
|
||||
path,
|
||||
component: () => import(`@/views/settings`),
|
||||
name: label,
|
||||
meta: { title: label }
|
||||
})
|
||||
})
|
||||
const routes = this.getMergedRoutes()
|
||||
this.$store.dispatch('GenerateRoutes', { roles: this.roles, _routesWithSettings: routes })
|
||||
}
|
||||
let isRequesting = true
|
||||
const step = () => {
|
||||
document.querySelector('#settings').scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
if (isRequesting) requestAnimationFrame(step)
|
||||
}
|
||||
requestAnimationFrame(step)
|
||||
setTimeout(() => {
|
||||
isRequesting = false
|
||||
}, 300) // this equals to the hide-timeout of the el-submenu
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -197,9 +197,6 @@ h1 {
|
|||
.router-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
.search-container {
|
||||
text-align: right;
|
||||
}
|
||||
.pagination {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="relays-container">
|
||||
<div class="relays-header-container">
|
||||
<h1>
|
||||
{{ $t('relays.relays') }}
|
||||
</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="follow-relay-container">
|
||||
<el-input v-model="newRelay" :placeholder="$t('settings.followRelay')" class="follow-relay" @keyup.enter.native="followRelay"/>
|
||||
<el-button @click.native="followRelay">{{ $t('settings.follow') }}</el-button>
|
||||
<el-input v-model="newRelay" :placeholder="$t('relays.followRelay')" class="follow-relay" @keyup.enter.native="followRelay"/>
|
||||
<el-button @click.native="followRelay">{{ $t('relays.follow') }}</el-button>
|
||||
</div>
|
||||
<el-table :data="relays">
|
||||
<el-table-column
|
||||
:label="$t('settings.instanceUrl')"
|
||||
:label="$t('relays.instanceUrl')"
|
||||
prop="actor"/>
|
||||
<el-table-column
|
||||
:label="$t('settings.followedBack')"
|
||||
:label="$t('relays.followedBack')"
|
||||
:width="getLabelWidth"
|
||||
prop="followed_back"
|
||||
align="center">
|
||||
|
@ -32,8 +38,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'Relays',
|
||||
components: { RebootButton },
|
||||
data() {
|
||||
return {
|
||||
newRelay: ''
|
||||
|
@ -70,5 +79,5 @@ export default {
|
|||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@include settings
|
||||
@include relays
|
||||
</style>
|
|
@ -56,6 +56,9 @@ export default {
|
|||
loading() {
|
||||
return this.$store.state.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
user() {
|
||||
return this.settings.description.find(setting => setting.key === ':user')
|
||||
},
|
||||
|
@ -63,6 +66,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', ':user']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -80,6 +92,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -81,6 +81,18 @@ export default {
|
|||
},
|
||||
pleromaAuthenticatorData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Auth.Authenticator']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -100,6 +112,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -61,6 +61,18 @@ export default {
|
|||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -80,6 +92,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
<template>
|
||||
<div class="emoji-packs">
|
||||
<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 class="reload-emoji-button" @click="reloadEmoji">{{ $t('emoji.reloadEmoji') }}</el-button>
|
||||
|
@ -15,7 +11,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<el-tabs v-model="activeTab" type="card" class="emoji-packs-tabs">
|
||||
<el-tab-pane :label="$t('emoji.localPacks')" name="local">
|
||||
<el-tab-pane v-if="!emojiPacksDisabled" :label="$t('emoji.localPacks')" name="local">
|
||||
<el-form :label-width="labelWidth" class="emoji-packs-form">
|
||||
<el-form-item :label="$t('emoji.localPacks')">
|
||||
<el-button @click="refreshLocalPacks">{{ $t('emoji.refreshLocalPacks') }}</el-button>
|
||||
|
@ -49,7 +45,7 @@
|
|||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('emoji.remotePacks')" name="remote">
|
||||
<el-tab-pane v-if="!emojiPacksDisabled" :label="$t('emoji.remotePacks')" name="remote">
|
||||
<el-form :label-width="labelWidth" class="emoji-packs-form">
|
||||
<el-form-item :label="$t('emoji.remotePacks')">
|
||||
<div class="create-pack">
|
||||
|
@ -82,18 +78,31 @@
|
|||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('settings.settings')" name="settings">
|
||||
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
|
||||
<el-form :model="emojiData" :label-position="labelPosition" :label-width="settingsLabelWidth">
|
||||
<setting :setting-group="emoji" :data="emojiData"/>
|
||||
</el-form>
|
||||
<div class="submit-button-container">
|
||||
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LocalEmojiPack from './components/LocalEmojiPack'
|
||||
import RemoteEmojiPack from './components/RemoteEmojiPack'
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
import LocalEmojiPack from '../../emojiPacks/LocalEmojiPack'
|
||||
import RemoteEmojiPack from '../../emojiPacks/RemoteEmojiPack'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
components: { LocalEmojiPack, RebootButton, RemoteEmojiPack },
|
||||
name: 'Emoji',
|
||||
components: { LocalEmojiPack, RemoteEmojiPack, Setting },
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'local',
|
||||
|
@ -104,18 +113,37 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'settings'
|
||||
]),
|
||||
currentLocalPacksPage() {
|
||||
return this.$store.state.emojiPacks.currentLocalPacksPage
|
||||
},
|
||||
currentRemotePacksPage() {
|
||||
return this.$store.state.emojiPacks.currentRemotePacksPage
|
||||
},
|
||||
emoji() {
|
||||
return this.settings.description.find(setting => setting.key === ':emoji')
|
||||
},
|
||||
emojiData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':emoji']) || {}
|
||||
},
|
||||
emojiPacksDisabled() {
|
||||
const disabledFeatures = process.env.DISABLED_FEATURES || []
|
||||
return disabledFeatures.includes('emoji-packs')
|
||||
},
|
||||
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'
|
||||
},
|
||||
labelPosition() {
|
||||
return this.isMobile ? 'top' : 'right'
|
||||
},
|
||||
labelWidth() {
|
||||
if (this.isMobile) {
|
||||
return '105px'
|
||||
|
@ -125,6 +153,9 @@ export default {
|
|||
return '200px'
|
||||
}
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
localPacks() {
|
||||
return this.$store.state.emojiPacks.localPacks
|
||||
},
|
||||
|
@ -147,12 +178,35 @@ export default {
|
|||
},
|
||||
remotePacksCount() {
|
||||
return this.$store.state.emojiPacks.remotePacksCount
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
settingsLabelWidth() {
|
||||
if (this.isMobile) {
|
||||
return '120px'
|
||||
} else if (this.isTablet) {
|
||||
return '200px'
|
||||
} else {
|
||||
return '280px'
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.refreshLocalPacks()
|
||||
|
||||
if (this.searchQuery.length > 0) {
|
||||
this.activeTab = 'settings'
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
console.log(selectedSetting)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeLocalTabs() {
|
||||
|
@ -193,6 +247,17 @@ export default {
|
|||
this.$store.dispatch('ReloadEmoji')
|
||||
})
|
||||
},
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.success')
|
||||
})
|
||||
},
|
||||
refreshLocalPacks() {
|
||||
try {
|
||||
this.$store.dispatch('FetchLocalEmojiPacks', this.currentLocalPacksPage)
|
||||
|
@ -225,120 +290,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
.create-pack {
|
||||
display: flex;
|
||||
justify-content: space-between
|
||||
}
|
||||
.create-pack-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.emoji-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 15px 22px 15px;
|
||||
}
|
||||
.emoji-name-warning {
|
||||
color: #666666;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
margin: 5px 0 0 0;
|
||||
overflow-wrap: break-word;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.emoji-packs-header-button-container {
|
||||
display: flex;
|
||||
}
|
||||
.emoji-packs-form {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.emoji-packs-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.emoji-packs-tabs {
|
||||
margin: 0 15px 15px 15px;
|
||||
}
|
||||
.import-pack-button {
|
||||
margin-left: 10px;
|
||||
width: 30%;
|
||||
max-width: 700px;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
.pagination {
|
||||
margin: 25px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1824px) {
|
||||
.emoji-packs {
|
||||
max-width: 1824px;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.create-pack {
|
||||
height: 82px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.create-pack-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
.divider {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.el-message {
|
||||
min-width: 80%;
|
||||
}
|
||||
.el-message-box {
|
||||
width: 80%;
|
||||
}
|
||||
.emoji-header-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.emoji-packs-form {
|
||||
margin: 0 7px;
|
||||
label {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.emoji-packs-header {
|
||||
margin: 15px;
|
||||
}
|
||||
.emoji-packs-header-button-container {
|
||||
height: 82px;
|
||||
flex-direction: column;
|
||||
.el-button+.el-button {
|
||||
margin: 7px 0 0 0;
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
.import-pack-button {
|
||||
width: 90%;
|
||||
}
|
||||
.reload-emoji-button {
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
@import '../../styles/settings';
|
||||
@include settings;
|
||||
@include emoji;
|
||||
</style>
|
|
@ -51,6 +51,18 @@ export default {
|
|||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -76,6 +88,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
<setting :setting-group="assets" :data="assetsData"/>
|
||||
</el-form>
|
||||
<el-divider v-if="assets" class="divider thick-line"/>
|
||||
<el-form :model="emojiData" :label-position="labelPosition" :label-width="labelWidth">
|
||||
<setting :setting-group="emoji" :data="emojiData"/>
|
||||
</el-form>
|
||||
<el-divider v-if="emoji" class="divider thick-line"/>
|
||||
<el-form :model="chatData" :label-position="labelPosition" :label-width="labelWidth">
|
||||
<setting :setting-group="chat" :data="chatData"/>
|
||||
</el-form>
|
||||
|
@ -65,12 +61,6 @@ export default {
|
|||
chatData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':chat']) || {}
|
||||
},
|
||||
emoji() {
|
||||
return this.settings.description.find(setting => setting.key === ':emoji')
|
||||
},
|
||||
emojiData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':emoji']) || {}
|
||||
},
|
||||
frontend() {
|
||||
return this.settings.description.find(setting => setting.key === ':frontend_configurations')
|
||||
},
|
||||
|
@ -122,6 +112,9 @@ export default {
|
|||
preloadData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Preload']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
staticFe() {
|
||||
return this.settings.description.find(setting => setting.key === ':static_fe')
|
||||
},
|
||||
|
@ -129,6 +122,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', ':static_fe']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -146,6 +148,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -51,6 +51,18 @@ export default {
|
|||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -70,6 +82,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -76,6 +76,9 @@ export default {
|
|||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
webCacheTtl() {
|
||||
return this.settings.description.find(setting => setting.key === ':web_cache_ttl')
|
||||
},
|
||||
|
@ -83,6 +86,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', ':web_cache_ttl']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -100,6 +112,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -394,6 +394,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -146,6 +146,9 @@ export default {
|
|||
restrictUnauthenticatedData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':restrict_unauthenticated']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
scheduledActivity() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === 'Pleroma.ScheduledActivity')
|
||||
},
|
||||
|
@ -172,6 +175,14 @@ export default {
|
|||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
|
||||
await this.$store.dispatch('FetchInstanceDocument', 'instance-panel')
|
||||
},
|
||||
methods: {
|
||||
|
@ -198,6 +209,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -96,6 +96,9 @@ export default {
|
|||
poolsData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':pools']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
workers() {
|
||||
return this.settings.description.find(setting => setting.key === ':workers')
|
||||
},
|
||||
|
@ -103,6 +106,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', ':workers']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -120,6 +132,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -51,6 +51,18 @@ export default {
|
|||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -70,6 +82,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -76,6 +76,9 @@ export default {
|
|||
loggerData() {
|
||||
return _.get(this.settings.settings, [':logger', ':backends']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
quack() {
|
||||
return this.settings.description.find(setting => setting.group === ':quack')
|
||||
},
|
||||
|
@ -83,6 +86,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':quack']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -100,6 +112,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -51,6 +51,18 @@ export default {
|
|||
},
|
||||
mrfSettings() {
|
||||
return this.settings.description.filter(el => el.tab === 'mrf')
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -83,6 +95,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -82,6 +82,9 @@ export default {
|
|||
newUsersDigestEmailData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Emails.NewUsersDigestEmail']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
swoosh() {
|
||||
return this.settings.description.find(setting => setting.group === ':swoosh')
|
||||
},
|
||||
|
@ -95,6 +98,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Emails.UserEmail']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -112,6 +124,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -76,6 +76,9 @@ export default {
|
|||
mediaProxyData() {
|
||||
return _.get(this.settings.settings, [':pleroma', ':media_proxy']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
scriptInvalidation() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.MediaProxy.Invalidation.Script')
|
||||
},
|
||||
|
@ -83,6 +86,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.MediaProxy.Invalidation.Script']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -100,6 +112,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -56,6 +56,9 @@ export default {
|
|||
metadataData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Metadata']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
richMedia() {
|
||||
return this.settings.description.find(setting => setting.key === ':rich_media')
|
||||
},
|
||||
|
@ -63,6 +66,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', ':rich_media']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -80,6 +92,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -110,6 +110,9 @@ export default {
|
|||
remoteIpData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Plugs.RemoteIp']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
termsOfServicesContent: {
|
||||
get() {
|
||||
return this.$store.state.settings.termsOfServices
|
||||
|
@ -120,6 +123,14 @@ export default {
|
|||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
|
||||
await this.$store.dispatch('FetchInstanceDocument', 'terms-of-service')
|
||||
},
|
||||
methods: {
|
||||
|
@ -146,6 +157,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -51,6 +51,18 @@ export default {
|
|||
},
|
||||
loading() {
|
||||
return this.$store.state.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -70,6 +82,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -179,6 +179,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -72,6 +72,9 @@ export default {
|
|||
s3Data() {
|
||||
return _.get(this.settings.settings, [':ex_aws', ':s3']) || {}
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
showUploadersS3() {
|
||||
const uploader = _.get(this.settings.settings, [':pleroma', 'Pleroma.Upload', ':uploader'])
|
||||
return uploader === 'Pleroma.Uploaders.S3'
|
||||
|
@ -111,6 +114,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Upload.Filter.AnonymizeFilename']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -128,6 +140,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -46,6 +46,9 @@ export default {
|
|||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
searchQuery() {
|
||||
return this.$store.state.settings.searchQuery
|
||||
},
|
||||
vapidDetails() {
|
||||
return this.settings.description.find(setting => setting.key === ':vapid_details')
|
||||
},
|
||||
|
@ -53,6 +56,15 @@ export default {
|
|||
return _.get(this.settings.settings, [':web_push_encryption', ':vapid_details']) || {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.searchQuery.length > 0) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${this.searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
this.$store.dispatch('SetSearchQuery', '')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
|
@ -70,6 +82,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@import '../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export { default as ActivityPub } from './ActivityPub'
|
||||
export { default as Authentication } from './Authentication'
|
||||
export { default as Captcha } from './Captcha'
|
||||
export { default as Emoji } from './Emoji'
|
||||
export { default as Esshd } from './Esshd'
|
||||
export { default as Frontend } from './Frontend'
|
||||
export { default as Gopher } from './Gopher'
|
||||
|
@ -15,6 +16,5 @@ export { default as Metadata } from './Metadata'
|
|||
export { default as Mrf } from './MRF'
|
||||
export { default as Other } from './Other'
|
||||
export { default as RateLimiters } from './RateLimiters'
|
||||
export { default as Relays } from './Relays'
|
||||
export { default as Upload } from './Upload'
|
||||
export { default as WebPush } from './WebPush'
|
||||
|
|
|
@ -115,6 +115,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -192,6 +192,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -202,6 +202,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include tiptap
|
||||
</style>
|
||||
|
|
|
@ -103,6 +103,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -124,7 +124,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings;
|
||||
|
||||
.image-upload-area {
|
||||
|
|
|
@ -103,6 +103,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -99,6 +99,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -77,6 +77,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -148,6 +148,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -69,6 +69,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -110,6 +110,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -93,6 +93,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -62,6 +62,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@import '../../../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
|
@ -16,9 +16,13 @@ export const tabs = description => {
|
|||
label: 'settings.captcha',
|
||||
settings: ['Pleroma.Captcha', 'Pleroma.Captcha.Kocaptcha']
|
||||
},
|
||||
'emoji': {
|
||||
label: 'settings.emoji',
|
||||
settings: [':emoji']
|
||||
},
|
||||
'frontend': {
|
||||
label: 'settings.frontend',
|
||||
settings: [':assets', ':chat', ':frontends', ':emoji', ':frontend_configurations', ':markup', ':static_fe']
|
||||
settings: [':assets', ':chat', ':frontends', ':emoji', ':frontend_configurations', ':markup', ':static_fe', 'Pleroma.Web.Preload']
|
||||
},
|
||||
'gopher': {
|
||||
label: 'settings.gopher',
|
||||
|
@ -64,10 +68,6 @@ export const tabs = description => {
|
|||
label: 'settings.rateLimiters',
|
||||
settings: [':rate_limit']
|
||||
},
|
||||
'relays': {
|
||||
label: 'settings.relays',
|
||||
settings: ['relays']
|
||||
},
|
||||
'web-push': {
|
||||
label: 'settings.webPush',
|
||||
settings: [':vapid_details']
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<reboot-button/>
|
||||
</div>
|
||||
<div v-if="isDesktop">
|
||||
<div :class="isSidebarOpen" class="settings-header-container">
|
||||
<div :class="isSidebarOpen">
|
||||
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
|
||||
<div class="docs-search-container">
|
||||
<el-link
|
||||
|
@ -29,31 +29,11 @@
|
|||
@select="handleSearchSelect"/>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs v-model="activeTab" tab-position="left">
|
||||
<el-tab-pane
|
||||
v-for="(value, componentName) in tabs"
|
||||
:label="$t(value.label)"
|
||||
:disabled="configDisabled || settingsCantBeChanged(value.settings)"
|
||||
:key="componentName"
|
||||
:name="componentName"
|
||||
lazy>
|
||||
<component :is="componentName"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div v-if="isMobile || isTablet">
|
||||
<div :class="isSidebarOpen" class="settings-header-container">
|
||||
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
|
||||
</div>
|
||||
<div class="nav-container">
|
||||
<el-select v-model="activeTab" class="settings-menu" placeholder="Select">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="configDisabled"/>
|
||||
</el-select>
|
||||
<el-link
|
||||
:underline="false"
|
||||
href="https://docs-develop.pleroma.social/backend/administration/CLI_tasks/config/"
|
||||
|
@ -66,38 +46,29 @@
|
|||
</el-button>
|
||||
</el-link>
|
||||
</div>
|
||||
<div class="settings-search-input-container"/>
|
||||
<activity-pub v-if="activeTab === 'activityPub'"/>
|
||||
<authentication v-if="activeTab === 'auth'"/>
|
||||
<link-formatter v-if="activeTab === 'linkFormatter'"/>
|
||||
<esshd v-if="activeTab === 'esshd'"/>
|
||||
<captcha v-if="activeTab === 'captcha'"/>
|
||||
<frontend v-if="activeTab === 'frontend'"/>
|
||||
<gopher v-if="activeTab === 'gopher'"/>
|
||||
<http v-if="activeTab === 'http'"/>
|
||||
<instance v-if="activeTab === 'instance'"/>
|
||||
<job-queue v-if="activeTab === 'jobQueue'"/>
|
||||
<logger v-if="activeTab === 'logger'"/>
|
||||
<mailer v-if="activeTab === 'mailer'"/>
|
||||
<media-proxy v-if="activeTab === 'mediaProxy'"/>
|
||||
<metadata v-if="activeTab === 'metadata'"/>
|
||||
<mrf v-if="activeTab === 'mrf'"/>
|
||||
<rate-limiters v-if="activeTab === 'rateLimiters'"/>
|
||||
<relays v-if="activeTab === 'relays'"/>
|
||||
<web-push v-if="activeTab === 'webPush'"/>
|
||||
<upload v-if="activeTab === 'upload'"/>
|
||||
<other v-if="activeTab === 'other'"/>
|
||||
<div class="settings-search-container">
|
||||
<el-autocomplete
|
||||
v-model="searchQuery"
|
||||
:fetch-suggestions="querySearch"
|
||||
:trigger-on-focus="false"
|
||||
clearable
|
||||
placeholder="Search"
|
||||
prefix-icon="el-icon-search"
|
||||
class="settings-search-input"
|
||||
@select="handleSearchSelect"/>
|
||||
</div>
|
||||
<component :is="componentName"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/lang'
|
||||
import { tabs } from './components/tabs'
|
||||
import {
|
||||
ActivityPub,
|
||||
Authentication,
|
||||
Captcha,
|
||||
Emoji,
|
||||
Esshd,
|
||||
Frontend,
|
||||
Gopher,
|
||||
|
@ -112,7 +83,6 @@ import {
|
|||
Mrf,
|
||||
Other,
|
||||
RateLimiters,
|
||||
Relays,
|
||||
Upload,
|
||||
WebPush
|
||||
} from './components'
|
||||
|
@ -123,6 +93,7 @@ export default {
|
|||
ActivityPub,
|
||||
Authentication,
|
||||
Captcha,
|
||||
Emoji,
|
||||
Esshd,
|
||||
Frontend,
|
||||
Gopher,
|
||||
|
@ -137,46 +108,18 @@ export default {
|
|||
Mrf,
|
||||
Other,
|
||||
RateLimiters,
|
||||
Relays,
|
||||
RebootButton,
|
||||
Upload,
|
||||
WebPush
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: [
|
||||
{ value: 'activityPub', label: i18n.t('settings.activityPub') },
|
||||
{ value: 'auth', label: i18n.t('settings.auth') },
|
||||
{ value: 'linkFormatter', label: i18n.t('settings.linkFormatter') },
|
||||
{ value: 'esshd', label: i18n.t('settings.esshd') },
|
||||
{ value: 'captcha', label: i18n.t('settings.captcha') },
|
||||
{ value: 'frontend', label: i18n.t('settings.frontend') },
|
||||
{ value: 'gopher', label: i18n.t('settings.gopher') },
|
||||
{ value: 'http', label: i18n.t('settings.http') },
|
||||
{ value: 'instance', label: i18n.t('settings.instance') },
|
||||
{ value: 'jobQueue', label: i18n.t('settings.jobQueue') },
|
||||
{ value: 'logger', label: i18n.t('settings.logger') },
|
||||
{ value: 'mailer', label: i18n.t('settings.mailer') },
|
||||
{ value: 'mediaProxy', label: i18n.t('settings.mediaProxy') },
|
||||
{ value: 'metadata', label: i18n.t('settings.metadata') },
|
||||
{ value: 'mrf', label: i18n.t('settings.mrf') },
|
||||
{ value: 'rateLimiters', label: i18n.t('settings.rateLimiters') },
|
||||
{ value: 'relays', label: i18n.t('settings.relays') },
|
||||
{ value: 'webPush', label: i18n.t('settings.webPush') },
|
||||
{ value: 'upload', label: i18n.t('settings.upload') },
|
||||
{ value: 'other', label: i18n.t('settings.other') }
|
||||
],
|
||||
searchQuery: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
activeTab: {
|
||||
get() {
|
||||
return this.$store.state.settings.activeTab
|
||||
},
|
||||
set(tab) {
|
||||
this.$store.dispatch('SetActiveTab', tab)
|
||||
}
|
||||
componentName() {
|
||||
return this.$route.path.split('/settings/').pop()
|
||||
},
|
||||
configDisabled() {
|
||||
return this.$store.state.settings.configDisabled
|
||||
|
@ -209,12 +152,19 @@ export default {
|
|||
this.$store.dispatch('FetchSettings')
|
||||
},
|
||||
methods: {
|
||||
async handleSearchSelect(selectedValue) {
|
||||
handleSearchSelect(selectedValue) {
|
||||
this.$store.dispatch('SetSearchQuery', selectedValue.key)
|
||||
const tab = Object.keys(this.tabs).find(tab => {
|
||||
return this.tabs[tab].settings.includes(selectedValue.group === ':pleroma' ? selectedValue.key : selectedValue.group)
|
||||
})
|
||||
await this.$store.dispatch('SetActiveTab', tab)
|
||||
const selectedSetting = document.querySelector(`[data-search="${selectedValue.key}"]`)
|
||||
if (this.$router.currentRoute.path === `/settings/${tab}`) {
|
||||
this.scrollTo(selectedValue.key)
|
||||
} else if (tab) {
|
||||
this.$router.push({ path: `/settings/${tab}` })
|
||||
}
|
||||
},
|
||||
scrollTo(searchQuery) {
|
||||
const selectedSetting = document.querySelector(`[data-search="${searchQuery}"]`)
|
||||
if (selectedSetting) {
|
||||
selectedSetting.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
|
@ -232,8 +182,6 @@ export default {
|
|||
return this.$store.state.settings.description.findIndex(el => el.group === setting) !== -1
|
||||
} else if (setting === 'Pleroma.Web.Auth.Authenticator' || setting === ':admin_token') {
|
||||
return this.$store.state.settings.description.findIndex(el => el.children[0].key === setting) !== -1
|
||||
} else if (setting === 'relays') {
|
||||
return [setting]
|
||||
} else {
|
||||
return this.$store.state.settings.description.findIndex(el => el.key === setting) !== -1
|
||||
}
|
||||
|
@ -245,6 +193,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss' scoped>
|
||||
@import './styles/main';
|
||||
@import '../styles/settings';
|
||||
@include settings
|
||||
</style>
|
||||
|
|
31
src/views/styles/main.scss
Normal file
31
src/views/styles/main.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
@mixin relays {
|
||||
.follow-relay {
|
||||
width: 350px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
.relays-container {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.relays-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
@media only screen and (max-width:480px) {
|
||||
.follow-relay {
|
||||
width: 75%;
|
||||
margin-right: 5px;
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.follow-relay-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.relays-container {
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,8 @@
|
|||
height: 2px;
|
||||
}
|
||||
.docs-search-container {
|
||||
float: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.editable-keyword-container {
|
||||
|
@ -68,10 +69,6 @@
|
|||
padding: 2px 3px;
|
||||
}
|
||||
}
|
||||
.follow-relay {
|
||||
width: 350px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
.form-container {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
@ -271,9 +268,6 @@
|
|||
right: 0;
|
||||
z-index: 2000;
|
||||
}
|
||||
.relays-container {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.replacement-input {
|
||||
width: 80%;
|
||||
margin-left: 8px;
|
||||
|
@ -325,9 +319,6 @@
|
|||
.header-sidebar-closed {
|
||||
max-width: 1728px;
|
||||
}
|
||||
.settings-header-container {
|
||||
height: 87px;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 350px;
|
||||
margin-left: 5px;
|
||||
|
@ -457,18 +448,6 @@
|
|||
.divider .thick-line {
|
||||
height: 2px;
|
||||
}
|
||||
.follow-relay {
|
||||
width: 75%;
|
||||
margin-right: 5px;
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.follow-relay-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.frontend-container {
|
||||
margin: 0 15px 10px 15px;
|
||||
.description-container {
|
||||
|
@ -515,13 +494,6 @@
|
|||
.limit-input {
|
||||
width: 45%;
|
||||
}
|
||||
.nav-container {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 15px;
|
||||
}
|
||||
.proxy-url-input {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
@ -567,19 +539,9 @@
|
|||
display: inline-block;
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.docs-search-container {
|
||||
float: right;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
.settings-search-input-container {
|
||||
margin: 0 15px 15px 15px;
|
||||
}
|
||||
.settings-menu {
|
||||
width: 163px;
|
||||
margin-right: 5px;
|
||||
margin: 0 15px 25px 15px;
|
||||
width: stretch;
|
||||
}
|
||||
.socks5-checkbox-container {
|
||||
width: 100%;
|
||||
|
@ -660,16 +622,15 @@
|
|||
width: 40%;
|
||||
margin-right: 4px
|
||||
}
|
||||
.relays-container {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.replacement-input {
|
||||
width: 60%;
|
||||
margin-left: 4px;
|
||||
margin-right: 5px
|
||||
}
|
||||
.settings-header-container {
|
||||
height: 45px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.value-input {
|
||||
width: 60%;
|
||||
|
@ -677,6 +638,7 @@
|
|||
margin-right: 8px
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:818px) and (min-width: 481px) {
|
||||
.delete-setting-button {
|
||||
margin: 4px 0 0 10px;
|
||||
|
@ -708,13 +670,6 @@
|
|||
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-content {
|
||||
width: 65%;
|
||||
}
|
||||
|
@ -725,7 +680,14 @@
|
|||
float: right;
|
||||
}
|
||||
.settings-header-container {
|
||||
height: 36px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.settings-search-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.settings-search-input {
|
||||
width: 250px;
|
||||
|
@ -898,3 +860,122 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin emoji {
|
||||
.create-pack {
|
||||
display: flex;
|
||||
justify-content: space-between
|
||||
}
|
||||
.create-pack-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.emoji-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 15px 22px 15px;
|
||||
}
|
||||
.emoji-name-warning {
|
||||
color: #666666;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
margin: 5px 0 0 0;
|
||||
overflow-wrap: break-word;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.emoji-packs-header-button-container {
|
||||
display: flex;
|
||||
}
|
||||
.emoji-packs-form {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.emoji-packs-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 10px 15px 15px 15px;
|
||||
}
|
||||
.emoji-packs-tabs {
|
||||
margin: 0 15px 15px 15px;
|
||||
}
|
||||
.import-pack-button {
|
||||
margin-left: 10px;
|
||||
width: 30%;
|
||||
max-width: 700px;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
.pagination {
|
||||
margin: 25px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1824px) {
|
||||
.emoji-packs {
|
||||
max-width: 1824px;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.create-pack {
|
||||
height: 82px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.create-pack-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
.divider {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.el-message {
|
||||
min-width: 80%;
|
||||
}
|
||||
.el-message-box {
|
||||
width: 80%;
|
||||
}
|
||||
.emoji-header-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.emoji-packs-form {
|
||||
margin: 0 7px;
|
||||
label {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.emoji-packs-header {
|
||||
margin: 15px;
|
||||
}
|
||||
.emoji-packs-header-button-container {
|
||||
height: 82px;
|
||||
flex-direction: column;
|
||||
.el-button+.el-button {
|
||||
margin: 7px 0 0 0;
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
.import-pack-button {
|
||||
width: 90%;
|
||||
}
|
||||
.reload-emoji-button {
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -173,7 +173,8 @@ describe('Form search object', () => {
|
|||
label: "Admin token" }
|
||||
]
|
||||
}]
|
||||
const expected = [{
|
||||
const expected = [
|
||||
{
|
||||
label: "Admin token",
|
||||
key: ":admin_token",
|
||||
groupKey: ":pleroma",
|
||||
|
@ -193,7 +194,8 @@ describe('Form search object', () => {
|
|||
key: ':terms_of_services',
|
||||
label: 'Terms of Services',
|
||||
search: ['Terms of Services', ':terms_of_services']
|
||||
}]
|
||||
}
|
||||
]
|
||||
expect(_.isEqual(formSearchObject(description), expected)).toBeTruthy()
|
||||
})
|
||||
|
||||
|
@ -269,7 +271,8 @@ describe('Form search object', () => {
|
|||
key: ':instance_panel',
|
||||
label: 'Instance Panel',
|
||||
search: ['Instance Panel', ':instance_panel']
|
||||
}, {
|
||||
},
|
||||
{
|
||||
groupKey: ':terms_of_services',
|
||||
groupLabel: 'Terms of Services',
|
||||
key: ':terms_of_services',
|
||||
|
|
|
@ -7,6 +7,7 @@ import app from '@/store/modules/app'
|
|||
import settings from '@/store/modules/settings'
|
||||
import user from '@/store/modules/user'
|
||||
import getters from '@/store/getters'
|
||||
import _ from 'lodash'
|
||||
|
||||
config.mocks["$t"] = () => {}
|
||||
|
||||
|
@ -22,6 +23,8 @@ describe('Settings search', () => {
|
|||
let store
|
||||
let actions
|
||||
let appActions
|
||||
let $route
|
||||
let $router
|
||||
|
||||
beforeEach(() => {
|
||||
appActions = { ...app.actions, NeedReboot: jest.fn() }
|
||||
|
@ -34,11 +37,17 @@ describe('Settings search', () => {
|
|||
},
|
||||
getters
|
||||
})
|
||||
$route = { path: '/settings/path' }
|
||||
$router = { push: jest.fn(), currentRoute: {} }
|
||||
})
|
||||
|
||||
it('shows search input', async (done) => {
|
||||
const wrapper = mount(Settings, {
|
||||
store,
|
||||
mocks: {
|
||||
$route,
|
||||
$router
|
||||
},
|
||||
localVue
|
||||
})
|
||||
|
||||
|
@ -47,22 +56,31 @@ describe('Settings search', () => {
|
|||
expect(searchInput.exists()).toBe(true)
|
||||
done()
|
||||
})
|
||||
|
||||
it('changes tab when search value was selected', async (done) => {
|
||||
const wrapper = mount(Settings, {
|
||||
store,
|
||||
mocks: {
|
||||
$route,
|
||||
$router
|
||||
},
|
||||
localVue
|
||||
})
|
||||
wrapper.vm.handleSearchSelect({ group: 'Pleroma.Upload', key: 'Pleroma.Upload' })
|
||||
expect(store.state.settings.activeTab).toBe('upload')
|
||||
expect(store.state.settings.searchQuery).toBe('Pleroma.Upload')
|
||||
expect($router.push).toHaveBeenCalledWith({ path: '/settings/upload' })
|
||||
|
||||
wrapper.vm.handleSearchSelect({ group: ':swoosh', key: ':serve_mailbox' })
|
||||
expect(store.state.settings.activeTab).toBe('mailer')
|
||||
expect(store.state.settings.searchQuery).toBe(':serve_mailbox')
|
||||
expect($router.push).toHaveBeenCalledWith({ path: '/settings/mailer' })
|
||||
|
||||
wrapper.vm.handleSearchSelect({ group: ':pleroma', key: ':admin_token' })
|
||||
expect(store.state.settings.activeTab).toBe('instance')
|
||||
expect(store.state.settings.searchQuery).toBe(':admin_token')
|
||||
expect($router.push).toHaveBeenCalledWith({ path: '/settings/instance' })
|
||||
|
||||
wrapper.vm.handleSearchSelect({ group: ':media_proxy', key: ':ssl_options' })
|
||||
expect(store.state.settings.activeTab).toBe('media-proxy')
|
||||
expect(store.state.settings.searchQuery).toBe(':ssl_options')
|
||||
expect($router.push).toHaveBeenCalledWith({ path: '/settings/media-proxy' })
|
||||
|
||||
done()
|
||||
})
|
||||
|
|
|
@ -11258,10 +11258,10 @@ vue-loader@15.3.0:
|
|||
vue-hot-reload-api "^2.3.0"
|
||||
vue-style-loader "^4.1.0"
|
||||
|
||||
vue-router@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be"
|
||||
integrity sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg==
|
||||
vue-router@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.1.tgz#edf3cf4907952d1e0583e079237220c5ff6eb6c9"
|
||||
integrity sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==
|
||||
|
||||
vue-splitpane@1.0.2:
|
||||
version "1.0.2"
|
||||
|
|
Loading…
Reference in a new issue