i need to make the library dialog a datagrid.
This commit is contained in:
parent
ee266ea372
commit
326f3788fa
@ -54,11 +54,11 @@ function App() {
|
|||||||
const promptItems = [
|
const promptItems = [
|
||||||
{
|
{
|
||||||
id: uuid4(), items: [
|
id: uuid4(), items: [
|
||||||
{ id: uuid4(), item: libItems[0] },
|
{ id: uuid4(), item: libItems[0], score: -2 },
|
||||||
{ id: uuid4(), item: libItems[1] },
|
{ id: uuid4(), item: libItems[1], score: 1 },
|
||||||
], op: Op.AND,
|
], op: Op.AND,
|
||||||
},
|
},
|
||||||
{ id: uuid4(), item: libItems[2] },
|
{ id: uuid4(), item: libItems[2], score: 0, },
|
||||||
] as Composition;
|
] as Composition;
|
||||||
|
|
||||||
$library.set(libItems);
|
$library.set(libItems);
|
||||||
|
@ -10,7 +10,7 @@ export interface StyleProps {
|
|||||||
export function LibraryItem(props: StyleProps) {
|
export function LibraryItem(props: StyleProps) {
|
||||||
const { item, onInsertItem } = props
|
const { item, onInsertItem } = props
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={`library-item ${item.category}`}>
|
||||||
<Button onClick={() => onInsertItem(item)} aria-label="Add">
|
<Button onClick={() => onInsertItem(item)} aria-label="Add">
|
||||||
<AddCircleOutlineOutlinedIcon/>
|
<AddCircleOutlineOutlinedIcon/>
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button, FormControl, InputLabel, MenuItem, TextField } from "@material-ui/core";
|
import { Button, Container, FormControl, InputLabel, MenuItem, Table, TableRow, TextField } from "@material-ui/core";
|
||||||
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
||||||
import { Category, LibraryItem, addItemToLibrary, categoryHasName } from "../lib/prompt";
|
import { Category, LibraryItem, addItemToLibrary, categoryHasName } from "../lib/prompt";
|
||||||
import { ChangeEvent, useState } from "react";
|
import { ChangeEvent, useState } from "react";
|
||||||
@ -46,32 +46,28 @@ export function NewLibraryItem(props: NewLibraryItemProps) {
|
|||||||
const catChoices = Object.keys(Category);
|
const catChoices = Object.keys(Category);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Container className="new-item-form">
|
||||||
<FormControl onSubmit={handleCreateItem}>
|
<FormControl onSubmitCapture={handleCreateItem}>
|
||||||
<div>
|
<InputLabel htmlFor="new-prompt-category">Category</InputLabel>
|
||||||
<InputLabel htmlFor="new-prompt-category">Category</InputLabel>
|
<Select
|
||||||
<Select
|
native
|
||||||
native
|
id="new-prompt-category"
|
||||||
id="new-prompt-category"
|
aria-label="Prompt Item Category"
|
||||||
aria-label="Prompt Item Category"
|
value={category}
|
||||||
value={category}
|
onChange={(e) => handleCategoryChange(e)}
|
||||||
onChange={(e) => handleCategoryChange(e)}
|
>
|
||||||
>
|
{catChoices.map(cat => (
|
||||||
{catChoices.map(cat => (
|
<option value={cat} id={cat} key={cat}>{titleCase(cat)}</option>
|
||||||
<option value={cat} id={cat} key={cat}>{titleCase(cat)}</option>
|
))}
|
||||||
))}
|
</Select>
|
||||||
</Select>
|
{categoryHasName(category) && <>
|
||||||
</div>
|
<InputLabel htmlFor="name">Name</InputLabel>
|
||||||
<div>
|
<TextField aria-label="Prompt Item Name" value={name} onChange={handleNameChange} id="name" />
|
||||||
{categoryHasName(category) ? (<InputLabel htmlFor="name">Name</InputLabel>) : <></>}
|
</>}
|
||||||
{categoryHasName(category) ? (<TextField aria-label="Prompt Item Name" value={name} onChange={handleNameChange} id="name" />) : <></>}
|
<InputLabel htmlFor="prompt">Prompt</InputLabel>
|
||||||
</div>
|
<TextField aria-label="Prompt Item Text" value={prompt} onChange={handlePromptChange} id="prompt" />
|
||||||
<div>
|
<Button onClick={handleCreateItem} >Create</Button>
|
||||||
<InputLabel htmlFor="prompt">Prompt</InputLabel>
|
|
||||||
<TextField aria-label="Prompt Item Text" value={prompt} onChange={handlePromptChange} id="prompt" />
|
|
||||||
<Button onClick={handleCreateItem} >Create</Button>
|
|
||||||
</div>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -1,13 +1,19 @@
|
|||||||
.nugget {
|
.nugget.toplevel {
|
||||||
border: 1px solid slategray;
|
border: 1px solid slategray;
|
||||||
border-radius: 10pt;
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
margin: 10pt;
|
}
|
||||||
|
|
||||||
|
.operation .nugget {
|
||||||
|
border: 1px solid white;
|
||||||
|
border-radius: 2pt;
|
||||||
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nugget > .text, .nugget > .score, .nugget.buttons {
|
.nugget > .text, .nugget > .score, .nugget.buttons {
|
||||||
display: flex;
|
|
||||||
padding: 4pt;
|
padding: 4pt;
|
||||||
margin-top: 10pt;
|
display: inline-block;
|
||||||
vertical-align: text-bottom;
|
}
|
||||||
|
|
||||||
|
.nugget .buttons button {
|
||||||
|
max-height: 12pt;
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ import { useStore } from '@nanostores/react';
|
|||||||
|
|
||||||
export interface NuggetProps extends PromptItemProps {
|
export interface NuggetProps extends PromptItemProps {
|
||||||
nugget: NuggetType,
|
nugget: NuggetType,
|
||||||
|
isTopLevel?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Nugget(props: NuggetProps) {
|
export default function Nugget(props: NuggetProps) {
|
||||||
@ -22,6 +23,7 @@ export default function Nugget(props: NuggetProps) {
|
|||||||
onDrop,
|
onDrop,
|
||||||
onMouseEnter,
|
onMouseEnter,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
|
isTopLevel,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const scoreDisp = nugget.score > 0 ? "+" + nugget.score : nugget.score;
|
const scoreDisp = nugget.score > 0 ? "+" + nugget.score : nugget.score;
|
||||||
@ -30,6 +32,8 @@ export default function Nugget(props: NuggetProps) {
|
|||||||
const composition = useStore($composition)
|
const composition = useStore($composition)
|
||||||
const thisId = `prompt-item-${nugget.id}`
|
const thisId = `prompt-item-${nugget.id}`
|
||||||
|
|
||||||
|
const className = isTopLevel ? 'nugget toplevel prompt-item' : 'nugget child prompt-item';
|
||||||
|
|
||||||
const handleOnDragStart = () => {
|
const handleOnDragStart = () => {
|
||||||
onDragStart ? onDragStart(nugget) : null;
|
onDragStart ? onDragStart(nugget) : null;
|
||||||
}
|
}
|
||||||
@ -66,7 +70,7 @@ export default function Nugget(props: NuggetProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='nugget prompt-item'
|
className={className}
|
||||||
id={thisId}
|
id={thisId}
|
||||||
draggable
|
draggable
|
||||||
onDragStart={handleOnDragStart}
|
onDragStart={handleOnDragStart}
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
.operation {
|
.operation {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
border: 1px solid lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.operation .title {
|
.operation .title {
|
||||||
padding: 4pt;
|
|
||||||
margin: 4pt;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.operation .nuggets {
|
.operation .nuggets {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
background-color: #ffdddd;
|
border-style: solid;
|
||||||
border: 1px solid coral;
|
|
||||||
border-radius: 10pt;
|
border-radius: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.operation.and .nuggets, .operation.joined .nuggets {
|
||||||
|
background-color: #b983a3;
|
||||||
|
border-color: #532e44;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operation.swapped .nuggets, .operation.swap .nuggets {
|
||||||
|
background-color: #8dacbd;
|
||||||
|
border-color: #4c6978;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operation.blended .nuggets, .operation.blend .nuggets {
|
||||||
|
background-color: #a1af86;
|
||||||
|
border-color: #58663d;
|
||||||
|
}
|
@ -92,7 +92,7 @@ function Operation(props: OperationProps) {
|
|||||||
onDragOver={handleOnDragOver}
|
onDragOver={handleOnDragOver}
|
||||||
onMouseEnter={handleOnMouseEnter}
|
onMouseEnter={handleOnMouseEnter}
|
||||||
onMouseOut={handleOnMouseLeave}
|
onMouseOut={handleOnMouseLeave}
|
||||||
className="operation"
|
className={`operation ${operation.op} prompt-item`}
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
data-promptitem-id={operation.id}
|
data-promptitem-id={operation.id}
|
||||||
>
|
>
|
||||||
@ -100,7 +100,7 @@ function Operation(props: OperationProps) {
|
|||||||
<div className="nuggets">
|
<div className="nuggets">
|
||||||
{
|
{
|
||||||
operation.items.map(nugget => {
|
operation.items.map(nugget => {
|
||||||
return <Nugget nugget={nugget} />
|
return <Nugget nugget={nugget} isTopLevel={false} />
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,3 +3,9 @@
|
|||||||
right: 10pt;
|
right: 10pt;
|
||||||
top: 10pt;
|
top: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prompt-item {
|
||||||
|
margin: 4pt;
|
||||||
|
padding: 2pt;
|
||||||
|
border-radius: 5pt;
|
||||||
|
}
|
@ -72,7 +72,7 @@ export default function PromptComposer(props: PromptComposerProps) {
|
|||||||
|
|
||||||
return ("op" in promptItem ?
|
return ("op" in promptItem ?
|
||||||
<Operation operation={promptItem} key={key} {...callbacks} />
|
<Operation operation={promptItem} key={key} {...callbacks} />
|
||||||
: <Nugget nugget={promptItem} key={key} {...callbacks} />)
|
: <Nugget nugget={promptItem} key={key} isTopLevel={true} {...callbacks} />)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -90,9 +90,9 @@ export default function PromptComposer(props: PromptComposerProps) {
|
|||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
slottedComposition.map((itemCol, i) => (
|
slottedComposition.map((itemCol, i) => (
|
||||||
<Stack>
|
<>
|
||||||
{itemCol.map((promptItem, j) => promptItemFactory(promptItem, `item-${j}-${j}`))}
|
{itemCol.map((promptItem, j) => promptItemFactory(promptItem, `item-${j}-${j}`))}
|
||||||
</Stack>
|
</>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
.prompt-library-dialog .categories div {
|
.prompt-library-dialog .categories div {
|
||||||
display: inline;
|
display: inline;
|
||||||
|
margin: 20pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.library-item button, .library-item span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-item-form {
|
||||||
|
border: 1px solid blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ export function PromptLibrary(props: SimpleDialogProps) {
|
|||||||
|
|
||||||
const [doCreate, setDoCreate] = useState(false);
|
const [doCreate, setDoCreate] = useState(false);
|
||||||
|
|
||||||
const [visibleCategories, setVisibleCategories] = useState([] as Category[]);
|
const [visibleCategories, setVisibleCategories] = useState(Object.keys(Category) as Category[]);
|
||||||
|
|
||||||
const handleOnAddItem = (item: LibItemType) => {
|
const handleOnAddItem = (item: LibItemType) => {
|
||||||
// onAddItem(item);
|
// onAddItem(item);
|
||||||
@ -44,12 +44,22 @@ export function PromptLibrary(props: SimpleDialogProps) {
|
|||||||
onInsertItem(item);
|
onInsertItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterCat = (catKey: string, v: ChangeEvent<HTMLInputElement>) => {
|
const filterCat = (catKey: string) => {
|
||||||
const isChecked = v.target.value === '1';
|
document.querySelectorAll(`.library-item`).forEach($el => {
|
||||||
setVisibleCategories((visibleCategories.includes(catKey as Category) && !isChecked) ? visibleCategories.filter(c => c != catKey) : [...visibleCategories, catKey as Category]);
|
console.log("Found %x", $el);
|
||||||
document.querySelectorAll(`.category-${catKey}`).forEach($el => {
|
show($el);
|
||||||
if (isChecked) show($el)
|
});
|
||||||
else hide($el)
|
if (visibleCategories.includes(catKey as Category)) {
|
||||||
|
setVisibleCategories(visibleCategories.filter((v) => v !== catKey));
|
||||||
|
} else {
|
||||||
|
setVisibleCategories([...visibleCategories, catKey as Category]);
|
||||||
|
}
|
||||||
|
console.log(visibleCategories);
|
||||||
|
document.querySelectorAll(`.library-item`).forEach($el => {
|
||||||
|
Object.keys(Category).forEach(c => {
|
||||||
|
if (c in visibleCategories) show($el)
|
||||||
|
else hide($el)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +79,8 @@ export function PromptLibrary(props: SimpleDialogProps) {
|
|||||||
<div className="categories">
|
<div className="categories">
|
||||||
{categoryChoices.map(catKey => {
|
{categoryChoices.map(catKey => {
|
||||||
return (
|
return (
|
||||||
<div key={catKey}>
|
<div key={catKey} onMouseDown={() => filterCat(catKey)}>
|
||||||
<Checkbox onChange={v => filterCat(catKey, v)} />
|
<Checkbox checked={visibleCategories.includes(catKey as Category)} />
|
||||||
<span>{title(catKey)}</span>
|
<span>{title(catKey)}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -3,9 +3,14 @@ import { $textComposition } from "../lib/prompt";
|
|||||||
import "./TextPrompt.css";
|
import "./TextPrompt.css";
|
||||||
import { useStore } from "@nanostores/react";
|
import { useStore } from "@nanostores/react";
|
||||||
|
|
||||||
export function TextPrompt () {
|
export function TextPrompt() {
|
||||||
const text = useStore($textComposition);
|
const text = useStore($textComposition);
|
||||||
return (
|
return (
|
||||||
<TextareaAutosize content={text} className="text-prompt" />
|
<>
|
||||||
|
<TextareaAutosize
|
||||||
|
className="text-prompt"
|
||||||
|
defaultValue={text}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user