Skip to content

Commit

Permalink
Simplify Instructions & show in main UI (#130)
Browse files Browse the repository at this point in the history
* refactor: remove unused state

* refactor: rename notes to instructions & hide json mode

* feat: show matched notes in main UI

* fix: skip knowledge display if no notes

* fix: tsc issue
  • Loading branch information
mondaychen authored Apr 23, 2024
1 parent 8e86d33 commit 7903a73
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/common/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const App = () => {

return (
<ChakraProvider>
<Box p="8" pb="16" fontSize="lg" w="full">
<Box p="8" pb="24" fontSize="lg" w="full">
<HStack mb={4} alignItems="center">
<Heading as="h1" size="lg" flex={1}>
WebWand 🪄
Expand Down
4 changes: 2 additions & 2 deletions src/common/CustomKnowledgeBase/DefaultKnowledge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const DefaultKnowledge = () => {
return (
<>
<Button size="sm" variant="link" colorScheme="blue" onClick={onOpen}>
View Default Knowledge
View Built-in Instructions
</Button>
<Modal
isOpen={isOpen}
Expand All @@ -30,7 +30,7 @@ const DefaultKnowledge = () => {
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Default Knowledge Base</ModalHeader>
<ModalHeader>Default Instructions</ModalHeader>
<ModalCloseButton />
<ModalBody>
{Object.keys(defaultKnowledgeBase).map((host) => (
Expand Down
93 changes: 60 additions & 33 deletions src/common/CustomKnowledgeBase/HostKnowledge.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DeleteIcon, CopyIcon, EditIcon } from "@chakra-ui/icons";
import { DeleteIcon, EditIcon } from "@chakra-ui/icons";
import {
Heading,
Accordion,
Expand All @@ -9,11 +9,11 @@ import {
IconButton,
Tooltip,
Flex,
useToast,
Box,
} from "@chakra-ui/react";
import { fetchAllDefaultKnowledge } from "../../helpers/knowledge";
import { useAppState } from "@root/src/state/store";
import Notes from "./Notes";

type HostKnowledgeProps = {
host: string;
Expand All @@ -26,7 +26,6 @@ const HostKnowledge = ({
isDefaultKnowledge,
onEdit,
}: HostKnowledgeProps) => {
const toast = useToast();
const updateSettings = useAppState((state) => state.settings.actions.update);
const customKnowledgeBase = useAppState(
(state) => state.settings.customKnowledgeBase,
Expand All @@ -35,16 +34,33 @@ const HostKnowledge = ({
? fetchAllDefaultKnowledge()
: customKnowledgeBase;

const getJsonString = (): string => {
return JSON.stringify(knowledgeBase[host], null, 2);
};
if (knowledgeBase[host] === undefined) {
return null;
}
const rules = knowledgeBase[host].rules;
if (rules === undefined) {
return null;
}
const hasNotes = rules.some(
(rule) => (rule.knowledge?.notes?.length ?? 0) > 0,
);
// skip if no notes
if (!hasNotes) {
return null;
}

const handleRemove = () => {
const newKnowledge = { ...knowledgeBase };
delete newKnowledge[host];
updateSettings({ customKnowledgeBase: newKnowledge });
};

// temporarily disable copy feature
/*
const getJsonString = (): string => {
return JSON.stringify(knowledgeBase[host], null, 2);
};
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(getJsonString());
Expand All @@ -65,13 +81,23 @@ const HostKnowledge = ({
});
}
};
*/

return (
<>
<Flex alignItems="flex-start">
<Heading as="h5" size="sm" flex="1" overflowWrap="anywhere">
<Flex alignItems="flex-start" mb="2">
<Heading
as="h5"
size="sm"
flex="1"
overflowWrap="anywhere"
lineHeight="1.5rem"
>
{!isDefaultKnowledge && (
<Box position="relative" style={{ float: "right" }}>
<Box
position="relative"
style={{ float: "right", marginTop: "-4px" }}
>
<Tooltip label="Edit knowledge">
<IconButton
aria-label="Edit knowledge"
Expand All @@ -83,15 +109,6 @@ const HostKnowledge = ({
}}
/>
</Tooltip>
<Tooltip label="Copy knowledge">
<IconButton
aria-label="Copy knowledge"
icon={<CopyIcon />}
size="sm"
variant="ghost"
onClick={handleCopy}
/>
</Tooltip>
<Tooltip label="Remove knowledge">
<IconButton
aria-label="Remove knowledge"
Expand All @@ -107,21 +124,31 @@ const HostKnowledge = ({
</Heading>
</Flex>
<Accordion allowToggle>
{knowledgeBase[host].rules?.map((rule, ruleIndex) => (
<AccordionItem key={ruleIndex} backgroundColor="white">
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Rule {ruleIndex + 1}
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<pre style={{ overflowX: "auto" }}>{getJsonString()}</pre>
</AccordionPanel>
</AccordionItem>
))}
{rules.map((rule, ruleIndex) => {
// Skip rules without notes
if (
rule.knowledge === undefined ||
rule.knowledge.notes === undefined ||
rule.knowledge.notes.length === 0
) {
return null;
}
return (
<AccordionItem key={ruleIndex} backgroundColor="white">
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Instructions Set {ruleIndex + 1}
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<Notes notes={rule.knowledge.notes} />
</AccordionPanel>
</AccordionItem>
);
})}
</Accordion>
</>
);
Expand Down
55 changes: 55 additions & 0 deletions src/common/CustomKnowledgeBase/MatchedNotes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useAppState } from "../../state/store";
import {
Alert,
AlertIcon,
AlertDescription,
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
useDisclosure,
} from "@chakra-ui/react";
import Notes from "./Notes";

export default function MatchedNotes() {
const { isOpen, onOpen, onClose } = useDisclosure();
const knowledge = useAppState((state) => state.currentTask.knowledgeInUse);
const notes = knowledge?.notes;
if (!notes || notes.length === 0) {
return null;
}

return (
<>
<Button variant="link" onClick={onOpen}>
Found {notes.length} instructions.
</Button>
<Modal
isOpen={isOpen}
onClose={onClose}
size="xl"
scrollBehavior="inside"
>
<ModalOverlay />
<ModalContent>
<ModalHeader>
WebWand uses the following instructions and tips:
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Notes notes={notes} />
<Alert status="info" borderRadius="md" my="1rem">
<AlertIcon />
<AlertDescription fontSize="1rem">
You can customize instructions in the settings menu.
</AlertDescription>
</Alert>
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
22 changes: 9 additions & 13 deletions src/common/CustomKnowledgeBase/NewKnowledgeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
ModalBody,
ModalFooter,
Box,
Heading,
InputGroup,
InputRightElement,
IconButton,
Expand Down Expand Up @@ -235,7 +234,7 @@ const NewKnowledgeForm = ({
// )

return (
<Modal isOpen={isOpen} onClose={closeForm}>
<Modal isOpen={isOpen} onClose={closeForm} size="xl">
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
Expand Down Expand Up @@ -264,13 +263,13 @@ const NewKnowledgeForm = ({
onClose={() => setShowDuplicateAlert(false)}
/>
<ModalHeader>
{isEditMode ? "Edit" : "New"} Host Knowledge
{isEditMode ? "Edit" : "New"} Instructions
</ModalHeader>
<ModalBody>
<FormControl isRequired mb={4}>
<FormLabel>Host</FormLabel>
<FormLabel>Instructions for:</FormLabel>
<FormHelperText mb={1} fontSize="xs">
e.g. github.com
host of the website (e.g. google.com)
</FormHelperText>
<Input
name="newHost"
Expand All @@ -282,9 +281,6 @@ const NewKnowledgeForm = ({
</FormControl>

{/* Rules Section */}
<Heading as="h5" size="sm" mb={2}>
Rules
</Heading>
{values.rules.map((rule, ruleIndex) => (
<Box
key={ruleIndex}
Expand Down Expand Up @@ -430,19 +426,19 @@ const NewKnowledgeForm = ({

{/* Notes Section */}
<FormControl mb={2}>
<FormLabel>Notes</FormLabel>
<FormLabel>Instructions</FormLabel>
{rule.knowledge.notes?.map((note, noteIndex) => (
<InputGroup key={noteIndex} size="md" mb={1}>
<Field
as={Textarea}
name={`rules[${ruleIndex}].knowledge.notes[${noteIndex}]`}
placeholder="Enter note"
placeholder="Enter Instructions"
/>
<InputRightElement>
{rule.knowledge.notes &&
rule.knowledge.notes.length > 1 && (
<IconButton
aria-label="Remove note"
aria-label="Remove Instructions"
icon={<SmallCloseIcon />}
variant="ghost"
onClick={() => {
Expand Down Expand Up @@ -476,7 +472,7 @@ const NewKnowledgeForm = ({
);
}}
>
Add more notes
Add another instruction
</Button>

{/* Annotation Rules Section */}
Expand Down Expand Up @@ -509,7 +505,7 @@ const NewKnowledgeForm = ({
setFieldValue("rules", updatedRules);
}}
>
Add more rules
Add another set of instructions
</Button>
</ModalBody>
<ModalFooter>
Expand Down
14 changes: 14 additions & 0 deletions src/common/CustomKnowledgeBase/Notes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { UnorderedList, ListItem } from "@chakra-ui/react";

export default function Notes({ notes }: { notes: string[] | undefined }) {
if (!notes || notes.length === 0) {
return null;
}
return (
<UnorderedList fontSize="0.8rem" styleType="circle">
{notes.map((note, index) => (
<ListItem key={index}>{note}</ListItem>
))}
</UnorderedList>
);
}
22 changes: 11 additions & 11 deletions src/common/CustomKnowledgeBase/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useState } from "react";
import { Button, Text, VStack, Box, useDisclosure } from "@chakra-ui/react";
import { Button, Text, VStack, Box } from "@chakra-ui/react";
import { useAppState } from "@root/src/state/store";
import NewKnowledgeForm from "./NewKnowledgeForm";
import { type EditingData } from "../../helpers/knowledge";
import DefaultKnowledge from "./DefaultKnowledge";
import HostKnowledge from "./HostKnowledge";
import NewKnowledgeJson from "./NewKnowledgeJson";
// import NewKnowledgeJson from "./NewKnowledgeJson";
import { findActiveTab } from "../../helpers/browserUtils";

const CustomKnowledgeBase = () => {
Expand All @@ -16,11 +16,11 @@ const CustomKnowledgeBase = () => {
const customKnowledgeBase = useAppState(
(state) => state.settings.customKnowledgeBase,
);
const {
isOpen: isJsonInputOpen,
onOpen: openJsonInput,
onClose: closeJsonInput,
} = useDisclosure();
// const {
// isOpen: isJsonInputOpen,
// onOpen: openJsonInput,
// onClose: closeJsonInput,
// } = useDisclosure();
const [defaultHost, setDefaultHost] = useState("");
const [currentURL, setCurrentUrl] = useState("");

Expand Down Expand Up @@ -76,10 +76,10 @@ const CustomKnowledgeBase = () => {
</Box>
))
) : (
<Text>No custom knowledge found</Text>
<Text>No instructions found</Text>
)}
<Button onClick={openForm}>Add Host Knowledge with Form</Button>
<Button onClick={openJsonInput}>Add Host Knowledge with JSON</Button>
<Button onClick={openForm}>Add Instructions</Button>
{/* <Button onClick={openJsonInput}>Add Host Knowledge with JSON</Button> */}
<NewKnowledgeForm
isOpen={isFormOpen}
isEditMode={!!editKnowledge}
Expand All @@ -88,7 +88,7 @@ const CustomKnowledgeBase = () => {
defaultHost={defaultHost}
currentURL={currentURL}
/>
<NewKnowledgeJson isOpen={isJsonInputOpen} onClose={closeJsonInput} />
{/* <NewKnowledgeJson isOpen={isJsonInputOpen} onClose={closeJsonInput} /> */}
</VStack>
);
};
Expand Down
Loading

0 comments on commit 7903a73

Please sign in to comment.