Adapt UI app to new data model

This commit is contained in:
Benedikt Kulmann
2020-08-19 10:27:06 +02:00
parent 8282f348eb
commit 0e8be0e195
9 changed files with 130 additions and 125 deletions
+7 -7
View File
@@ -18,16 +18,16 @@
</template>
<template v-if="settingsValuesLoaded">
<settings-bundle
v-for="bundle in selectedSettingsBundles"
:key="'bundle-' + bundle.identifier.bundleKey"
v-for="bundle in selectedBundles"
:key="'bundle-' + bundle.id"
:bundle="bundle"
class="uk-margin-top"
/>
</template>
<div class="uk-margin-top" v-else>
<oc-loader :aria-label="$gettext('Loading settings values')" />
<oc-loader :aria-label="$gettext('Loading personal settings')" />
<oc-alert :aria-hidden="true" varition="primary" no-close>
<p v-translate>Loading settings values...</p>
<p v-translate>Loading personal settings...</p>
</oc-alert>
</div>
</template>
@@ -53,7 +53,7 @@ export default {
...mapGetters('Settings', [
'extensions',
'initialized',
'getSettingsBundlesByExtension'
'getBundlesByExtension'
]),
extensionRouteParam () {
return this.$route.params.extension
@@ -61,9 +61,9 @@ export default {
selectedExtensionName () {
return this.getExtensionName(this.selectedExtension)
},
selectedSettingsBundles () {
selectedBundles () {
if (this.selectedExtension) {
return this.getSettingsBundlesByExtension(this.selectedExtension)
return this.getBundlesByExtension(this.selectedExtension)
}
return []
}
+22 -29
View File
@@ -5,15 +5,15 @@
</div>
<oc-grid gutter="small">
<template>
<div class="uk-width-1-1" v-for="setting in bundle.settings" :key="getElementId(bundle, setting)">
<label class="oc-label" :for="getElementId(bundle, setting)">{{ setting.displayName }}</label>
<div class="uk-width-1-1" v-for="setting in bundle.settings" :key="setting.id">
<label class="oc-label" :for="setting.id">{{ setting.displayName }}</label>
<div class="uk-position-relative"
:is="getSettingComponent(setting)"
:id="getElementId(bundle, setting)"
:id="setting.id"
:bundle="bundle"
:setting="setting"
:persisted-value="getSettingsValue(bundle, setting)"
@onSave="onSaveSettingsValue"
:persisted-value="getValue(setting)"
@onSave="onSaveValue"
/>
</div>
</template>
@@ -22,6 +22,7 @@
</template>
<script>
import assign from 'lodash/assign'
import { mapGetters, mapActions } from 'vuex'
import SettingBoolean from './settings/SettingBoolean.vue'
import SettingMultiChoice from './settings/SettingMultiChoice.vue'
@@ -29,7 +30,6 @@ import SettingNumber from './settings/SettingNumber.vue'
import SettingSingleChoice from './settings/SettingSingleChoice.vue'
import SettingString from './settings/SettingString.vue'
import SettingUnknown from './settings/SettingUnknown.vue'
export default {
name: 'SettingsBundle',
props: {
@@ -38,34 +38,27 @@ export default {
required: true
}
},
computed: mapGetters(['getSettingsValueByIdentifier']),
computed: mapGetters(['getSettingsValue']),
methods: {
...mapActions('Settings', ['saveSettingsValue']),
getElementId (bundle, setting) {
return `setting-${bundle.identifier.bundleKey}-${setting.settingKey}`
},
...mapActions('Settings', ['saveValue']),
getSettingComponent (setting) {
return 'Setting' + setting.type[0].toUpperCase() + setting.type.substr(1)
},
getSettingsValue (bundle, setting) {
const identifier = {
extension: bundle.identifier.extension,
bundleKey: bundle.identifier.bundleKey,
settingKey: setting.settingKey
}
return this.getSettingsValueByIdentifier(identifier)
getValue (setting) {
return this.getSettingsValue({ settingId: setting.id })
},
async onSaveSettingsValue ({ bundle, setting, value }) {
const payload = {
identifier: {
accountUuid: 'me',
extension: bundle.identifier.extension,
bundleKey: bundle.identifier.bundleKey,
settingKey: setting.settingKey
},
...value
}
await this.saveSettingsValue(payload)
async onSaveValue ({ bundle, setting, payload }) {
payload = assign({}, payload, {
bundleId: bundle.id,
settingId: setting.id,
accountUuid: 'me',
resource: setting.resource
})
await this.saveValue({
bundle,
setting,
payload
})
}
},
components: {
+5 -2
View File
@@ -29,13 +29,16 @@ export default {
},
methods: {
async applyValue () {
const value = {
const payload = {
boolValue: this.value
}
if (!isNil(this.persistedValue)) {
payload.id = this.persistedValue.id
}
await this.$emit('onSave', {
bundle: this.bundle,
setting: this.setting,
value
value: payload
})
// TODO: show a spinner while the request for saving the value is running!
}
+12 -8
View File
@@ -65,15 +65,15 @@ export default {
return Array.from(this.selectedOptions).map(option => option.displayValue).join(', ')
},
dropElementId () {
return `multi-choice-drop-${this.bundle.identifier.bundleKey}-${this.setting.settingKey}`
return `multi-choice-drop-${this.setting.id}`
},
buttonElementId () {
return `multi-choice-toggle-${this.bundle.identifier.bundleKey}-${this.setting.settingKey}`
return `multi-choice-toggle-${this.setting.id}`
}
},
methods: {
getOptionElementId (index) {
return `${this.bundle.identifier.bundleKey}-${this.setting.settingKey}-${index}`
return `${this.setting.id}-${index}`
},
async onSelectedOption () {
const values = []
@@ -87,14 +87,18 @@ export default {
}
})
}
const payload = {
listValue: {
values
}
}
if (!isNil(this.persistedValue)) {
payload.id = this.persistedValue.id
}
await this.$emit('onSave', {
bundle: this.bundle,
setting: this.setting,
value: {
listValue: {
values
}
}
payload
})
// TODO: show a spinner while the request for saving the value is running!
}
+5 -2
View File
@@ -69,13 +69,16 @@ export default {
this.value = this.initialValue
},
async applyValue () {
const value = {
const payload = {
intValue: this.value
}
if (!isNil(this.persistedValue)) {
payload.id = this.persistedValue.id
}
await this.$emit('onSave', {
bundle: this.bundle,
setting: this.setting,
value
payload
})
// TODO: show a spinner while the request for saving the value is running!
this.initialValue = this.value
+12 -8
View File
@@ -63,15 +63,15 @@ export default {
},
computed: {
dropElementId () {
return `single-choice-drop-${this.bundle.identifier.bundleKey}-${this.setting.settingKey}`
return `single-choice-drop-${this.setting.id}`
},
buttonElementId () {
return `single-choice-toggle-${this.bundle.identifier.bundleKey}-${this.setting.settingKey}`
return `single-choice-toggle-${this.setting.id}`
}
},
methods: {
getOptionElementId (index) {
return `${this.bundle.identifier.bundleKey}-${this.setting.settingKey}-${index}`
return `${this.setting.id}-${index}`
},
async onSelectedOption () {
const values = []
@@ -83,14 +83,18 @@ export default {
values.push({ stringValue: this.selectedOption.value.stringValue })
}
}
const payload = {
listValue: {
values
}
}
if (!isNil(this.persistedValue)) {
payload.id = this.persistedValue.id
}
await this.$emit('onSave', {
bundle: this.bundle,
setting: this.setting,
value: {
listValue: {
values
}
}
payload
})
// TODO: show a spinner while the request for saving the value is running!
}
+5 -2
View File
@@ -51,13 +51,16 @@ export default {
},
methods: {
async applyValue () {
const value = {
const payload = {
stringValue: this.value
}
if (!isNil(this.persistedValue)) {
payload.id = this.persistedValue.id
}
await this.$emit('onSave', {
bundle: this.bundle,
setting: this.setting,
value
payload
})
// TODO: show a spinner while the request for saving the value is running!
this.initialValue = this.value
+59 -64
View File
@@ -1,30 +1,30 @@
import {
// eslint-disable-next-line camelcase
BundleService_ListSettingsBundles,
BundleService_ListBundles,
// eslint-disable-next-line camelcase
ValueService_SaveSettingsValue
ValueService_SaveValue
} from '../client/settings'
import axios from 'axios'
import keyBy from 'lodash/keyBy'
const state = {
config: null,
initialized: false,
settingsBundles: {}
bundles: {}
}
const getters = {
config: state => state.config,
initialized: state => state.initialized,
extensions: state => {
return Array.from(state.settingsBundles.keys()).sort()
return [...new Set(Object.values(state.bundles).map(bundle => bundle.extension))].sort()
},
getSettingsBundlesByExtension: state => extension => {
if (state.settingsBundles.has(extension)) {
return Array.from(state.settingsBundles.get(extension).values()).sort((b1, b2) => {
return b1.identifier.bundleKey.localeCompare(b2.identifier.bundleKey)
getBundlesByExtension: state => extension => {
return Object.values(state.bundles)
.filter(bundle => bundle.extension === extension)
.sort((b1, b2) => {
return b1.name.localeCompare(b2.name)
})
}
return []
}
}
@@ -32,15 +32,8 @@ const mutations = {
SET_INITIALIZED (state, value) {
state.initialized = value
},
SET_SETTINGS_BUNDLES (state, settingsBundles) {
const map = new Map()
Array.from(settingsBundles).forEach(bundle => {
if (!map.has(bundle.identifier.extension)) {
map.set(bundle.identifier.extension, new Map())
}
map.get(bundle.identifier.extension).set(bundle.identifier.bundleKey, bundle)
})
state.settingsBundles = map
SET_BUNDLES (state, bundles) {
state.bundles = keyBy(bundles, 'id')
},
LOAD_CONFIG (state, config) {
state.config = config
@@ -54,66 +47,68 @@ const actions = {
},
async initialize ({ commit, dispatch }) {
await dispatch('fetchSettingsBundles')
await dispatch('fetchBundles')
commit('SET_INITIALIZED', true)
},
async fetchSettingsBundles ({ commit, dispatch, getters, rootGetters }) {
async fetchBundles ({ commit, dispatch, rootGetters }) {
injectAuthToken(rootGetters)
const response = await BundleService_ListSettingsBundles({
$domain: rootGetters.configuration.server,
body: {}
})
if (response.status === 201) {
// the settings markup has implicit typing. inject an explicit type variable here
const settingsBundles = response.data.settingsBundles
if (settingsBundles) {
settingsBundles.forEach(bundle => {
bundle.settings.forEach(setting => {
if (setting.intValue) {
setting.type = 'number'
} else if (setting.stringValue) {
setting.type = 'string'
} else if (setting.boolValue) {
setting.type = 'boolean'
} else if (setting.singleChoiceValue) {
setting.type = 'singleChoice'
} else if (setting.multiChoiceValue) {
setting.type = 'multiChoice'
} else {
setting.type = 'unknown'
}
try {
const response = await BundleService_ListBundles({
$domain: rootGetters.configuration.server,
body: {
accountUuid: 'me'
}
})
if (response.status === 201) {
// the settings markup has implicit typing. inject an explicit type variable here
const bundles = response.data.bundles
if (bundles) {
bundles.forEach(bundle => {
bundle.settings.forEach(setting => {
if (setting.intValue) {
setting.type = 'number'
} else if (setting.stringValue) {
setting.type = 'string'
} else if (setting.boolValue) {
setting.type = 'boolean'
} else if (setting.singleChoiceValue) {
setting.type = 'singleChoice'
} else if (setting.multiChoiceValue) {
setting.type = 'multiChoice'
} else {
setting.type = 'unknown'
}
})
})
})
commit('SET_SETTINGS_BUNDLES', settingsBundles)
} else {
commit('SET_SETTINGS_BUNDLES', [])
commit('SET_BUNDLES', bundles)
} else {
commit('SET_BUNDLES', [])
}
}
} else {
} catch (err) {
dispatch('showMessage', {
title: 'Failed to fetch settings bundles.',
desc: response.statusText,
title: 'Failed to fetch bundles.',
status: 'danger'
}, { root: true })
}
},
async saveSettingsValue ({ commit, dispatch, getters, rootGetters }, payload) {
async saveValue ({ commit, dispatch, getters, rootGetters }, { setting, payload }) {
injectAuthToken(rootGetters)
const response = await ValueService_SaveSettingsValue({
$domain: rootGetters.configuration.server,
body: {
settingsValue: payload
try {
const response = await ValueService_SaveValue({
$domain: rootGetters.configuration.server,
body: {
value: payload
}
})
if (response.status === 201 && response.data.value) {
commit('SET_SETTINGS_VALUE', response.data.value, { root: true })
}
})
if (response.status === 201) {
if (response.data.settingsValue) {
commit('SET_SETTINGS_VALUE', response.data.settingsValue, { root: true })
}
} else {
} catch (e) {
dispatch('showMessage', {
title: 'Failed to save settings value.',
desc: response.statusText,
title: `Failed to save »${setting.displayName}«.`,
status: 'danger'
}, { root: true })
}