Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/integrate slots front #92

Merged
merged 23 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6d6818b
feat: Integrate slots
Ramimashkouk Jul 26, 2024
ca676f8
Merge branch 'dev' into feat/integrate-slots-front
MXerFix Sep 10, 2024
606c864
refactor: Update to chatsky 1.0.0rc1
Ramimashkouk Sep 12, 2024
d0c2449
refactor: Use `ast` to deal with cnd&rsp
Ramimashkouk Sep 12, 2024
d5cc8c5
feat: Add slot converstion
Ramimashkouk Sep 13, 2024
cbefcf2
chore: Update converter to chatsky1.0.0rc1 format
Ramimashkouk Sep 13, 2024
4ad5418
chore: Strip messages before sending to ui
Ramimashkouk Sep 13, 2024
ffdb2f8
chore: Update autocomplet feat to 1.0.0rc1
Ramimashkouk Sep 13, 2024
4bcb0b2
fix: Stop all processes when shutting down
Ramimashkouk Sep 13, 2024
a24c7e3
chore: Delete handshaking with ws
Ramimashkouk Sep 13, 2024
8fe351a
style: Black up
Ramimashkouk Sep 13, 2024
ebdad14
chore: Check if slots key exists in front graph
Ramimashkouk Sep 17, 2024
48dca4b
fix: Stop process after disconnection only if running
Ramimashkouk Sep 17, 2024
95e78e3
refactor: init new base input elements
MXerFix Sep 20, 2024
755f696
chore: configuration changes
MXerFix Sep 20, 2024
9045a4f
feat: slots implement + modals rework init
MXerFix Sep 20, 2024
5ae111b
chore: icons fixes + modals rework fixes + sidebar&utils improvements
MXerFix Sep 20, 2024
4c5fe26
Merge branch 'feat/integrate-slots-new' into feat/integrate-slots-front
MXerFix Sep 20, 2024
71ff448
fix: slots filling and saving fixes
MXerFix Sep 20, 2024
a530c49
chore: add slot condition settings & rework condition modal & add sha…
MXerFix Sep 23, 2024
2ce3b47
chore: add quiet save handlers
MXerFix Sep 24, 2024
2809b37
chore: slots components refactor & add condition icons
MXerFix Sep 24, 2024
9d169d1
Merge branch 'dev' into feat/integrate-slots-front
Ramimashkouk Oct 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions backend/chatsky_ui/services/json_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@

from omegaconf.dictconfig import DictConfig

from chatsky_ui.core.logger_config import get_logger
from chatsky_ui.core.config import settings
from chatsky_ui.core.logger_config import get_logger
from chatsky_ui.db.base import read_conf, write_conf
from chatsky_ui.services.condition_finder import ServiceReplacer


logger = get_logger(__name__)

PRE_TRANSITIONS_PROCESSING = "PRE_TRANSITIONS_PROCESSING"


PRE_TRANSITION = "PRE_TRANSITION"


PRE_TRANSITION = "PRE_TRANSITION"

