mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
feat: Add Kubernetes documentation and mobile apps download section; update navigation and icons
This commit is contained in:
@@ -151,8 +151,8 @@ const DashboardNavbar: FunctionComponent<ComponentProps> = (
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTERS] as Route,
|
||||
),
|
||||
activeRoute: RouteMap[PageMap.KUBERNETES_CLUSTERS],
|
||||
icon: IconProp.Cube,
|
||||
iconColor: "teal",
|
||||
icon: IconProp.Kubernetes,
|
||||
iconColor: "blue",
|
||||
category: "Observability",
|
||||
},
|
||||
// Automation & Analytics
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import ExceptionsTable from "../../Components/Exceptions/ExceptionsTable";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const ArchivedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -16,13 +17,16 @@ const ArchivedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
|
||||
return (
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isArchived: true,
|
||||
}}
|
||||
title="Archived Exceptions"
|
||||
description="All the exceptions that have been archived. You will not be notified about these exceptions."
|
||||
/>
|
||||
<Fragment>
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isArchived: true,
|
||||
}}
|
||||
title="Archived Exceptions"
|
||||
description="All the exceptions that have been archived. You will not be notified about these exceptions."
|
||||
/>
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import ExceptionsTable from "../../Components/Exceptions/ExceptionsTable";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const ResolvedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -16,14 +17,17 @@ const ResolvedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
|
||||
return (
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isResolved: true,
|
||||
isArchived: false,
|
||||
}}
|
||||
title="Resolved Exceptions"
|
||||
description="All the exceptions that have been resolved."
|
||||
/>
|
||||
<Fragment>
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isResolved: true,
|
||||
isArchived: false,
|
||||
}}
|
||||
title="Resolved Exceptions"
|
||||
description="All the exceptions that have been resolved."
|
||||
/>
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import ExceptionsTable from "../../Components/Exceptions/ExceptionsTable";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const UnresolvedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -16,14 +17,17 @@ const UnresolvedExceptionsPage: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
|
||||
return (
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isResolved: false,
|
||||
isArchived: false,
|
||||
}}
|
||||
title="Unresolved Exceptions"
|
||||
description="All the exceptions that have not been resolved."
|
||||
/>
|
||||
<Fragment>
|
||||
<ExceptionsTable
|
||||
query={{
|
||||
isResolved: false,
|
||||
isArchived: false,
|
||||
}}
|
||||
title="Unresolved Exceptions"
|
||||
description="All the exceptions that have not been resolved."
|
||||
/>
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
import PageComponentProps from "../../PageComponentProps";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import Navigation from "Common/UI/Utils/Navigation";
|
||||
import KubernetesCluster from "Common/Models/DatabaseModels/KubernetesCluster";
|
||||
import Card from "Common/UI/Components/Card/Card";
|
||||
import React, {
|
||||
Fragment,
|
||||
FunctionComponent,
|
||||
ReactElement,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
|
||||
import API from "Common/UI/Utils/API/API";
|
||||
import PageLoader from "Common/UI/Components/Loader/PageLoader";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
|
||||
import MarkdownViewer from "Common/UI/Components/Markdown.tsx/MarkdownViewer";
|
||||
|
||||
const KubernetesClusterDocumentation: FunctionComponent<
|
||||
PageComponentProps
|
||||
> = (): ReactElement => {
|
||||
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
|
||||
|
||||
const [cluster, setCluster] = useState<KubernetesCluster | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
const fetchCluster: PromiseVoidFunction = async (): Promise<void> => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const item: KubernetesCluster | null = await ModelAPI.getItem({
|
||||
modelType: KubernetesCluster,
|
||||
id: modelId,
|
||||
select: {
|
||||
name: true,
|
||||
clusterIdentifier: true,
|
||||
},
|
||||
});
|
||||
setCluster(item);
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
}
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchCluster().catch((err: Error) => {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (isLoading) {
|
||||
return <PageLoader isVisible={true} />;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <ErrorMessage message={error} />;
|
||||
}
|
||||
|
||||
if (!cluster) {
|
||||
return <ErrorMessage message="Cluster not found." />;
|
||||
}
|
||||
|
||||
const clusterName: string = cluster.clusterIdentifier || cluster.name || "my-cluster";
|
||||
|
||||
const installationMarkdown: string = `
|
||||
## Prerequisites
|
||||
|
||||
- A running Kubernetes cluster (v1.23+)
|
||||
- \`kubectl\` configured to access your cluster
|
||||
- \`helm\` v3 installed
|
||||
- A OneUptime project API key (found in **Project Settings > API Keys**)
|
||||
|
||||
## Step 1: Add the OneUptime Helm Repository
|
||||
|
||||
\`\`\`bash
|
||||
helm repo add oneuptime https://helm.oneuptime.com
|
||||
helm repo update
|
||||
\`\`\`
|
||||
|
||||
## Step 2: Install the Kubernetes Agent
|
||||
|
||||
\`\`\`bash
|
||||
helm install kubernetes-agent oneuptime/kubernetes-agent \\
|
||||
--namespace oneuptime-agent \\
|
||||
--create-namespace \\
|
||||
--set oneuptime.url="YOUR_ONEUPTIME_URL" \\
|
||||
--set oneuptime.apiKey="YOUR_API_KEY" \\
|
||||
--set clusterName="${clusterName}"
|
||||
\`\`\`
|
||||
|
||||
Replace the following values:
|
||||
- **YOUR_ONEUPTIME_URL**: The URL of your OneUptime instance (e.g., \`https://oneuptime.example.com\`)
|
||||
- **YOUR_API_KEY**: Your project API key from OneUptime
|
||||
|
||||
## Step 3: Verify the Installation
|
||||
|
||||
Check that the agent pods are running:
|
||||
|
||||
\`\`\`bash
|
||||
kubectl get pods -n oneuptime-agent
|
||||
\`\`\`
|
||||
|
||||
You should see a **Deployment** pod (for metrics and events collection) and **DaemonSet** pods (one per node, for log collection):
|
||||
|
||||
\`\`\`
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
kubernetes-agent-deployment-xxxxx-xxxxx 1/1 Running 0 1m
|
||||
kubernetes-agent-daemonset-xxxxx 1/1 Running 0 1m
|
||||
\`\`\`
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Namespace Filtering
|
||||
|
||||
By default, \`kube-system\` is excluded. To monitor only specific namespaces:
|
||||
|
||||
\`\`\`bash
|
||||
helm install kubernetes-agent oneuptime/kubernetes-agent \\
|
||||
--namespace oneuptime-agent \\
|
||||
--create-namespace \\
|
||||
--set oneuptime.url="YOUR_ONEUPTIME_URL" \\
|
||||
--set oneuptime.apiKey="YOUR_API_KEY" \\
|
||||
--set clusterName="${clusterName}" \\
|
||||
--set "namespaceFilters.include={default,production,staging}"
|
||||
\`\`\`
|
||||
|
||||
### Disable Log Collection
|
||||
|
||||
If you only need metrics and events (no pod logs):
|
||||
|
||||
\`\`\`bash
|
||||
helm install kubernetes-agent oneuptime/kubernetes-agent \\
|
||||
--namespace oneuptime-agent \\
|
||||
--create-namespace \\
|
||||
--set oneuptime.url="YOUR_ONEUPTIME_URL" \\
|
||||
--set oneuptime.apiKey="YOUR_API_KEY" \\
|
||||
--set clusterName="${clusterName}" \\
|
||||
--set logs.enabled=false
|
||||
\`\`\`
|
||||
|
||||
### Enable Control Plane Monitoring
|
||||
|
||||
For self-managed clusters (not EKS/GKE/AKS), you can enable control plane metrics:
|
||||
|
||||
\`\`\`bash
|
||||
helm install kubernetes-agent oneuptime/kubernetes-agent \\
|
||||
--namespace oneuptime-agent \\
|
||||
--create-namespace \\
|
||||
--set oneuptime.url="YOUR_ONEUPTIME_URL" \\
|
||||
--set oneuptime.apiKey="YOUR_API_KEY" \\
|
||||
--set clusterName="${clusterName}" \\
|
||||
--set controlPlane.enabled=true
|
||||
\`\`\`
|
||||
|
||||
> **Note:** Managed Kubernetes services (EKS, GKE, AKS) typically do not expose control plane metrics. Only enable this for self-managed clusters.
|
||||
|
||||
## Upgrading the Agent
|
||||
|
||||
\`\`\`bash
|
||||
helm repo update
|
||||
helm upgrade kubernetes-agent oneuptime/kubernetes-agent \\
|
||||
--namespace oneuptime-agent
|
||||
\`\`\`
|
||||
|
||||
## Uninstalling the Agent
|
||||
|
||||
\`\`\`bash
|
||||
helm uninstall kubernetes-agent --namespace oneuptime-agent
|
||||
kubectl delete namespace oneuptime-agent
|
||||
\`\`\`
|
||||
|
||||
## What Gets Collected
|
||||
|
||||
The OneUptime Kubernetes Agent collects:
|
||||
|
||||
| Category | Data |
|
||||
|----------|------|
|
||||
| **Node Metrics** | CPU utilization, memory usage, filesystem usage, network I/O |
|
||||
| **Pod Metrics** | CPU usage, memory usage, network I/O, restarts |
|
||||
| **Container Metrics** | CPU usage, memory usage per container |
|
||||
| **Cluster Metrics** | Node conditions, allocatable resources, pod counts |
|
||||
| **Kubernetes Events** | Warnings, errors, scheduling events |
|
||||
| **Pod Logs** | stdout/stderr logs from all containers (via DaemonSet) |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Agent shows "Disconnected"
|
||||
|
||||
1. Check that the agent pods are running: \`kubectl get pods -n oneuptime-agent\`
|
||||
2. Check the agent logs: \`kubectl logs -n oneuptime-agent deployment/kubernetes-agent-deployment\`
|
||||
3. Verify your OneUptime URL and API key are correct
|
||||
4. Ensure your cluster can reach the OneUptime instance over the network
|
||||
|
||||
### No metrics appearing
|
||||
|
||||
1. Check that the cluster identifier matches: this cluster uses **\`${clusterName}\`**
|
||||
2. Verify the RBAC permissions: \`kubectl get clusterrolebinding | grep kubernetes-agent\`
|
||||
3. Check the OTel collector logs for export errors
|
||||
`;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Card
|
||||
title="Agent Installation Guide"
|
||||
description="Follow these steps to install the OneUptime Kubernetes Agent on your cluster."
|
||||
>
|
||||
<div className="px-2 pb-4">
|
||||
<MarkdownViewer text={installationMarkdown} />
|
||||
</div>
|
||||
</Card>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default KubernetesClusterDocumentation;
|
||||
@@ -30,24 +30,15 @@ const KubernetesClusterSideMenu: FunctionComponent<ComponentProps> = (
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: "Settings",
|
||||
title: "Documentation",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_SETTINGS] as Route,
|
||||
RouteMap[
|
||||
PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION
|
||||
] as Route,
|
||||
{ modelId: props.modelId },
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Settings}
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: "Delete Cluster",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_DELETE] as Route,
|
||||
{ modelId: props.modelId },
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Trash}
|
||||
className="danger-on-hover"
|
||||
icon={IconProp.Book}
|
||||
/>
|
||||
</SideMenuSection>
|
||||
|
||||
@@ -89,12 +80,38 @@ const KubernetesClusterSideMenu: FunctionComponent<ComponentProps> = (
|
||||
link={{
|
||||
title: "Control Plane",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_CONTROL_PLANE] as Route,
|
||||
RouteMap[
|
||||
PageMap.KUBERNETES_CLUSTER_VIEW_CONTROL_PLANE
|
||||
] as Route,
|
||||
{ modelId: props.modelId },
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Activity}
|
||||
/>
|
||||
</SideMenuSection>
|
||||
|
||||
<SideMenuSection title="Advanced">
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: "Settings",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_SETTINGS] as Route,
|
||||
{ modelId: props.modelId },
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Settings}
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: "Delete Cluster",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_DELETE] as Route,
|
||||
{ modelId: props.modelId },
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Trash}
|
||||
className="danger-on-hover"
|
||||
/>
|
||||
</SideMenuSection>
|
||||
</SideMenu>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import DashboardLogsViewer from "../../Components/Logs/LogsViewer";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const LogsPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -16,13 +17,16 @@ const LogsPage: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
|
||||
return (
|
||||
<DashboardLogsViewer
|
||||
showFilters={true}
|
||||
serviceIds={[]}
|
||||
limit={100}
|
||||
enableRealtime={true}
|
||||
id="logs"
|
||||
/>
|
||||
<Fragment>
|
||||
<DashboardLogsViewer
|
||||
showFilters={true}
|
||||
serviceIds={[]}
|
||||
limit={100}
|
||||
enableRealtime={true}
|
||||
id="logs"
|
||||
/>
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import MetricsTable from "../../Components/Metrics/MetricsTable";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const MetricsPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -15,7 +16,12 @@ const MetricsPage: FunctionComponent<PageComponentProps> = (
|
||||
);
|
||||
}
|
||||
|
||||
return <MetricsTable />;
|
||||
return (
|
||||
<Fragment>
|
||||
<MetricsTable />
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default MetricsPage;
|
||||
|
||||
56
App/FeatureSet/Dashboard/src/Pages/Settings/MobileApps.tsx
Normal file
56
App/FeatureSet/Dashboard/src/Pages/Settings/MobileApps.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import IconProp from "Common/Types/Icon/IconProp";
|
||||
import Card from "Common/UI/Components/Card/Card";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
|
||||
const MobileApps: FunctionComponent<PageComponentProps> = (): ReactElement => {
|
||||
return (
|
||||
<Fragment>
|
||||
<Card
|
||||
title="OneUptime On-Call - iOS"
|
||||
description="Download the OneUptime On-Call app for iOS to receive push notifications and manage on-call schedules from your iPhone or iPad."
|
||||
buttons={[
|
||||
{
|
||||
title: "Download on the App Store",
|
||||
icon: IconProp.Download,
|
||||
onClick: () => {
|
||||
window.open(
|
||||
"https://apps.apple.com/us/app/oneuptime-on-call/id6759615391",
|
||||
"_blank",
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Card
|
||||
title="OneUptime On-Call - Android"
|
||||
description="Download the OneUptime On-Call app for Android to receive push notifications and manage on-call schedules from your Android device."
|
||||
buttons={[
|
||||
{
|
||||
title: "Download on Google Play",
|
||||
icon: IconProp.Download,
|
||||
onClick: () => {
|
||||
window.open(
|
||||
"https://play.google.com/store/apps/details?id=com.oneuptime.oncall",
|
||||
"_blank",
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Download APK",
|
||||
icon: IconProp.Download,
|
||||
onClick: () => {
|
||||
window.open(
|
||||
"https://github.com/OneUptime/oneuptime/releases/latest/download/oneuptime-on-call-android-app.apk",
|
||||
"_blank",
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default MobileApps;
|
||||
@@ -147,6 +147,15 @@ const DashboardSideMenu: () => JSX.Element = (): ReactElement => {
|
||||
},
|
||||
icon: IconProp.Bell,
|
||||
},
|
||||
{
|
||||
link: {
|
||||
title: "Mobile Apps",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.SETTINGS_MOBILE_APPS] as Route,
|
||||
),
|
||||
},
|
||||
icon: IconProp.DevicePhoneMobile,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import TraceTable from "../../Components/Traces/TraceTable";
|
||||
import TelemetryDocumentation from "../../Components/Telemetry/Documentation";
|
||||
|
||||
const TracesPage: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
@@ -15,7 +16,12 @@ const TracesPage: FunctionComponent<PageComponentProps> = (
|
||||
);
|
||||
}
|
||||
|
||||
return <TraceTable />;
|
||||
return (
|
||||
<Fragment>
|
||||
<TraceTable />
|
||||
<TelemetryDocumentation />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default TracesPage;
|
||||
|
||||
@@ -18,6 +18,7 @@ import KubernetesClusterViewEvents from "../Pages/Kubernetes/View/Events";
|
||||
import KubernetesClusterViewControlPlane from "../Pages/Kubernetes/View/ControlPlane";
|
||||
import KubernetesClusterViewDelete from "../Pages/Kubernetes/View/Delete";
|
||||
import KubernetesClusterViewSettings from "../Pages/Kubernetes/View/Settings";
|
||||
import KubernetesClusterViewDocumentation from "../Pages/Kubernetes/View/Documentation";
|
||||
|
||||
const KubernetesRoutes: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
@@ -129,6 +130,16 @@ const KubernetesRoutes: FunctionComponent<ComponentProps> = (
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<PageRoute
|
||||
path={RouteUtil.getLastPathForKey(PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION)}
|
||||
element={
|
||||
<KubernetesClusterViewDocumentation
|
||||
{...props}
|
||||
pageRoute={RouteMap[PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION] as Route}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</PageRoute>
|
||||
</Routes>
|
||||
);
|
||||
|
||||
@@ -64,6 +64,7 @@ import SettingsLogPipelineView from "../Pages/Settings/LogPipelineView";
|
||||
import SettingsLogDropFilters from "../Pages/Settings/LogDropFilters";
|
||||
import SettingsLogDropFilterView from "../Pages/Settings/LogDropFilterView";
|
||||
import SettingsLogScrubRules from "../Pages/Settings/LogScrubRules";
|
||||
import SettingsMobileApps from "../Pages/Settings/MobileApps";
|
||||
|
||||
const SettingsRoutes: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
@@ -92,6 +93,15 @@ const SettingsRoutes: FunctionComponent<ComponentProps> = (
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<PageRoute
|
||||
path={RouteUtil.getLastPathForKey(PageMap.SETTINGS_MOBILE_APPS)}
|
||||
element={
|
||||
<SettingsMobileApps
|
||||
{...props}
|
||||
pageRoute={RouteMap[PageMap.SETTINGS_MOBILE_APPS] as Route}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<PageRoute
|
||||
path={RouteUtil.getLastPathForKey(PageMap.SETTINGS_AI_LOGS)}
|
||||
element={
|
||||
|
||||
@@ -59,6 +59,10 @@ export function getKubernetesBreadcrumbs(
|
||||
"View Cluster",
|
||||
"Settings",
|
||||
]),
|
||||
...BuildBreadcrumbLinksByTitles(
|
||||
PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION,
|
||||
["Project", "Kubernetes", "View Cluster", "Documentation"],
|
||||
),
|
||||
};
|
||||
return breadcrumpLinksMap[path];
|
||||
}
|
||||
|
||||
@@ -226,6 +226,7 @@ enum PageMap {
|
||||
KUBERNETES_CLUSTER_VIEW_CONTROL_PLANE = "KUBERNETES_CLUSTER_VIEW_CONTROL_PLANE",
|
||||
KUBERNETES_CLUSTER_VIEW_DELETE = "KUBERNETES_CLUSTER_VIEW_DELETE",
|
||||
KUBERNETES_CLUSTER_VIEW_SETTINGS = "KUBERNETES_CLUSTER_VIEW_SETTINGS",
|
||||
KUBERNETES_CLUSTER_VIEW_DOCUMENTATION = "KUBERNETES_CLUSTER_VIEW_DOCUMENTATION",
|
||||
|
||||
// Code Repository
|
||||
CODE_REPOSITORY_ROOT = "CODE_REPOSITORY_ROOT",
|
||||
@@ -445,6 +446,9 @@ enum PageMap {
|
||||
|
||||
SETTINGS_NOTIFICATION_LOGS = "SETTINGS_NOTIFICATION_LOGS",
|
||||
|
||||
// Mobile Apps
|
||||
SETTINGS_MOBILE_APPS = "SETTINGS_MOBILE_APPS",
|
||||
|
||||
// AI Logs
|
||||
SETTINGS_AI_LOGS = "SETTINGS_AI_LOGS",
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ export const KubernetesRoutePath: Dictionary<string> = {
|
||||
[PageMap.KUBERNETES_CLUSTER_VIEW_CONTROL_PLANE]: `${RouteParams.ModelID}/control-plane`,
|
||||
[PageMap.KUBERNETES_CLUSTER_VIEW_DELETE]: `${RouteParams.ModelID}/delete`,
|
||||
[PageMap.KUBERNETES_CLUSTER_VIEW_SETTINGS]: `${RouteParams.ModelID}/settings`,
|
||||
[PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION]: `${RouteParams.ModelID}/documentation`,
|
||||
};
|
||||
|
||||
export const WorkflowRoutePath: Dictionary<string> = {
|
||||
@@ -311,6 +312,7 @@ export const SettingsRoutePath: Dictionary<string> = {
|
||||
[PageMap.SETTINGS_DANGERZONE]: "danger-zone",
|
||||
[PageMap.SETTINGS_NOTIFICATION_SETTINGS]: "notification-settings",
|
||||
[PageMap.SETTINGS_NOTIFICATION_LOGS]: "notification-logs",
|
||||
[PageMap.SETTINGS_MOBILE_APPS]: "mobile-apps",
|
||||
[PageMap.SETTINGS_AI_LOGS]: "ai-logs",
|
||||
[PageMap.SETTINGS_APIKEYS]: `api-keys`,
|
||||
[PageMap.SETTINGS_APIKEY_VIEW]: `api-keys/${RouteParams.ModelID}`,
|
||||
@@ -1541,6 +1543,12 @@ const RouteMap: Dictionary<Route> = {
|
||||
}`,
|
||||
),
|
||||
|
||||
[PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION]: new Route(
|
||||
`/dashboard/${RouteParams.ProjectID}/kubernetes/${
|
||||
KubernetesRoutePath[PageMap.KUBERNETES_CLUSTER_VIEW_DOCUMENTATION]
|
||||
}`,
|
||||
),
|
||||
|
||||
// Dashboards
|
||||
|
||||
[PageMap.DASHBOARDS_ROOT]: new Route(
|
||||
@@ -2181,6 +2189,12 @@ const RouteMap: Dictionary<Route> = {
|
||||
}`,
|
||||
),
|
||||
|
||||
[PageMap.SETTINGS_MOBILE_APPS]: new Route(
|
||||
`/dashboard/${RouteParams.ProjectID}/settings/${
|
||||
SettingsRoutePath[PageMap.SETTINGS_MOBILE_APPS]
|
||||
}`,
|
||||
),
|
||||
|
||||
[PageMap.SETTINGS_AI_LOGS]: new Route(
|
||||
`/dashboard/${RouteParams.ProjectID}/settings/${
|
||||
SettingsRoutePath[PageMap.SETTINGS_AI_LOGS]
|
||||
|
||||
@@ -320,6 +320,7 @@ enum IconProp {
|
||||
TableCellsIcon = "TableCellsIcon",
|
||||
UserIcon = "UserIcon",
|
||||
XCircle = "XCircle",
|
||||
Kubernetes = "Kubernetes",
|
||||
}
|
||||
|
||||
export default IconProp;
|
||||
|
||||
@@ -2733,6 +2733,28 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
||||
d="m15 11.25 1.5 1.5.75-.75V8.758l2.276-.61a3 3 0 1 0-3.675-3.675l-.61 2.277H12l-.75.75 1.5 1.5M15 11.25l-8.47 8.47c-.34.34-.8.53-1.28.53s-.94-.19-1.28-.53a1.818 1.818 0 0 1 0-2.56l8.47-8.47M15 11.25 12 8.25"
|
||||
/>,
|
||||
);
|
||||
} else if (icon === IconProp.Kubernetes) {
|
||||
// Kubernetes helm wheel icon (heptagon outline + inner wheel spokes)
|
||||
return getSvgWrapper(
|
||||
<>
|
||||
{/* Heptagonal border */}
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M12 2l5.09 2.33 3.41 4.67.5 5.5-2.09 5.17L14.5 22h-5l-4.41-2.33L3 14.5l.5-5.5L6.91 4.33Z"
|
||||
/>
|
||||
{/* Center circle */}
|
||||
<circle cx="12" cy="12" r="2" strokeWidth="1.5" fill="none" stroke="currentColor" />
|
||||
{/* Spokes radiating from center - 7 directions */}
|
||||
<line x1="12" y1="10" x2="12" y2="5" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="13.9" y1="10.7" x2="16.5" y2="6.5" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="13.9" y1="13.3" x2="17.5" y2="14" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="12" y1="14" x2="14.5" y2="18" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="10.1" y1="13.3" x2="6.5" y2="14" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="10.1" y1="10.7" x2="7.5" y2="6.5" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
<line x1="12" y1="14" x2="9.5" y2="18" strokeWidth="1.5" stroke="currentColor" strokeLinecap="round" />
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
|
||||
@@ -208,7 +208,7 @@ const CodeBlock: FunctionComponent<{
|
||||
(language ? language.charAt(0).toUpperCase() + language.slice(1) : "");
|
||||
|
||||
return (
|
||||
<div className="relative rounded-lg mt-4 mb-4 overflow-hidden border border-gray-700">
|
||||
<div className="relative rounded-md mt-3 mb-3 overflow-hidden border border-gray-700">
|
||||
{/* Header bar */}
|
||||
<div className="flex items-center justify-between px-3 py-1.5 bg-gray-800/60 border-b border-gray-700/60">
|
||||
<span className="text-[11px] font-medium uppercase tracking-wider text-gray-400 select-none">
|
||||
@@ -261,7 +261,7 @@ const CodeBlock: FunctionComponent<{
|
||||
children={content}
|
||||
language={language}
|
||||
style={vscDarkPlus}
|
||||
className="!rounded-none !mt-0 !mb-0 !bg-gray-900 !pt-6 !pb-4 !px-4 text-sm !border-0"
|
||||
className="!rounded-none !mt-0 !mb-0 !bg-gray-900 !pt-3 !pb-3 !px-4 text-sm !border-0"
|
||||
codeTagProps={{ className: "font-mono" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user