UNPKG

@grafana/ui

Version:
1 lines 6.72 kB
{"version":3,"file":"AutoSaveField.mjs","sources":["../../../../src/components/AutoSaveField/AutoSaveField.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { debounce } from 'lodash';\nimport { useCallback, useMemo, useRef } from 'react';\nimport * as React from 'react';\n\nimport { Trans } from '@grafana/i18n';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { Field, FieldProps } from '../Forms/Field';\nimport { InlineToast } from '../InlineToast/InlineToast';\n\nimport { EllipsisAnimated } from './EllipsisAnimated';\n\nconst SHOW_SUCCESS_DURATION = 2 * 1000;\n\nexport interface Props<T = string> extends Omit<FieldProps, 'children'> {\n /** Saving request that will be triggered 600ms after changing the value */\n onFinishChange: (inputValue: T) => Promise<void>;\n /** Custom error message to display on saving */\n saveErrorMessage?: string;\n /** Input that will save its value on change */\n children: (onChange: (newValue: T) => void) => React.ReactElement;\n}\nexport function AutoSaveField<T = string>(props: Props<T>) {\n const {\n invalid,\n loading,\n onFinishChange,\n saveErrorMessage = 'Error saving this value',\n error,\n children,\n disabled,\n ...restProps\n } = props;\n\n const [fieldState, setFieldState] = React.useState({\n isLoading: false,\n showSuccess: false,\n showError: invalid,\n });\n\n const fieldRef = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n let timeoutId: ReturnType<typeof setTimeout>;\n if (fieldState.showSuccess) {\n const time = fieldState.showError ? 0 : SHOW_SUCCESS_DURATION;\n timeoutId = setTimeout(() => {\n setFieldState({ ...fieldState, showSuccess: false });\n }, time);\n }\n\n return () => {\n window.clearTimeout(timeoutId);\n };\n }, [fieldState]);\n\n const handleChange = useCallback(\n (nextValue: T) => {\n if (invalid) {\n return;\n }\n setFieldState({ ...fieldState, isLoading: true, showSuccess: false });\n onFinishChange(nextValue)\n .then(() => {\n setFieldState({\n isLoading: false,\n showSuccess: true,\n showError: false,\n });\n })\n .catch(() => {\n setFieldState({\n ...fieldState,\n isLoading: false,\n showError: true,\n });\n });\n },\n [invalid, fieldState, onFinishChange]\n );\n\n const lodashDebounce = useMemo(() => debounce(handleChange, 600, { leading: false }), [handleChange]);\n //We never want to pass false to field, because it won't be deleted with deleteUndefinedProps() being false\n const isInvalid = invalid || fieldState.showError || undefined;\n /**\n * use Field around input to pass the error message\n * use InlineToast.tsx to show the save message\n */\n const styles = useStyles2(getStyles);\n\n return (\n <>\n <Field\n {...restProps}\n loading={loading || undefined}\n invalid={isInvalid}\n disabled={disabled}\n error={error || (fieldState.showError && saveErrorMessage)}\n ref={fieldRef}\n className={styles.widthFitContent}\n >\n {React.cloneElement(\n children((newValue) => {\n lodashDebounce(newValue);\n })\n )}\n </Field>\n {fieldState.isLoading && (\n <InlineToast referenceElement={fieldRef.current} placement=\"right\">\n <Trans i18nKey=\"grafana-ui.auto-save-field.saving\">\n Saving <EllipsisAnimated />\n </Trans>\n </InlineToast>\n )}\n {fieldState.showSuccess && (\n <InlineToast suffixIcon={'check'} referenceElement={fieldRef.current} placement=\"right\">\n <Trans i18nKey=\"grafana-ui.auto-save-field.saved\">Saved!</Trans>\n </InlineToast>\n )}\n </>\n );\n}\n\nAutoSaveField.displayName = 'AutoSaveField';\n\nconst getStyles = () => {\n return {\n widthFitContent: css({\n width: 'fit-content',\n }),\n };\n};\n"],"names":[],"mappings":"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"}