From 40b37ddf5c4f073baf75c37b3268acc784b1a4a8 Mon Sep 17 00:00:00 2001 From: Lukas Hirt Date: Tue, 10 Dec 2024 12:01:55 +0100 Subject: [PATCH] feat: call api to save values --- .../useNotificationsSettings.ts | 58 ++++---- packages/web-runtime/src/helpers/settings.ts | 105 ++++++++++---- packages/web-runtime/src/pages/account.vue | 131 +++++++++++++----- 3 files changed, 206 insertions(+), 88 deletions(-) diff --git a/packages/web-runtime/src/composables/notificationsSettings/useNotificationsSettings.ts b/packages/web-runtime/src/composables/notificationsSettings/useNotificationsSettings.ts index 0ef58a015b5..b66690cd820 100644 --- a/packages/web-runtime/src/composables/notificationsSettings/useNotificationsSettings.ts +++ b/packages/web-runtime/src/composables/notificationsSettings/useNotificationsSettings.ts @@ -1,64 +1,66 @@ -import { computed, ref, Ref } from 'vue' +import { computed, Ref, unref } from 'vue' import { getSettingsDefaultValue, + getSettingsValue, SETTINGS_EMAIL_NOTIFICATION_BUNDLE_IDS, SETTINGS_NOTIFICATION_BUNDLE_IDS, SettingsBundle, - SettingsNotificationBundle, SettingsValue } from '../../helpers/settings' -export const useNotificationsSettings = (bundle: Ref) => { - const values = ref({ - [SettingsNotificationBundle.ShareCreated]: { mail: false, inapp: false }, - [SettingsNotificationBundle.ShareRemoved]: { mail: false, inapp: false }, - [SettingsNotificationBundle.ShareExpired]: { mail: false, inapp: false }, - [SettingsNotificationBundle.SpaceShared]: { mail: false, inapp: false }, - [SettingsNotificationBundle.SpaceUnshared]: { mail: false, inapp: false }, - [SettingsNotificationBundle.SpaceMembershipExpired]: { mail: false, inapp: false }, - [SettingsNotificationBundle.SpaceDisabled]: { mail: false, inapp: false }, - [SettingsNotificationBundle.SpaceDeleted]: { mail: false, inapp: false }, - [SettingsNotificationBundle.PostprocessingStepFinished]: { mail: false, inapp: false }, - [SettingsNotificationBundle.ScienceMeshInviteTokenGenerated]: { mail: false, inapp: false } - }) - - const defaultValues = computed(() => { - if (!bundle.value) { +export const useNotificationsSettings = ( + valueList: Ref, + bundle: Ref +) => { + const values = computed(() => { + if (!unref(bundle)) { return {} } - return bundle.value.settings.reduce((acc, curr) => { + return unref(bundle).settings.reduce((acc, curr) => { if (!SETTINGS_NOTIFICATION_BUNDLE_IDS.includes(curr.id)) { return acc } - acc[curr.id] = getSettingsDefaultValue(curr) + acc[curr.id] = getSettingsValue(curr, unref(valueList)) || getSettingsDefaultValue(curr) return acc }, {}) }) const options = computed(() => { - if (!bundle.value) { + if (!unref(bundle)) { return [] } - return bundle.value.settings.filter(({ id }) => SETTINGS_NOTIFICATION_BUNDLE_IDS.includes(id)) + return unref(bundle).settings.filter(({ id }) => SETTINGS_NOTIFICATION_BUNDLE_IDS.includes(id)) }) const emailOptions = computed(() => { - if (!bundle.value) { + if (!unref(bundle)) { return [] } - return bundle.value.settings.filter(({ id }) => + return unref(bundle).settings.filter(({ id }) => SETTINGS_EMAIL_NOTIFICATION_BUNDLE_IDS.includes(id) ) }) - const updateDefaultValues = (values: SettingsValue[], bundle: SettingsBundle) => { - // TODO: process and return values - } + const emailValues = computed(() => { + if (!unref(bundle)) { + return {} + } + + return unref(bundle).settings.reduce((acc, curr) => { + if (!SETTINGS_EMAIL_NOTIFICATION_BUNDLE_IDS.includes(curr.id)) { + return acc + } + + acc[curr.id] = getSettingsValue(curr, unref(valueList)) || getSettingsDefaultValue(curr) + + return acc + }, {}) + }) - return { values, options, emailOptions, updateDefaultValues } + return { values, options, emailOptions, emailValues } } diff --git a/packages/web-runtime/src/helpers/settings.ts b/packages/web-runtime/src/helpers/settings.ts index 03d5fe14046..44103e40bf7 100644 --- a/packages/web-runtime/src/helpers/settings.ts +++ b/packages/web-runtime/src/helpers/settings.ts @@ -1,3 +1,5 @@ +import { captureException } from '@sentry/vue' + export interface SettingsValue { identifier: { bundle: string @@ -18,7 +20,39 @@ export interface SettingsValue { stringValue: string }[] } + collectionValue?: { + values: { + key: string + boolValue: boolean + }[] + } + } +} + +interface SettingsBundleSetting { + description: string + displayName: string + id: string + name: string + resource: { + type: string + } + singleChoiceValue?: { + options: Record[] + } + multiChoiceCollectionValue?: { + options: { + value: { + boolValue: { + default?: boolean + } + } + key: string + displayValue: string + attribute?: 'disabled' + }[] } + boolValue?: Record } export interface SettingsBundle { @@ -29,31 +63,7 @@ export interface SettingsBundle { resource: { type: string } - settings: { - description: string - displayName: string - id: string - name: string - resource: { - type: string - } - singleChoiceValue?: { - options: Record[] - } - multiChoiceCollectionValue?: { - options: { - value: { - boolValue: { - default?: boolean - } - } - key: string - displayValue: string - attribute?: 'disabled' - }[] - } - boolValue?: Record - }[] + settings: SettingsBundleSetting[] type: string roleId?: string } @@ -100,10 +110,53 @@ export const SETTINGS_EMAIL_NOTIFICATION_BUNDLE_IDS: string[] = [ SettingsEmailNotificationBundle.EmailSendingInterval ] -export function getSettingsDefaultValue(setting: SettingsBundle['settings']) { +export function getSettingsDefaultValue(setting: SettingsBundleSetting) { if (setting.singleChoiceValue) { + const [option] = setting.singleChoiceValue.options + + return { + value: option.value.stringValue, + displayValue: option.displayValue + } } if (setting.multiChoiceCollectionValue) { + return setting.multiChoiceCollectionValue.options.reduce((acc, curr) => { + acc[curr.key] = curr.value.boolValue.default + + return acc + }, {}) + } + + const error = new Error('Unsupported setting value') + + console.error(error) + captureException(error) + + return null +} + +export function getSettingsValue( + setting: SettingsBundleSetting, + valueList: SettingsValue[] +): boolean | string | null | { [key: string]: boolean } { + const { value } = valueList.find((v) => v.identifier.setting === setting.name) || {} + + if (!value) { + return null + } + + if (value.collectionValue) { + return setting.multiChoiceCollectionValue.options.reduce((acc, curr) => { + const val = value.collectionValue.values.find((v) => v.key === curr.key) + + if (val) { + acc[curr.key] = val.boolValue + return acc + } + + acc[curr.key] = curr.value.boolValue.default + return acc + }, {}) } } diff --git a/packages/web-runtime/src/pages/account.vue b/packages/web-runtime/src/pages/account.vue index cad5f14ae78..c6d566957dc 100644 --- a/packages/web-runtime/src/pages/account.vue +++ b/packages/web-runtime/src/pages/account.vue @@ -167,24 +167,23 @@ {{ option.displayName }} {{ option.description }} - - - - - - - - - - + + {{ option.displayName }} {{ option.description }} - - + + + @@ -323,8 +329,9 @@ export default defineComponent({ const { options: notificationsOptions, emailOptions: emailNotificationsOptions, - updateDefaultValues: updateDefaultNotificationSettingsValues - } = useNotificationsSettings(accountBundle) + values: notificationsValues, + emailValues: emailNotificationsValues + } = useNotificationsSettings(valuesList, accountBundle) const isMobileWidth = ref(window.innerWidth < MOBILE_BREAKPOINT) const onResize = () => { @@ -577,13 +584,6 @@ export default defineComponent({ }) }) - const emailNotificationsFrequencies = computed(() => [ - { label: $gettext('Daily') }, - { label: $gettext('Weekly') }, - { label: $gettext('Never') }, - { label: $gettext('Instant') } - ]) - const notificationsSettingsFields = computed(() => [ { label: $gettext('Event') }, { label: $gettext('Event description'), hidden: true }, @@ -597,6 +597,69 @@ export default defineComponent({ { label: $gettext('Option value'), hidden: true } ]) + const updateValueInValueList = (value: SettingsValue) => { + const index = unref(valuesList).findIndex( + (v) => v.identifier.setting === value.identifier.setting + ) + + if (index < 0) { + valuesList.value.push(value) + return + } + + valuesList.value.splice(index, 1, value) + } + + const updateMultiChoiceSettingsValue = async ( + identifier: string, + key: string, + value: boolean | string + ) => { + try { + if (typeof value === 'boolean') { + const currentValue = unref(valuesList).find((v) => v.identifier.setting === identifier) + + await saveValue({ + identifier, + valueOptions: { + collectionValue: { + values: [ + ...currentValue?.value.collectionValue.values.filter((val) => val.key !== key), + { key, boolValue: value } + ] + } + } + }) + + updateValueInValueList({ + identifier: { setting: identifier }, + ...currentValue, + value: { + ...currentValue?.value, + collectionValue: { + values: ( + currentValue?.value.collectionValue.values.filter((v) => v.key !== key) || [] + ).concat([{ key, boolValue: value }]) + } + } + }) + showMessage({ title: $gettext('Preference saved.') }) + + return + } + } catch (error) { + console.error(error) + showErrorMessage({ + title: $gettext('Unable to save preference…'), + errors: [error] + }) + } + } + + const updateSingleChoiceValue = async (identifier: string, value: string): Promise => { + console.log(value) + } + onMounted(async () => { window.addEventListener('resize', onResize) @@ -616,9 +679,6 @@ export default defineComponent({ disableEmailNotificationsValue.value = disableEmailNotificationsConfiguration ? !disableEmailNotificationsConfiguration.value?.boolValue : true - - // TODO: assign values - updateDefaultNotificationSettingsValues(unref(valuesList), unref(accountBundle)) }) onBeforeUnmount(() => { @@ -659,11 +719,14 @@ export default defineComponent({ showEditPasswordModal, quota, isMobileWidth, - emailNotificationsFrequencies, notificationsOptions, notificationsSettingsFields, emailNotificationsOptionsFields, - emailNotificationsOptions + emailNotificationsOptions, + notificationsValues, + updateMultiChoiceSettingsValue, + emailNotificationsValues, + updateSingleChoiceValue } } })