blob: 1a5091b301205bc0a85fb91e47df73937e6528ed [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import styles from "./FeaturesGrid.module.css";
interface FeatureItem {
title: string;
description: string;
icon: JSX.Element;
}
const FEATURES: FeatureItem[] = [
{
title: "Change Point Detection",
description: "Say goodbye to fragile static thresholds. Otava analyzes historical distributions to spot persistent performance shifts, ignoring temporary spikes and random noise.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M3 3v18h18" />
<path d="M18.7 8l-5.1 5.2-2.8-2.7L7 14.3" />
<line x1="12" y1="5" x2="12" y2="19" strokeDasharray="3,3" />
</svg>
),
},
{
title: "Feature Branch CI",
description: "Verify regressions before merging. Run benchmarks against your branch and compare the tail performance directly with your main branch baseline using the CLI.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<line x1="6" y1="3" x2="6" y2="15" />
<circle cx="18" cy="6" r="3" />
<circle cx="6" cy="18" r="3" />
<path d="M18 9a9 9 0 0 1-9 9" />
</svg>
),
},
{
title: "Flexible Data Ingestion",
description: "Ingest metrics directly from Graphite, PostgreSQL, Google BigQuery, or simple CSV files. Integrates smoothly with your existing benchmarking infrastructure.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<ellipse cx="12" cy="5" rx="9" ry="3" />
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
<path d="M3 12c0 1.66 4 3 9 3s9-1.34 9-3" />
</svg>
),
},
{
title: "Slack & Grafana Alerts",
description: "Automatically annotate Grafana dashboards with detected change points and send Slack alerts when regressions are isolated to a specific commit range.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
</svg>
),
},
{
title: "In-Browser Playground",
description: "Try before you install. Run Otava directly inside your browser on our interactive playground website to analyze sample performance datasets instantly.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<polyline points="4 17 10 11 4 5" />
<line x1="12" y1="19" x2="20" y2="19" />
</svg>
),
},
];
export default function FeaturesGrid(): JSX.Element {
return (
<div className={styles.container}>
<div className={styles.grid}>
{FEATURES.map((feature, idx) => (
<div key={idx} className={styles.card} id={`feature-card-${idx}`}>
<div className={styles.iconWrapper}>{feature.icon}</div>
<h3 className={styles.cardTitle}>{feature.title}</h3>
<p className={styles.cardDesc}>{feature.description}</p>
</div>
))}
</div>
</div>
);
}