added mass-draft-push and mass-draft-reset, small stylistic fixes

This commit is contained in:
Henry Jameson 2023-03-22 18:57:23 +02:00
parent 9153417202
commit ece69f01b7
4 changed files with 88 additions and 4 deletions

View File

@ -5,7 +5,7 @@ import getResettableAsyncComponent from 'src/services/resettable_async_component
import Popover from '../popover/popover.vue' import Popover from '../popover/popover.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep } from 'lodash' import { cloneDeep, isEqual } from 'lodash'
import { import {
newImporter, newImporter,
newExporter newExporter
@ -155,6 +155,12 @@ const SettingsModal = {
PLEROMAFE_SETTINGS_MINOR_VERSION PLEROMAFE_SETTINGS_MINOR_VERSION
] ]
return clone return clone
},
resetAdminDraft () {
this.$store.commit('resetAdminDraft')
},
pushAdminDraft () {
this.$store.dispatch('pushAdminDraft')
} }
}, },
computed: { computed: {
@ -183,6 +189,12 @@ const SettingsModal = {
set (value) { set (value) {
this.$store.dispatch('setOption', { name: 'expertLevel', value: value ? 1 : 0 }) this.$store.dispatch('setOption', { name: 'expertLevel', value: value ? 1 : 0 })
} }
},
adminDraftAny () {
return !isEqual(
this.$store.state.adminSettings.config,
this.$store.state.adminSettings.draft
)
} }
} }
} }

View File

@ -51,6 +51,8 @@
.settings-footer { .settings-footer {
display: flex; display: flex;
flex-wrap: wrap;
line-height: 2;
>* { >* {
margin-right: 0.5em; margin-right: 0.5em;

View File

@ -45,7 +45,7 @@
<SettingsModalUserContent v-if="modalMode === 'user' && modalOpenedOnceUser" /> <SettingsModalUserContent v-if="modalMode === 'user' && modalOpenedOnceUser" />
<SettingsModalAdminContent v-if="modalMode === 'admin' && modalOpenedOnceAdmin" /> <SettingsModalAdminContent v-if="modalMode === 'admin' && modalOpenedOnceAdmin" />
</div> </div>
<div class="panel-footer settings-footer"> <div class="panel-footer settings-footer -flexible-height">
<Popover <Popover
v-if="modalMode === 'user'" v-if="modalMode === 'user'"
class="export" class="export"
@ -125,6 +125,23 @@
id="unscrolled-content" id="unscrolled-content"
class="extra-content" class="extra-content"
/> />
<span class="admin-buttons" v-if="modalMode === 'admin'">
<button
class="button-default btn"
@click="resetAdminDraft"
:disabled="!adminDraftAny"
>
{{ $t("admin_dash.reset_all") }}
</button>
{{ ' ' }}
<button
class="button-default btn"
@click="pushAdminDraft"
:disabled="!adminDraftAny"
>
{{ $t("admin_dash.commit_all") }}
</button>
</span>
</div> </div>
</div> </div>
</Modal> </Modal>

View File

@ -1,4 +1,4 @@
import { set, get, cloneDeep } from 'lodash' import { set, get, cloneDeep, differenceWith, isEqual, flatten } from 'lodash'
export const defaultState = { export const defaultState = {
needsReboot: null, needsReboot: null,
@ -42,7 +42,7 @@ const adminSettingsStorage = {
actions: { actions: {
setInstanceAdminSettings ({ state, commit, dispatch }, { backendDbConfig }) { setInstanceAdminSettings ({ state, commit, dispatch }, { backendDbConfig }) {
const config = state.config || {} const config = state.config || {}
const modifiedPaths = state.modifiedPaths || new Set() const modifiedPaths = new Set()
backendDbConfig.configs.forEach(c => { backendDbConfig.configs.forEach(c => {
const path = [c.group, c.key] const path = [c.group, c.key]
if (c.db) { if (c.db) {
@ -82,6 +82,59 @@ const adminSettingsStorage = {
console.log(descriptions[':pleroma']['Pleroma.Captcha']) console.log(descriptions[':pleroma']['Pleroma.Captcha'])
commit('updateAdminDescriptions', { descriptions }) 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 }) { pushAdminSetting ({ rootState, state, commit, dispatch }, { path, value }) {
const [group, key, ...rest] = Array.isArray(path) ? path : 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 const clone = {} // not actually cloning the entire thing to avoid excessive writes