Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Commit

Permalink
finalize
Browse files Browse the repository at this point in the history
  • Loading branch information
DmytroHryshyn committed Jan 29, 2024
1 parent 1dfcd9b commit 2ef2a6c
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 73 deletions.
22 changes: 13 additions & 9 deletions intuita-webview/src/codemodList/CodemodArguments/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ type Props = Readonly<{
hashDigest: CodemodNodeHashDigest;
arguments: ReadonlyArray<CodemodArgumentWithValue>;
autocompleteItems: ReadonlyArray<string>;
rootPath: string | null;
executionPath: T.These<{ message: string }, string>;
}>;

const buildTargetPath = (path: string, rootPath: string) => {
return path.replace(rootPath, '');
const updatePath = (value: string, codemodHash: CodemodHash) => {
vscode.postMessage({
kind: 'webview.codemodList.updatePathToExecute',
value: {
newPath: value,
codemodHash,
errorMessage: '',
warningMessage: '',
revertToPrevExecutionIfInvalid: false,
},
});
};

const CodemodArguments = ({
hashDigest,
arguments: args,
autocompleteItems,
rootPath,
executionPath,
}: Props) => {
const onChangeFormField = (fieldName: string) => (value: string) => {
Expand All @@ -54,15 +61,12 @@ const CodemodArguments = ({
),
);

const targetPath =
rootPath !== null ? buildTargetPath(path, rootPath) : '/';

return (
<div className={styles.root}>
<form className={styles.form}>
<DirectorySelector
defaultValue={targetPath}
codemodHash={hashDigest as unknown as CodemodHash}
initialValue={path}
onChange={(value: string) => updatePath(value, hashDigest as unknown as CodemodHash )}
autocompleteItems={autocompleteItems}
/>
{args.map((props) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ type Props = Omit<CodemodItemNode, 'name' | 'kind'> &
progress: Progress | null;
screenWidth: number | null;
focused: boolean;
rootPath: string | null;
autocompleteItems: ReadonlyArray<string>;
argumentsExpanded: boolean;
}>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const getIndent = (depth: number) => {
type Deps = {
progress: Progress | null;
screenWidth: number | null;
rootPath: string | null;
autocompleteItems: ReadonlyArray<string>;
};

Expand Down Expand Up @@ -53,7 +52,7 @@ const renderProgressBar = (progress: Progress | null) => {
};

const getCodemodNodeRenderer =
({ rootPath, autocompleteItems, progress, screenWidth }: Deps) =>
({ autocompleteItems, progress, screenWidth }: Deps) =>
({ nodeDatum, onFlip }: Props) => {
const { node, focused, expanded, argumentsExpanded } = nodeDatum;
const { hashDigest, label } = node;
Expand Down Expand Up @@ -105,8 +104,6 @@ const getCodemodNodeRenderer =
screenWidth={screenWidth}
permalink={node.permalink}
executionPath={node.executionPath}
autocompleteItems={autocompleteItems}
rootPath={rootPath}
argumentsExpanded={argumentsExpanded}
args={node.args}
/>
Expand All @@ -122,7 +119,6 @@ const getCodemodNodeRenderer =
>
<CodemodArguments
autocompleteItems={autocompleteItems}
rootPath={rootPath}
executionPath={node.executionPath}
hashDigest={hashDigest}
arguments={node.args}
Expand Down
78 changes: 42 additions & 36 deletions intuita-webview/src/codemodList/components/DirectorySelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,51 @@ import {
VSCodeTextField,
} from '@vscode/webview-ui-toolkit/react';
import styles from './style.module.css';
import { vscode } from '../../shared/utilities/vscode';
import { CodemodHash } from '../../shared/types';
import cn from 'classnames';

const updatePath = (value: string, codemodHash: CodemodHash) => {
vscode.postMessage({
kind: 'webview.codemodList.updatePathToExecute',
value: {
newPath: value,
codemodHash,
errorMessage: '',
warningMessage: '',
revertToPrevExecutionIfInvalid: false,
},
});
};

type Props = {
defaultValue: string;
codemodHash: CodemodHash;
initialValue: string;
autocompleteItems: ReadonlyArray<string>;
onChange: (value: string) => void;
};

const AUTOCOMPLETE_OPTIONS_LENGTH = 20;

const getFilteredOptions = (allOptions: ReadonlyArray<string>, value: string) => {

// ignores slashes at the beginning, ignores whitespaces
const trimmedLowerCaseValue = value
.replace(/^[/\\]+/, '')
.trim()
.toLocaleLowerCase();

return allOptions
.filter((i) =>
i.toLocaleLowerCase().startsWith(trimmedLowerCaseValue),
)
.slice(0, AUTOCOMPLETE_OPTIONS_LENGTH);
}
export const DirectorySelector = ({
defaultValue,
codemodHash,
initialValue,
onChange,
autocompleteItems,
}: Props) => {
const [value, setValue] = useState(defaultValue);
const [focusedOptionIdx, setFocusedOptionIdx] = useState(0);
const [value, setValue] = useState(initialValue);
const [focusedOptionIdx, setFocusedOptionIdx] = useState<number | null>(null);
const [showOptions, setShowOptions] = useState(false);

console.log(defaultValue, '?');
useEffect(() => {
setValue(defaultValue);
}, [defaultValue]);
setValue(initialValue);
}, [initialValue]);

const autocompleteOptions = autocompleteItems
.filter((i) =>
i.toLocaleLowerCase().includes(value.trim().toLocaleLowerCase()),
)
.slice(0, 5);
const autocompleteOptions = getFilteredOptions(autocompleteItems, value);

const handleChange = (e: Event | React.FormEvent<HTMLElement>) => {
setValue((e.target as HTMLInputElement)?.value);
};

const handleFocus = () => {
setFocusedOptionIdx(-1);
setShowOptions(true);
};

Expand All @@ -64,26 +61,36 @@ export const DirectorySelector = ({
}

if (e.key === 'Enter') {
const nextValue = autocompleteOptions[focusedOptionIdx] ?? '';
setShowOptions(false);

if(focusedOptionIdx === null) {
return;
}

const nextValue = autocompleteOptions[focusedOptionIdx] ?? '';

onChange(nextValue);
setValue(nextValue);
updatePath(nextValue, codemodHash);
}

if (e.key === 'ArrowUp') {
setFocusedOptionIdx((focusedOptionIdx - 1 + maxLength) % maxLength);
const nextValue = focusedOptionIdx === null ? maxLength : (focusedOptionIdx - 1 + maxLength) % maxLength;
setFocusedOptionIdx(nextValue);
e.stopPropagation();
e.preventDefault();
}

if (e.key === 'ArrowDown') {
setFocusedOptionIdx((focusedOptionIdx + 1) % maxLength);
const nextValue = focusedOptionIdx === null ? 0 : (focusedOptionIdx + 1) % maxLength;

setFocusedOptionIdx(nextValue);
e.stopPropagation();
e.preventDefault();
}

if (e.key === 'Tab') {
setFocusedOptionIdx((focusedOptionIdx + 1) % maxLength);
const nextValue = focusedOptionIdx === null ? 0 : (focusedOptionIdx + 1) % maxLength;
setFocusedOptionIdx(nextValue);
e.stopPropagation();
e.preventDefault();
}
Expand Down Expand Up @@ -123,10 +130,9 @@ export const DirectorySelector = ({
id={`option_${i}`}
className={styles.option}
onClick={() => {
console.log(item);
setShowOptions(false);
setValue(item);
updatePath(item, codemodHash);
onChange(item);
}}
>
{item}
Expand Down
2 changes: 2 additions & 0 deletions intuita-webview/src/codemodList/components/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@
.autocompleteItems {
background-color: var(--vscode-editor-background);
padding: 4px;
max-height: 250px;
overflow-y: auto;
}
40 changes: 34 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2ef2a6c

Please sign in to comment.