display actions

This commit is contained in:
Robert 2024-03-09 04:48:50 +07:00
parent bbee6bc2ed
commit a51c43c500
No known key found for this signature in database
GPG Key ID: F631C7FD957D5F22
2 changed files with 94 additions and 14 deletions

View File

@ -45,12 +45,16 @@ interface ActionEditorProps {
actionIndex?: number; actionIndex?: number;
initialAction?: CommentAction; initialAction?: CommentAction;
onSave?: (actionIndex: number, action: CommentAction) => Promise<void> | void; onSave?: (actionIndex: number, action: CommentAction) => Promise<void> | void;
onClose?: () => Promise<void> | void;
canExit?: boolean;
} }
export default function ActionEditor({ export default function ActionEditor({
actionIndex = 0, actionIndex = 0,
initialAction, initialAction,
onSave, onSave,
onClose,
canExit = false,
}: ActionEditorProps) { }: ActionEditorProps) {
const [value, setValue] = useState(0); const [value, setValue] = useState(0);
@ -117,7 +121,17 @@ export default function ActionEditor({
</Box> </Box>
</div> </div>
<div className="mt-4"> <div className="mt-4 flex gap-x-4">
{canExit && (
<Button
color="error"
onClick={() => {
if (onClose) onClose();
}}
>
Отменить
</Button>
)}
<Button <Button
variant="contained" variant="contained"
type="submit" type="submit"

View File

@ -2,24 +2,29 @@ import type { Chain } from "@/entities/chain/schema";
import { useChainState } from "@/entities/chain/model"; import { useChainState } from "@/entities/chain/model";
import { useNavigate } from "@tanstack/react-router"; import { useNavigate } from "@tanstack/react-router";
import { useState, useRef } from "react";
import humanizeDuration from "humanize-duration";
import { upsertChain } from "@/entities/chain/api/upsert"; import { upsertChain } from "@/entities/chain/api/upsert";
import { ActionEditor } from "@/widgets/action-editor"; import { ActionEditor } from "@/widgets/action-editor";
import { RenameChainButton } from "@/features/rename-chain"; import { RenameChainButton } from "@/features/rename-chain";
import { DeleteChainButton } from "@/features/delete-chain"; import { DeleteChainButton } from "@/features/delete-chain";
import { Typography } from "@mui/material"; import { Typography, Button } from "@mui/material";
import Breadcrumbs from "@mui/material/Breadcrumbs"; import Breadcrumbs from "@mui/material/Breadcrumbs";
import SettingsIcon from "@mui/icons-material/Settings";
interface ChainEditorProps { interface ChainEditorProps {
chain: Chain; chain: Chain;
} }
export default function ChainEditor({ chain }: ChainEditorProps) { export default function ChainEditor({ chain }: ChainEditorProps) {
const actionsListRef = useRef<HTMLDivElement>(null);
const [addingNewAction, setAddingNewAction] = useState(false);
const navigate = useNavigate({ from: "/$namespace/$chainId" }); const navigate = useNavigate({ from: "/$namespace/$chainId" });
const addCommentAction = useChainState((state) => state.addCommentAction); const addCommentAction = useChainState((state) => state.addCommentAction);
if (!chain.actions || chain.actions.length === 0) if (!chain.actions || chain.actions.length === 0 || addingNewAction)
return ( return (
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -51,26 +56,87 @@ export default function ChainEditor({ chain }: ChainEditorProps) {
onSave={async (_, action) => { onSave={async (_, action) => {
addCommentAction(chain._id!, action); addCommentAction(chain._id!, action);
await upsertChain(chain); await upsertChain(chain);
if (addingNewAction) setAddingNewAction(false);
navigate({ to: "/$namespace/$chainId" }); navigate({ to: "/$namespace/$chainId" });
setTimeout(
() =>
actionsListRef.current?.scrollTo({
behavior: "smooth",
top: actionsListRef.current.scrollHeight,
}),
0,
);
}} }}
onClose={() => {
if (addingNewAction) setAddingNewAction(false);
}}
canExit={addingNewAction}
/> />
</div> </div>
</div> </div>
); );
return ( return (
<div className="flex items-center justify-between"> <div className="relative flex h-full flex-col">
<Typography <div className="flex items-center justify-between">
variant="h5" <Typography
sx={{ color: "#4C4E64DE", opacity: "87%" }} variant="h5"
className="select-none" sx={{ color: "#4C4E64DE", opacity: "87%" }}
> className="select-none"
{chain.name} >
</Typography> {chain.name}
</Typography>
<div className="flex items-center gap-x-5">
<RenameChainButton chain={chain} />
<DeleteChainButton chain={chain} />
</div>
</div>
<div className="flex items-center gap-x-5"> <div
<RenameChainButton chain={chain} /> ref={actionsListRef}
<DeleteChainButton chain={chain} /> className="no-scrollbar mt-8 flex grow flex-col items-center gap-y-24 overflow-y-scroll pb-20"
>
{chain.actions.map((action, index) => {
if (action.actionType === "comment")
return (
<div
key={index}
className="relative w-[450px] select-none whitespace-pre-line rounded-md bg-white p-4 text-[#4C4E64DE] opacity-[84%] shadow-lg after:absolute after:left-1/2 after:top-20 after:h-8 after:w-1 after:-translate-x-1/2 after:rounded-md after:bg-[#666CFF] after:opacity-[12%]"
>
{action.text}
</div>
);
return (
<div
key={index}
className="relative flex select-none items-center gap-x-2 text-[#4C4E64DE] opacity-[84%] before:absolute before:-top-6 before:left-1/2 before:h-4 before:w-4 before:-translate-x-1/2 before:rounded-full before:border-[2.5px] before:border-primary after:absolute after:left-1/2 after:top-11 after:h-16 after:w-1 after:-translate-x-1/2 after:rounded-md after:bg-[#666CFF] after:opacity-[12%]"
>
<span>
Ожидание:{" "}
{humanizeDuration(action.waitFor * 1000, { language: "ru" })}
</span>
<button className="flex h-[20px] items-center justify-center rounded-sm bg-[#4C4E648A] bg-opacity-[54%] p-0">
<SettingsIcon sx={{ width: "20px", color: "white" }} />
</button>
</div>
);
})}
<div className="-mt-4">
<Button
variant="outlined"
sx={{
width: "450px",
}}
onClick={() => setAddingNewAction(true)}
>
Добавить
</Button>
</div>
</div> </div>
</div> </div>
); );