Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pleroma/admin-fe
  • linafilippova/admin-fe
  • Exilat_a_Tolosa/admin-fe
  • mkljczk/admin-fe
  • maxf/admin-fe
  • kphrx/admin-fe
  • vaartis/admin-fe
  • ELR/admin-fe
  • eugenijm/admin-fe
  • jp/admin-fe
  • mkfain/admin-fe
  • lorenzoancora/admin-fe
  • alexgleason/admin-fe
  • seanking/admin-fe
  • ilja/admin-fe
15 results
Show changes
Showing
with 1308 additions and 417 deletions
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="pleromaAuthenticatorData" :model="pleromaAuthenticatorData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="pleromaAuthenticatorData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="pleromaAuthenticator" :data="pleromaAuthenticatorData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="authData" :model="authData" :label-width="labelWidth">
<el-divider v-if="pleromaAuthenticator" class="divider thick-line"/>
<el-form :model="authData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="auth" :data="authData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="ldapData" :model="ldapData" :label-width="labelWidth">
<el-divider v-if="auth" class="divider thick-line"/>
<el-form :model="ldapData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="ldap" :data="ldapData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="oauth2" :model="oauth2Data" :label-width="labelWidth">
<el-divider v-if="ldap" class="divider thick-line"/>
<el-form :model="oauth2Data" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="oauth2" :data="oauth2Data"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -43,9 +48,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -75,6 +86,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: {
......@@ -94,6 +117,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="captchaData" :model="captchaData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="captchaData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="captcha" :data="captchaData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="kocaptchaData" :model="kocaptchaData" :label-width="labelWidth">
<el-divider v-if="captcha" class="divider thick-line"/>
<el-form :model="kocaptchaData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="kocaptcha" :data="kocaptchaData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -35,6 +40,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'
},
......@@ -44,6 +52,9 @@ export default {
kocaptchaData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Captcha.Kocaptcha']) || {}
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -55,6 +66,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: {
......@@ -74,6 +97,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div class="emoji-packs">
<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>
<el-tooltip :content="$t('emoji.importEmojiTooltip')" effects="dark" placement="bottom" popper-class="import-pack-button">
<el-button @click="importFromFS">
{{ $t('emoji.importPacks') }}
</el-button>
</el-tooltip>
</div>
</div>
<el-tabs v-model="activeTab" type="card" class="emoji-packs-tabs">
<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>
</el-form-item>
<el-form-item :label="$t('emoji.createLocalPack')">
<div class="create-pack">
<el-input v-model="newPackName" :placeholder="$t('users.name')" />
<el-button
:disabled="newPackName.trim() === ''"
class="create-pack-button"
@click="createLocalPack">
{{ $t('users.create') }}
</el-button>
</div>
<span class="emoji-name-warning">{{ $t('emoji.emojiWarning') }}</span>
</el-form-item>
<el-form-item v-if="Object.keys(localPacks).length > 0" :label="$t('emoji.packs')">
<el-collapse v-for="(pack, name) in localPacks" :key="name" v-model="activeLocalPack" accordion @change="closeRemoteTabs">
<local-emoji-pack ref="localEmojiPack" :name="name" :pack="pack" :host="$store.getters.authHost" :is-local="true" />
</el-collapse>
</el-form-item>
</el-form>
<div class="pagination">
<el-pagination
:total="localPacksCount"
:current-page="currentLocalPacksPage"
:page-size="pageSize"
hide-on-single-page
layout="prev, pager, next"
@current-change="handleLocalPageChange"
/>
</div>
</el-tab-pane>
<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">
<el-input
v-model="remoteInstanceAddress"
:placeholder="$t('emoji.remoteInstanceAddress')" />
<el-button
v-loading.fullscreen.lock="fullscreenLoading"
:disabled="remoteInstanceAddress.trim() === ''"
class="create-pack-button"
@click="refreshRemotePacks">
{{ $t('emoji.refreshRemote') }}
</el-button>
</div>
</el-form-item>
<el-form-item v-if="Object.keys(remotePacks).length > 0" :label="$t('emoji.packs')">
<el-collapse v-for="(pack, name) in remotePacks" :key="name" v-model="activeRemotePack" accordion @change="closeLocalTabs">
<remote-emoji-pack ref="remoteEmojiPack" :active-tab="activeRemotePack" :name="name" :pack="pack" :host="$store.getters.authHost" :is-local="false" />
</el-collapse>
</el-form-item>
</el-form>
<div class="pagination">
<el-pagination
:total="remotePacksCount"
:current-page="currentRemotePacksPage"
:page-size="pageSize"
hide-on-single-page
layout="prev, pager, next"
@current-change="handleRemotePageChange"
/>
</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 { mapGetters } from 'vuex'
import i18n from '@/lang'
import LocalEmojiPack from '../../emojiPacks/LocalEmojiPack'
import RemoteEmojiPack from '../../emojiPacks/RemoteEmojiPack'
import Setting from './Setting'
import _ from 'lodash'
export default {
name: 'Emoji',
components: { LocalEmojiPack, RemoteEmojiPack, Setting },
data() {
return {
activeTab: 'local',
newPackName: '',
activeLocalPack: '',
activeRemotePack: '',
fullscreenLoading: false
}
},
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'
} else if (this.isTablet) {
return '180px'
} else {
return '200px'
}
},
loading() {
return this.settings.loading
},
localPacks() {
return this.$store.state.emojiPacks.localPacks
},
localPacksCount() {
return this.$store.state.emojiPacks.localPacksCount
},
pageSize() {
return this.$store.state.emojiPacks.pageSize
},
remoteInstanceAddress: {
get() {
return this.$store.state.emojiPacks.remoteInstance
},
set(instance) {
this.$store.dispatch('SetRemoteInstance', instance)
}
},
remotePacks() {
return this.$store.state.emojiPacks.remotePacks
},
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() {
this.collapseExistingEmojis()
this.activeLocalPack = ''
},
closeRemoteTabs() {
this.collapseExistingEmojis()
this.activeRemotePack = ''
},
collapseExistingEmojis() {
if (this.$refs.localEmojiPack && this.$refs.localEmojiPack.length > 0) {
this.$refs.localEmojiPack.forEach(el => el.collapse())
}
if (this.$refs.remoteEmojiPack && this.$refs.remoteEmojiPack.length > 0) {
this.$refs.remoteEmojiPack.forEach(el => el.collapse())
}
},
createLocalPack() {
this.$store.dispatch('CreatePack', { name: this.newPackName })
.then(() => {
this.newPackName = ''
this.$store.dispatch('FetchLocalEmojiPacks', this.currentLocalPacksPage)
this.$store.dispatch('ReloadEmoji')
})
},
handleLocalPageChange(page) {
this.$store.dispatch('FetchLocalEmojiPacks', page)
},
handleRemotePageChange(page) {
this.$store.dispatch('SetRemoteEmojiPacks', { page, remoteInstance: this.remoteInstanceAddress })
},
importFromFS() {
this.$store.dispatch('ImportFromFS')
.then(() => {
this.$store.dispatch('FetchLocalEmojiPacks', this.currentLocalPacksPage)
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)
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('emoji.refreshed')
})
},
async refreshRemotePacks() {
this.fullscreenLoading = true
await this.$store.dispatch('SetRemoteEmojiPacks', { page: 1, remoteInstance: this.remoteInstanceAddress })
this.fullscreenLoading = false
},
async reloadEmoji() {
try {
this.$store.dispatch('ReloadEmoji')
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('emoji.reloaded')
})
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../../styles/settings';
@include settings;
@include emoji;
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="esshdData" :model="esshdData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="esshdData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="esshd" :data="esshdData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -31,9 +36,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -45,6 +56,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 +93,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="frontendData" :model="frontendData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<frontends-table />
<el-divider v-if="frontend" class="divider thick-line"/>
<el-form :model="frontendData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="frontend" :data="frontendData"/>
</el-form>
<el-form ref="staticFeData" :model="staticFeData" :label-width="labelWidth">
<el-divider v-if="frontend" class="divider thick-line"/>
<el-form :model="staticFeData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="staticFe" :data="staticFeData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="assetsData" :model="assetsData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">{{ $t('settings.assets') }}</span>
</el-form-item>
<setting :setting-group="assets" :data="assetsData"/>
<el-divider v-if="staticFe" class="divider thick-line"/>
<el-form :model="frontendsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="frontends" :data="frontendsData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="emojiData" :model="emojiData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">{{ $t('settings.emoji') }}</span>
</el-form-item>
<setting :setting-group="emoji" :data="emojiData"/>
<el-divider v-if="frontends" class="divider thick-line"/>
<el-form :model="assetsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="assets" :data="assetsData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="chatData" :model="chatData" :label-width="labelWidth">
<el-divider v-if="assets" class="divider thick-line"/>
<el-form :model="chatData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="chat" :data="chatData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="markupData" :model="markupData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">{{ $t('settings.markup') }}</span>
</el-form-item>
<el-divider v-if="chat" class="divider thick-line"/>
<el-form :model="markupData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="markup" :data="markupData"/>
</el-form>
<el-divider v-if="preload" class="divider thick-line"/>
<el-form :model="preloadData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="preload" :data="preloadData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -41,11 +44,12 @@
import { mapGetters } from 'vuex'
import i18n from '@/lang'
import Setting from './Setting'
import FrontendsTable from './inputComponents/FrontendsTable'
import _ from 'lodash'
export default {
name: 'Frontend',
components: { Setting },
components: { FrontendsTable, Setting },
computed: {
...mapGetters([
'settings'
......@@ -62,24 +66,33 @@ 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')
},
frontendData() {
return _.get(this.settings.settings, [':pleroma', ':frontend_configurations']) || {}
},
frontends() {
return this.settings.description.find(setting => setting.key === ':frontends')
},
frontendsData() {
return _.get(this.settings.settings, [':pleroma', ':frontends']) || {}
},
isDesktop() {
return this.$store.state.app.device === 'desktop'
},
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 '120px'
......@@ -98,6 +111,15 @@ export default {
markupData() {
return _.get(this.settings.settings, [':pleroma', ':markup']) || {}
},
preload() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Preload')
},
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')
},
......@@ -105,6 +127,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 {
......@@ -122,6 +153,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form v-if="!loading" ref="gopher" :model="gopherData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form v-if="!loading" :model="gopherData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="gopher" :data="gopherData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -31,9 +36,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -45,6 +56,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: {
......@@ -64,6 +87,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="httpData" :model="httpData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="httpData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="http" :data="httpData"/>
</el-form>
<el-form ref="corsPlugData" :model="corsPlugData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">{{ $t('settings.corsPlug') }}</span>
</el-form-item>
<el-divider v-if="http" class="divider thick-line"/>
<el-form :model="corsPlugData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="corsPlug" :data="corsPlugData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="httpSignatures" :model="httpSignaturesData" :label-width="labelWidth">
<setting :setting-group="httpSignatures" :data="httpSignaturesData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="httpSecurityData" :model="httpSecurityData" :label-width="labelWidth">
<el-divider v-if="corsPlug" class="divider thick-line"/>
<el-form :model="httpSecurityData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="httpSecurity" :data="httpSecurityData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="webCacheTtl" :model="webCacheTtlData" :label-width="labelWidth">
<el-divider v-if="webCacheTtl" class="divider thick-line"/>
<el-form :model="webCacheTtlData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="webCacheTtl" :data="webCacheTtlData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -58,18 +57,18 @@ export default {
httpSecurityData() {
return _.get(this.settings.settings, [':pleroma', ':http_security']) || {}
},
httpSignatures() {
return this.settings.description.find(setting => setting.group === ':http_signatures')
},
httpSignaturesData() {
return _.get(this.settings.settings, [':http_signatures']) || {}
},
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 '120px'
......@@ -82,6 +81,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')
},
......@@ -89,6 +91,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 {
......@@ -106,6 +117,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div class="input-container">
<div v-if="setting.type === 'keyword'" class="keyword-container">
<el-form-item :label-width="customLabelWidth" :class="labelClass" :style="`margin-left:${margin}px;margin-bottom:0`" >
<el-form-item
:label-width="customLabelWidth"
:class="labelClass"
:style="`margin-left:${margin}px;margin-bottom:0`"
:data-search="setting.key || setting.group">
<span slot="label">
{{ setting.label }}
<el-tooltip v-if="canBeDeleted && isDesktop" :content="$t('settings.removeFromDB')" placement="bottom-end">
......@@ -21,23 +30,42 @@
:nested="true"/>
</el-form-item>
</div>
<el-form-item v-if="setting.type !== 'keyword'" :label-width="customLabelWidth" :class="labelClass">
<el-form-item v-if="setting.type !== 'keyword'" :label-width="customLabelWidth" :class="labelClass" :style="isDesktop ? '' : `margin-left:${margin}px`">
<span slot="label">
{{ setting.label }}
<el-tooltip v-if="canBeDeleted && isDesktop" :content="$t('settings.removeFromDB')" placement="bottom-end">
<el-tooltip v-if="canBeDeleted && (isDesktop || isMobile)" :content="$t('settings.removeFromDB')" placement="bottom-end">
<el-button icon="el-icon-delete" circle size="mini" class="delete-setting-button" @click="removeSetting"/>
</el-tooltip>
</span>
<div class="input-row">
<image-upload-input
v-if="isImageUrl"
:data="data"
:setting-group="settingGroup"
:setting="setting"
:input-value="inputValue"
@change="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"
/>
<el-input
v-if="setting.type === 'string' || (setting.type.includes('string') && setting.type.includes('atom'))"
v-if="textareaInput"
:value="inputValue"
:placeholder="setting.suggestions ? setting.suggestions[0] : null"
:data-search="setting.key || setting.group"
type="textarea"
class="input"
@input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
<el-input
v-else-if="setting.type === 'string' ||
(Array.isArray(setting.type) && setting.type.includes('string') && setting.type.includes('atom'))"
:value="inputValue"
:placeholder="setting.suggestions ? setting.suggestions[0] : null"
:data-search="setting.key || setting.group"
class="input"
@input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
<el-switch
v-if="setting.type === 'boolean'"
v-if="setting.type === 'boolean' && ![':registrations_open', ':invites_enabled'].includes(setting.key)"
:value="inputValue"
:data-search="setting.key || setting.group"
class="switch-input"
@change="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
<el-input-number
......@@ -46,10 +74,12 @@
:placeholder="setting.suggestions ? setting.suggestions[0].toString() : null"
:min="0"
:size="isDesktop ? 'large' : 'medium'"
:data-search="setting.key || setting.group"
@change="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
<el-select
v-if="setting.type === 'module' || (setting.type.includes('atom') && setting.type.includes('dropdown'))"
v-if="renderSingleSelect(setting.type)"
:value="inputValue === false ? 'false' : inputValue"
:data-search="setting.key || setting.group"
clearable
class="input"
@change="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)">
......@@ -60,7 +90,8 @@
</el-select>
<el-select
v-if="renderMultipleSelect(setting.type)"
:value="setting.key === ':rewrite_policy' ? rewritePolicyValue : inputValue"
:value="inputValue"
:data-search="setting.key || setting.group"
multiple
filterable
allow-create
......@@ -71,29 +102,33 @@
<el-input
v-if="setting.key === ':ip'"
:value="inputValue"
:data-search="setting.key || setting.group"
placeholder="xxx.xxx.xxx.xx"
class="input"
@input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
<el-input
v-if="setting.type === 'atom'"
:value="inputValue"
:placeholder="setting.suggestions[0] ? setting.suggestions[0].substr(1) : ''"
:placeholder="setting.suggestions && setting.suggestions[0] ? setting.suggestions[0].substr(1) : ''"
:data-search="setting.key || setting.group"
class="input"
@input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)">
<template slot="prepend">:</template>
</el-input>
<!-- special inputs -->
<auto-linker-input v-if="settingGroup.group === ':auto_linker'" :data="data" :setting-group="settingGroup" :setting="setting"/>
<crontab-input v-if="setting.key === ':crontab'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/>
<editable-keyword-input v-if="editableKeyword(setting.key, setting.type)" :data="keywordData" :setting-group="settingGroup" :setting="setting"/>
<editable-keyword-input v-if="editableKeyword(setting.key, setting.type)" :data="keywordData" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/>
<icons-input v-if="setting.key === ':icons'" :data="iconsData" :setting-group="settingGroup" :setting="setting"/>
<boolean-combined-input v-if="booleanCombinedInput" :data="data" :setting-group="settingGroup" :setting="setting"/>
<mascots-input v-if="setting.key === ':mascots'" :data="keywordData" :setting-group="settingGroup" :setting="setting"/>
<multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/>
<proxy-url-input v-if="setting.key === ':proxy_url'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/>
<prune-input v-if="setting.key === ':prune'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/>
<rate-limit-input v-if="settingGroup.key === ':rate_limit'" :data="data" :setting-group="settingGroup" :setting="setting"/>
<reg-invites-input v-if="[':registrations_open', ':invites_enabled'].includes(setting.key)" :data="data" :setting-group="settingGroup" :setting="setting"/>
<select-input-with-reduced-labels v-if="reducedSelects" :data="data" :setting-group="settingGroup" :setting="setting"/>
<specific-multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/>
<sender-input v-if="senderInput(setting)" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/>
<!-------------------->
<el-tooltip v-if="canBeDeleted && (isMobile || isTablet)" :content="$t('settings.removeFromDB')" placement="bottom-end" class="delete-setting-button-container">
<el-tooltip v-if="canBeDeleted && isTablet" :content="$t('settings.removeFromDB')" placement="bottom-end" class="delete-setting-button-container">
<el-button icon="el-icon-delete" circle size="mini" class="delete-setting-button" @click="removeSetting"/>
</el-tooltip>
</div>
......@@ -107,23 +142,38 @@
<script>
import i18n from '@/lang'
import { AutoLinkerInput, CrontabInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput } from './inputComponents'
import { processNested } from '@/store/modules/normalizers'
import {
EditableKeywordInput,
IconsInput,
ImageUploadInput,
BooleanCombinedInput,
MascotsInput,
ProxyUrlInput,
PruneInput,
RateLimitInput,
RegInvitesInput,
SelectInputWithReducedLabels,
SenderInput,
SpecificMultipleSelect } from './inputComponents'
import { getBooleanValue, processNested } from '@/store/modules/normalizers'
import _ from 'lodash'
import marked from 'marked'
export default {
name: 'Inputs',
components: {
AutoLinkerInput,
CrontabInput,
EditableKeywordInput,
IconsInput,
ImageUploadInput,
BooleanCombinedInput,
MascotsInput,
MultipleSelect,
ProxyUrlInput,
PruneInput,
RateLimitInput
RateLimitInput,
RegInvitesInput,
SelectInputWithReducedLabels,
SenderInput,
SpecificMultipleSelect
},
props: {
customLabelWidth: {
......@@ -180,21 +230,24 @@ export default {
}
},
computed: {
booleanCombinedInput() {
return Array.isArray(this.setting.type) && this.setting.type.includes('boolean')
},
canBeDeleted() {
const { group, key } = this.settingGroup
return _.get(this.$store.state.settings.db, [group, key]) &&
this.$store.state.settings.db[group][key].includes(this.setting.key)
},
iconsData() {
return Array.isArray(this.data[':icons']) ? this.data[':icons'] : []
return Array.isArray(this.data) ? this.data : []
},
inputValue() {
if ([':esshd', ':cors_plug', ':quack', ':http_signatures', ':tesla', ':swoosh'].includes(this.settingGroup.group) &&
if ([':esshd', ':cors_plug', ':tesla', ':swoosh'].includes(this.settingGroup.group) &&
this.data[this.setting.key]) {
return this.setting.type === 'atom' && this.data[this.setting.key].value[0] === ':'
? this.data[this.setting.key].value.substr(1)
: this.data[this.setting.key].value
} else if ((this.settingGroup.group === ':logger' && this.setting.key === ':backends') ||
} else if (
this.setting.key === 'Pleroma.Web.Auth.Authenticator' ||
this.setting.key === ':admin_token') {
return this.data.value
......@@ -202,6 +255,9 @@ export default {
return this.data.value ? this.data.value[this.setting.key] : []
} else if (this.setting.type === 'atom') {
return this.data[this.setting.key] && this.data[this.setting.key][0] === ':' ? this.data[this.setting.key].substr(1) : this.data[this.setting.key]
} else if (Array.isArray(this.setting.type) &&
this.setting.type.find(el => Array.isArray(el) && el.includes('list'))) {
return typeof this.data[this.setting.key] === 'string' ? [this.data[this.setting.key]] : this.data[this.setting.key]
} else {
return this.data[this.setting.key]
}
......@@ -225,24 +281,50 @@ export default {
}
},
keywordData() {
if (this.settingParent.length > 0 ||
(Array.isArray(this.setting.type) && this.setting.type.includes('tuple') && this.setting.type.includes('list'))) {
return Array.isArray(this.data[this.setting.key]) ? this.data[this.setting.key] : []
}
return Array.isArray(this.data) ? this.data : []
},
rewritePolicyValue() {
return typeof this.data[this.setting.key] === 'string' ? [this.data[this.setting.key]] : this.data[this.setting.key]
reducedSelects() {
return [
':filters',
':uploader',
':federation_publisher_modules',
':scrub_policy',
':ttl_setters',
':parsers',
':providers',
':method',
':policies',
'Pleroma.Web.Auth.Authenticator'
].includes(this.setting.key) ||
(this.settingGroup.key === 'Pleroma.Emails.Mailer' && this.setting.key === ':adapter')
},
settings() {
return this.$store.state.settings.settings
},
textareaInput() {
return this.settingGroup.key === ':welcome' && this.setting.key === ':message'
},
updatedSettings() {
return this.$store.state.settings.updatedSettings
},
isImageUrl() {
return Array.isArray(this.setting.type) && this.setting.type.includes('image')
}
},
methods: {
editableKeyword(key, type) {
return key === ':replace' ||
type === 'map' ||
(Array.isArray(type) && type.includes('keyword') && type.includes('integer')) ||
(Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1)
return Array.isArray(type) && (
(type.includes('map') && type.includes('string')) ||
(type.includes('map') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) ||
(type.includes('keyword') && type.includes('integer')) ||
(type.includes('keyword') && type.includes('string')) ||
(type.includes('tuple') && type.includes('list')) ||
(type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1)
)
},
getFormattedDescription(desc) {
return marked(desc)
......@@ -258,32 +340,55 @@ export default {
{ group, key: parentKey, input: setting.key, value: valueForState })
},
async removeSetting() {
const config = this.settingGroup.key
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [this.setting.key] }]
: [{ group: this.settingGroup.group, key: this.setting.key, delete: true }]
try {
await this.$store.dispatch('RemoveSetting', config)
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.successfullyRemoved')
this.$confirm(
this.$t('settings.removeSettingConfirmation'),
{
confirmButtonText: this.$t('users.ok'),
cancelButtonText: this.$t('users.cancel'),
type: 'warning'
}).then(async() => {
const config = this.settingGroup.key
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [this.setting.key] }]
: [{ group: this.settingGroup.group, key: this.setting.key, delete: true }]
try {
await this.$store.dispatch('RemoveSetting', config)
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.successfullyRemoved')
})
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('users.canceled')
})
})
},
renderMultipleSelect(type) {
return Array.isArray(type) && this.setting.key !== ':backends' && this.setting.key !== ':args' && (
return !this.reducedSelects && Array.isArray(type) && this.setting.key !== ':backends' && this.setting.key !== ':args' && (
this.setting.key === ':ip_whitelist' ||
type.includes('module') ||
(type.includes('list') && type.includes('string')) ||
(type.includes('list') && type.includes('atom')) ||
(type.includes('regex') && type.includes('string')) ||
this.setting.key === ':args'
(!type.includes('keyword') && type.includes('regex') && type.includes('string'))
)
},
renderSingleSelect(type) {
return !this.reducedSelects && (
type === 'module' ||
(Array.isArray(type) && type.includes('atom') && type.includes('dropdown'))
)
},
senderInput({ key, type }) {
return Array.isArray(type) && type.includes('string') && type.includes('tuple') && key === ':sender'
},
update(value, group, key, parents, input, type, nested) {
const updatedValue = this.renderSingleSelect(type) ? getBooleanValue(value) : value
nested
? this.processNestedData(value, group, key, parents)
: this.updateSetting(value, group, key, input, type)
? this.processNestedData(updatedValue, group, key, parents)
: this.updateSetting(updatedValue, group, key, input, type)
},
updateSetting(value, group, key, input, type) {
this.$store.dispatch('UpdateSettings', { group, key, input, value, type })
......@@ -294,6 +399,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="instanceData" :model="instanceData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="instanceData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="instance" :data="instanceData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="adminToken" :model="adminTokenData" :label-width="labelWidth">
<editor-input v-model="instancePanelContent" :name="'instance-panel'" @input="handleEditorUpdate"/>
<el-divider v-if="instance" class="divider thick-line"/>
<el-form :model="restrictUnauthenticatedData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="restrictUnauthenticated" :data="restrictUnauthenticatedData"/>
</el-form>
<el-divider v-if="restrictUnauthenticated" class="divider thick-line"/>
<el-form :model="adminTokenData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="adminToken" :data="adminTokenData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="scheduledActivity" :model="scheduledActivityData" :label-width="labelWidth">
<setting :setting-group="scheduledActivity" :data="scheduledActivityData"/>
<el-divider v-if="adminToken" class="divider thick-line"/>
<el-form :model="welcomeData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="welcome" :data="welcomeData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="fetchInitialPosts" :model="fetchInitialPostsData" :label-width="labelWidth">
<setting :setting-group="fetchInitialPosts" :data="fetchInitialPostsData"/>
<el-divider v-if="welcome" class="divider thick-line"/>
<el-form :model="scheduledActivityData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="scheduledActivity" :data="scheduledActivityData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="manifest" :model="manifestData" :label-width="labelWidth">
<el-divider v-if="scheduledActivity" class="divider thick-line"/>
<el-form :model="manifestData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="manifest" :data="manifestData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="pleromaUser" :model="pleromaUserData" :label-width="labelWidth">
<el-divider v-if="manifest" class="divider thick-line"/>
<el-form :model="pleromaUserData" :label-position="labelPosition" :label-width="labelWidth" data-search="Pleroma.User">
<setting :setting-group="pleromaUser" :data="pleromaUserData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="uriSchemes" :model="uriSchemesData" :label-width="labelWidth">
<el-divider v-if="pleromaUser" class="divider thick-line"/>
<el-form :model="faviconsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="favicons" :data="faviconsData"/>
</el-form>
<el-divider v-if="favicons" class="divider thick-line"/>
<el-form :model="uriSchemesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uriSchemes" :data="uriSchemesData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="feed" :model="feedData" :label-width="labelWidth">
<el-divider v-if="uriSchemes" class="divider thick-line"/>
<el-form :model="feedData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="feed" :data="feedData"/>
</el-form>
<el-form ref="streamer" :model="streamerData" :label-width="labelWidth">
<el-divider v-if="feed" class="divider thick-line"/>
<el-form :model="streamerData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="streamer" :data="streamerData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -44,13 +59,20 @@
import { mapGetters } from 'vuex'
import i18n from '@/lang'
import Setting from './Setting'
import { EditorInput } from './inputComponents'
import _ from 'lodash'
export default {
name: 'Instance',
components: {
EditorInput,
Setting
},
data() {
return {
editorContent: ''
}
},
computed: {
...mapGetters([
'settings'
......@@ -61,18 +83,26 @@ export default {
adminTokenData() {
return _.get(this.settings.settings, [':pleroma', ':admin_token']) || {}
},
instancePanelContent: {
get() {
return this.$store.state.settings.instancePanel
},
set(content) {
this.editorContent = content
}
},
favicons() {
return this.settings.description.find(setting => setting.key === ':instances_favicons')
},
faviconsData() {
return _.get(this.settings.settings, [':pleroma', ':instances_favicons']) || {}
},
feed() {
return this.settings.description.find(setting => setting.key === ':feed')
},
feedData() {
return _.get(this.settings.settings, [':pleroma', ':feed']) || {}
},
fetchInitialPosts() {
return this.settings.description.find(setting => setting.key === ':fetch_initial_posts')
},
fetchInitialPostsData() {
return _.get(this.settings.settings, [':pleroma', ':fetch_initial_posts']) || {}
},
instance() {
return this.settings.description.find(setting => setting.key === ':instance')
},
......@@ -82,9 +112,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -109,6 +145,15 @@ export default {
pleromaUserData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.User']) || {}
},
restrictUnauthenticated() {
return this.settings.description.find(setting => setting.key === ':restrict_unauthenticated')
},
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')
},
......@@ -126,12 +171,36 @@ export default {
},
uriSchemesData() {
return _.get(this.settings.settings, [':pleroma', ':uri_schemes']) || {}
},
welcome() {
return this.settings.description.find(setting => setting.key === ':welcome')
},
welcomeData() {
return _.get(this.settings.settings, [':pleroma', ':welcome']) || {}
}
},
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: {
handleEditorUpdate(content) {
this.editorContent = content
},
async onSubmit() {
try {
await this.$store.dispatch('SubmitChanges')
await this.$store.dispatch('UpdateInstanceDocs', {
name: 'instance-panel',
content: this.editorContent.length > 0 ? this.editorContent : this.instancePanelContent
})
} catch (e) {
return
}
......@@ -145,6 +214,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="obanQueuesData" :model="obanQueuesData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="obanQueuesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="obanQueues" :data="obanQueuesData"/>
</el-form>
<el-form ref="workersData" :model="workersData" :label-width="labelWidth">
<el-divider v-if="obanQueues" class="divider thick-line"/>
<el-form :model="workersData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="workers" :data="workersData"/>
</el-form>
<el-form ref="activityExpiration" :model="activityExpirationData" :label-width="labelWidth">
<el-divider v-if="workers" class="divider thick-line"/>
<el-form :model="activityExpirationData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="activityExpiration" :data="activityExpirationData"/>
</el-form>
<el-divider v-if="activityExpiration" class="divider thick-line"/>
<el-form :model="connectionsPoolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="connectionsPools" :data="connectionsPoolsData"/>
</el-form>
<el-divider v-if="connectionsPools" class="divider thick-line"/>
<el-form :model="poolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="pools" :data="poolsData"/>
</el-form>
<el-divider v-if="pools" class="divider thick-line"/>
<el-form :model="hackneyPoolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="hackneyPools" :data="hackneyPoolsData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -29,17 +48,35 @@ export default {
'settings'
]),
activityExpiration() {
return this.settings.description.find(setting => setting.key === 'Pleroma.ActivityExpiration')
return this.settings.description.find(setting => setting.key === 'Pleroma.Workers.PurgeExpiredActivity')
},
activityExpirationData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.ActivityExpiration']) || {}
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Workers.PurgeExpiredActivity']) || {}
},
connectionsPools() {
return this.settings.description.find(setting => setting.key === ':connections_pool')
},
connectionsPoolsData() {
return _.get(this.settings.settings, [':pleroma', ':connections_pool']) || {}
},
hackneyPools() {
return this.settings.description.find(setting => setting.key === ':hackney_pools')
},
hackneyPoolsData() {
return _.get(this.settings.settings, [':pleroma', ':hackney_pools']) || {}
},
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 '120px'
......@@ -58,6 +95,15 @@ export default {
obanQueuesData() {
return _.get(this.settings.settings, [':pleroma', 'Oban']) || {}
},
pools() {
return this.settings.description.find(setting => setting.key === ':pools')
},
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')
},
......@@ -65,6 +111,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 {
......@@ -82,6 +137,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="autoLinker" :model="autoLinkerData" :label-width="labelWidth">
<setting :setting-group="autoLinker" :data="autoLinkerData"/>
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="linkFormatterData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="linkFormatter" :data="linkFormatterData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -16,24 +21,30 @@ import Setting from './Setting'
import _ from 'lodash'
export default {
name: 'AutoLinker',
name: 'LinkFormatter',
components: { Setting },
computed: {
...mapGetters([
'settings'
]),
autoLinker() {
return this.settings.description.find(setting => setting.key === ':opts')
linkFormatter() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Formatter')
},
autoLinkerData() {
return _.get(this.settings.settings, [':auto_linker', ':opts']) || {}
linkFormatterData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Formatter']) || {}
},
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 '120px'
......@@ -45,6 +56,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: {
......@@ -64,6 +87,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<template>
<div v-if="!loading" class="form-container">
<el-form ref="loggerData" :model="loggerData" :label-width="labelWidth">
<setting :setting-group="logger" :data="loggerData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="consoleData" :model="consoleData" :label-width="labelWidth">
<setting :setting-group="console" :data="consoleData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="exsysloggerData" :model="exsysloggerData" :label-width="labelWidth">
<setting :setting-group="exsyslogger" :data="exsysloggerData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="quackData" :model="quackData" :label-width="labelWidth">
<setting :setting-group="quack" :data="quackData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import i18n from '@/lang'
import Setting from './Setting'
import _ from 'lodash'
export default {
name: 'Logger',
components: { Setting },
computed: {
...mapGetters([
'settings'
]),
console() {
return this.settings.description.find(setting => setting.key === ':console')
},
consoleData() {
return _.get(this.settings.settings, [':logger', ':console']) || {}
},
exsyslogger() {
return this.settings.description.find(setting => setting.key === ':ex_syslogger')
},
exsysloggerData() {
return _.get(this.settings.settings, [':logger', ':ex_syslogger']) || {}
},
isMobile() {
return this.$store.state.app.device === 'mobile'
},
isTablet() {
return this.$store.state.app.device === 'tablet'
},
labelWidth() {
if (this.isMobile) {
return '120px'
} else if (this.isTablet) {
return '200px'
} else {
return '280px'
}
},
loading() {
return this.settings.loading
},
logger() {
return this.settings.description.find(setting => setting.group === ':logger')
},
loggerData() {
return _.get(this.settings.settings, [':logger', ':backends']) || {}
},
quack() {
return this.settings.description.find(setting => setting.group === ':quack')
},
quackData() {
return _.get(this.settings.settings, [':quack']) || {}
}
},
methods: {
async onSubmit() {
try {
await this.$store.dispatch('SubmitChanges')
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.success')
})
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="mrfSimple" :model="mrfSimpleData" :label-width="labelWidth">
<setting :setting-group="mrfSimple" :data="mrfSimpleData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfRejectnonpublic" :model="mrfRejectnonpublicData" :label-width="labelWidth">
<setting :setting-group="mrfRejectnonpublic" :data="mrfRejectnonpublicData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfHellthread" :model="mrfHellthreadData" :label-width="labelWidth">
<setting :setting-group="mrfHellthread" :data="mrfHellthreadData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfKeyword" :model="mrfKeywordData" :label-width="labelWidth">
<setting :setting-group="mrfKeyword" :data="mrfKeywordData"/>
</el-form>
<el-form ref="mrfSubchain" :model="mrfSubchainData" :label-width="labelWidth">
<setting :setting-group="mrfSubchain" :data="mrfSubchainData"/>
</el-form>
<el-form ref="mrfMention" :model="mrfMentionData" :label-width="labelWidth">
<setting :setting-group="mrfMention" :data="mrfMentionData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfNormalizeMarkup" :model="mrfNormalizeMarkupData" :label-width="labelWidth">
<setting :setting-group="mrfNormalizeMarkup" :data="mrfNormalizeMarkupData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfVocabulary" :model="mrfVocabularyData" :label-width="labelWidth">
<setting :setting-group="mrfVocabulary" :data="mrfVocabularyData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="mrfObjectAge" :model="mrfObjectAgeData" :label-width="labelWidth">
<setting :setting-group="mrfObjectAge" :data="mrfObjectAgeData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="modules" :model="modulesData" :label-width="labelWidth">
<setting :setting-group="modules" :data="modulesData"/>
</el-form>
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<div v-for="setting in mrfSettings" :key="setting.key">
<el-form v-if="showMrfPolicy(setting.key)" :model="getSettingData(setting)" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="setting" :data="getSettingData(setting)"/>
<el-divider v-if="setting" class="divider thick-line"/>
</el-form>
</div>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -59,9 +33,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -74,68 +54,26 @@ export default {
loading() {
return this.settings.loading
},
modules() {
return this.settings.description.find(setting => setting.key === ':modules')
},
modulesData() {
return _.get(this.settings.settings, [':pleroma', ':modules']) || {}
},
mrfSimple() {
return this.settings.description.find(setting => setting.key === ':mrf_simple')
},
mrfSimpleData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_simple']) || {}
},
mrfRejectnonpublic() {
return this.settings.description.find(setting => setting.key === ':mrf_rejectnonpublic')
},
mrfRejectnonpublicData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_rejectnonpublic']) || {}
},
mrfHellthread() {
return this.settings.description.find(setting => setting.key === ':mrf_hellthread')
},
mrfHellthreadData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_hellthread']) || {}
},
mrfKeyword() {
return this.settings.description.find(setting => setting.key === ':mrf_keyword')
},
mrfKeywordData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_keyword']) || {}
},
mrfObjectAge() {
return this.settings.description.find(setting => setting.key === ':mrf_object_age')
mrfSettings() {
return this.settings.description.filter(el => el.tab === 'mrf')
},
mrfObjectAgeData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_object_age']) || {}
},
mrfSubchain() {
return this.settings.description.find(setting => setting.key === ':mrf_subchain')
},
mrfSubchainData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_subchain']) || {}
},
mrfMention() {
return this.settings.description.find(setting => setting.key === ':mrf_mention')
},
mrfMentionData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_mention']) || {}
},
mrfNormalizeMarkup() {
return this.settings.description.find(setting => setting.key === ':mrf_normalize_markup')
},
mrfNormalizeMarkupData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_normalize_markup']) || {}
},
mrfVocabulary() {
return this.settings.description.find(setting => setting.key === ':mrf_vocabulary')
},
mrfVocabularyData() {
return _.get(this.settings.settings, [':pleroma', ':mrf_vocabulary']) || {}
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: {
getSettingData(setting) {
return _.get(this.settings.settings, [setting.group, setting.key]) || {}
},
async onSubmit() {
try {
await this.$store.dispatch('SubmitChanges')
......@@ -146,12 +84,22 @@ export default {
type: 'success',
message: i18n.t('settings.success')
})
},
showMrfPolicy(key) {
const selectedMrfPolicies = _.get(this.settings.settings, [':pleroma', ':mrf', ':policies']) || []
const mappedPolicies = this.mrfSettings.reduce((acc, { key, related_policy }) => {
if (key !== ':mrf') {
acc[key] = related_policy
}
return acc
}, {})
return !Object.keys(mappedPolicies).includes(key) || selectedMrfPolicies.includes(mappedPolicies[key])
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="mailer" :model="mailerData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="mailerData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="mailer" :data="mailerData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="swoosh" :model="swooshData" :label-width="labelWidth">
<el-divider v-if="mailer" class="divider thick-line"/>
<el-form :model="swooshData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="swoosh" :data="swooshData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="emailNotifications" :model="emailNotificationsData" :label-width="labelWidth">
<el-divider v-if="swoosh" class="divider thick-line"/>
<el-form :model="emailNotificationsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="emailNotifications" :data="emailNotificationsData"/>
</el-form>
<el-form ref="userEmail" :model="userEmail" :label-width="labelWidth">
<el-divider v-if="emailNotifications" class="divider thick-line"/>
<el-form :model="userEmailData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="userEmail" :data="userEmailData"/>
</el-form>
<el-divider v-if="userEmail" class="divider thick-line"/>
<el-form :model="newUsersDigestEmailData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="newUsersDigestEmail" :data="newUsersDigestEmailData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -44,9 +54,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -65,6 +81,15 @@ export default {
mailerData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Emails.Mailer']) || {}
},
newUsersDigestEmail() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Emails.NewUsersDigestEmail')
},
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')
},
......@@ -78,6 +103,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 {
......@@ -95,6 +129,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form v-if="!loading" ref="mediaProxy" :model="mediaProxyData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form v-if="!loading" :model="mediaProxyData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="mediaProxy" :data="mediaProxyData"/>
</el-form>
<el-divider v-if="mediaProxy" class="divider thick-line"/>
<el-form v-if="!loading" :model="mediaPreviewProxyData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="mediaPreviewProxy" :data="mediaPreviewProxyData"/>
</el-form>
<el-divider v-if="mediaPreviewProxy" class="divider thick-line"/>
<el-form v-if="!loading" :model="httpInvalidationData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="httpInvalidation" :data="httpInvalidationData"/>
</el-form>
<el-divider v-if="httpInvalidation" class="divider thick-line"/>
<el-form v-if="!loading" :model="scriptInvalidationData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="scriptInvalidation" :data="scriptInvalidationData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -22,12 +39,24 @@ export default {
...mapGetters([
'settings'
]),
httpInvalidation() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.MediaProxy.Invalidation.Http')
},
httpInvalidationData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.MediaProxy.Invalidation.Http']) || {}
},
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 '120px'
......@@ -40,11 +69,35 @@ export default {
loading() {
return this.settings.loading
},
mediaPreviewProxy() {
return this.settings.description.find(setting => setting.key === ':media_preview_proxy')
},
mediaPreviewProxyData() {
return _.get(this.settings.settings, [':pleroma', ':media_preview_proxy']) || {}
},
mediaProxy() {
return this.settings.description.find(setting => setting.key === ':media_proxy')
},
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')
},
scriptInvalidationData() {
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: {
......@@ -64,6 +117,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="metadata" :model="metadataData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="metadataData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="metadata" :data="metadataData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="richMedia" :model="richMediaData" :label-width="labelWidth">
<el-divider v-if="metadata" class="divider thick-line"/>
<el-form :model="richMediaData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="richMedia" :data="richMediaData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -29,9 +34,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -50,6 +61,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')
},
......@@ -57,6 +71,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 {
......@@ -74,6 +97,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="mimeTypes" :model="mimeTypesData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<editor-input v-model="termsOfServicesContent" :name="'terms-of-service'" @input="handleEditorUpdate"/>
<el-divider class="divider thick-line"/>
<el-form :model="prometheusMetricsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="prometheusMetrics" :data="prometheusMetricsData"/>
</el-form>
<el-divider v-if="prometheusMetrics" class="divider thick-line"/>
<el-form :model="backupData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="backup" :data="backupData"/>
</el-form>
<el-divider v-if="backup" class="divider thick-line"/>
<el-form :model="mimeTypesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="mimeTypes" :data="mimeTypesData"/>
</el-form>
<el-form ref="remoteIp" :model="remoteIpData" :label-width="labelWidth">
<el-divider v-if="mimeTypes" class="divider thick-line"/>
<el-form :model="remoteIpData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="remoteIp" :data="remoteIpData"/>
</el-form>
<el-divider v-if="remoteIpData" class="divider thick-line"/>
<el-form :model="modulesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="modules" :data="modulesData"/>
</el-form>
<el-divider v-if="castAndValidate" class="divider thick-line"/>
<el-form :model="castAndValidateData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="castAndValidate" :data="castAndValidateData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -16,21 +40,45 @@
import { mapGetters } from 'vuex'
import i18n from '@/lang'
import Setting from './Setting'
import { EditorInput } from './inputComponents'
import _ from 'lodash'
export default {
name: 'Other',
components: { Setting },
components: { EditorInput, Setting },
data() {
return {
termsOfServices: ''
}
},
computed: {
...mapGetters([
'settings'
]),
backup() {
return this.settings.description.find(setting => setting.key === 'Pleroma.User.Backup')
},
backupData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.User.Backup']) || {}
},
castAndValidate() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.ApiSpec.CastAndValidate')
},
castAndValidateData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.ApiSpec.CastAndValidate']) || {}
},
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 '120px'
......@@ -49,17 +97,58 @@ export default {
mimeTypesData() {
return _.get(this.settings.settings, [':mime']) || {}
},
modules() {
return this.settings.description.find(setting => setting.key === ':modules')
},
modulesData() {
return _.get(this.settings.settings, [':pleroma', ':modules']) || {}
},
prometheusMetrics() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Endpoint.MetricsExporter')
},
prometheusMetricsData() {
return _.get(this.settings.settings, [':prometheus', 'Pleroma.Web.Endpoint.MetricsExporter']) || {}
},
remoteIp() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Plugs.RemoteIp')
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Plugs.RemoteIp')
},
remoteIpData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Plugs.RemoteIp']) || {}
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
},
set(content) {
this.termsOfServices = content
}
}
},
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: {
handleEditorUpdate(content) {
this.termsOfServices = content
},
async onSubmit() {
try {
await this.$store.dispatch('SubmitChanges')
await this.$store.dispatch('UpdateInstanceDocs', {
name: 'terms-of-service',
content: this.termsOfServices.length > 0 ? this.termsOfServices : this.termsOfServicesContent
})
} catch (e) {
return
}
......@@ -73,6 +162,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form v-if="!loading" ref="rateLimiters" :model="rateLimitersData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form v-if="!loading" :model="rateLimitersData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="rateLimiters" :data="rateLimitersData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -31,9 +36,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -45,6 +56,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: {
......@@ -64,6 +87,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading">
<el-form-item v-if="settingGroup.description" class="description-container">
<span class="description" v-html="getFormattedDescription(settingGroup.description)"/>
<el-form-item v-if="settingGroup.label || settingGroup.description" :data-search="settingGroup.key || settingGroup.group" class="description-container">
<span v-if="settingGroup.label" class="setting-label">{{ settingGroup.label }}</span>
<span v-if="settingGroup.description" class="expl no-top-margin" v-html="getFormattedDescription(settingGroup.description)"/>
</el-form-item>
<div v-if="settingGroup.key === 'Pleroma.Emails.Mailer'">
<div v-for="setting in settingGroup.children.filter(setting => !setting.group)" :key="setting.key">
<inputs
v-if="followsRules(setting.key, settingGroup.key, state)"
:setting-group="settingGroup"
:setting="setting"
:data="data"/>
......@@ -14,6 +21,7 @@
v-for="setting in emailAdapterChildren"
:key="setting.key">
<inputs
v-if="followsRules(setting.key, settingGroup.key, state)"
:setting-group="settingGroup"
:setting="setting"
:data="data"/>
......@@ -23,6 +31,7 @@
<div v-for="setting in settingGroup.children" :key="setting.key">
<div v-if="!compound(setting)">
<inputs
v-if="followsRules(setting.key, settingGroup.key, state)"
:setting-group="settingGroup"
:setting="setting"
:data="data"
......@@ -32,6 +41,7 @@
<el-divider v-if="divideSetting(setting.key)" class="divider"/>
<div v-if="!setting.children">
<inputs
v-if="followsRules(setting.key, settingGroup.key, state)"
:setting-group="settingGroup"
:setting="setting"
:data="data[setting.key]"
......@@ -39,7 +49,7 @@
</div>
<div v-else>
<div class="input-container">
<el-form-item class="grouped-settings-header">
<el-form-item :data-search="setting.key || setting.group" class="grouped-settings-header">
<span slot="label">
<el-tooltip v-if="isDesktop && canBeDeleted(setting.key)" :content="$t('settings.removeFromDB')" placement="bottom-end">
<el-button icon="el-icon-delete" circle size="mini" style="margin-left:5px" @click="removeSetting(setting.key)"/>
......@@ -60,7 +70,7 @@
:nested="true"/>
</div>
</div>
<el-divider class="divider"/>
<el-divider v-if="notLastInGroup(setting.key)" class="divider"/>
</div>
</div>
</div>
......@@ -72,6 +82,7 @@ import Inputs from './Inputs'
import i18n from '@/lang'
import _ from 'lodash'
import marked from 'marked'
import { settingFollowsRules } from '../rules'
export default {
name: 'Setting',
......@@ -108,6 +119,9 @@ export default {
},
loading() {
return this.$store.state.settings.loading
},
state() {
return this.$store.state.settings.settings
}
},
methods: {
......@@ -121,26 +135,45 @@ export default {
return type === 'keyword' ||
type === 'map' ||
type.includes('keyword') ||
key === ':replace'
type.includes('map')
},
divideSetting(key) {
return [':sslopts', ':tlsopts', ':adapter', ':poll_limits', ':queues', ':styling', ':proxy_opts'].includes(key)
return [':sslopts', ':tlsopts', ':adapter', ':poll_limits', ':queues', ':styling', ':invalidation', ':multi_factor_authentication'].includes(key)
},
followsRules(setting, settingGroup, state) {
return settingFollowsRules(setting, settingGroup, state)
},
getFormattedDescription(desc) {
return marked(desc)
},
notLastInGroup(key) {
return this.settingGroup.children.slice(-1)[0].key !== key
},
async removeSetting(key) {
const config = this.settingGroup.key
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [key] }]
: [{ group: this.settingGroup.group, key, delete: true }]
try {
await this.$store.dispatch('RemoveSetting', config)
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.successfullyRemoved')
this.$confirm(
this.$t('settings.removeSettingConfirmation'),
{
confirmButtonText: this.$t('users.ok'),
cancelButtonText: this.$t('users.cancel'),
type: 'warning'
}).then(async() => {
const config = this.settingGroup.key
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [key] }]
: [{ group: this.settingGroup.group, key, delete: true }]
try {
await this.$store.dispatch('RemoveSetting', config)
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.successfullyRemoved')
})
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('users.canceled')
})
})
},
updateSetting(value, tab, input) {
......@@ -151,6 +184,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="!loading" class="form-container">
<el-form ref="uploadData" :model="uploadData" :label-width="labelWidth">
<div v-if="!loading" :class="isSidebarOpen" class="form-container">
<el-form :model="uploadData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="upload" :data="uploadData"/>
</el-form>
<el-form v-if="showUploadersLocal" ref="uploadersLocal" :model="uploadersLocalData" :label-width="labelWidth">
<el-form-item class="grouped-settings-header">
<span class="label-font">Pleroma.Uploaders.Local</span>
</el-form-item>
<el-divider v-if="upload" class="divider thick-line"/>
<el-form v-if="showUploadersLocal" :model="uploadersLocalData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uploadersLocal" :data="uploadersLocalData"/>
<el-divider class="divider thick-line"/>
<el-divider v-if="uploadersLocal" class="divider thick-line"/>
</el-form>
<el-form v-if="showUploadersS3" :model="s3Data" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="s3" :data="s3Data"/>
<el-divider v-if="s3" class="divider thick-line"/>
</el-form>
<el-form v-if="showUploadersS3" ref="uploadersS3" :model="uploadersS3Data" :label-width="labelWidth">
<el-form v-if="showUploadersS3" :model="uploadersS3Data" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uploadersS3" :data="uploadersS3Data"/>
<el-divider class="divider thick-line"/>
<el-divider v-if="uploadersS3" class="divider thick-line"/>
</el-form>
<el-form ref="uploadFilterMogrify" :model="uploadFilterMogrifyData" :label-width="labelWidth">
<el-form :model="uploadFilterMogrifyData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uploadFilterMogrify" :data="uploadFilterMogrifyData"/>
</el-form>
<el-divider class="divider thick-line"/>
<el-form ref="uploadAnonymizeFilename" :model="uploadAnonymizeFilenameData" :label-width="labelWidth">
<el-divider v-if="uploadFilterMogrify" class="divider thick-line"/>
<el-form :model="uploadAnonymizeFilenameData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uploadAnonymizeFilename" :data="uploadAnonymizeFilenameData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
<el-button class="submit-button" type="primary" @click="onSubmit">{{ $t('settings.submit') }}</el-button>
</div>
</div>
</template>
......@@ -43,9 +50,15 @@ 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'
},
labelPosition() {
return this.isMobile ? 'top' : 'right'
},
labelWidth() {
if (this.isMobile) {
return '120px'
......@@ -58,6 +71,15 @@ export default {
loading() {
return this.settings.loading
},
s3() {
return this.settings.description.find(setting => setting.key === ':s3')
},
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'
......@@ -97,6 +119,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 {
......@@ -114,6 +145,6 @@ export default {
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../styles/main';
@import '../../styles/settings';
@include settings
</style>