Expand Down Expand Up @@ -147,7 +151,7 @@ def _get_slot(slots, id_):
def _fill_nodes_into_script(nodes: dict, script: dict) -> None:
"""Fill nodes into chatsky script dictunary."""
for _, node in nodes.items():
if node["info"].type == "link_node":
if node["info"].type in ["link_node", "slots_node"]:
continue
if node["flow"] not in script["script"]:
script["script"][node["flow"]] = {}
Expand All @@ -171,7 +175,7 @@ async def update_responses_lines(nodes: dict) -> Tuple[dict, List[str]]:
"""
responses_list = []
for node in nodes.values():
if node["info"].type == "link_node":
if node["info"].type in ["link_node", "slots_node"]:
continue
response = node["info"].data.response
logger.debug("response type: %s", response.type)
Expand Down
Binary file modified frontend/bun.lockb
Binary file not shown.
20 changes: 20 additions & 0 deletions frontend/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": false,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
1 change: 1 addition & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</head>
<body>
<div id="root"></div>
<!-- <div id="modal_root"></div> -->
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
16 changes: 15 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@
"@babel/preset-react": "^7.24.1",
"@babel/preset-typescript": "^7.24.1",
"@codemirror/lang-python": "^6.1.5",
"@headlessui/react": "^2.1.8",
"@jest/globals": "^29.7.0",
"@nextui-org/react": "^2.2.9",
"@radix-ui/react-context-menu": "^2.1.5",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@react-spring/web": "^9.7.3",
"@rollup/rollup-linux-arm64-gnu": "4.13.0",
"@testing-library/jest-dom": "^6.4.5",
Expand All @@ -42,7 +48,10 @@
"@xyflow/react": "^12.2.0",
"axios": "^1.6.7",
"babel-jest": "^29.7.0",
"class-variance-authority": "^0.7.0",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"cmdk": "1.0.0",
"esbuild": "^0.21.4",
"esbuild-wasm": "0.20.2",
"framer-motion": "^11.0.6",
Expand All @@ -52,7 +61,7 @@
"jest-fetch-mock": "^3.0.3",
"jsdom": "^24.0.0",
"lodash": "^4.17.21",
"lucide-react": "^0.343.0",
"lucide-react": "^0.445.0",
"random-words": "^2.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -61,15 +70,20 @@
"react-router-dom": "^6.22.2",
"react-test-renderer": "^18.3.1",
"react-xarrows": "^2.0.2",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-children": "^2.1.0",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"uuid": "^9.0.1",
"vaul": "^0.9.4",
"yaml": "^2.4.1"
},
"devDependencies": {
"@types/bun": "latest",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.17.0",
"@types/node": "^22.5.5",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@types/uuid": "^9.0.8",
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { ReactFlowProvider } from "@xyflow/react"
import { RouterProvider, createBrowserRouter } from "react-router-dom"
import { Preloader } from "./UI/Preloader/Preloader"
import ContextWrapper from "./contexts"
import PopUpProvider from "./contexts/popUpContext"
import { UndoRedoProvider } from "./contexts/undoRedoContext"
import Fallback from "./pages/Fallback"
import Flow from "./pages/Flow"
import Home from "./pages/Home"
import Index from "./pages/Index"

const App = () => {

const router = createBrowserRouter([
{
path: "/",
Expand All @@ -26,9 +26,11 @@ const App = () => {
path: "app/flow/:flowId",
element: (
<ReactFlowProvider>
<UndoRedoProvider>
<Flow />
</UndoRedoProvider>
<PopUpProvider>
<UndoRedoProvider>
<Flow />
</UndoRedoProvider>
</PopUpProvider>
</ReactFlowProvider>
),
loader: Preloader,
Expand Down
132 changes: 132 additions & 0 deletions frontend/src/UI/Input/DefCombobox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as Popover from "@radix-ui/react-popover"
import classNames from "classnames"
import { CheckIcon } from "lucide-react"
import React, { ReactNode, useCallback, useEffect, useRef, useState } from "react"

interface ComboboxProps {
items: string[]
placeholder?: string
selected: string
setSelected: (value: string) => void
startContent?: ReactNode // Дополнительный контент в начале input
endContent?: ReactNode // Дополнительный контент в конце input
}

const DefCombobox: React.FC<ComboboxProps> = ({
selected,
setSelected,
items,
placeholder = "Select an option",
endContent,
startContent,
}) => {
const [inputValue, setInputValue] = useState("")
const [isOpen, setIsOpen] = useState(false)
const [filteredItems, setFilteredItems] = useState(items)
const [highlightedIndex, setHighlightedIndex] = useState(-1)
const containerRef = useRef<HTMLDivElement>(null)
const inputRef = useRef<HTMLInputElement>(null)

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setInputValue(value)
setFilteredItems(items.filter((item) => item.toLowerCase().includes(value.toLowerCase())))
setHighlightedIndex(-1) // Сбрасываем выделение
setIsOpen(true)
}

const handleSelectItem = useCallback(
(item: string) => {
setInputValue(item)
setSelected(item)
setIsOpen(false)
},
[setSelected]
)

useEffect(() => {
if (isOpen && inputRef.current) {
inputRef.current.focus() // Ставим фокус обратно на input при открытии
}
}, [isOpen])

useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (isOpen) {
if (e.key === "ArrowDown") {
setHighlightedIndex((prev) => Math.min(prev + 1, filteredItems.length - 1))
e.preventDefault() // Предотвращаем прокрутку страницы
} else if (e.key === "ArrowUp") {
setHighlightedIndex((prev) => Math.max(prev - 1, 0))
e.preventDefault() // Предотвращаем прокрутку страницы
} else if (e.key === "Enter" && highlightedIndex >= 0) {
handleSelectItem(filteredItems[highlightedIndex])
e.preventDefault() // Предотвращаем отправку формы, если она есть
}
}
}
window.addEventListener("keydown", handleKeyDown)

return () => {
window.removeEventListener("keydown", handleKeyDown)
}
}, [isOpen, highlightedIndex, filteredItems, handleSelectItem])

return (
<div className='combobox-container'>
<div
ref={containerRef}
className='w-full flex items-center justify-between bg-background p-2 rounded-lg border border-input-border hover:bg-bg-secondary transition-colors'>
{startContent && <span style={{ marginRight: "8px" }}>{startContent}</span>}
<input
ref={inputRef}
type='text'
value={inputValue}
onChange={handleInputChange}
placeholder={placeholder}
className='w-full bg-transparent outline-none placeholder:text-input-border text-sm'
/>
{endContent && <span style={{ marginLeft: "8px" }}>{endContent}</span>}
</div>

{/* Popover for dropdown menu */}
<Popover.Root
open={isOpen}
onOpenChange={setIsOpen}>
<Popover.Trigger asChild>
<div />
</Popover.Trigger>

<Popover.Content
onOpenAutoFocus={(e) => e.preventDefault()}
align='start'
side='bottom'
style={{
width: containerRef.current?.offsetWidth ?? "320px",
}}
className={`mt-2 bg-background border border-input-border rounded-lg py-1 z-[9999] overflow-x-hidden *:text-sm`}>
{filteredItems.length ? (
filteredItems.map((item, index) => (
<div
key={item}
className={classNames(
"flex items-center justify-between hover:bg-bg-secondary py-1 px-3 cursor-pointer transition-colors",
highlightedIndex === index && "bg-bg-secondary"
)}
onClick={() => handleSelectItem(item)}>
{item}
{selected === item && <CheckIcon className='size-4' />}
</div>
))
) : (
<div className='p-2'>No items found</div>
)}
</Popover.Content>
</Popover.Root>

{/* Стили для компонента */}
</div>
)
}

export default DefCombobox
52 changes: 52 additions & 0 deletions frontend/src/UI/Input/DefInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Input, InputProps, InputSlots, SlotsToClasses } from "@nextui-org/react"
import classNames from "classnames"


// const DefInput = ({ className, label, labelClassName, wrapperClassName, ...props }: DefInputType) => {
// return (
// <div className={classNames("flex flex-col w-full", wrapperClassName)}>
// <label className={classNames("text-sm text-input-border-focus font-medium", labelClassName)}>{label}</label>
// <input
// className={classNames(
// "min-h-10 h-10 bg-input-background text-input-foreground border border-input-border focus:border-input-border-focus focus:outline-input-border-focus placeholder:text-input-border-focus rounded-[8px] px-3.5",
// className
// )}
// {...props}
// />
// </div>
// )
// }

const defInputStyles: SlotsToClasses<InputSlots> = {
label: "text-black/50 dark:text-white/90",
input: [
"bg-transparent",
"placeholder:text-input-border-focus",
],
innerWrapper: "bg-transparent",
inputWrapper: [
"min-h-10 h-10",
"px-3.5",
"rounded-[8px]",
"shadow-none",
"bg-input-background",
"border border-input-border",
"hover:bg-transparent",
"group-data-[focus=true]:bg-input-background",
"group-data-[hover=true]:bg-input-background-disabled",
"!cursor-text",
],
}

const DefInput = ({ className, ...props }: InputProps) => {
return (
<Input
labelPlacement="outside"
classNames={defInputStyles}
className={classNames("w-full", className)}
{...props}
/>
)
}

export default DefInput
Loading
Loading