add toast message for first API run

This commit is contained in:
Danglewood
2025-10-20 13:51:51 -07:00
parent a58faac59d
commit acc2026ea7
6 changed files with 182 additions and 5 deletions

2
desktop/Cargo.lock generated vendored
View File

@@ -5673,7 +5673,7 @@ dependencies = [
[[package]]
name = "openbb-platform"
version = "0.8.2"
version = "0.9.0"
dependencies = [
"cc",
"chrono",

View File

@@ -1,6 +1,6 @@
[package]
name = "openbb-platform"
version = "0.8.2"
version = "0.9.0"
description = "Open Data Platform - by OpenBB - Desktop Application for managing virtual environments, application backend servers."
authors = ["OpenBB, Inc."]
license = "AGPL-3.0"

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Open Data Platform",
"version": "0.8.2",
"version": "0.9.0",
"identifier": "co.openbb.platform",
"build": {
"frontendDist": "../dist",
@@ -49,7 +49,7 @@
"icons/icon.icns",
"icons/icon.ico"
],
"category": "Finance",
"category": "DeveloperTool",
"publisher": "OpenBB, Inc.",
"copyright": "Copyright © 2025 OpenBB, Inc.",
"license": "AGPLv3",

55
desktop/src/components/Toast.tsx vendored Normal file
View File

@@ -0,0 +1,55 @@
import React from "react";
import { Button } from "@openbb/ui-pro";
import CustomIcon from "../components/Icon";
interface ToastProps {
title: string;
children: React.ReactNode;
onClose: () => void;
buttonText?: string;
onButtonClick?: () => void;
}
const Toast: React.FC<ToastProps> = ({
title,
children,
onClose,
buttonText,
onButtonClick,
}) => {
return (
<div className="toast-container">
<div className="flex-col">
<div className="flex flex-1 items-center justify-between">
<div className="flex flex1 gap-2 items-start">
<CustomIcon id="info" className="toast-info-icon w-5 h-5"/>
<div className="body-sm-bold">{title}</div>
</div>
<Button
type="button"
variant="icon"
onClick={onClose}
>
<span className="items-end body-lg-bold">x</span>
</Button>
</div>
<div className="flex-1 mt-2 body-sm-medium justify-left mr-5 pr-10">{children}</div>
{buttonText && onButtonClick && (
<div className="mt-5 mr-5 flex justify-end">
<Button
type="button"
className="button-toast"
onClick={onButtonClick}
size="xs"
>
{buttonText}
</Button>
</div>
)}
</div>
</div>
);
};
export default Toast;

View File

@@ -15,6 +15,7 @@ import Select, { components } from 'react-select';
import { CopyIcon, DocumentationIcon, FileIcon, FolderIcon, HelpIcon, SettingsIcon } from "../components/Icon";
import CustomIcon from "~/components/Icon";
import Toast from "../components/Toast";
// ============== TYPES ==============
@@ -2171,6 +2172,13 @@ function loadEnvironmentsFromCache(): Environment[] {
export default function BackendsPage() {
const isMounted = useRef(true);
const [showToast, setShowToast] = useState(false);
const [toastContent, setToastContent] = useState<{
title: string;
content: React.ReactNode;
buttonText: string;
}>({ title: "", content: <></>, buttonText: "" });
// Core state
const [backends, setBackends] = useState<BackendService[]>([]);
const [selectedBackend, setSelectedBackend] = useState<string | null>(null);
@@ -2221,7 +2229,56 @@ export default function BackendsPage() {
!localStorage.getItem("platform-api-run-once")
) {
localStorage.setItem("platform-api-run-once", "true");
openUrl(finalUrl).catch(console.error);
setToastContent({
title: "Connect Backend with OpenBB Workspace",
content: (
<ol className="list-decimal list-inside">
<li>Sign in to your OpenBB Workspace account.</li>
<li>Go to the "Apps" tab in the top menu.</li>
<li>Click on "Connect backend".</li>
<li>
Fill in the connection form with the following details:
<ul className="list-disc list-inside ml-4">
<li>Name: OpenBB Platform</li>
<li>URL: {finalUrl}</li>
</ul>
</li>
<li>Click "Test".</li>
<li>Click "Add" to finalize the integration.</li>
</ol>
),
buttonText: "Check Documentation",
});
setShowToast(true);
}
if (
backend.name === "OpenBB MCP" &&
!localStorage.getItem("platform-mcp-run-once")
) {
localStorage.setItem("platform-mcp-run-once", "true");
setToastContent({
title: "Connect MCP with OpenBB Workspace",
content: (
<ol className="list-decimal list-inside">
<li>Sign in to your OpenBB Workspace account.</li>
<li>Go to the Chat on the right side.</li>
<li>Click on "MCP Tools" button above the chat input.</li>
<li>Click on "+" in the top-right to open the configuration panel.</li>
<li>Click on "Add Server".</li>
<li>
Fill in the connection form with the following details:
<ul className="list-disc list-inside ml-4">
<li>Name: OpenBB MCP</li>
<li>URL: {finalUrl}</li>
</ul>
</li>
<li>Check the box "Local Server".</li>
<li>Click "Add" to finalize the integration.</li>
</ol>
),
buttonText: "Check Documentation",
});
setShowToast(true);
}
}
return prevBackends.map((b) =>
@@ -2493,6 +2550,24 @@ export default function BackendsPage() {
return (
<div className="w-full h-full">
{showToast && (
<div className="fixed top-3 right-3 z-50">
<Toast
title={toastContent.title}
onClose={() => setShowToast(false)}
buttonText={toastContent.buttonText}
onButtonClick={() => {
const url = toastContent.title.includes("MCP")
? "https://docs.openbb.co/python/quickstart/mcp"
: "https://docs.openbb.co/python/quickstart/workspace";
openUrl(url).catch(console.error);
setShowToast(false);
}}
>
{toastContent.content}
</Toast>
</div>
)}
{isCreating || isEditing ? (
// Form View
<div className="fixed inset-0 z-50 bg-black/90 flex items-center justify-center overflow-auto" role="dialog">

View File

@@ -45,8 +45,10 @@
--bg-secondary: #f7f7f9;
--bg-tertiary: #efeff2;
--bg-accent: rgb(0, 136, 204, 0.3);
--bg-toast: rgba(212, 229, 252, 1);
--text-primary: #151518;
--text-primary-inverse: #ffffff;
--text-secondary: #2c2c32;
--text-tertiary: #6f6d80;
--text-muted: rgba(21, 21, 24, 0.35);
@@ -73,6 +75,7 @@
--info-icon: rgba(138, 138, 144, 1);
--tab-border-active: #007acc;
--tag-bg: rgba(90, 89, 97, 0.3);
--info-icon: rgba(138, 138, 144, 1);
}
.dark {
@@ -82,6 +85,7 @@
--bg-quartary: rgba(36, 36, 42, 1);
--bg-accent: rgb(0, 136, 204, 0.3);
--text-primary: #ffffff;
--text-primary-inverse: #151518;
--text-secondary: #EBEBED;
--text-tertiary: #9793b0;
--text-muted: rgba(138, 138, 144, 1);
@@ -107,6 +111,7 @@
--tag-bg: rgba(90, 89, 97, 0.3);
--dropdown-bg: rgba(36, 36, 42, 1);
--info-icon: rgba(138, 138, 144, 1);
--bg-toast: rgba(212, 229, 252, 1);
}
.info-icon {
@@ -119,6 +124,48 @@
background-color: var(--tag-bg);
}
.bg-theme-toast {
background-color: var(--bg-toast);
}
.button-toast,
.button-toast:focus,
.button-toast:focus-visible,
.dark .button-toast,
.dark .button-toast:focus,
.dark .button-toast:focus-visible {
background-color: rgb(0, 136, 204, 1);
color: #ffffff;
padding: 8px;
border-radius: 0.375rem;
}
.button-toast:hover,
.dark .button-toast:hover {
background-color: rgb(0, 136, 204, 0.85);
color: #ffffff;
}
.toast-container, .dark .toast-container {
background-color: var(--bg-toast);
border-radius: 0.5rem;
color: var(--text-primary-inverse);
padding-top: 10px;
padding-bottom: 20px;
padding-left: 20px;
padding-right: 0;
font-weight: medium;
box-shadow: 0 10px 12px rgba(0, 0, 0, 0.3);
}
.toast-info-icon {
color: var(--button-neutral-bg);
width: 25px;
height: 25px;
font-weight: bold;
}
/* UTILITY CLASSES */
.text-theme-accent {
color: var(--text-accent);