Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
15 changes: 0 additions & 15 deletions frontend/src/components/custom-tools/header/Header.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
/* Styles for Header */

.custom-tools-header-layout {
padding: 8px;
background-color: #f5f7f9;
display: flex;
align-items: center;
}

.custom-tools-header-btns {
display: flex;
justify-content: space-between;
Expand All @@ -17,14 +10,6 @@
padding: 0px 5px;
}

.custom-tools-name {
padding: 0px 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
}

.custom-tools-header-v-divider {
border-right: 1px #d9d9d9 solid;
padding: 0;
Expand Down
101 changes: 87 additions & 14 deletions frontend/src/components/custom-tools/header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SettingOutlined } from "@ant-design/icons";
import { Button, Dropdown, Modal, Tooltip, Typography } from "antd";
import { Button, Dropdown, Form, Input, Modal, Tooltip } from "antd";
import PropTypes from "prop-types";
import { useCallback, useState } from "react";
import { ExportToolIcon } from "../../../assets";
Expand All @@ -10,9 +10,9 @@ import { useAlertStore } from "../../../store/alert-store";
import { useCustomToolStore } from "../../../store/custom-tool-store";
import { useSessionStore } from "../../../store/session-store";
import { CreateApiDeploymentFromPromptStudio } from "../../deployments/create-api-deployment-from-prompt-studio/CreateApiDeploymentFromPromptStudio.jsx";
import { ToolNavBar } from "../../navigations/tool-nav-bar/ToolNavBar";
import { CustomButton } from "../../widgets/custom-button/CustomButton";
import { ExportTool } from "../export-tool/ExportTool";
import { HeaderTitle } from "../header-title/HeaderTitle.jsx";
import "./Header.css";

