Skip to content

Commit 85319ab

Browse files
committed
feat: refactor cost module state management and validation in ClusterForm
1 parent 4ac4e0f commit 85319ab

File tree

1 file changed

+50
-33
lines changed
  • src/Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterForm

1 file changed

+50
-33
lines changed

src/Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterForm/ClusterForm.tsx

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,13 @@ const ClusterForm = ({
9393
)
9494

9595
const [costModuleState, setCostModuleState] = useState<
96-
Pick<ClusterDetailListType['costModuleConfig'], 'config' | 'enabled'>
96+
Pick<ClusterDetailListType['costModuleConfig'], 'enabled'> & { config: string }
9797
>({
9898
enabled: costModuleConfig?.enabled || false,
99-
config: {
100-
cloudProviderApiKey: costModuleConfig?.config?.cloudProviderApiKey || '',
101-
},
99+
config: costModuleConfig?.config ? JSON.stringify(costModuleConfig.config) : '',
102100
})
101+
const [costModuleConfigErrorState, setCostModuleErrorState] = useState<string>('')
103102

104-
const [costModuleErrorState, setCostModuleErrorState] = useState<{ cloudProviderApiKey: string }>({
105-
cloudProviderApiKey: '',
106-
})
107103
const [prometheusToggleEnabled, setPrometheusToggleEnabled] = useState(!!prometheusUrl)
108104
const [prometheusAuthenticationType, setPrometheusAuthenticationType] = useState({
109105
type: prometheusAuth?.userName ? AuthenticationType.BASIC : AuthenticationType.ANONYMOUS,
@@ -183,19 +179,41 @@ const ClusterForm = ({
183179
setIsConnectedViaSSHTunnelTemp(false)
184180
}
185181

182+
const validateCostModuleConfig = (requiredConfig: string = costModuleState.config): string => {
183+
try {
184+
if (requiredConfig) {
185+
JSON.parse(requiredConfig)
186+
}
187+
188+
return ''
189+
} catch (e) {
190+
return e.message || 'Invalid JSON'
191+
}
192+
}
193+
194+
const getParsedConfigValue = (): ClusterCostModuleConfigPayload['config'] => {
195+
if (costModuleState.config) {
196+
try {
197+
const parsedConfig = JSON.parse(costModuleState.config)
198+
return parsedConfig
199+
} catch {
200+
return {}
201+
}
202+
}
203+
return null
204+
}
205+
186206
const getCostModulePayload = (): ClusterCostModuleConfigPayload | null => {
187207
if (!costModuleState.enabled) {
188208
return {
189209
enabled: false,
190210
}
191211
}
192212

193-
if (clusterProvider === 'GCP' && costModuleState.config.cloudProviderApiKey) {
213+
if (costModuleState.config) {
194214
return {
195215
enabled: true,
196-
config: {
197-
cloudProviderApiKey: costModuleState.config.cloudProviderApiKey,
198-
},
216+
config: getParsedConfigValue(),
199217
}
200218
}
201219

@@ -246,16 +264,16 @@ const ClusterForm = ({
246264
payload.server_url = urlValue
247265
}
248266

249-
if (clusterProvider === 'GCP' && costModuleState.enabled && !costModuleState.config.cloudProviderApiKey) {
250-
setCostModuleErrorState((prev) => ({
251-
...prev,
252-
cloudProviderApiKey: 'Cloud Provider API Key is required',
253-
}))
254-
ToastManager.showToast({
255-
variant: ToastVariantType.error,
256-
description: 'Please provide Cloud Provider API Key to enable cost tracking',
257-
})
258-
return
267+
if (costModuleState.enabled) {
268+
const costConfigError = validateCostModuleConfig()
269+
if (costConfigError) {
270+
setCostModuleErrorState(costConfigError)
271+
ToastManager.showToast({
272+
variant: ToastVariantType.error,
273+
description: 'Invalid cost visibility configuration',
274+
})
275+
return
276+
}
259277
}
260278

261279
if (remoteConnectionMethod === RemoteConnectionType.Proxy) {
@@ -470,18 +488,14 @@ const ClusterForm = ({
470488
}))
471489
}
472490

473-
const handleProviderAPIKeyChange = (apiKey: string) => {
491+
const handleCostConfigChange = (newConfig: string) => {
474492
setCostModuleState((prev) => ({
475493
...prev,
476-
config: {
477-
cloudProviderApiKey: apiKey,
478-
},
494+
config: newConfig,
479495
}))
480496

481-
setCostModuleErrorState((prev) => ({
482-
...prev,
483-
cloudProviderApiKey: apiKey ? '' : 'Cloud Provider API Key is required',
484-
}))
497+
const error = validateCostModuleConfig(newConfig)
498+
setCostModuleErrorState(error)
485499
}
486500

487501
const renderFooter = () => (
@@ -573,11 +587,10 @@ const ClusterForm = ({
573587
costModuleEnabled={costModuleState.enabled}
574588
toggleCostModule={toggleCostModule}
575589
installationStatus={costModuleConfig.installationStatus}
576-
installationError={costModuleConfig.installationError}
577590
clusterProvider={clusterProvider}
578-
handleProviderAPIKeyChange={handleProviderAPIKeyChange}
579-
providerAPIKey={costModuleState.config.cloudProviderApiKey || ''}
580-
providerAPIKeyError={costModuleErrorState.cloudProviderApiKey}
591+
handleCostConfigChange={handleCostConfigChange}
592+
config={costModuleState.config || ''}
593+
configError={costModuleConfigErrorState}
581594
/>
582595
</div>
583596
) : null
@@ -595,6 +608,10 @@ const ClusterForm = ({
595608
return <span className="cy-7 fs-12">Installing...</span>
596609
}
597610

611+
if (costModuleConfig.installationStatus === 'Upgrading') {
612+
return <span className="cy-7 fs-12">Upgrading...</span>
613+
}
614+
598615
if (costModuleConfig.installationStatus === 'Failed') {
599616
return (
600617
<div className="flexbox dc__gap-4 dc__align-items-center">

0 commit comments

Comments
 (0)