diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js
index e033d9997b..ff58f2c38e 100644
--- a/src/components/settings_modal/settings_modal.js
+++ b/src/components/settings_modal/settings_modal.js
@@ -5,7 +5,7 @@ import getResettableAsyncComponent from 'src/services/resettable_async_component
import Popover from '../popover/popover.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
-import { cloneDeep } from 'lodash'
+import { cloneDeep, isEqual } from 'lodash'
import {
newImporter,
newExporter
@@ -155,6 +155,12 @@ const SettingsModal = {
PLEROMAFE_SETTINGS_MINOR_VERSION
]
return clone
+ },
+ resetAdminDraft () {
+ this.$store.commit('resetAdminDraft')
+ },
+ pushAdminDraft () {
+ this.$store.dispatch('pushAdminDraft')
}
},
computed: {
@@ -183,6 +189,12 @@ const SettingsModal = {
set (value) {
this.$store.dispatch('setOption', { name: 'expertLevel', value: value ? 1 : 0 })
}
+ },
+ adminDraftAny () {
+ return !isEqual(
+ this.$store.state.adminSettings.config,
+ this.$store.state.adminSettings.draft
+ )
}
}
}
diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss
index 4cce60993f..4cb506f930 100644
--- a/src/components/settings_modal/settings_modal.scss
+++ b/src/components/settings_modal/settings_modal.scss
@@ -51,6 +51,8 @@
.settings-footer {
display: flex;
+ flex-wrap: wrap;
+ line-height: 2;
>* {
margin-right: 0.5em;
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index 303050e433..57ec5535b7 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -45,7 +45,7 @@
-
diff --git a/src/modules/adminSettings.js b/src/modules/adminSettings.js
index 27d5b37d34..25fb8e5019 100644
--- a/src/modules/adminSettings.js
+++ b/src/modules/adminSettings.js
@@ -1,4 +1,4 @@
-import { set, get, cloneDeep } from 'lodash'
+import { set, get, cloneDeep, differenceWith, isEqual, flatten } from 'lodash'
export const defaultState = {
needsReboot: null,
@@ -42,7 +42,7 @@ const adminSettingsStorage = {
actions: {
setInstanceAdminSettings ({ state, commit, dispatch }, { backendDbConfig }) {
const config = state.config || {}
- const modifiedPaths = state.modifiedPaths || new Set()
+ const modifiedPaths = new Set()
backendDbConfig.configs.forEach(c => {
const path = [c.group, c.key]
if (c.db) {
@@ -82,6 +82,59 @@ const adminSettingsStorage = {
console.log(descriptions[':pleroma']['Pleroma.Captcha'])
commit('updateAdminDescriptions', { descriptions })
},
+
+ // This action takes draft state, diffs it with live config state and then pushes
+ // only differences between the two. Difference detection only work up to subkey (third) level.
+ pushAdminDraft ({ rootState, state, commit, dispatch }) {
+ // 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] }))
+ }
+ }
+
+ // Getting all group-keys used in config
+ const allGroupKeys = flatten(
+ Object
+ .entries(state.config)
+ .map(
+ ([group, lv1data]) => Object
+ .keys(lv1data)
+ .map((key) => ({ group, key }))
+ )
+ )
+
+ // Only using group-keys where there are changes detected
+ const changedGroupKeys = allGroupKeys.filter(({ group, key }) => {
+ return !isEqual(state.config[group][key], state.draft[group][key])
+ })
+
+ // Here we take all changed group-keys and get all changed subkeys
+ const changed = changedGroupKeys.map(({ group, key }) => {
+ const config = state.config[group][key]
+ const draft = state.draft[group][key]
+
+ // We convert group-key value into entries arrays
+ const eConfig = Object.entries(config)
+ const eDraft = Object.entries(draft)
+
+ // Then those entries array we diff so only changed subkey entries remain
+ // We use the diffed array to reconstruct the object and then shove it into convert()
+ return ({ group, key, value: convert(Object.fromEntries(differenceWith(eDraft, eConfig, isEqual))) })
+ })
+
+ rootState.api.backendInteractor.pushInstanceDBConfig({
+ payload: {
+ configs: changed
+ }
+ })
+ .then(() => rootState.api.backendInteractor.fetchInstanceDBConfig())
+ .then(backendDbConfig => dispatch('setInstanceAdminSettings', { backendDbConfig }))
+ },
pushAdminSetting ({ rootState, state, commit, dispatch }, { path, value }) {
const [group, key, ...rest] = Array.isArray(path) ? path : path.split(/\./g)
const clone = {} // not actually cloning the entire thing to avoid excessive writes