You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.5 KiB
97 lines
2.5 KiB
import React, { useState, useContext } from 'react'; |
|
import { Switch } from 'antd'; |
|
import { FormItemProps } from 'antd/es/form'; |
|
|
|
import { RESET_TIMEOUT, SUCCESS_STATES, postConfigUpdateToAPI } from './constants'; |
|
|
|
import { ServerStatusContext } from '../../../utils/server-status-context'; |
|
import InfoTip from '../info-tip'; |
|
|
|
interface ToggleSwitchProps { |
|
apiPath: string; |
|
fieldName: string; |
|
|
|
checked?: boolean; |
|
configPath?: string; |
|
disabled?: boolean; |
|
label?: string; |
|
tip?: string; |
|
} |
|
|
|
export default function ToggleSwitch(props: ToggleSwitchProps) { |
|
const [submitStatus, setSubmitStatus] = useState<FormItemProps['validateStatus']>(''); |
|
const [submitStatusMessage, setSubmitStatusMessage] = useState(''); |
|
|
|
let resetTimer = null; |
|
|
|
const serverStatusData = useContext(ServerStatusContext); |
|
const { setFieldInConfigState } = serverStatusData || {}; |
|
|
|
const { |
|
apiPath, |
|
checked, |
|
configPath = '', |
|
disabled = false, |
|
fieldName, |
|
label, |
|
tip, |
|
} = props; |
|
|
|
const resetStates = () => { |
|
setSubmitStatus(''); |
|
clearTimeout(resetTimer); |
|
resetTimer = null; |
|
} |
|
|
|
const handleChange = async (isChecked: boolean) => { |
|
setSubmitStatus('validating'); |
|
await postConfigUpdateToAPI({ |
|
apiPath, |
|
data: { value: isChecked }, |
|
onSuccess: () => { |
|
setFieldInConfigState({ fieldName, value: isChecked, path: configPath }); |
|
setSubmitStatus('success'); |
|
}, |
|
onError: (message: string) => { |
|
setSubmitStatus('error'); |
|
setSubmitStatusMessage(`There was an error: ${message}`); |
|
}, |
|
}); |
|
resetTimer = setTimeout(resetStates, RESET_TIMEOUT); |
|
} |
|
|
|
const { |
|
icon: newStatusIcon = null, |
|
message: newStatusMessage = '', |
|
} = SUCCESS_STATES[submitStatus] || {}; |
|
|
|
return ( |
|
<div className="toggleswitch-container"> |
|
<div className="toggleswitch"> |
|
<Switch |
|
className={`switch field-${fieldName}`} |
|
loading={submitStatus === 'validating'} |
|
onChange={handleChange} |
|
defaultChecked={checked} |
|
checked={checked} |
|
checkedChildren="ON" |
|
unCheckedChildren="OFF" |
|
disabled={disabled} |
|
/> |
|
<span className="label">{label} <InfoTip tip={tip} /></span> |
|
{submitStatus} |
|
</div> |
|
<div className={`status-message ${submitStatus || ''}`}> |
|
{newStatusIcon} {newStatusMessage} {submitStatusMessage} |
|
</div> |
|
</div> |
|
); |
|
} |
|
|
|
ToggleSwitch.defaultProps = { |
|
checked: false, |
|
configPath: '', |
|
disabled: false, |
|
label: '', |
|
tip: '', |
|
};
|
|
|