Page MenuHomePhorge

No OneTemporary

Size
18 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/settings_modal/admin_tabs/instance_tab.vue b/src/components/settings_modal/admin_tabs/instance_tab.vue
index ad27129343..ff784287cd 100644
--- a/src/components/settings_modal/admin_tabs/instance_tab.vue
+++ b/src/components/settings_modal/admin_tabs/instance_tab.vue
@@ -1,119 +1,170 @@
<template>
<div :label="$t('admin_dash.instance')">
<div class="setting-item">
<h2>{{ $t('admin_dash.instance') }}</h2>
<ul class="setting-list">
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:name"
draft-mode
>
NAME
</StringSetting>
</li>
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:email"
draft-mode
>
ADMIN EMAIL
</StringSetting>
</li>
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:description"
draft-mode
>
DESCRIPTION
</StringSetting>
</li>
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:short_description"
draft-mode
>
SHORT DESCRIPTION
</StringSetting>
</li>
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:instance_thumbnail"
draft-mode
>
INSTANCE THUMBNAIL
</StringSetting>
</li>
<li>
<StringSetting
source="admin"
path=":pleroma.:instance.:background_image"
draft-mode
>
BACKGROUND IMAGE
</StringSetting>
</li>
<li>
<BooleanSetting
source="admin"
path=":pleroma.:instance.:public"
draft-mode
>
PUBLIC
</BooleanSetting>
</li>
</ul>
</div>
<div class="setting-item">
<h2>{{ $t('admin_dash.registrations') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting
source="admin"
path=":pleroma.:instance.:registrations_open"
draft-mode
>
REGISTRATIONS OPEN
</BooleanSetting>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
source="admin"
path=":pleroma.:instance.:invites_enabled"
parent-path=":pleroma.:instance.:registrations_open"
:parent-invert="true"
draft-mode
>
INVITES ENABLED
</BooleanSetting>
</li>
</ul>
</li>
<li>
<BooleanSetting
source="admin"
path=":pleroma.:instance.:account_activation_required"
draft-mode
>
ACTIVATION REQUIRED
</BooleanSetting>
</li>
<li>
<BooleanSetting
source="admin"
path=":pleroma.:instance.:account_approval_required"
draft-mode
>
APPROVAL REQUIRED
</BooleanSetting>
</li>
+ <li>
+ <h3>{{ $t('admin_dash.captcha.header') }}</h3>
+ </li>
+ <li>
+ <BooleanSetting
+ source="admin"
+ :path="[':pleroma', 'Pleroma.Captcha', ':enabled']"
+ draft-mode
+ >
+ CAPTCHA
+ </BooleanSetting>
+ <ul class="setting-list suboptions">
+ <li>
+ <ChoiceSetting
+ source="admin"
+ :path="[':pleroma', 'Pleroma.Captcha', ':method']"
+ :parent-path="[':pleroma', 'Pleroma.Captcha', ':enabled']"
+ :option-label-map="{
+ 'Pleroma.Captcha.Native': $t('admin_dash.captcha.native'),
+ 'Pleroma.Captcha.Kocaptcha': $t('admin_dash.captcha.kocaptcha')
+ }"
+ draft-mode
+ >
+ CAPTCHA TYPE
+ </ChoiceSetting>
+ <IntegerSetting
+ source="admin"
+ :path="[':pleroma', 'Pleroma.Captcha', ':seconds_valid']"
+ :parent-path="[':pleroma', 'Pleroma.Captcha', ':enabled']"
+ draft-mode
+ >
+ VALID
+ </IntegerSetting>
+ </li>
+ </ul>
+ <ul
+ v-if="adminConfig[':pleroma']['Pleroma.Captcha'][':enabled'] && adminConfig[':pleroma']['Pleroma.Captcha'][':method'] === 'Pleroma.Captcha.Kocaptcha'"
+ class="setting-list suboptions"
+ >
+ <h4>{{ $t('admin_dash.kocaptcha') }}</h4>
+ <li>
+ <StringSetting
+ source="admin"
+ :path="[':pleroma', 'Pleroma.Captcha.Kocaptcha', ':endpoint']"
+ draft-mode
+ >
+ cockAPTCHA ENDPOINT
+ </StringSetting>
+ </li>
+ </ul>
+ </li>
</ul>
</div>
</div>
</template>
<script src="./instance_tab.js"></script>
diff --git a/src/components/settings_modal/helpers/choice_setting.js b/src/components/settings_modal/helpers/choice_setting.js
index a3c3bf4432..3ff81bc904 100644
--- a/src/components/settings_modal/helpers/choice_setting.js
+++ b/src/components/settings_modal/helpers/choice_setting.js
@@ -1,17 +1,42 @@
import Select from 'src/components/select/select.vue'
import Setting from './setting.js'
export default {
...Setting,
components: {
...Setting.components,
Select
},
props: {
...Setting.props,
options: {
type: Array,
- required: true
+ required: false
+ },
+ optionLabelMap: {
+ type: Object,
+ required: false,
+ default: {}
+ }
+ },
+ computed: {
+ ...Setting.computed,
+ realOptions () {
+ if (this.source === 'admin') {
+ console.log(this.backendDescriptionSuggestions)
+ return this.backendDescriptionSuggestions.map(x => ({
+ key: x,
+ value: x,
+ label: this.optionLabelMap[x] || x
+ }))
+ }
+ return this.options
+ }
+ },
+ methods: {
+ ...Setting.methods,
+ getValue (e) {
+ return e
}
}
}
diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue
index 4c4cdefec8..55f9a62ca9 100644
--- a/src/components/settings_modal/helpers/choice_setting.vue
+++ b/src/components/settings_modal/helpers/choice_setting.vue
@@ -1,30 +1,42 @@
<template>
<label
v-if="matchesExpertLevel"
class="ChoiceSetting"
>
- <slot />
+ <template v-if="backendDescription">
+ {{ backendDescriptionLabel }}
+ </template>
+ <template v-else>
+ <slot />
+ </template>
{{ ' ' }}
<Select
- :model-value="state"
+ :model-value="draftMode ? draft :state"
:disabled="disabled"
@update:modelValue="update"
>
<option
- v-for="option in options"
+ v-for="option in realOptions"
:key="option.key"
:value="option.value"
>
{{ option.label }}
{{ option.value === defaultState ? $t('settings.instance_default_simple') : '' }}
</option>
</Select>
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
+ <DraftButtons />
+ <p
+ v-if="backendDescriptionDescription"
+ class="setting-description"
+ >
+ {{ backendDescriptionDescription + ' ' }}
+ </p>
</label>
</template>
<script src="./choice_setting.js"></script>
diff --git a/src/components/settings_modal/helpers/number_setting.vue b/src/components/settings_modal/helpers/number_setting.vue
index 813357622a..93a7a79ae8 100644
--- a/src/components/settings_modal/helpers/number_setting.vue
+++ b/src/components/settings_modal/helpers/number_setting.vue
@@ -1,27 +1,40 @@
<template>
<span
v-if="matchesExpertLevel"
class="NumberSetting"
>
<label :for="path">
- <slot />
+ <template v-if="backendDescription">
+ {{ backendDescriptionLabel + ' ' }}
+ </template>
+ <template v-else>
+ <slot />
+ </template>
</label>
<input
:id="path"
class="number-input"
type="number"
:step="step || 1"
:disabled="disabled"
:min="min || 0"
:value="draftMode ? draft :state"
@change="update"
>
{{ ' ' }}
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
+ <ProfileSettingIndicator :is-profile="isProfileSetting" />
+ <DraftButtons />
+ <p
+ v-if="backendDescriptionDescription"
+ class="setting-description"
+ >
+ {{ backendDescriptionDescription + ' ' }}
+ </p>
</span>
</template>
<script src="./number_setting.js"></script>
diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js
index 8c7074a57f..a6d35fb980 100644
--- a/src/components/settings_modal/helpers/setting.js
+++ b/src/components/settings_modal/helpers/setting.js
@@ -1,161 +1,164 @@
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ModifiedIndicator from './modified_indicator.vue'
import ProfileSettingIndicator from './profile_setting_indicator.vue'
import DraftButtons from './draft_buttons.vue'
import { get, set } from 'lodash'
export default {
components: {
Checkbox,
ModifiedIndicator,
DraftButtons,
ProfileSettingIndicator
},
props: {
path: {
- type: String,
+ type: [String, Array],
required: true
},
disabled: {
type: Boolean,
default: false
},
parentPath: {
- type: String
+ type: [String, Array]
},
parentInvert: {
type: Boolean,
default: false
},
expert: {
type: [Number, String],
default: 0
},
source: {
type: String,
default: 'default'
},
draftMode: {
type: Boolean,
default: false
}
},
data () {
return {
draft: null
}
},
created () {
if (this.draftMode) {
this.draft = this.state
}
},
computed: {
state () {
const value = get(this.configSource, this.path)
if (value === undefined) {
return this.defaultState
} else {
return value
}
},
backendDescription () {
return get(this.$store.state.adminSettings.descriptions, this.path)
},
backendDescriptionLabel () {
return this.backendDescription?.label
},
backendDescriptionDescription () {
return this.backendDescription?.description
},
+ backendDescriptionSuggestions () {
+ return this.backendDescription?.suggestions
+ },
shouldBeDisabled () {
const parentValue = this.parentPath !== undefined ? get(this.configSource, this.parentPath) : null
return this.disabled || (parentValue !== null ? (this.parentInvert ? parentValue : !parentValue) : false)
},
configSource () {
switch (this.source) {
case 'profile':
return this.$store.state.profileConfig
case 'admin':
return this.$store.state.adminSettings.config
default:
return this.$store.getters.mergedConfig
}
},
configSink () {
switch (this.source) {
case 'profile':
return (k, v) => this.$store.dispatch('setProfileOption', { name: k, value: v })
case 'admin':
return (k, v) => this.$store.dispatch('pushAdminSetting', { path: k, value: v })
default:
return (k, v) => this.$store.dispatch('setOption', { name: k, value: v })
}
},
defaultState () {
switch (this.source) {
case 'profile':
return {}
default:
return get(this.$store.getters.defaultConfig, this.path)
}
},
isProfileSetting () {
return this.source === 'profile'
},
isChanged () {
switch (this.source) {
case 'profile':
case 'admin':
return false
default:
return this.state !== this.defaultState
}
},
isDirty () {
return this.draftMode && this.draft !== this.state
},
canHardReset () {
return this.source === 'admin' && this.$store.state.adminSettings.modifiedPaths.has(this.path)
},
matchesExpertLevel () {
return (this.expert || 0) <= this.$store.state.config.expertLevel > 0
}
},
methods: {
getValue (e) {
return e.target.value
},
update (e) {
if (this.draftMode) {
this.draft = this.getValue(e)
} else {
this.configSink(this.path, this.getValue(e))
}
},
commitDraft () {
if (this.draftMode) {
this.configSink(this.path, this.draft)
}
},
reset () {
console.log('reset')
if (this.draftMode) {
console.log(this.draft)
console.log(this.state)
this.draft = this.state
} else {
set(this.$store.getters.mergedConfig, this.path, this.defaultState)
}
},
hardReset () {
switch (this.source) {
case 'admin':
return this.$store.dispatch('resetAdminSetting', { path: this.path })
.then(() => { this.draft = this.state })
default:
console.warn('Hard reset not implemented yet!')
}
}
}
}
diff --git a/src/components/settings_modal/helpers/shared_computed_object.js b/src/components/settings_modal/helpers/shared_computed_object.js
index 912999ce7a..d02db542af 100644
--- a/src/components/settings_modal/helpers/shared_computed_object.js
+++ b/src/components/settings_modal/helpers/shared_computed_object.js
@@ -1,13 +1,16 @@
const SharedComputedObject = () => ({
user () {
return this.$store.state.users.currentUser
},
expertLevel () {
return this.$store.getters.mergedConfig.expertLevel > 0
},
mergedConfig () {
return this.$store.getters.mergedConfig
+ },
+ adminConfig () {
+ return this.$store.state.adminSettings.config
}
})
export default SharedComputedObject
diff --git a/src/modules/adminSettings.js b/src/modules/adminSettings.js
index 44a4d409e9..a84fadbf9e 100644
--- a/src/modules/adminSettings.js
+++ b/src/modules/adminSettings.js
@@ -1,115 +1,116 @@
import { set, cloneDeep } from 'lodash'
export const defaultState = {
needsReboot: null,
config: null,
modifiedPaths: null,
descriptions: null
}
export const newUserFlags = {
...defaultState.flagStorage
}
const adminSettingsStorage = {
state: {
...cloneDeep(defaultState)
},
mutations: {
updateAdminSettings (state, { config, modifiedPaths }) {
state.config = config
state.modifiedPaths = modifiedPaths
},
updateAdminDescriptions (state, { descriptions }) {
state.descriptions = descriptions
}
},
actions: {
setInstanceAdminSettings ({ state, commit, dispatch }, { backendDbConfig }) {
const config = state.config || {}
const modifiedPaths = state.modifiedPaths || new Set()
backendDbConfig.configs.forEach(c => {
- const path = c.group + '.' + c.key
+ const path = [c.group, c.key]
if (c.db) {
c.db.forEach(x => modifiedPaths.add(path + '.' + x))
}
const convert = (value) => {
if (Array.isArray(value) && value.length > 0 && value[0].tuple) {
return value.reduce((acc, c) => {
return { ...acc, [c.tuple[0]]: convert(c.tuple[1]) }
}, {})
} else {
return value
}
}
set(config, path, convert(c.value))
})
- console.log(config[':pleroma'][':welcome'])
+ console.log(config[':pleroma'])
commit('updateAdminSettings', { config, modifiedPaths })
},
setInstanceAdminDescriptions ({ state, commit, dispatch }, { backendDescriptions }) {
const convert = ({ children, description, label, key = '<ROOT>', group, suggestions }, path, acc) => {
- const newPath = group ? group + '.' + key : key
+ const newPath = group ? [group, key] : [key]
const obj = { description, label, suggestions }
if (Array.isArray(children)) {
children.forEach(c => {
- convert(c, '.' + newPath, obj)
+ convert(c, newPath, obj)
})
}
set(acc, newPath, obj)
}
const descriptions = {}
backendDescriptions.forEach(d => convert(d, '', descriptions))
+ console.log(descriptions[':pleroma']['Pleroma.Captcha'])
commit('updateAdminDescriptions', { descriptions })
},
pushAdminSetting ({ rootState, state, commit, dispatch }, { path, value }) {
- const [group, key, ...rest] = path.split(/\./g)
+ const [group, key, ...rest] = Array.isArray(path) ? path : path.split(/\./g)
const clone = {} // not actually cloning the entire thing to avoid excessive writes
- set(clone, rest.join('.'), value)
+ set(clone, rest, value)
// TODO cleanup paths in modifiedPaths
const convert = (value) => {
if (typeof value !== 'object') {
return value
} else if (Array.isArray(value)) {
return value.map(convert)
} else {
return Object.entries(value).map(([k, v]) => ({ tuple: [k, v] }))
}
}
rootState.api.backendInteractor.pushInstanceDBConfig({
payload: {
configs: [{
group,
key,
value: convert(clone)
}]
}
})
.then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
.then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
},
resetAdminSetting ({ rootState, state, commit, dispatch }, { path }) {
const [group, key, subkey] = path.split(/\./g)
state.modifiedPaths.delete(path)
return rootState.api.backendInteractor.pushInstanceDBConfig({
payload: {
configs: [{
group,
key,
delete: true,
subkeys: [subkey]
}]
}
})
.then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
.then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
}
}
}
export default adminSettingsStorage

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 19, 8:24 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1769200
Default Alt Text
(18 KB)

Event Timeline