MapSetting component

This commit is contained in:
Henry Jameson 2025-12-06 14:38:53 +02:00
commit 9c043533f2
4 changed files with 191 additions and 4 deletions

View file

@ -6,7 +6,7 @@ import TupleSetting from '../helpers/tuple_setting.vue'
import GroupSetting from '../helpers/group_setting.vue'
import AttachmentSetting from '../helpers/attachment_setting.vue'
import ListSetting from '../helpers/list_setting.vue'
import ListTupleSetting from '../helpers/list_tuple_setting.vue'
import MapSetting from '../helpers/map_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
@ -26,7 +26,7 @@ const AuthTab = {
AttachmentSetting,
GroupSetting,
ListSetting,
ListTupleSetting
MapSetting
},
computed: {
...SharedComputedObject(),

View file

@ -67,13 +67,21 @@
<BooleanSetting path=":pleroma.:ldap.:tls" />
</li>
<li>
<ListTupleSetting tuple path=":pleroma.:ldap.:tlsopts" />
<!-- CONFIRM old admin FE only supports ONE setting which is Verify, is that correct or should we allow more than one? -->
<MapSetting
:allow-new="false"
path=":pleroma.:ldap.:tlsopts"
/>
</li>
<li>
<BooleanSetting path=":pleroma.:ldap.:ssl" />
</li>
<li>
<ListTupleSetting tuple path=":pleroma.:ldap.:sslopts" />
<!-- CONFIRM old admin FE only supports ONE setting which is Verify, is that correct or should we allow more than one? -->
<MapSetting
:allow-new="false"
path=":pleroma.:ldap.:sslopts"
/>
</li>
<li>
<StringSetting path=":pleroma.:ldap.:base" />

View file

@ -0,0 +1,70 @@
import Setting from './setting.js'
export default {
...Setting,
props: {
...Setting.props,
allowNew: {
required: false,
type: Boolean,
default: true
}
},
data () {
return {
newValue: ['',''] // avoiding extra complexity by just using an array instead of an object
}
},
computed: {
...Setting.computed,
// state that we'll show in the UI, i.e. transforming map into list
displayState () {
return Object.entries(this.visibleState)
}
},
methods: {
...Setting.methods,
getValue ({ event, key, eventType, isKey }) {
switch (eventType) {
case 'add': {
if (key === '') return this.visibleState
const res = {...this.visibleState, ...Object.fromEntries([this.newValue])}
this.newValue = ['', '']
return res
}
case 'remove': {
// initial state for this type is empty array
if (Array.isArray(this.visibleState)) return this.visibleState
const newEntries = Object.entries(this.visibleState).filter(([k]) => k !== key)
if (newEntries.length === 0 ) return []
return Object.fromEntries(newEntries)
}
case 'edit': {
const string = event.target.value
const newEntries = Object
.entries(this.visibleState)
.map(([k, v]) => {
if (isKey) {
if (k === key) {
return [string, v]
} else {
return [k, v]
}
} else {
if (k === key) {
return [k, string]
} else {
return [k, v]
}
}
})
return Object.fromEntries(newEntries)
}
}
}
}
}

View file

@ -0,0 +1,109 @@
<template>
<div
v-if="matchesExpertLevel"
class="MapSetting"
>
<label
class="setting-label"
:class="{ 'faint': shouldBeDisabled }"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
<ul class="setting-list">
<li v-for="item in displayState">
<div class="btn-group">
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:value="item[0]"
@change="e => update({ event: e, key: item[0], eventType: 'edit', isKey: true })"
>
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:value="item[1]"
@change="e => update({ event: e, key: item[0], eventType: 'edit', isKey: false })"
>
<button
class="button-default"
@click="e => update({ key: item[0], eventType: 'remove' })"
>
<FAIcon icon="times" />
</button>
</div>
</li>
<li v-if="allowNew">
<div class="btn-group">
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:disabled="shouldBeDisabled"
:placeholder="backendDescriptionSuggestions[0][0]"
v-model="newValue[0]"
>
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:disabled="shouldBeDisabled"
:placeholder="backendDescriptionSuggestions[0][1]"
v-model="newValue[1]"
>
<button
class="button-default"
@click="e => update({ eventType: 'add' })"
>
<FAIcon icon="plus" />
</button>
</div>
</li>
</ul>
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons />
</div>
</template>
<style lang="scss">
.ListSetting {
.btn-group {
display: flex
}
dl {
display: inline-grid;
grid-template-columns: auto auto;
gap: 0.5em;
dt {
display: inline;
font-weight: 800;
&::after {
content: ':'
}
}
dd {
display: inline;
margin: 0
}
}
}
</style>
<script src="./map_setting.js"></script>