style: auto format whole project
This commit is contained in:
@@ -6,12 +6,7 @@ import InputLabel from '@mui/material/InputLabel';
|
||||
import FormHelperText from '@mui/material/FormHelperText';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { Editor, Transforms, Range, createEditor } from 'slate';
|
||||
import {
|
||||
Slate,
|
||||
Editable,
|
||||
useSelected,
|
||||
useFocused,
|
||||
} from 'slate-react';
|
||||
import { Slate, Editable, useSelected, useFocused } from 'slate-react';
|
||||
|
||||
import {
|
||||
serialize,
|
||||
@@ -39,7 +34,7 @@ type PowerInputProps = {
|
||||
docUrl?: string;
|
||||
clickToCopy?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
const PowerInput = (props: PowerInputProps) => {
|
||||
const { control } = useFormContext();
|
||||
@@ -54,21 +49,28 @@ const PowerInput = (props: PowerInputProps) => {
|
||||
} = props;
|
||||
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
|
||||
const editorRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const renderElement = React.useCallback(props => <Element {...props} />, []);
|
||||
const renderElement = React.useCallback(
|
||||
(props) => <Element {...props} />,
|
||||
[]
|
||||
);
|
||||
const [editor] = React.useState(() => customizeEditor(createEditor()));
|
||||
const [showVariableSuggestions, setShowVariableSuggestions] = React.useState(false);
|
||||
const [showVariableSuggestions, setShowVariableSuggestions] =
|
||||
React.useState(false);
|
||||
|
||||
const stepsWithVariables = React.useMemo(() => {
|
||||
return processStepWithExecutions(priorStepsWithExecutions);
|
||||
}, [priorStepsWithExecutions])
|
||||
}, [priorStepsWithExecutions]);
|
||||
|
||||
const handleBlur = React.useCallback((value) => {
|
||||
onBlur?.(value);
|
||||
}, [onBlur]);
|
||||
const handleBlur = React.useCallback(
|
||||
(value) => {
|
||||
onBlur?.(value);
|
||||
},
|
||||
[onBlur]
|
||||
);
|
||||
|
||||
const handleVariableSuggestionClick = React.useCallback(
|
||||
(variable: Pick<VariableElement, "name" | "value">) => {
|
||||
insertVariable(editor, variable, stepsWithVariables);
|
||||
(variable: Pick<VariableElement, 'name' | 'value'>) => {
|
||||
insertVariable(editor, variable, stepsWithVariables);
|
||||
},
|
||||
[stepsWithVariables]
|
||||
);
|
||||
@@ -80,17 +82,25 @@ const PowerInput = (props: PowerInputProps) => {
|
||||
control={control}
|
||||
defaultValue={defaultValue}
|
||||
shouldUnregister={false}
|
||||
render={({ field: { value, onChange: controllerOnChange, onBlur: controllerOnBlur, } }) => (
|
||||
render={({
|
||||
field: {
|
||||
value,
|
||||
onChange: controllerOnChange,
|
||||
onBlur: controllerOnBlur,
|
||||
},
|
||||
}) => (
|
||||
<Slate
|
||||
editor={editor}
|
||||
value={deserialize(value, stepsWithVariables)}
|
||||
onChange={value => {
|
||||
onChange={(value) => {
|
||||
controllerOnChange(serialize(value));
|
||||
}}
|
||||
>
|
||||
<ClickAwayListener
|
||||
mouseEvent="onMouseDown"
|
||||
onClickAway={() => { setShowVariableSuggestions(false); }}
|
||||
onClickAway={() => {
|
||||
setShowVariableSuggestions(false);
|
||||
}}
|
||||
>
|
||||
{/* ref-able single child for ClickAwayListener */}
|
||||
<div style={{ width: '100%' }} data-test="power-input">
|
||||
@@ -100,7 +110,7 @@ const PowerInput = (props: PowerInputProps) => {
|
||||
shrink={true}
|
||||
disabled={disabled}
|
||||
variant="outlined"
|
||||
sx={{ bgcolor: 'white', display: 'inline-block', px: .75 }}
|
||||
sx={{ bgcolor: 'white', display: 'inline-block', px: 0.75 }}
|
||||
>
|
||||
{label}
|
||||
</InputLabel>
|
||||
@@ -113,17 +123,16 @@ const PowerInput = (props: PowerInputProps) => {
|
||||
onFocus={() => {
|
||||
setShowVariableSuggestions(true);
|
||||
}}
|
||||
onBlur={() => { controllerOnBlur(); handleBlur(value); }}
|
||||
onBlur={() => {
|
||||
controllerOnBlur();
|
||||
handleBlur(value);
|
||||
}}
|
||||
/>
|
||||
</FakeInput>
|
||||
{/* ghost placer for the variables popover */}
|
||||
<div ref={editorRef} style={{ width: '100%' }} />
|
||||
|
||||
<FormHelperText
|
||||
variant="outlined"
|
||||
>
|
||||
{description}
|
||||
</FormHelperText>
|
||||
<FormHelperText variant="outlined">{description}</FormHelperText>
|
||||
|
||||
<SuggestionsPopper
|
||||
open={showVariableSuggestions}
|
||||
@@ -136,36 +145,28 @@ const PowerInput = (props: PowerInputProps) => {
|
||||
</Slate>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const SuggestionsPopper = (props: any) => {
|
||||
const {
|
||||
open,
|
||||
anchorEl,
|
||||
data,
|
||||
onSuggestionClick,
|
||||
} = props;
|
||||
const { open, anchorEl, data, onSuggestionClick } = props;
|
||||
|
||||
return (
|
||||
<Popper
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
style={{ width: anchorEl?.clientWidth, zIndex: 1, }}
|
||||
style={{ width: anchorEl?.clientWidth, zIndex: 1 }}
|
||||
modifiers={[
|
||||
{
|
||||
name: 'flip',
|
||||
enabled: false,
|
||||
options: {
|
||||
altBoundary: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Suggestions
|
||||
data={data}
|
||||
onSuggestionClick={onSuggestionClick}
|
||||
/>
|
||||
<Suggestions data={data} onSuggestionClick={onSuggestionClick} />
|
||||
</Popper>
|
||||
);
|
||||
};
|
||||
@@ -178,9 +179,9 @@ const Element = (props: any) => {
|
||||
default:
|
||||
return <p {...attributes}>{children}</p>;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Variable = ({ attributes, children, element }: any) => {
|
||||
const Variable = ({ attributes, children, element }: any) => {
|
||||
const selected = useSelected();
|
||||
const focused = useFocused();
|
||||
const label = (
|
||||
@@ -200,7 +201,7 @@ const Variable = ({ attributes, children, element }: any) => {
|
||||
size="small"
|
||||
label={label}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default PowerInput;
|
||||
|
@@ -7,17 +7,21 @@ export const InputLabelWrapper = styled('div')`
|
||||
left: -6px;
|
||||
`;
|
||||
|
||||
export const FakeInput = styled('div', { shouldForwardProp: prop => prop !== 'disabled'})<{ disabled?: boolean }>`
|
||||
export const FakeInput = styled('div', {
|
||||
shouldForwardProp: (prop) => prop !== 'disabled',
|
||||
})<{ disabled?: boolean }>`
|
||||
border: 1px solid #eee;
|
||||
min-height: 52px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: ${({ theme }) => theme.spacing(0, 1.75)};
|
||||
border-radius: ${({ theme }) => theme.spacing(.5)};
|
||||
border-radius: ${({ theme }) => theme.spacing(0.5)};
|
||||
border-color: rgba(0, 0, 0, 0.23);
|
||||
position: relative;
|
||||
|
||||
${({ disabled, theme }) => !!disabled && `
|
||||
${({ disabled, theme }) =>
|
||||
!!disabled &&
|
||||
`
|
||||
color: ${theme.palette.action.disabled},
|
||||
border-color: ${theme.palette.action.disabled},
|
||||
`}
|
||||
|
@@ -6,7 +6,7 @@ export type VariableElement = {
|
||||
value?: unknown;
|
||||
name?: string;
|
||||
children: Text[];
|
||||
}
|
||||
};
|
||||
|
||||
export type ParagraphElement = {
|
||||
type: 'paragraph';
|
||||
|
@@ -2,13 +2,12 @@ import { Text, Descendant, Transforms } from 'slate';
|
||||
import { withHistory } from 'slate-history';
|
||||
import { withReact } from 'slate-react';
|
||||
|
||||
import type {
|
||||
CustomEditor,
|
||||
CustomElement,
|
||||
VariableElement,
|
||||
} from './types';
|
||||
import type { CustomEditor, CustomElement, VariableElement } from './types';
|
||||
|
||||
function getStepPosition(id: string, stepsWithVariables: Record<string, unknown>[]) {
|
||||
function getStepPosition(
|
||||
id: string,
|
||||
stepsWithVariables: Record<string, unknown>[]
|
||||
) {
|
||||
const stepIndex = stepsWithVariables.findIndex((stepWithVariables) => {
|
||||
return stepWithVariables.id === id;
|
||||
});
|
||||
@@ -16,30 +15,42 @@ function getStepPosition(id: string, stepsWithVariables: Record<string, unknown>
|
||||
return stepIndex + 1;
|
||||
}
|
||||
|
||||
function humanizeVariableName(variableName: string, stepsWithVariables: Record<string, unknown>[]) {
|
||||
function humanizeVariableName(
|
||||
variableName: string,
|
||||
stepsWithVariables: Record<string, unknown>[]
|
||||
) {
|
||||
const nameWithoutCurlies = variableName.replace(/{{|}}/g, '');
|
||||
const stepId = nameWithoutCurlies.match(stepIdRegExp)?.[1] || '';
|
||||
const stepPosition = getStepPosition(stepId, stepsWithVariables);
|
||||
const humanizedVariableName = nameWithoutCurlies.replace(`step.${stepId}.`, `step${stepPosition}.`);
|
||||
const humanizedVariableName = nameWithoutCurlies.replace(
|
||||
`step.${stepId}.`,
|
||||
`step${stepPosition}.`
|
||||
);
|
||||
|
||||
return humanizedVariableName;
|
||||
}
|
||||
|
||||
const variableRegExp = /({{.*?}})/;
|
||||
const stepIdRegExp = /^step.([\da-zA-Z-]*)/;
|
||||
export const deserialize = (value: string, stepsWithVariables: any[]): Descendant[] => {
|
||||
if (!value) return [{
|
||||
type: 'paragraph',
|
||||
children: [{ text: '', }],
|
||||
}];
|
||||
export const deserialize = (
|
||||
value: string,
|
||||
stepsWithVariables: any[]
|
||||
): Descendant[] => {
|
||||
if (!value)
|
||||
return [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [{ text: '' }],
|
||||
},
|
||||
];
|
||||
|
||||
return value.split('\n').map(line => {
|
||||
return value.split('\n').map((line) => {
|
||||
const nodes = line.split(variableRegExp);
|
||||
|
||||
if (nodes.length > 1) {
|
||||
return {
|
||||
type: 'paragraph',
|
||||
children: nodes.map(node => {
|
||||
children: nodes.map((node) => {
|
||||
if (node.match(variableRegExp)) {
|
||||
return {
|
||||
type: 'variable',
|
||||
@@ -52,19 +63,19 @@ export const deserialize = (value: string, stepsWithVariables: any[]): Descendan
|
||||
return {
|
||||
text: node,
|
||||
};
|
||||
})
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'paragraph',
|
||||
children: [{ text: line }],
|
||||
}
|
||||
})
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const serialize = (value: Descendant[]): string => {
|
||||
return value.map(node => serializeNode(node)).join('\n');
|
||||
return value.map((node) => serializeNode(node)).join('\n');
|
||||
};
|
||||
|
||||
const serializeNode = (node: CustomElement | Descendant): string => {
|
||||
@@ -76,7 +87,7 @@ const serializeNode = (node: CustomElement | Descendant): string => {
|
||||
return node.value as string;
|
||||
}
|
||||
|
||||
return node.children.map(n => serializeNode(n)).join('');
|
||||
return node.children.map((n) => serializeNode(n)).join('');
|
||||
};
|
||||
|
||||
export const withVariables = (editor: CustomEditor) => {
|
||||
@@ -84,16 +95,20 @@ export const withVariables = (editor: CustomEditor) => {
|
||||
|
||||
editor.isInline = (element: CustomElement) => {
|
||||
return element.type === 'variable' ? true : isInline(element);
|
||||
}
|
||||
};
|
||||
|
||||
editor.isVoid = (element: CustomElement) => {
|
||||
return element.type === 'variable' ? true : isVoid(element);
|
||||
}
|
||||
};
|
||||
|
||||
return editor;
|
||||
}
|
||||
};
|
||||
|
||||
export const insertVariable = (editor: CustomEditor, variableData: Pick<VariableElement, "name" | "value">, stepsWithVariables: Record<string, unknown>[]) => {
|
||||
export const insertVariable = (
|
||||
editor: CustomEditor,
|
||||
variableData: Pick<VariableElement, 'name' | 'value'>,
|
||||
stepsWithVariables: Record<string, unknown>[]
|
||||
) => {
|
||||
const variable: VariableElement = {
|
||||
type: 'variable',
|
||||
name: humanizeVariableName(variableData.name as string, stepsWithVariables),
|
||||
@@ -103,7 +118,7 @@ export const insertVariable = (editor: CustomEditor, variableData: Pick<Variable
|
||||
|
||||
Transforms.insertNodes(editor, variable);
|
||||
Transforms.move(editor);
|
||||
}
|
||||
};
|
||||
|
||||
export const customizeEditor = (editor: CustomEditor): CustomEditor => {
|
||||
return withVariables(withReact(withHistory(editor)));
|
||||
|
Reference in New Issue
Block a user