add prompt library dialog.
This commit is contained in:
parent
199ddb6848
commit
5c3c8a0beb
11
package.json
11
package.json
@ -8,6 +8,7 @@
|
|||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
"@mui/icons-material": "^5.15.10",
|
"@mui/icons-material": "^5.15.10",
|
||||||
"@mui/material": "^5.15.10",
|
"@mui/material": "^5.15.10",
|
||||||
|
"@reduxjs/toolkit": "^2.2.1",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
@ -17,22 +18,20 @@
|
|||||||
"@types/react-dom": "^18.2.19",
|
"@types/react-dom": "^18.2.19",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-redux": "^9.1.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
|
"browser": {
|
||||||
|
"crypto": false
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"react-app/jest"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
">0.2%",
|
">0.2%",
|
||||||
|
11382
pnpm-lock.yaml
Normal file
11382
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,8 +4,10 @@ import './App.css';
|
|||||||
import PromptArea from './components/PromptArea';
|
import PromptArea from './components/PromptArea';
|
||||||
import { Op, Operation } from './components/Operation';
|
import { Op, Operation } from './components/Operation';
|
||||||
import Nugget from './components/Nugget';
|
import Nugget from './components/Nugget';
|
||||||
|
import { Ast } from './lib/ast';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const ast = new Ast();
|
||||||
const c = (
|
const c = (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<PromptArea>
|
<PromptArea>
|
||||||
|
@ -1,25 +1,19 @@
|
|||||||
import { Badge, Chip, Menu, MenuItem } from "@material-ui/core";
|
import { Menu, MenuItem } from "@material-ui/core";
|
||||||
import Nugget from "./Nugget";
|
import React, { Children, ReactNode } from 'react';
|
||||||
import React, { Children, Component, ReactNode, ReactPropTypes } from 'react';
|
|
||||||
import { Composable } from "./IComposable";
|
|
||||||
import "./Operation.css";
|
import "./Operation.css";
|
||||||
|
import { Op } from "../lib/operator";
|
||||||
|
import { randomUUID } from "crypto";
|
||||||
|
|
||||||
enum Op {
|
|
||||||
JOINED = "joined",
|
|
||||||
AND = "and",
|
|
||||||
SWAPPED = "swaped",
|
|
||||||
SWAP = "swap",
|
|
||||||
BLENDED = "blended",
|
|
||||||
BLEND = "blend",
|
|
||||||
}
|
|
||||||
|
|
||||||
function Operation({ children, initialOp }: { children: ReactNode[], initialOp: Op }) {
|
function Operation({ children, initialOp }: { children: ReactNode[], initialOp: Op}) {
|
||||||
const [op, setOp] = React.useState(initialOp);
|
const [op, setOp] = React.useState(initialOp);
|
||||||
const [contextMenu, setContextMenu] = React.useState<{
|
const [contextMenu, setContextMenu] = React.useState<{
|
||||||
mouseX: number;
|
mouseX: number;
|
||||||
mouseY: number;
|
mouseY: number;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
|
const [id, ] = React.useState(randomUUID);
|
||||||
|
|
||||||
const handleContextMenu = (event: React.MouseEvent) => {
|
const handleContextMenu = (event: React.MouseEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setContextMenu(
|
setContextMenu(
|
||||||
|
5
src/components/PromptArea.css
Normal file
5
src/components/PromptArea.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.add-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 10pt;
|
||||||
|
top: 10pt;
|
||||||
|
}
|
@ -1,14 +1,37 @@
|
|||||||
import { Button, ButtonGroup, Chip } from '@material-ui/core';
|
import { Button } from '@material-ui/core';
|
||||||
import React, { Children, Component, ReactNode } from 'react';
|
import { Children, ReactNode } from 'react';
|
||||||
import Nugget from './Nugget';
|
import Nugget from './Nugget';
|
||||||
import { Operation } from './Operation';
|
import { Operation } from './Operation';
|
||||||
// import { Composable } from './IComposable';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import "./PromptArea.css";
|
||||||
|
import { PromptLibrary } from './PromptLibrary';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
type Composable = (typeof Nugget) | (typeof Operation);
|
type Composable = (typeof Nugget) | (typeof Operation);
|
||||||
|
|
||||||
export default function PromptArea({ children }: { children?: any }) {
|
export default function PromptArea({ children }: { children?: any }) {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
const handleClickOpen = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = (value: string) => {
|
||||||
|
setOpen(false);
|
||||||
|
setSelectedValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<Button className="add-button">
|
||||||
|
<AddIcon />
|
||||||
|
<PromptLibrary
|
||||||
|
open={isPromptLibraryOpen}
|
||||||
|
onClose={handleClose}
|
||||||
|
></PromptLibrary>
|
||||||
|
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
{
|
{
|
||||||
Children.map(children, child => {
|
Children.map(children, child => {
|
||||||
return (<div>
|
return (<div>
|
||||||
@ -16,6 +39,7 @@ export default function PromptArea({ children }: { children?: any }) {
|
|||||||
</div>)
|
</div>)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
43
src/components/PromptLibrary.tsx
Normal file
43
src/components/PromptLibrary.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Dialog, DialogTitle, List, ListItem, ListItemAvatar, Avatar, ListItemText } from "@material-ui/core";
|
||||||
|
import { blue } from "@material-ui/core/colors";
|
||||||
|
import ListItemButton from "@mui/material/ListItemButton";
|
||||||
|
|
||||||
|
export type Category = {
|
||||||
|
id: string,
|
||||||
|
label: string,
|
||||||
|
color?: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const categories = [
|
||||||
|
{ id: "style", label: "Styles", color: "blue" },
|
||||||
|
{ id: "subject", label: "Subjects", color: "black" },
|
||||||
|
{ id: "vibes", label: "Vibes", color: "gold" },
|
||||||
|
{ id: "mediums", label: "Mediums", color: "black" },
|
||||||
|
] as Category[];
|
||||||
|
|
||||||
|
export interface SimpleDialogProps {
|
||||||
|
open: boolean;
|
||||||
|
selectedValue: string;
|
||||||
|
onClose: (value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PromptLibrary(props: SimpleDialogProps) {
|
||||||
|
const { onClose, selectedValue, open } = props;
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
onClose(selectedValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNuggetClick = (value: string) => {
|
||||||
|
onClose(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog onClose={handleClose} open={open}>
|
||||||
|
<DialogTitle>Prompt Library</DialogTitle>
|
||||||
|
<div>
|
||||||
|
Prompt Library
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
@ -3,13 +3,17 @@ import ReactDOM from 'react-dom/client';
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from './reportWebVitals';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import store from "./store"
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
);
|
);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<Provider store={store}>
|
||||||
|
<App />
|
||||||
|
</Provider >
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,86 @@
|
|||||||
export interface AstNode {
|
import { randomUUID } from "crypto";
|
||||||
|
import { Op } from "./operator";
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
export interface IAstNode {
|
||||||
|
id: string;
|
||||||
|
toPrompt(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Ast {
|
export interface IToPrompt {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
export class Nugget implements IAstNode, IToPrompt {
|
||||||
|
public score: number = 0;
|
||||||
|
public id: string;
|
||||||
|
public constructor(public text: string) {
|
||||||
|
this.id = randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
get sign() {
|
||||||
|
return this.score > 0 ? "+" : (this.score < 0 ? "-" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
get repeatSign() {
|
||||||
|
return Array(this.score).map(() => this.sign).join("")
|
||||||
|
}
|
||||||
|
|
||||||
|
public toPrompt() {
|
||||||
|
return `(${this.text})${this.repeatSign}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Operation extends Array<Nugget> implements IAstNode, IToPrompt {
|
||||||
|
public id: string;
|
||||||
|
public constructor(public op: Op, ...items: Nugget[]) {
|
||||||
|
super(...items);
|
||||||
|
this.id = randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
get nuggetStr() {
|
||||||
|
return this.map(i => i.toPrompt()).join(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
toPrompt(): string {
|
||||||
|
return `(${this.nuggetStr}).${this.op}()`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Ast extends Array<IAstNode> implements IToPrompt {
|
||||||
|
public toPrompt(): string {
|
||||||
|
return this.map(i => i.toPrompt()).join(",");
|
||||||
|
}
|
||||||
|
public changeOp(id : string, op : Op) : Ast {
|
||||||
|
return this.map(n => {
|
||||||
|
if (n.id != id) return n;
|
||||||
|
if (n instanceof Operation) {
|
||||||
|
n.op = op;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}) as Ast;
|
||||||
|
}
|
||||||
|
public removeNode(id : string) : Ast{
|
||||||
|
return this.filter(n => n.id != id) as Ast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const astSlice = createSlice({
|
||||||
|
name: "ast",
|
||||||
|
initialState: new Ast(),
|
||||||
|
reducers: {
|
||||||
|
addNugget (state, action) {
|
||||||
|
state.push(
|
||||||
|
new Nugget(action.payload)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// addOperation (state, action) {
|
||||||
|
// state.push(
|
||||||
|
// new Operation(...action.payload)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { addNugget } = astSlice.actions
|
||||||
|
|
||||||
|
export default astSlice.reducer;
|
8
src/lib/operator.ts
Normal file
8
src/lib/operator.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export enum Op {
|
||||||
|
JOINED = "joined",
|
||||||
|
AND = "and",
|
||||||
|
SWAPPED = "swaped",
|
||||||
|
SWAP = "swap",
|
||||||
|
BLENDED = "blended",
|
||||||
|
BLEND = "blend",
|
||||||
|
}
|
9
src/store.ts
Normal file
9
src/store.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { configureStore } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
import astReducer from "./lib/ast"
|
||||||
|
|
||||||
|
export default configureStore({
|
||||||
|
reducer: {
|
||||||
|
ast: astReducer,
|
||||||
|
},
|
||||||
|
});
|
@ -7,8 +7,7 @@
|
|||||||
"esnext"
|
"esnext"
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"@material-ui/*": ["./node_modules/@material-ui/core/esm/*"],
|
||||||
"@material-ui/*": ["./node_modules/@material-ui/core/esm/*"]
|
|
||||||
},
|
},
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types",
|
"node_modules/@types",
|
||||||
|
Loading…
Reference in New Issue
Block a user