1- import { isNil } from 'lodash' ;
2-
31import type {
42 GetSettingsParams ,
53 GetSingleSettingParams ,
64 SetSingleSettingParams ,
7- Setting ,
85} from '../../../types/api/settings' ;
96import type { AppDispatch } from '../../defaultStore' ;
7+ import { serializeError } from '../../utils' ;
108import { api } from '../api' ;
119
1210import { SETTINGS_OPTIONS } from './constants' ;
11+ import { getSettingDefault , parseSettingValue , stringifySettingValue } from './utils' ;
1312
1413export const settingsApi = api . injectEndpoints ( {
1514 endpoints : ( builder ) => ( {
16- getSingleSetting : builder . query ( {
17- queryFn : async ( { name, user} : GetSingleSettingParams , baseApi ) => {
15+ getSingleSetting : builder . query < unknown , Partial < GetSingleSettingParams > > ( {
16+ queryFn : async ( { name, user} ) => {
1817 try {
19- if ( ! window . api . metaSettings ) {
20- throw new Error ( 'MetaSettings API is not available' ) ;
18+ if ( ! name || ! window . api . metaSettings ) {
19+ throw new Error (
20+ 'Cannot get setting, no MetaSettings API or neccessary params are missing' ,
21+ ) ;
2122 }
23+
24+ const defaultValue = getSettingDefault ( name ) as unknown ;
25+
26+ if ( ! user ) {
27+ return { data : defaultValue } ;
28+ }
29+
2230 const data = await window . api . metaSettings . getSingleSetting ( {
2331 name,
2432 user,
2533 // Directly access options here to avoid them in cache key
2634 preventBatching : SETTINGS_OPTIONS [ name ] ?. preventBatching ,
2735 } ) ;
2836
29- const dispatch = baseApi . dispatch as AppDispatch ;
30-
31- // Try to sync local value if there is no backend value
32- syncLocalValueToMetaIfNoData ( data , dispatch ) ;
33-
34- return { data} ;
37+ return { data : parseSettingValue ( data ?. value ) ?? defaultValue } ;
3538 } catch ( error ) {
36- return { error} ;
39+ return { error : serializeError ( error ) } ;
3740 }
3841 } ,
3942 } ) ,
4043 setSingleSetting : builder . mutation ( {
41- queryFn : async ( params : SetSingleSettingParams ) => {
44+ queryFn : async ( {
45+ name,
46+ user,
47+ value,
48+ } : Partial < Omit < SetSingleSettingParams , 'value' > > & { value : unknown } ) => {
4249 try {
43- if ( ! window . api . metaSettings ) {
44- throw new Error ( 'MetaSettings API is not available' ) ;
50+ if ( ! name || ! user || ! window . api . metaSettings ) {
51+ throw new Error (
52+ 'Cannot set setting, no MetaSettings API or neccessary params are missing' ,
53+ ) ;
4554 }
4655
47- const data = await window . api . metaSettings . setSingleSetting ( params ) ;
56+ const data = await window . api . metaSettings . setSingleSetting ( {
57+ name,
58+ user,
59+ value : stringifySettingValue ( value ) ,
60+ } ) ;
4861
4962 if ( data . status !== 'SUCCESS' ) {
50- throw new Error ( 'Setting status is not SUCCESS' ) ;
63+ throw new Error ( 'Cannot set setting - status is not SUCCESS' ) ;
5164 }
5265
5366 return { data} ;
5467 } catch ( error ) {
55- return { error} ;
68+ return { error : serializeError ( error ) } ;
5669 }
5770 } ,
5871 async onQueryStarted ( args , { dispatch, queryFulfilled} ) {
5972 const { name, user, value} = args ;
6073
74+ if ( ! name ) {
75+ return ;
76+ }
77+
6178 // Optimistically update existing cache entry
6279 const patchResult = dispatch (
63- settingsApi . util . updateQueryData ( 'getSingleSetting' , { name, user} , ( draft ) => {
64- return { ...draft , name, user, value} ;
65- } ) ,
80+ settingsApi . util . updateQueryData ( 'getSingleSetting' , { name, user} , ( ) => value ) ,
6681 ) ;
6782 try {
6883 await queryFulfilled ;
@@ -72,41 +87,41 @@ export const settingsApi = api.injectEndpoints({
7287 } ,
7388 } ) ,
7489 getSettings : builder . query ( {
75- queryFn : async ( { name, user} : GetSettingsParams , baseApi ) => {
90+ queryFn : async ( { name, user} : Partial < GetSettingsParams > , baseApi ) => {
7691 try {
77- if ( ! window . api . metaSettings ) {
78- throw new Error ( 'MetaSettings API is not available' ) ;
92+ if ( ! window . api . metaSettings || ! name || ! user ) {
93+ throw new Error (
94+ 'Cannot get settings, no MetaSettings API or neccessary params are missing' ,
95+ ) ;
7996 }
8097 const data = await window . api . metaSettings . getSettings ( { name, user} ) ;
8198
82- const patches : Promise < void > [ ] = [ ] ;
99+ const patches : Promise < unknown > [ ] = [ ] ;
83100 const dispatch = baseApi . dispatch as AppDispatch ;
84101
85- // Upsert received data in getSingleSetting cache
102+ // Upsert received data in getSingleSetting cache to prevent further redundant requests
86103 name . forEach ( ( settingName ) => {
87- const settingData = data [ settingName ] ?? { } ;
104+ const settingData = data [ settingName ] ;
105+
106+ const defaultValue = getSettingDefault ( settingName ) ;
88107
89108 const cacheEntryParams : GetSingleSettingParams = {
90109 name : settingName ,
91110 user,
92111 } ;
93- const newValue = { name : settingName , user, value : settingData ?. value } ;
112+ const newSetting = {
113+ name : settingName ,
114+ user,
115+ value : parseSettingValue ( settingData ?. value ) ?? defaultValue ,
116+ } ;
94117
95118 const patch = dispatch (
96119 settingsApi . util . upsertQueryData (
97120 'getSingleSetting' ,
98121 cacheEntryParams ,
99- newValue ,
122+ newSetting ,
100123 ) ,
101- ) . then ( ( ) => {
102- // Try to sync local value if there is no backend value
103- // Do it after upsert if finished to ensure proper values update order
104- // 1. New entry added to cache with nil value
105- // 2. Positive entry update - local storage value replace nil in cache
106- // 3.1. Set is successful, local value in cache
107- // 3.2. Set is not successful, cache value reverted to previous nil
108- syncLocalValueToMetaIfNoData ( settingData , dispatch ) ;
109- } ) ;
124+ ) ;
110125
111126 patches . push ( patch ) ;
112127 } ) ;
@@ -116,24 +131,10 @@ export const settingsApi = api.injectEndpoints({
116131
117132 return { data} ;
118133 } catch ( error ) {
119- return { error} ;
134+ return { error : serializeError ( error ) } ;
120135 }
121136 } ,
122137 } ) ,
123138 } ) ,
124139 overrideExisting : 'throw' ,
125140} ) ;
126-
127- function syncLocalValueToMetaIfNoData ( params : Setting , dispatch : AppDispatch ) {
128- const localValue = localStorage . getItem ( params . name ) ;
129-
130- if ( isNil ( params . value ) && ! isNil ( localValue ) ) {
131- dispatch (
132- settingsApi . endpoints . setSingleSetting . initiate ( {
133- name : params . name ,
134- user : params . user ,
135- value : localValue ,
136- } ) ,
137- ) ;
138- }
139- }
0 commit comments