@@ -10,13 +10,16 @@ import {
10
10
} from "api/typesGenerated" ;
11
11
import { FullScreenLoader } from "components/Loader/FullScreenLoader" ;
12
12
import {
13
+ type FC ,
14
+ type PropsWithChildren ,
13
15
createContext ,
14
- FC ,
15
- PropsWithChildren ,
16
+ useCallback ,
16
17
useContext ,
17
18
useState ,
18
19
} from "react" ;
19
20
import { appearance } from "api/queries/appearance" ;
21
+ import { hslToHex , isHexColor , isHslColor } from "utils/colors" ;
22
+ import { displayError } from "components/GlobalSnackbar/utils" ;
20
23
21
24
interface Appearance {
22
25
config : AppearanceConfig ;
@@ -45,8 +48,35 @@ export const DashboardProvider: FC<PropsWithChildren> = ({ children }) => {
45
48
! entitlementsQuery . data ||
46
49
! appearanceQuery . data ||
47
50
! experimentsQuery . data ;
51
+
48
52
const [ configPreview , setConfigPreview ] = useState < AppearanceConfig > ( ) ;
49
53
54
+ // Centralizing the logic for catching malformed configs in one spot, just to
55
+ // be on the safe side; don't want to expose raw setConfigPreview outside
56
+ // the provider
57
+ const setPreview = useCallback ( ( newConfig : AppearanceConfig ) => {
58
+ // Have runtime safety nets in place, just because so much of the codebase
59
+ // relies on HSL for formatting, but server expects hex values. Can't catch
60
+ // color format mismatches at the type level
61
+ const incomingBg = newConfig . service_banner . background_color ;
62
+ let configForDispatch = newConfig ;
63
+
64
+ if ( typeof incomingBg === "string" && isHslColor ( incomingBg ) ) {
65
+ configForDispatch = {
66
+ ...newConfig ,
67
+ service_banner : {
68
+ ...newConfig . service_banner ,
69
+ background_color : hslToHex ( incomingBg ) ,
70
+ } ,
71
+ } ;
72
+ } else if ( typeof incomingBg === "string" && ! isHexColor ( incomingBg ) ) {
73
+ displayError ( `The value ${ incomingBg } is not a valid hex string` ) ;
74
+ return ;
75
+ }
76
+
77
+ setConfigPreview ( configForDispatch ) ;
78
+ } , [ ] ) ;
79
+
50
80
if ( isLoading ) {
51
81
return < FullScreenLoader /> ;
52
82
}
@@ -59,7 +89,7 @@ export const DashboardProvider: FC<PropsWithChildren> = ({ children }) => {
59
89
experiments : experimentsQuery . data ,
60
90
appearance : {
61
91
config : configPreview ?? appearanceQuery . data ,
62
- setPreview : setConfigPreview ,
92
+ setPreview : setPreview ,
63
93
isPreview : configPreview !== undefined ,
64
94
} ,
65
95
} }
0 commit comments