refactor(web): remove typescript

This commit is contained in:
Ali BARIN
2024-02-27 15:23:23 +00:00
parent 636870a075
commit b3ae2d2748
337 changed files with 2067 additions and 4997 deletions

View File

@@ -1,17 +1,6 @@
import * as React from 'react';
import { Controller as RHFController, useFormContext } from 'react-hook-form';
interface ControllerProps {
defaultValue?: string;
name: string;
required?: boolean;
shouldUnregister?: boolean;
children: React.ReactElement;
}
function Controller(
props: ControllerProps
): React.ReactElement {
function Controller(props) {
const { control } = useFormContext();
const {
defaultValue = '',
@@ -20,7 +9,6 @@ function Controller(
shouldUnregister,
children,
} = props;
return (
<RHFController
rules={{ required }}
@@ -28,11 +16,8 @@ function Controller(
control={control}
defaultValue={defaultValue}
shouldUnregister={shouldUnregister ?? false}
render={({
field,
}) => React.cloneElement(children, { field })}
render={({ field }) => React.cloneElement(children, { field })}
/>
);
}
export default Controller;

View File

@@ -2,27 +2,11 @@ import Paper from '@mui/material/Paper';
import Popper from '@mui/material/Popper';
import Tab from '@mui/material/Tab';
import * as React from 'react';
import type { IFieldDropdownOption } from 'types';
import Suggestions from 'components/PowerInput/Suggestions';
import TabPanel from 'components/TabPanel';
import Options from './Options';
import { Tabs } from './style';
interface CustomOptionsProps {
open: boolean;
anchorEl: any;
data: any;
options: readonly IFieldDropdownOption[];
onSuggestionClick: any;
onOptionClick: (event: React.MouseEvent, option: any) => void;
onTabChange: (tabIndex: 0 | 1) => void;
label?: string;
initialTabIndex?: 0 | 1;
}
const CustomOptions = (props: CustomOptionsProps) => {
const CustomOptions = (props) => {
const {
open,
anchorEl,
@@ -34,24 +18,18 @@ const CustomOptions = (props: CustomOptionsProps) => {
label,
initialTabIndex,
} = props;
const [activeTabIndex, setActiveTabIndex] = React.useState<
number | undefined
>(undefined);
const [activeTabIndex, setActiveTabIndex] = React.useState(undefined);
React.useEffect(
function applyInitialActiveTabIndex() {
setActiveTabIndex((currentActiveTabIndex) => {
if (currentActiveTabIndex === undefined) {
return initialTabIndex;
}
return currentActiveTabIndex;
});
},
[initialTabIndex]
[initialTabIndex],
);
return (
<Popper
open={open}
@@ -91,5 +69,4 @@ const CustomOptions = (props: CustomOptionsProps) => {
</Popper>
);
};
export default CustomOptions;

View File

@@ -1,35 +1,23 @@
import type { IFieldDropdownOption } from 'types';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import throttle from 'lodash/throttle';
import * as React from 'react';
import { FixedSizeList, ListChildComponentProps } from 'react-window';
import { FixedSizeList } from 'react-window';
import { Typography } from '@mui/material';
import SearchInput from 'components/SearchInput';
import useFormatMessage from 'hooks/useFormatMessage';
import { SearchInputWrapper } from './style';
interface OptionsProps {
data: readonly IFieldDropdownOption[];
onOptionClick: (event: React.MouseEvent, option: any) => void;
}
const SHORT_LIST_LENGTH = 4;
const LIST_ITEM_HEIGHT = 64;
const computeListHeight = (currentLength: number) => {
const computeListHeight = (currentLength) => {
const numberOfRenderedItems = Math.min(SHORT_LIST_LENGTH, currentLength);
return LIST_ITEM_HEIGHT * numberOfRenderedItems;
};
const renderItemFactory =
({ onOptionClick }: Pick<OptionsProps, 'onOptionClick'>) =>
(props: ListChildComponentProps) => {
({ onOptionClick }) =>
(props) => {
const { index, style, data } = props;
const suboption = data[index];
return (
<ListItemButton
sx={{ pl: 4 }}
@@ -56,55 +44,45 @@ const renderItemFactory =
</ListItemButton>
);
};
const Options = (props: OptionsProps) => {
const Options = (props) => {
const formatMessage = useFormatMessage();
const { data, onOptionClick } = props;
const [filteredData, setFilteredData] =
React.useState<readonly IFieldDropdownOption[]>(data);
const [filteredData, setFilteredData] = React.useState(data);
React.useEffect(
function syncOptions() {
setFilteredData((filteredData) => {
if (filteredData.length === 0 && filteredData.length !== data.length) {
return data;
}
return filteredData;
});
},
[data]
[data],
);
const renderItem = React.useMemo(
() =>
renderItemFactory({
onOptionClick,
}),
[onOptionClick]
[onOptionClick],
);
const onSearchChange = React.useMemo(
() =>
throttle((event: React.ChangeEvent) => {
const search = (event.target as HTMLInputElement).value.toLowerCase();
throttle((event) => {
const search = event.target.value.toLowerCase();
if (!search) {
setFilteredData(data);
return;
}
const newFilteredData = data.filter((option) =>
`${option.label}\n${option.value}`
.toLowerCase()
.includes(search.toLowerCase())
.includes(search.toLowerCase()),
);
setFilteredData(newFilteredData);
}, 400),
[data]
[data],
);
return (
<>
<SearchInputWrapper>
@@ -130,5 +108,4 @@ const Options = (props: OptionsProps) => {
</>
);
};
export default Options;

View File

@@ -2,20 +2,15 @@ import * as React from 'react';
import { useController, useFormContext } from 'react-hook-form';
import { IconButton } from '@mui/material';
import FormHelperText from '@mui/material/FormHelperText';
import { AutocompleteProps } from '@mui/material/Autocomplete';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import ClearIcon from '@mui/icons-material/Clear';
import type { IFieldDropdownOption } from 'types';
import { ActionButtonsWrapper } from './style';
import ClickAwayListener from '@mui/base/ClickAwayListener';
import InputLabel from '@mui/material/InputLabel';
import { createEditor } from 'slate';
import { Editable, ReactEditor } from 'slate-react';
import Slate from 'components/Slate';
import Element from 'components/Slate/Element';
import {
serialize,
deserialize,
@@ -30,32 +25,10 @@ import {
InputLabelWrapper,
ChildrenWrapper,
} from 'components/PowerInput/style';
import { VariableElement } from 'components/Slate/types';
import CustomOptions from './CustomOptions';
import { processStepWithExecutions } from 'components/PowerInput/data';
import { StepExecutionsContext } from 'contexts/StepExecutions';
interface ControlledCustomAutocompleteProps
extends AutocompleteProps<IFieldDropdownOption, boolean, boolean, boolean> {
showOptionValue?: boolean;
dependsOn?: string[];
defaultValue?: string;
name: string;
label?: string;
type?: string;
required?: boolean;
readOnly?: boolean;
description?: string;
docUrl?: string;
clickToCopy?: boolean;
disabled?: boolean;
shouldUnregister?: boolean;
}
function ControlledCustomAutocomplete(
props: ControlledCustomAutocompleteProps
): React.ReactElement {
function ControlledCustomAutocomplete(props) {
const {
defaultValue = '',
name,
@@ -83,63 +56,48 @@ function ControlledCustomAutocomplete(
} = field;
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
const [isInitialValueSet, setInitialValue] = React.useState(false);
const [isSingleChoice, setSingleChoice] = React.useState<boolean | undefined>(
undefined
);
const [isSingleChoice, setSingleChoice] = React.useState(undefined);
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
const editorRef = React.useRef<HTMLDivElement | null>(null);
const editorRef = React.useRef(null);
const renderElement = React.useCallback(
(props) => <Element {...props} disabled={disabled} />,
[disabled]
[disabled],
);
const [editor] = React.useState(() => customizeEditor(createEditor()));
const [showVariableSuggestions, setShowVariableSuggestions] =
React.useState(false);
let dependsOnValues: unknown[] = [];
let dependsOnValues = [];
if (dependsOn?.length) {
dependsOnValues = watch(dependsOn);
}
React.useEffect(() => {
const ref = ReactEditor.toDOMNode(editor, editor);
resizeObserver.observe(ref);
return () => resizeObserver.unobserve(ref);
}, []);
const promoteValue = () => {
const serializedValue = serialize(editor.children);
controllerOnChange(serializedValue);
};
const resizeObserver = React.useMemo(function syncCustomOptionsPosition() {
return new ResizeObserver(() => {
forceUpdate();
});
}, []);
React.useEffect(() => {
const hasDependencies = dependsOnValues.length;
if (hasDependencies) {
// Reset the field when a dependent has been updated
resetEditor(editor);
}
}, dependsOnValues);
React.useEffect(
function updateInitialValue() {
const hasOptions = options.length;
const isOptionsLoaded = loading === false;
if (!isInitialValueSet && hasOptions && isOptionsLoaded) {
setInitialValue(true);
const option: IFieldDropdownOption | undefined = options.find(
(option) => option.value === value
);
const option = options.find((option) => option.value === value);
if (option) {
overrideEditorValue(editor, { option, focus: false });
setSingleChoice(true);
@@ -148,70 +106,56 @@ function ControlledCustomAutocomplete(
}
}
},
[isInitialValueSet, options, loading]
[isInitialValueSet, options, loading],
);
React.useEffect(() => {
if (!showVariableSuggestions && value !== serialize(editor.children)) {
promoteValue();
}
}, [showVariableSuggestions]);
const hideSuggestionsOnShift = (
event: React.KeyboardEvent<HTMLInputElement>
) => {
const hideSuggestionsOnShift = (event) => {
if (event.code === 'Tab') {
setShowVariableSuggestions(false);
}
};
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
const handleKeyDown = (event) => {
hideSuggestionsOnShift(event);
if (event.code === 'Tab') {
promoteValue();
}
if (isSingleChoice && event.code !== 'Tab') {
event.preventDefault();
}
};
const stepsWithVariables = React.useMemo(() => {
return processStepWithExecutions(priorStepsWithExecutions);
}, [priorStepsWithExecutions]);
const handleVariableSuggestionClick = React.useCallback(
(variable: Pick<VariableElement, 'name' | 'value'>) => {
(variable) => {
insertVariable(editor, variable, stepsWithVariables);
},
[stepsWithVariables]
[stepsWithVariables],
);
const handleOptionClick = React.useCallback(
(event: React.MouseEvent, option: IFieldDropdownOption) => {
(event, option) => {
event.stopPropagation();
overrideEditorValue(editor, { option, focus: false });
setShowVariableSuggestions(false);
setSingleChoice(true);
},
[stepsWithVariables]
[stepsWithVariables],
);
const handleClearButtonClick = (event: React.MouseEvent) => {
const handleClearButtonClick = (event) => {
event.stopPropagation();
resetEditor(editor);
promoteValue();
setSingleChoice(undefined);
};
const reset = (tabIndex: 0 | 1) => {
const reset = (tabIndex) => {
const isOptions = tabIndex === 0;
setSingleChoice(isOptions);
resetEditor(editor, { focus: true });
};
return (
<Slate
editor={editor}
@@ -313,5 +257,4 @@ function ControlledCustomAutocomplete(
</Slate>
);
}
export default ControlledCustomAutocomplete;

View File

@@ -1,18 +1,15 @@
import { styled } from '@mui/material/styles';
import Stack from '@mui/material/Stack';
import MuiTabs from '@mui/material/Tabs';
export const ActionButtonsWrapper = styled(Stack)`
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
`;
export const Tabs = styled(MuiTabs)`
border-bottom: 1px solid ${({ theme }) => theme.palette.divider};
`;
export const SearchInputWrapper = styled('div')`
padding: ${({ theme }) => theme.spacing(0, 2, 2, 2)};
`;