import { CloseCircleFilled, ExclamationCircleOutlined, } from '@ant-design/icons'; import { useMachine } from '@xstate/react'; import { Button, Input, message, Modal } from 'antd'; import { map } from 'lodash-es'; import React, { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import { Labels } from 'types/api/alerts/def'; import AppReducer from 'types/reducer/app'; import { v4 as uuid } from 'uuid'; import { ResourceAttributesFilterMachine } from './Labels.machine'; import QueryChip from './QueryChip'; import { QueryChipItem, SearchContainer } from './styles'; import { ILabelRecord } from './types'; import { createQuery, flattenLabels, prepareLabels } from './utils'; interface LabelSelectProps { onSetLabels: (q: Labels) => void; initialValues: Labels | undefined; } function LabelSelect({ onSetLabels, initialValues, }: LabelSelectProps): JSX.Element | null { const { t } = useTranslation('alerts'); const { isDarkMode } = useSelector((state) => state.app); const [currentVal, setCurrentVal] = useState(''); const [staging, setStaging] = useState([]); const [queries, setQueries] = useState( initialValues ? flattenLabels(initialValues) : [], ); const dispatchChanges = (updatedRecs: ILabelRecord[]): void => { onSetLabels(prepareLabels(updatedRecs, initialValues)); setQueries(updatedRecs); }; const [state, send] = useMachine(ResourceAttributesFilterMachine, { actions: { onSelectLabelKey: () => {}, onSelectLabelValue: () => { if (currentVal !== '') { setStaging((prevState) => [...prevState, currentVal]); } else { return; } setCurrentVal(''); }, onValidateQuery: (): void => { if (currentVal === '') { return; } const generatedQuery = createQuery([...staging, currentVal]); if (generatedQuery) { dispatchChanges([...queries, generatedQuery]); setStaging([]); setCurrentVal(''); send('RESET'); } }, }, }); const handleFocus = (): void => { if (state.value === 'Idle') { send('NEXT'); } }; const handleBlur = useCallback((): void => { if (staging.length === 1 && staging[0] !== undefined) { send('onBlur'); } }, [send, staging]); useEffect(() => { handleBlur(); }, [handleBlur]); const handleChange = (e: React.ChangeEvent): void => { setCurrentVal(e.target?.value); }; const handleClose = (key: string): void => { dispatchChanges(queries.filter((queryData) => queryData.key !== key)); }; const handleClearAll = (): void => { Modal.confirm({ title: 'Confirm', icon: , content: t('remove_label_confirm'), onOk() { send('RESET'); dispatchChanges([]); setStaging([]); message.success(t('remove_label_success')); }, okText: t('button_yes'), cancelText: t('button_no'), }); }; const renderPlaceholder = useCallback((): string => { if (state.value === 'LabelKey') return 'Enter a label key then press ENTER.'; if (state.value === 'LabelValue') return `Enter a value for label key(${staging[0]}) then press ENTER.`; return t('placeholder_label_key_pair'); }, [t, state, staging]); return (
{queries.length > 0 && map( queries, (query): JSX.Element => { return ( ); }, )}
{map(staging, (item) => { return {item}; })}
{ if (e.key === 'Enter' || e.code === 'Enter') { send('NEXT'); } }} bordered={false} value={currentVal as never} style={{ flex: 1 }} onFocus={handleFocus} onBlur={handleBlur} /> {queries.length || staging.length || currentVal ? (
); } export default LabelSelect;