From 2d3d96e5b55a225eb97251850909eb7a0a7242ed Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Sun, 20 Aug 2023 20:21:33 -0700 Subject: feat: :sparkles: delete context groups --- extension/react-app/src/components/ComboBox.tsx | 109 ++------------------ extension/react-app/src/components/TextDialog.tsx | 13 +++ .../components/dialogs/AddContextGroupDialog.tsx | 50 ++++++++++ .../dialogs/SelectContextGroupDialog.tsx | 111 +++++++++++++++++++++ .../src/hooks/AbstractContinueGUIClientProtocol.ts | 2 + .../src/hooks/ContinueGUIClientProtocol.ts | 4 + 6 files changed, 186 insertions(+), 103 deletions(-) create mode 100644 extension/react-app/src/components/dialogs/AddContextGroupDialog.tsx create mode 100644 extension/react-app/src/components/dialogs/SelectContextGroupDialog.tsx (limited to 'extension/react-app') diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index c407a779..31cb4371 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -7,8 +7,6 @@ import React, { import { useCombobox } from "downshift"; import styled from "styled-components"; import { - Button, - TextInput, defaultBorderRadius, lightGray, secondaryDark, @@ -33,44 +31,14 @@ import { } from "../redux/slices/uiStateSlice"; import { useDispatch, useSelector } from "react-redux"; import { RootStore } from "../redux/store"; +import SelectContextGroupDialog from "./dialogs/SelectContextGroupDialog"; +import AddContextGroupDialog from "./dialogs/AddContextGroupDialog"; const SEARCH_INDEX_NAME = "continue_context_items"; // #region styled components const mainInputFontSize = 13; -const MiniPillSpan = styled.span` - padding: 3px; - padding-left: 6px; - padding-right: 6px; - border-radius: ${defaultBorderRadius}; - color: ${vscForeground}; - background-color: #fff3; - overflow: hidden; - font-size: 12px; - display: flex; - align-items: center; - text-align: center; - justify-content: center; -`; - -const ContextGroupSelectDiv = styled.div` - display: flex; - align-items: center; - gap: 8px; - padding: 8px; - border-radius: ${defaultBorderRadius}; - background-color: ${secondaryDark}; - color: ${vscForeground}; - margin-top: 8px; - cursor: pointer; - - &:hover { - background-color: ${vscBackground}; - color: ${vscForeground}; - } -`; - const EmptyPillDiv = styled.div` padding: 4px; padding-left: 8px; @@ -374,81 +342,16 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { }, [inputRef.current]); const showSelectContextGroupDialog = () => { - dispatch( - setDialogMessage( -
-

Saved Context Groups

- - {savedContextGroups && Object.keys(savedContextGroups).length > 0 ? ( -
- {Object.keys(savedContextGroups).map((key: string) => { - const contextGroup = savedContextGroups[key]; - return ( - { - dispatch(setDialogMessage(undefined)); - dispatch(setShowDialog(false)); - client?.selectContextGroup(key); - }} - > - {key}: - - {contextGroup.map((contextItem) => { - return ( - - {contextItem.description.name} - - ); - })} - - ); - })} -
- ) : ( -
No saved context groups
- )} - -
- ) - ); + dispatch(setDialogMessage()); dispatch(setShowDialog(true)); }; const showDialogToSaveContextGroup = () => { - let inputElement: HTMLInputElement | null = null; dispatch( setDialogMessage( -
- { - inputElement = input; - }} - /> -
- -
+ ) ); dispatch(setShowDialog(true)); diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx index 7fcc41f1..44d25ae6 100644 --- a/extension/react-app/src/components/TextDialog.tsx +++ b/extension/react-app/src/components/TextDialog.tsx @@ -58,6 +58,19 @@ const TextDialog = (props: { onClose: () => void; message?: string | JSX.Element; }) => { + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + props.onClose(); + } + }; + + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("keydown", handleKeyDown); + }; + }, [props]); + return ( { diff --git a/extension/react-app/src/components/dialogs/AddContextGroupDialog.tsx b/extension/react-app/src/components/dialogs/AddContextGroupDialog.tsx new file mode 100644 index 00000000..f6c7c626 --- /dev/null +++ b/extension/react-app/src/components/dialogs/AddContextGroupDialog.tsx @@ -0,0 +1,50 @@ +import { useContext } from "react"; +import { Button, TextInput } from ".."; +import { GUIClientContext } from "../../App"; +import { useDispatch } from "react-redux"; +import { + setDialogMessage, + setShowDialog, +} from "../../redux/slices/uiStateSlice"; +import { ContextItem } from "../../../../schema/FullState"; + +function AddContextGroupDialog({ + selectedContextItems, +}: { + selectedContextItems: ContextItem[]; +}) { + const dispatch = useDispatch(); + const client = useContext(GUIClientContext); + + let inputElement: HTMLInputElement | null = null; + + const handleCreate = () => { + dispatch(setDialogMessage(undefined)); + dispatch(setShowDialog(false)); + const title = inputElement ? inputElement.value : "My Context Group"; + client?.saveContextGroup(title, selectedContextItems); + }; + + return ( +
+ { + inputElement = input; + }} + onKeyDown={(e) => { + if (e.key === "Enter") { + handleCreate(); + } + }} + /> +
+ +
+ ); +} + +export default AddContextGroupDialog; diff --git a/extension/react-app/src/components/dialogs/SelectContextGroupDialog.tsx b/extension/react-app/src/components/dialogs/SelectContextGroupDialog.tsx new file mode 100644 index 00000000..b8fc2bb7 --- /dev/null +++ b/extension/react-app/src/components/dialogs/SelectContextGroupDialog.tsx @@ -0,0 +1,111 @@ +import { useDispatch, useSelector } from "react-redux"; +import { RootStore } from "../../redux/store"; +import { useContext } from "react"; +import { GUIClientContext } from "../../App"; +import { TrashIcon } from "@heroicons/react/24/outline"; +import HeaderButtonWithText from "../HeaderButtonWithText"; +import { + setDialogMessage, + setShowDialog, +} from "../../redux/slices/uiStateSlice"; +import { + Button, + defaultBorderRadius, + secondaryDark, + vscBackground, + vscForeground, +} from ".."; +import styled from "styled-components"; + +const MiniPillSpan = styled.span` + padding: 3px; + padding-left: 6px; + padding-right: 6px; + border-radius: ${defaultBorderRadius}; + color: ${vscForeground}; + background-color: #fff3; + overflow: hidden; + font-size: 12px; + display: flex; + align-items: center; + text-align: center; + justify-content: center; +`; + +const ContextGroupSelectDiv = styled.div` + display: flex; + align-items: center; + gap: 8px; + padding: 8px; + border-radius: ${defaultBorderRadius}; + background-color: ${secondaryDark}; + color: ${vscForeground}; + margin-top: 8px; + cursor: pointer; + + &:hover { + background-color: ${vscBackground}; + color: ${vscForeground}; + } +`; + +function SelectContextGroupDialog() { + const dispatch = useDispatch(); + const savedContextGroups = useSelector( + (state: RootStore) => state.serverState.saved_context_groups + ); + const client = useContext(GUIClientContext); + + return ( +
+

Saved Context Groups

+ + {savedContextGroups && Object.keys(savedContextGroups).length > 0 ? ( +
+ {Object.keys(savedContextGroups).map((key: string) => { + const contextGroup = savedContextGroups[key]; + return ( + { + dispatch(setDialogMessage(undefined)); + dispatch(setShowDialog(false)); + client?.selectContextGroup(key); + }} + > + {key}: + + {contextGroup.map((contextItem) => { + return ( + {contextItem.description.name} + ); + })} + { + e.stopPropagation(); + client?.deleteContextGroup(key); + }} + > + + + + ); + })} +
+ ) : ( +
No saved context groups
+ )} + +
+ ); +} + +export default SelectContextGroupDialog; diff --git a/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts index 2e8aaeef..c9e7def2 100644 --- a/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts +++ b/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts @@ -40,6 +40,8 @@ abstract class AbstractContinueGUIClientProtocol { abstract saveContextGroup(title: string, contextItems: ContextItem[]): void; abstract selectContextGroup(id: string): void; + + abstract deleteContextGroup(id: string): void; } export default AbstractContinueGUIClientProtocol; diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts index aa558adb..b3ac2570 100644 --- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts +++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts @@ -143,6 +143,10 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol { selectContextGroup(id: string): void { this.messenger?.send("select_context_group", { id }); } + + deleteContextGroup(id: string): void { + this.messenger?.send("delete_context_group", { id }); + } } export default ContinueGUIClientProtocol; -- cgit v1.2.3-70-g09d2