Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
105 changes: 91 additions & 14 deletions frontend/src/components/custom-tools/header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { SettingOutlined } from "@ant-design/icons";
import { Button, Dropdown, Modal, Tooltip, Typography } from "antd";
import {
Button,
Dropdown,
Form,
Input,
Modal,
Tooltip,
Typography,

Check warning on line 9 in frontend/src/components/custom-tools/header/Header.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused import of 'Typography'.

See more on https://sonarcloud.io/project/issues?id=Zipstack_unstract&issues=AZ1Dj5CcE68WA7jOmXrj&open=AZ1Dj5CcE68WA7jOmXrj&pullRequest=1882
} from "antd";
import PropTypes from "prop-types";
import { useCallback, useState } from "react";
import { ExportToolIcon } from "../../../assets";
Expand All @@ -10,9 +18,9 @@
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 +78,8 @@
] = 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 +304,34 @@
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 +411,56 @@
/>
)}
</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 ? undefined : `/${sessionDetails?.orgName}/tools`
}
onEditTitle={isPublicSource ? 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 +522,7 @@
)}
<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
97 changes: 77 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,88 @@
/* 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;
}

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

.api-search-input {
.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 icon: hidden by default, appears on title-area hover */
.tool-nav-bar__edit-icon {
font-size: 16px;
color: var(--ant-color-text-secondary, #8c8c8c);
cursor: pointer;
opacity: 0;
transition:
opacity 0.15s,
color 0.15s;
}

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