let SinglePassToggleSwitch;
Expand Down Expand Up @@ -70,6 +70,8 @@ function Header({
] = useState(false);
const [existingApiDeployments, setExistingApiDeployments] = useState([]);
const [isApiDeploymentLoading, setIsApiDeploymentLoading] = useState(false);
const [editModalOpen, setEditModalOpen] = useState(false);
const [editForm] = Form.useForm();

const handleExport = (
selectedUsers,
Expand Down Expand Up @@ -294,17 +296,34 @@ function Header({
setOpenCreateApiDeploymentModal(true);
}, []);

return (
<div className="custom-tools-header-layout">
{isPublicSource ? (
<div>
<Typography.Text className="custom-tools-name" strong>
{details?.tool_name}
</Typography.Text>
</div>
) : (
<HeaderTitle />
)}
const handleOpenEditModal = useCallback(() => {
editForm.setFieldsValue({
tool_name: details?.tool_name || "",
description: details?.description || "",
});
setEditModalOpen(true);
}, [details, editForm]);

const handleEditSubmit = useCallback(async () => {
try {
const values = await editForm.validateFields();
const res = await handleUpdateTool(values);
const updatedData = res?.data;
if (updatedData) {
useCustomToolStore
.getState()
.updateCustomTool({ details: updatedData });
}
setEditModalOpen(false);
setAlertDetails({ type: "success", content: "Updated successfully" });
} catch (err) {
if (err?.errorFields) return;
setAlertDetails(handleException(err, "Failed to update"));
}
}, [editForm, handleUpdateTool, setAlertDetails, handleException]);

const ActionButtons = useCallback(
() => (
<div className="custom-tools-header-btns">
{SinglePassToggleSwitch && (
<SinglePassToggleSwitch handleUpdateTool={handleUpdateTool} />
Expand Down Expand Up @@ -384,6 +403,60 @@ function Header({
/>
)}
</div>
),
[
handleUpdateTool,
setOpenSettings,
setOpenCloneModal,
setOpenShareModal,
isPublicSource,
isExportLoading,
isApiDeploymentLoading,
userList,
openExportToolModal,
toolDetails,
details,
openCreateApiDeploymentModal,
],
);

return (
<>
<ToolNavBar
title={details?.tool_name || ""}
subtitle={isPublicSource ? undefined : details?.description || ""}
previousRoute={
isPublicSource || !sessionDetails?.orgName
? undefined
: `/${sessionDetails.orgName}/tools`
}
onEditTitle={
isPublicSource || !details?.tool_id ? undefined : handleOpenEditModal
}
CustomButtons={ActionButtons}
/>
<Modal
title="Edit Project"
open={editModalOpen}
onOk={handleEditSubmit}
onCancel={() => setEditModalOpen(false)}
okText="Save"
centered
destroyOnClose
>
<Form form={editForm} layout="vertical">
<Form.Item
name="tool_name"
label="Project Name"
rules={[{ required: true, message: "Name is required" }]}
>
<Input />
</Form.Item>
<Form.Item name="description" label="Description">
<Input.TextArea rows={3} />
</Form.Item>
</Form>
</Modal>
<Modal
onOk={handleConfirmForceExport} // Pass the confirm action
onCancel={() => setConfirmModalVisible(false)} // Close the modal on cancel
Expand Down Expand Up @@ -445,7 +518,7 @@ function Header({
)}
<p>Do you want to proceed with creating the API deployment?</p>
</Modal>
</div>
</>
);
}

Expand Down
14 changes: 6 additions & 8 deletions frontend/src/components/custom-tools/tool-ide/ToolIde.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,12 @@ function ToolIde() {
isExporting={isExporting}
/>
)}
<div>
<Header
handleUpdateTool={handleUpdateTool}
setOpenSettings={setOpenSettings}
setOpenShareModal={setOpenShareModal}
setOpenCloneModal={setOpenCloneModal}
/>
</div>
<Header
handleUpdateTool={handleUpdateTool}
setOpenSettings={setOpenSettings}
setOpenShareModal={setOpenShareModal}
setOpenCloneModal={setOpenCloneModal}
/>
<div
className={isPublicSource ? "public-tool-ide-body" : "tool-ide-body"}
>
Expand Down
95 changes: 75 additions & 20 deletions frontend/src/components/navigations/tool-nav-bar/ToolNavBar.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,86 @@
/* Styles for ToolNavBar */
/* ToolNavBar — top navigation bar for pages and detail views */

.search-navbar-dp {
height: 25px;
width: 25px;
.tool-nav-bar {
display: flex;
align-items: center;
justify-content: center;
background-color: #184772;
border-radius: 5px;
cursor: pointer;
justify-content: space-between;
gap: 12px;
padding: 8px 12px 8px 20px;
background-color: var(--page-bg-1, #f5f7f9);
box-shadow: 0 1px 3px 0 rgba(24, 50, 71, 0.08);
border-bottom: 1px solid var(--border-color-1, #dce4e4);
}

.tool-nav-bar__left {
display: flex;
align-items: center;
gap: 4px;
min-width: 0;
flex: 1;
}

.api-search-input {
.tool-nav-bar__right {
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}

.tool-nav-bar__search {
width: 250px;
margin-right: 10px;
}

.searchNav {
background-color: #f5f7f9;
padding-block: 12px;
padding-inline-start: 20px;
padding-inline-end: 12px;
height: 56px;
box-shadow: 0px 1px 3px 0px #18324714;
border: 1px solid #dce4e4;
.tool-nav-bar__segment {
background-color: rgba(0, 0, 0, 0.06);
}

/* Title area: hover reveals edit icon */
.tool-nav-bar__title-area {
display: flex;
align-items: center;
min-width: 0;
flex: 1;
}

.tool-nav-bar__title-area:hover .tool-nav-bar__edit-icon {
opacity: 1;
}

/* Title + subtitle stacked, centered vertically within available height */
.tool-nav-bar__title-group {
display: flex;
flex-direction: column;
justify-content: center;
min-width: 0;
}

/* Title text + edit icon inline */
.tool-nav-bar__title-row {
display: flex;
align-items: center;
gap: 6px;
}

.tool-nav-bar__title {
font-size: var(--font-size-16, 16px);
}

.tool-nav-bar .tool-nav-bar__subtitle {
font-size: var(--font-size-12, 12px);
line-height: 18px;
margin-bottom: 0;
max-width: min(600px, 45vw);
}

/* Edit button: hidden by default, appears on title-area hover */
.tool-nav-bar__edit-icon.ant-btn {
opacity: 0;
color: var(--ant-color-text-secondary, #8c8c8c);
transition:
opacity 0.15s,
color 0.15s;
}

.tool-bar-segment {
background-color: #0000000f;
.tool-nav-bar__edit-icon.ant-btn:hover {
color: var(--ant-color-primary, #1677ff);
}
Loading
Loading