Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
84 changes: 36 additions & 48 deletions frontend/src/components/ChangeWarning/index.jsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,49 @@
import { Warning, X } from "@phosphor-icons/react";
import { Warning } from "@phosphor-icons/react";
import {
ModalHeader,
ModalBody,
ModalFooter,
ModalSecondaryButton,
ModalDangerButton,
} from "@/components/lib/Modal";

export default function ChangeWarningModal({
warningText = "",
onClose,
onConfirm,
}) {
return (
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden z-9999">
<div className="relative px-6 py-5 border-b rounded-t border-theme-modal-border">
<div className="w-full flex gap-x-2 items-center">
<Warning className="text-red-500 w-6 h-6" weight="fill" />
<h3 className="text-xl font-semibold text-red-500 overflow-hidden overflow-ellipsis whitespace-nowrap">
<div className="flex flex-col gap-y-5">
<ModalHeader
title={
<span className="flex items-center gap-x-2 text-red-500">
<Warning className="w-6 h-6 shrink-0" weight="fill" />
WARNING - This action is irreversible
</h3>
</div>
<button
onClick={onClose}
type="button"
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
>
<X size={24} weight="bold" className="text-white" />
</button>
</div>
<div
className="h-full w-full overflow-y-auto"
style={{ maxHeight: "calc(100vh - 200px)" }}
>
<div className="py-7 px-9 space-y-2 flex-col">
<p className="text-white">
{warningText.split("\\n").map((line, index) => (
<span key={index}>
{line}
<br />
</span>
))}
<br />
<br />
Are you sure you want to proceed?
</p>
</div>
</div>
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
<button
onClick={onClose}
type="button"
className="transition-all duration-300 bg-transparent text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm border-none"
>
</span>
}
onClose={onClose}
/>
<ModalBody>
<p className="text-zinc-300 light:text-slate-700">
{warningText.split("\\n").map((line, index) => (
<span key={index}>
{line}
<br />
</span>
))}
<br />
<br />
Are you sure you want to proceed?
</p>
</ModalBody>
<ModalFooter className="justify-end">
<ModalSecondaryButton onClick={onClose} type="button">
Cancel
</button>
<button
onClick={onConfirm}
type="submit"
className="transition-all duration-300 bg-red-500 light:text-white text-white hover:opacity-60 px-4 py-2 rounded-lg text-sm border-none"
>
</ModalSecondaryButton>
<ModalDangerButton onClick={onConfirm} type="submit">
Confirm
</button>
</div>
</ModalDangerButton>
</ModalFooter>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ import { useState, useRef } from "react";
import { useTranslation } from "react-i18next";
import CommunityHub from "@/models/communityHub";
import showToast from "@/utils/toast";
import paths from "@/utils/paths";
import { X, CaretRight } from "@phosphor-icons/react";
import { BLOCK_INFO } from "@/pages/Admin/AgentBuilder/BlockList";
import { Link } from "react-router-dom";
import {
ModalHeader,
ModalPrimaryButton,
ModalLabel,
ModalHint,
ModalInput,
ModalTextarea,
} from "@/components/lib/Modal";

export default function AgentFlows({ entity }) {
export default function AgentFlows({ entity, onSuccess }) {
const { t } = useTranslation();
const formRef = useRef(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [tags, setTags] = useState([]);
const [tagInput, setTagInput] = useState("");
const [isSuccess, setIsSuccess] = useState(false);
const [itemId, setItemId] = useState(null);
const [expandedStep, setExpandedStep] = useState(null);

const handleSubmit = async (e) => {
Expand All @@ -39,8 +43,7 @@ export default function AgentFlows({ entity }) {
const { success, error, itemId } =
await CommunityHub.createAgentFlow(data);
if (!success) throw new Error(error);
setItemId(itemId);
setIsSuccess(true);
onSuccess(itemId);
} catch (error) {
console.error("Failed to publish agent flow:", error);
showToast(`Failed to publish agent flow: ${error.message}`, "error", {
Expand All @@ -67,99 +70,58 @@ export default function AgentFlows({ entity }) {
setTags(tags.filter((tag) => tag !== tagToRemove));
};

if (isSuccess) {
return (
<div className="p-6 -mt-12 w-[400px]">
<div className="flex flex-col items-center justify-center gap-y-2">
<h3 className="text-lg font-semibold text-theme-text-primary">
{t("community_hub.publish.agent_flow.success_title")}
</h3>
<p className="text-lg text-theme-text-primary text-center max-w-2xl">
{t("community_hub.publish.agent_flow.success_description")}
</p>
<p className="text-theme-text-secondary text-center text-sm">
{t("community_hub.publish.agent_flow.success_thank_you")}
</p>
<Link
to={paths.communityHub.viewItem("agent-flow", itemId)}
target="_blank"
rel="noreferrer"
className="w-[265px] bg-theme-bg-secondary hover:bg-theme-sidebar-item-hover text-theme-text-primary py-2 px-4 rounded-lg transition-colors mt-4 text-sm font-semibold text-center"
>
{t("community_hub.publish.agent_flow.view_on_hub")}
</Link>
</div>
</div>
);
}

return (
<>
<div className="w-full flex gap-x-2 items-center mb-3 -mt-8">
<h3 className="text-xl font-semibold text-theme-text-primary px-6 py-3">
{t("community_hub.publish.agent_flow.modal_title")}
</h3>
<div className="w-full flex gap-x-2 items-center mb-3 -mt-8 px-6 py-3">
<ModalHeader
title={t("community_hub.publish.agent_flow.modal_title")}
/>
</div>
<form ref={formRef} className="flex" onSubmit={handleSubmit}>
<div className="w-1/2 p-6 pt-0 space-y-4">
<div>
<label className="block text-sm font-semibold text-theme-text-primary mb-1">
{t("community_hub.publish.agent_flow.name_label")}
</label>
<div className="text-xs text-theme-text-secondary mb-2">
{t("community_hub.publish.agent_flow.name_description")}
</div>
<input
type="text"
name="name"
required
minLength={3}
maxLength={300}
defaultValue={entity.name}
placeholder={t(
"community_hub.publish.agent_flow.name_placeholder"
)}
className="border-none w-full bg-theme-bg-secondary rounded-lg p-2 text-theme-text-primary text-sm focus:outline-primary-button active:outline-primary-button outline-none placeholder:text-theme-text-placeholder"
/>
</div>
<ModalInput
label={t("community_hub.publish.agent_flow.name_label")}
hint={t("community_hub.publish.agent_flow.name_description")}
type="text"
name="name"
required
minLength={3}
maxLength={300}
defaultValue={entity.name}
placeholder={t("community_hub.publish.agent_flow.name_placeholder")}
/>

<ModalTextarea
label={t("community_hub.publish.agent_flow.description_label")}
hint={t("community_hub.publish.agent_flow.description_description")}
name="description"
required
minLength={10}
maxLength={1000}
defaultValue={entity.description}
placeholder={t(
"community_hub.publish.agent_flow.description_description"
)}
className="min-h-[80px]"
/>
<div>
<label className="block text-sm font-semibold text-theme-text-primary mb-1">
{t("community_hub.publish.agent_flow.description_label")}
</label>
<div className="text-xs text-white/60 mb-2">
{t("community_hub.publish.agent_flow.description_description")}
</div>
<textarea
name="description"
required
minLength={10}
maxLength={1000}
defaultValue={entity.description}
placeholder={t(
"community_hub.publish.agent_flow.description_description"
)}
className="border-none w-full bg-theme-bg-secondary rounded-lg p-2 text-white text-sm focus:outline-primary-button active:outline-primary-button outline-none min-h-[80px] placeholder:text-theme-text-placeholder"
/>
</div>
<div>
<label className="block text-sm font-semibold text-white mb-1">
<ModalLabel>
{t("community_hub.publish.agent_flow.tags_label")}
</label>
<div className="text-xs text-white/60 mb-2">
</ModalLabel>
<ModalHint className="mb-2">
{t("community_hub.publish.agent_flow.tags_description")}
</div>
<div className="flex flex-wrap gap-2 p-2 bg-theme-bg-secondary rounded-lg min-h-[42px]">
</ModalHint>
<div className="flex flex-wrap gap-2 p-2 bg-zinc-800 light:bg-white border border-zinc-800 light:border-slate-300 rounded-lg min-h-[42px]">
{tags.map((tag, index) => (
<span
key={index}
className="flex items-center gap-1 px-2 py-1 text-sm text-theme-text-primary bg-white/10 light:bg-black/10 rounded-md"
className="flex items-center gap-1 px-2 py-1 text-sm text-slate-50 light:text-slate-900 bg-white/10 light:bg-black/10 rounded-md"
>
{tag}
<button
type="button"
onClick={() => removeTag(tag)}
className="border-none text-theme-text-primary hover:text-theme-text-secondary cursor-pointer"
className="border-none bg-transparent text-slate-50 light:text-slate-900 hover:text-zinc-400 light:hover:text-slate-600 cursor-pointer"
>
<X size={14} />
</button>
Expand All @@ -173,27 +135,25 @@ export default function AgentFlows({ entity }) {
placeholder={t(
"community_hub.publish.agent_flow.tags_placeholder"
)}
className="flex-1 min-w-[200px] border-none text-sm bg-transparent text-theme-text-primary placeholder:text-theme-text-placeholder p-0 h-[24px] focus:outline-none"
className="flex-1 min-w-[200px] border-none text-sm bg-transparent text-slate-50 light:text-slate-900 placeholder:text-zinc-400 light:placeholder:text-slate-400 p-0 h-[24px] focus:outline-none"
/>
</div>
</div>
<div>
<label className="block text-sm font-semibold text-white">
<ModalLabel>
{t("community_hub.publish.agent_flow.visibility_label")}
</label>
<span className="text-xs text-theme-text-secondary">
</ModalLabel>
<ModalHint>
{t("community_hub.publish.agent_flow.privacy_note")}
</span>
</ModalHint>
</div>
</div>
<div className="w-1/2 p-6 pt-0 flex flex-col gap-y-4">
<div>
<label className="block text-sm font-semibold text-theme-text-primary mb-1">
Flow Steps
</label>
<div className="text-xs text-white/60">
<ModalLabel>Flow Steps</ModalLabel>
<ModalHint>
The steps the agent will follow when the flow is triggered.
</div>
</ModalHint>
</div>
<div className="flex flex-col gap-y-0.5">
{entity.steps && entity.steps.length > 0 ? (
Expand All @@ -206,54 +166,54 @@ export default function AgentFlows({ entity }) {
return (
<div key={idx} className="flex flex-col items-center w-full">
<div
className="flex flex-col bg-theme-bg-secondary rounded-lg px-3 py-2 w-full cursor-pointer group"
className="flex flex-col bg-zinc-800 light:bg-white border border-zinc-800 light:border-slate-300 rounded-lg px-3 py-2 w-full cursor-pointer group"
onClick={() => setExpandedStep(isExpanded ? null : idx)}
>
<div className="flex items-center gap-x-3 w-full">
<span>{info?.icon}</span>
<span className="text-theme-text-primary text-sm font-medium flex-1">
<span className="text-slate-50 light:text-slate-900 text-sm font-medium flex-1">
{info?.label || step.type}
</span>
{!isExpanded && (
<span className="text-theme-text-secondary text-xs ml-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-[120px] min-w-0">
<span className="text-zinc-400 light:text-slate-600 text-xs ml-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-[120px] min-w-0">
{summary}
</span>
)}
<span
className={`ml-2 text-theme-text-secondary transition-transform duration-200 ${isExpanded ? "rotate-90" : ""}`}
className={`ml-2 text-zinc-400 light:text-slate-600 transition-transform duration-200 ${isExpanded ? "rotate-90" : ""}`}
>
<CaretRight size={16} />
</span>
</div>
{isExpanded && summary && (
<div className="w-full text-theme-text-secondary text-xs mt-1 whitespace-pre-line break-words">
<div className="w-full text-zinc-400 light:text-slate-600 text-xs mt-1 whitespace-pre-line break-words">
{summary}
</div>
)}
</div>
{idx < entity.steps.length - 1 && (
<span className="text-theme-text-secondary text-lg my-1">
<span className="text-zinc-400 light:text-slate-600 text-lg my-1">
↓
</span>
)}
</div>
);
})
) : (
<div className="text-theme-text-secondary text-xs">
<div className="text-zinc-400 light:text-slate-600 text-xs">
No steps defined.
</div>
)}
</div>
<button
<ModalPrimaryButton
type="submit"
disabled={isSubmitting}
className="border-none mt-4 w-full bg-cta-button hover:opacity-80 text-theme-text-primary font-medium py-2 px-4 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
className="mt-4 w-full"
>
{isSubmitting
? t("community_hub.publish.agent_flow.submitting")
: t("community_hub.publish.agent_flow.submit")}
</button>
</ModalPrimaryButton>
</div>
</form>
</>
Expand Down
Loading
Loading