* chore(release): bump 0.8.2 -> 0.8.3 Version bumped across desktop/package.json, Cargo.toml (+ only the `gridline` entry in Cargo.lock — the sqlx family is untouched), tauri.conf.json, both landing-page `const version` strings, the README's two download tables and 'current release' banners, the MAINTENANCE comment, and the version tests. Adds the 0.8.3 changelog entry and README release note covering the external client-tool resolution fix (issue #44), the MariaDB client-option fix, the four restyled tool pages, and the app-icon revert. Historical references (older changelog entries, '(v0.8.2)' feature notes) are deliberately left alone. * test(ui): scope CopyButton's unhandled-rejection capture to its own error The listener is process-global and Vitest runs several test files per worker, so an unrelated file's rejection could be recorded and fail this test. Filter the capture to the error this test creates, and stop the listener in a finally so a failing assertion cannot leak it into later tests. Verified non-vacuous: against a CopyButton without the try/catch both 'stays quiet' tests still fail with the expected assertion.
221 lines
9.9 KiB
Plaintext
221 lines
9.9 KiB
Plaintext
---
|
||
import Layout from "../layouts/Layout.astro";
|
||
import { faqItems } from "../data/faq";
|
||
import {
|
||
buildSoftwareApplicationJsonLd,
|
||
buildFaqJsonLd,
|
||
buildOrganizationJsonLd,
|
||
buildWebSiteJsonLd,
|
||
buildProductJsonLd,
|
||
buildBreadcrumbJsonLd,
|
||
} from "../lib/seo";
|
||
import { Image } from "astro:assets";
|
||
import HeroDbViewer from "../components/hero/HeroDbViewer";
|
||
import queryEditor from "../assets/screenshots/query-editor.png";
|
||
import erDiagram from "../assets/screenshots/er-diagram.png";
|
||
import home from "../assets/screenshots/home.png";
|
||
import dataGrid from "../assets/screenshots/data-grid.png";
|
||
const version = "0.8.3";
|
||
const site = "https://getgridline.app";
|
||
const jsonLd = [
|
||
buildSoftwareApplicationJsonLd({
|
||
name: "Gridline",
|
||
url: `${site}/`,
|
||
description:
|
||
"The open-source database GUI for PostgreSQL, MySQL, SQLite, and Redis. No paywalls, no tab limits, fully open source.",
|
||
image: `${site}/og.png`,
|
||
operatingSystem: "macOS, Windows, Linux",
|
||
applicationCategory: "DeveloperApplication",
|
||
offersPrice: 0,
|
||
offersCurrency: "USD",
|
||
downloadUrl: "https://github.com/AdrianBonpin/gridline/releases",
|
||
}),
|
||
buildFaqJsonLd(faqItems),
|
||
buildOrganizationJsonLd({
|
||
name: "Gridline",
|
||
url: `${site}/`,
|
||
logo: `${site}/gridline-icon.svg`,
|
||
sameAs: [
|
||
"https://github.com/AdrianBonpin/gridline",
|
||
"https://x.com/AdrianBonpin",
|
||
],
|
||
}),
|
||
buildWebSiteJsonLd({
|
||
name: "Gridline",
|
||
url: `${site}/`,
|
||
}),
|
||
buildProductJsonLd({
|
||
name: "Gridline",
|
||
url: `${site}/`,
|
||
description:
|
||
"The open-source database GUI for PostgreSQL, MySQL, SQLite, and Redis. No paywalls, no tab limits, fully open source.",
|
||
image: `${site}/og.png`,
|
||
offersPrice: 0,
|
||
offersCurrency: "USD",
|
||
}),
|
||
buildBreadcrumbJsonLd([
|
||
{ name: "Home", url: `${site}/` },
|
||
]),
|
||
];
|
||
---
|
||
<Layout title="Gridline, Free Open-Source Database GUI" jsonLd={jsonLd}>
|
||
<script src="/landing.js" defer></script>
|
||
|
||
<!-- Hero -->
|
||
<header id="hero" class="relative pt-32 pb-20 md:pt-44 md:pb-28 overflow-hidden">
|
||
<div class="max-w-7xl mx-auto px-6 text-center">
|
||
<div class="hero-animate">
|
||
<p class="font-mono text-xs tracking-[0.15em] uppercase text-[var(--accent)] mb-5">Open-Source Database GUI</p>
|
||
<h1 class="font-serif text-5xl md:text-7xl lg:text-8xl leading-[1.05] tracking-tight max-w-4xl mx-auto lowercase">
|
||
the open-source database <span class="text-[var(--accent)]">gui</span>
|
||
</h1>
|
||
<p class="mt-6 text-lg md:text-xl text-[var(--text-muted)] max-w-xl mx-auto">
|
||
Query, explore, sync, and edit PostgreSQL, MySQL, SQLite, and Redis, with no paywalls, no tab limits, no account required.
|
||
</p>
|
||
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||
<a id="download" href="https://github.com/AdrianBonpin/gridline/releases" class="primary-btn" data-download>
|
||
Download
|
||
</a>
|
||
<a href="https://github.com/AdrianBonpin/gridline" target="_blank" rel="noopener" class="ghost-btn">
|
||
View on GitHub
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-screenshot mt-14 md:mt-20 mx-auto max-w-6xl">
|
||
<div class="hidden md:block aspect-[16/9]">
|
||
<HeroDbViewer client:visible />
|
||
</div>
|
||
<div class="md:hidden">
|
||
<Image
|
||
src={queryEditor}
|
||
alt="Gridline query editor and data grid"
|
||
widths={[640, 1024, 1600]}
|
||
sizes="(max-width: 1024px) 100vw, 1024px"
|
||
formats={["webp", "avif"]}
|
||
loading="eager"
|
||
fetchpriority="high"
|
||
class="w-full h-auto"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<p class="mt-8 text-xs md:text-sm text-[var(--text-muted)] font-mono">
|
||
Free for personal and commercial use · Apache 2.0 · v{version}
|
||
</p>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Why Gridline -->
|
||
<section id="why" class="section-animate py-20 md:py-28">
|
||
<div class="max-w-7xl mx-auto px-6">
|
||
<h2 class="font-serif text-3xl md:text-5xl text-center max-w-2xl mx-auto">
|
||
Everything the paid apps lock behind a subscription.
|
||
</h2>
|
||
<div class="mt-12 grid md:grid-cols-3 gap-5">
|
||
<article class="glass-card">
|
||
<p class="font-mono text-xs text-[var(--accent)] mb-3">01</p>
|
||
<h3 class="text-xl font-semibold mb-2">No limits</h3>
|
||
<p class="text-[var(--text-muted)] text-sm leading-relaxed">
|
||
Unlimited connections, open tabs, saved queries, and exports. The free plan is the full plan.
|
||
</p>
|
||
</article>
|
||
<article class="glass-card">
|
||
<p class="font-mono text-xs text-[var(--accent)] mb-3">02</p>
|
||
<h3 class="text-xl font-semibold mb-2">DB-to-DB sync</h3>
|
||
<p class="text-[var(--text-muted)] text-sm leading-relaxed">
|
||
Pipe <code class="font-mono text-xs">pg_dump</code> directly into <code class="font-mono text-xs">pg_restore</code> between two live connections. No file round-trip needed.
|
||
</p>
|
||
</article>
|
||
<article class="glass-card">
|
||
<p class="font-mono text-xs text-[var(--accent)] mb-3">03</p>
|
||
<h3 class="text-xl font-semibold mb-2">Deeper PG explorer</h3>
|
||
<p class="text-[var(--text-muted)] text-sm leading-relaxed">
|
||
Full detail views for functions, triggers, sequences, enums, extensions, roles, and grants.
|
||
</p>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Feature highlights -->
|
||
<section id="features" class="section-animate py-20 md:py-28">
|
||
<div class="max-w-7xl mx-auto px-6">
|
||
<p class="font-mono text-xs text-[var(--accent)] uppercase tracking-[0.15em] text-center mb-3">Features</p>
|
||
<h2 class="font-serif text-3xl md:text-5xl text-center mb-14">Explore, query, and move data.</h2>
|
||
<div class="grid md:grid-cols-2 gap-5">
|
||
<article class="feature-card">
|
||
<p class="font-mono text-xs text-[var(--text-muted)] mb-3">QUERY & EDIT</p>
|
||
<h3 class="text-xl font-semibold mb-2">SQL editor + virtualized grid</h3>
|
||
<p class="text-[var(--text-muted)] text-sm mb-4">Run queries with autocomplete, inline edit cells, and browse 100k+ rows without breaking a sweat.</p>
|
||
<Image src={queryEditor} alt="SQL query editor" widths={[640, 1024]} sizes="(max-width: 1024px) 100vw, 640px" formats={["webp", "avif"]} loading="lazy" class="w-full h-auto" />
|
||
</article>
|
||
<article class="feature-card">
|
||
<p class="font-mono text-xs text-[var(--text-muted)] mb-3">VISUALIZE</p>
|
||
<h3 class="text-xl font-semibold mb-2">ER diagram</h3>
|
||
<p class="text-[var(--text-muted)] text-sm mb-4">Auto-layout schema graphs with crow’s foot relationships across schemas, right inside the app.</p>
|
||
<Image src={erDiagram} alt="ER diagram" widths={[640, 1024]} sizes="(max-width: 1024px) 100vw, 640px" formats={["webp", "avif"]} loading="lazy" class="w-full h-auto" />
|
||
</article>
|
||
<article class="feature-card">
|
||
<p class="font-mono text-xs text-[var(--text-muted)] mb-3">MOVE DATA</p>
|
||
<h3 class="text-xl font-semibold mb-2">Backup, restore, and sync</h3>
|
||
<p class="text-[var(--text-muted)] text-sm mb-4">Point-and-click <code class="font-mono text-xs">pg_dump</code>/<code class="font-mono text-xs">pg_restore</code>, SQLite dumps, and live DB-to-DB sync.</p>
|
||
<Image src={home} alt="Gridline home screen" widths={[640, 1024]} sizes="(max-width: 1024px) 100vw, 640px" formats={["webp", "avif"]} loading="lazy" class="w-full h-auto" />
|
||
</article>
|
||
<article class="feature-card">
|
||
<p class="font-mono text-xs text-[var(--text-muted)] mb-3">MANAGE</p>
|
||
<h3 class="text-xl font-semibold mb-2">Objects, roles, and grants</h3>
|
||
<p class="text-[var(--text-muted)] text-sm mb-4">Create and edit tables, foreign keys, indexes, functions, triggers, sequences, roles, and privileges.</p>
|
||
<Image src={dataGrid} alt="Data grid with foreign key preview" widths={[640, 1024]} sizes="(max-width: 1024px) 100vw, 640px" formats={["webp", "avif"]} loading="lazy" class="w-full h-auto" />
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Open source -->
|
||
<section id="oss" class="section-animate py-20 md:py-28 text-center">
|
||
<div class="max-w-[800px] mx-auto px-6">
|
||
<p class="font-mono text-xs text-[var(--accent)] uppercase tracking-[0.15em] mb-3">Open Source</p>
|
||
<h2 class="font-serif text-3xl md:text-5xl mb-5">Free. Open source. Apache 2.0.</h2>
|
||
<p class="text-[var(--text-muted)] mb-8 max-w-md mx-auto">
|
||
Gridline is Apache 2.0 and developed openly. Contributions, issues, and feature requests are welcome.
|
||
</p>
|
||
<div class="flex flex-wrap items-center justify-center gap-3">
|
||
<a href="https://github.com/AdrianBonpin/gridline" target="_blank" rel="noopener" class="ghost-btn">
|
||
Star on GitHub
|
||
</a>
|
||
<a href="https://ko-fi.com/adrianbonpin" target="_blank" rel="noopener" class="ghost-btn">
|
||
☕ Support on Ko-fi
|
||
</a>
|
||
</div>
|
||
<p class="mt-6 text-xs text-[var(--text-muted)] max-w-sm mx-auto">
|
||
Gridline stays free. No feature is ever behind a payment. Ko-fi is only for those who want to say thanks.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- FAQ -->
|
||
<section id="faq" class="section-animate py-20 md:py-28">
|
||
<div class="max-w-[800px] mx-auto px-6">
|
||
<h2 class="font-serif text-3xl md:text-5xl text-center mb-12">Questions? Answered.</h2>
|
||
<div class="faq-list space-y-3">
|
||
{
|
||
faqItems.map((item, i) => (
|
||
<details class="faq-item" open={i === 0}>
|
||
<summary class="faq-summary">
|
||
<span>{item.question}</span>
|
||
<span class="faq-chevron">⌄</span>
|
||
</summary>
|
||
<div class="faq-body">
|
||
<p class="text-[var(--text-muted)] text-sm leading-relaxed">{item.answer}</p>
|
||
</div>
|
||
</details>
|
||
))
|
||
}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</Layout>
|
||
|