mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
add toast message for first API run
This commit is contained in:
2
desktop/Cargo.lock
generated
vendored
2
desktop/Cargo.lock
generated
vendored
@@ -5673,7 +5673,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openbb-platform"
|
||||
version = "0.8.2"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"chrono",
|
||||
|
||||
2
desktop/src-tauri/Cargo.toml
vendored
2
desktop/src-tauri/Cargo.toml
vendored
@@ -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"
|
||||
|
||||
4
desktop/src-tauri/tauri.conf.json
vendored
4
desktop/src-tauri/tauri.conf.json
vendored
@@ -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
55
desktop/src/components/Toast.tsx
vendored
Normal 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;
|
||||
77
desktop/src/routes/backends.tsx
vendored
77
desktop/src/routes/backends.tsx
vendored
@@ -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">
|
||||
|
||||
47
desktop/src/styles.css
vendored
47
desktop/src/styles.css
vendored
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user