feat: use librechat instead of own chat (#14)
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com> Reviewed-on: #14
This commit was merged in pull request #14.
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_free_icons::icons::bs_icons::{
|
||||
BsBoxArrowRight, BsBuilding, BsChatDots, BsCloudArrowUp, BsCodeSlash, BsCollection, BsGithub,
|
||||
BsGlobe2, BsGrid, BsHouseDoor, BsMoonFill, BsPuzzle, BsSunFill,
|
||||
BsBoxArrowRight, BsBuilding, BsChatDots, BsCloudArrowUp, BsCodeSlash, BsGithub, BsGlobe2,
|
||||
BsGrid, BsHouseDoor, BsMoonFill, BsSunFill,
|
||||
};
|
||||
use dioxus_free_icons::Icon;
|
||||
|
||||
use crate::i18n::{t, Locale};
|
||||
use crate::Route;
|
||||
|
||||
/// Destination for a sidebar link: either an internal route or an external URL.
|
||||
enum NavTarget {
|
||||
/// Internal Dioxus route (rendered as `Link { to: route }`).
|
||||
Internal(Route),
|
||||
/// External URL opened in a new tab (rendered as `<a href>`).
|
||||
External(&'static str),
|
||||
}
|
||||
|
||||
/// Navigation entry for the sidebar.
|
||||
///
|
||||
/// `key` is a stable identifier used for active-route detection and never
|
||||
@@ -15,7 +23,7 @@ use crate::Route;
|
||||
struct NavItem {
|
||||
key: &'static str,
|
||||
label: String,
|
||||
route: Route,
|
||||
target: NavTarget,
|
||||
/// Bootstrap icon element rendered beside the label.
|
||||
icon: Element,
|
||||
}
|
||||
@@ -45,43 +53,32 @@ pub fn Sidebar(
|
||||
NavItem {
|
||||
key: "dashboard",
|
||||
label: t(locale_val, "nav.dashboard"),
|
||||
route: Route::DashboardPage {},
|
||||
target: NavTarget::Internal(Route::DashboardPage {}),
|
||||
icon: rsx! { Icon { icon: BsHouseDoor, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "providers",
|
||||
label: t(locale_val, "nav.providers"),
|
||||
route: Route::ProvidersPage {},
|
||||
target: NavTarget::Internal(Route::ProvidersPage {}),
|
||||
icon: rsx! { Icon { icon: BsCloudArrowUp, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "chat",
|
||||
label: t(locale_val, "nav.chat"),
|
||||
route: Route::ChatPage {},
|
||||
// Opens LibreChat in a new tab; SSO via shared Keycloak realm.
|
||||
target: NavTarget::External("http://localhost:3080"),
|
||||
icon: rsx! { Icon { icon: BsChatDots, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "tools",
|
||||
label: t(locale_val, "nav.tools"),
|
||||
route: Route::ToolsPage {},
|
||||
icon: rsx! { Icon { icon: BsPuzzle, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "knowledge_base",
|
||||
label: t(locale_val, "nav.knowledge_base"),
|
||||
route: Route::KnowledgePage {},
|
||||
icon: rsx! { Icon { icon: BsCollection, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "developer",
|
||||
label: t(locale_val, "nav.developer"),
|
||||
route: Route::AgentsPage {},
|
||||
target: NavTarget::Internal(Route::AgentsPage {}),
|
||||
icon: rsx! { Icon { icon: BsCodeSlash, width: 18, height: 18 } },
|
||||
},
|
||||
NavItem {
|
||||
key: "organization",
|
||||
label: t(locale_val, "nav.organization"),
|
||||
route: Route::OrgPricingPage {},
|
||||
target: NavTarget::Internal(Route::OrgPricingPage {}),
|
||||
icon: rsx! { Icon { icon: BsBuilding, width: 18, height: 18 } },
|
||||
},
|
||||
];
|
||||
@@ -100,25 +97,45 @@ pub fn Sidebar(
|
||||
nav { class: "sidebar-nav",
|
||||
for item in nav_items {
|
||||
{
|
||||
// Active detection for nested routes: highlight the parent nav
|
||||
// item when any child route within the nested shell is active.
|
||||
let is_active = match ¤t_route {
|
||||
Route::AgentsPage {} | Route::FlowPage {} | Route::AnalyticsPage {} => {
|
||||
item.key == "developer"
|
||||
match &item.target {
|
||||
NavTarget::Internal(route) => {
|
||||
// Active detection for nested routes: highlight the parent
|
||||
// nav item when any child route within the nested shell
|
||||
// is active.
|
||||
let is_active = match ¤t_route {
|
||||
Route::AgentsPage {} | Route::FlowPage {} | Route::AnalyticsPage {} => {
|
||||
item.key == "developer"
|
||||
}
|
||||
Route::OrgPricingPage {} | Route::OrgDashboardPage {} => {
|
||||
item.key == "organization"
|
||||
}
|
||||
_ => *route == current_route,
|
||||
};
|
||||
let cls = if is_active { "sidebar-link active" } else { "sidebar-link" };
|
||||
let route = route.clone();
|
||||
rsx! {
|
||||
Link {
|
||||
to: route,
|
||||
class: cls,
|
||||
onclick: move |_| on_nav.call(()),
|
||||
{item.icon}
|
||||
span { "{item.label}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
Route::OrgPricingPage {} | Route::OrgDashboardPage {} => {
|
||||
item.key == "organization"
|
||||
}
|
||||
_ => item.route == current_route,
|
||||
};
|
||||
let cls = if is_active { "sidebar-link active" } else { "sidebar-link" };
|
||||
rsx! {
|
||||
Link {
|
||||
to: item.route,
|
||||
class: cls,
|
||||
onclick: move |_| on_nav.call(()),
|
||||
{item.icon}
|
||||
span { "{item.label}" }
|
||||
NavTarget::External(url) => {
|
||||
let url = *url;
|
||||
rsx! {
|
||||
a {
|
||||
href: url,
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer",
|
||||
class: "sidebar-link",
|
||||
onclick: move |_| on_nav.call(()),
|
||||
{item.icon}
|
||||
span { "{item.label}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user