1
0
mirror of https://github.com/prometheus/docs.git synced 2026-02-05 06:45:01 +01:00

More work on new docs site

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz
2025-05-12 14:03:08 +02:00
parent 90504ed638
commit 18209a3827
35 changed files with 1721 additions and 433 deletions

View File

@@ -31,4 +31,23 @@ export default {
ltsVersions: {
prometheus: ["2.53"],
},
// Repositories for the downloads page. The order in this file is the
// order in which they will be displayed on the downloads page.
downloads: {
owner: "prometheus",
repos: [
"prometheus",
"alertmanager",
"blackbox_exporter",
"consul_exporter",
"graphite_exporter",
"memcached_exporter",
"mysqld_exporter",
"node_exporter",
"promlens",
"pushgateway",
"statsd_exporter",
],
},
} satisfies DocsConfig;

View File

@@ -14,6 +14,10 @@ const eslintConfig = [
{
rules: {
"@next/next/no-img-element": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
},
},
];

349
package-lock.json generated
View File

@@ -8,10 +8,13 @@
"name": "prometheus-next",
"version": "0.1.0",
"dependencies": {
"@docsearch/js": "^3.9.0",
"@mantine/code-highlight": "^8.0.0",
"@mantine/core": "^8.0.0",
"@mantine/hooks": "^8.0.0",
"@mantine/spotlight": "^8.0.0",
"@tabler/icons-react": "^3.31.0",
"@types/semver": "^7.7.0",
"gray-matter": "^4.0.3",
"hast-util-from-html": "^2.0.3",
"hast-util-select": "^6.0.4",
@@ -25,6 +28,7 @@
"rehype-slug": "^6.0.0",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"semver": "^7.7.1",
"shiki": "^3.4.0"
},
"devDependencies": {
@@ -43,6 +47,231 @@
"typescript": "^5"
}
},
"node_modules/@algolia/autocomplete-core": {
"version": "1.17.9",
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz",
"integrity": "sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==",
"license": "MIT",
"dependencies": {
"@algolia/autocomplete-plugin-algolia-insights": "1.17.9",
"@algolia/autocomplete-shared": "1.17.9"
}
},
"node_modules/@algolia/autocomplete-plugin-algolia-insights": {
"version": "1.17.9",
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz",
"integrity": "sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==",
"license": "MIT",
"dependencies": {
"@algolia/autocomplete-shared": "1.17.9"
},
"peerDependencies": {
"search-insights": ">= 1 < 3"
}
},
"node_modules/@algolia/autocomplete-preset-algolia": {
"version": "1.17.9",
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz",
"integrity": "sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==",
"license": "MIT",
"dependencies": {
"@algolia/autocomplete-shared": "1.17.9"
},
"peerDependencies": {
"@algolia/client-search": ">= 4.9.1 < 6",
"algoliasearch": ">= 4.9.1 < 6"
}
},
"node_modules/@algolia/autocomplete-shared": {
"version": "1.17.9",
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz",
"integrity": "sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==",
"license": "MIT",
"peerDependencies": {
"@algolia/client-search": ">= 4.9.1 < 6",
"algoliasearch": ">= 4.9.1 < 6"
}
},
"node_modules/@algolia/client-abtesting": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.24.0.tgz",
"integrity": "sha512-pNTIB5YqVVwu6UogvdX8TqsRZENaflqMMjdY7/XIPMNGrBoNH9tewINLI7+qc9tIaOLcAp3ZldqoEwAihZZ3ig==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-analytics": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.24.0.tgz",
"integrity": "sha512-IF+r9RRQsIf0ylIBNFxo7c6hDxxuhIfIbffhBXEF1HD13rjhP5AVfiaea9RzbsAZoySkm318plDpH/nlGIjbRA==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-common": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.24.0.tgz",
"integrity": "sha512-p8K6tiXQTebRBxbrzWIfGCvfkT+Umml+2lzI92acZjHsvl6KYH6igOfVstKqXJRei9pvRzEEvVDNDLXDVleGTA==",
"license": "MIT",
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-insights": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.24.0.tgz",
"integrity": "sha512-jOHF0+tixR3IZJMhZPquFNdCVPzwzzXoiqVsbTvfKojeaY6ZXybgUiTSB8JNX+YpsUT8Ebhu3UvRy4mw2PbEzw==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-personalization": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.24.0.tgz",
"integrity": "sha512-Fx/Fp6d8UmDBHecTt0XYF8C9TAaA3qeCQortfGSZzWp4gVmtrUCFNZ1SUwb8ULREnO9DanVrM5hGE8R8C4zZTQ==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-query-suggestions": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.24.0.tgz",
"integrity": "sha512-F8ypOedSMhz6W7zuT5O1SXXsdXSOVhY2U6GkRbYk/mzrhs3jWFR3uQIfeQVWmsJjUwIGZmPoAr9E+T/Zm2M4wA==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/client-search": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.24.0.tgz",
"integrity": "sha512-k+nuciQuq7WERNNE+hsx3DX636zIy+9R4xdtvW3PANT2a2BDGOv3fv2mta8+QUMcVTVcGe/Mo3QCb4pc1HNoxA==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/ingestion": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.24.0.tgz",
"integrity": "sha512-/lqVxmrvwoA+OyVK4XLMdz/PJaCTW4qYchX1AZ+98fdnH3K6XM/kMydQLfP0bUNGBQbmVrF88MqhqZRnZEn/MA==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/monitoring": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.24.0.tgz",
"integrity": "sha512-cRisDXQJhvfZCXL4hD22qca2CmW52TniOx6L7pvkaBDx0oQk1k9o+3w11fgfcCG+47OndMeNx5CMpu+K+COMzg==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/recommend": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.24.0.tgz",
"integrity": "sha512-JTMz0JqN2gidvKa2QCF/rMe8LNtdHaght03px2cluZaZfBRYy8TgHgkCeBspKKvV/abWJwl7J0FzWThCshqT3w==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/requester-browser-xhr": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.24.0.tgz",
"integrity": "sha512-B2Gc+iSxct1WSza5CF6AgfNgmLvVb61d5bqmIWUZixtJIhyAC6lSQZuF+nvt+lmKhQwuY2gYjGGClil8onQvKQ==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/requester-fetch": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.24.0.tgz",
"integrity": "sha512-6E5+hliqGc5w8ZbyTAQ+C3IGLZ/GiX623Jl2bgHA974RPyFWzVSj4rKqkboUAxQmrFY7Z02ybJWVZS5OhPQocA==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@algolia/requester-node-http": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.24.0.tgz",
"integrity": "sha512-zM+nnqZpiQj20PyAh6uvgdSz+hD7Rj7UfAZwizqNP+bLvcbGXZwABERobuilkCQqyDBBH4uv0yqIcPRl8dSBEg==",
"license": "MIT",
"dependencies": {
"@algolia/client-common": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
@@ -52,6 +281,54 @@
"node": ">=6.9.0"
}
},
"node_modules/@docsearch/css": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz",
"integrity": "sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==",
"license": "MIT"
},
"node_modules/@docsearch/js": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.9.0.tgz",
"integrity": "sha512-4bKHcye6EkLgRE8ze0vcdshmEqxeiJM77M0JXjef7lrYZfSlMunrDOCqyLjiZyo1+c0BhUqA2QpFartIjuHIjw==",
"license": "MIT",
"dependencies": {
"@docsearch/react": "3.9.0",
"preact": "^10.0.0"
}
},
"node_modules/@docsearch/react": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz",
"integrity": "sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ==",
"license": "MIT",
"dependencies": {
"@algolia/autocomplete-core": "1.17.9",
"@algolia/autocomplete-preset-algolia": "1.17.9",
"@docsearch/css": "3.9.0",
"algoliasearch": "^5.14.2"
},
"peerDependencies": {
"@types/react": ">= 16.8.0 < 20.0.0",
"react": ">= 16.8.0 < 20.0.0",
"react-dom": ">= 16.8.0 < 20.0.0",
"search-insights": ">= 1 < 3"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
},
"search-insights": {
"optional": true
}
}
},
"node_modules/@emnapi/core": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz",
@@ -1188,6 +1465,30 @@
"react": "^18.x || ^19.x"
}
},
"node_modules/@mantine/spotlight": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@mantine/spotlight/-/spotlight-8.0.0.tgz",
"integrity": "sha512-E8YS+q78IYvXGcTvLX+OFUJPNkf73o/ZWmO4OKdI0Hxvw5XFELCzRkYnLGQ5npeTfn74t4X3fitWBfQT26lJzQ==",
"license": "MIT",
"dependencies": {
"@mantine/store": "8.0.0"
},
"peerDependencies": {
"@mantine/core": "8.0.0",
"@mantine/hooks": "8.0.0",
"react": "^18.x || ^19.x",
"react-dom": "^18.x || ^19.x"
}
},
"node_modules/@mantine/store": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.0.0.tgz",
"integrity": "sha512-42RWCsXMNuhpX+d/hwr5aHj+HWyi5ltbc0R0xdiUnAmqSB7CHbWxDDLh4+DbmqPrN9pTeYvpPGp3v/CG2vuGBg==",
"license": "MIT",
"peerDependencies": {
"react": "^18.x || ^19.x"
}
},
"node_modules/@modelcontextprotocol/sdk": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz",
@@ -2001,6 +2302,12 @@
"@types/react": "^19.0.0"
}
},
"node_modules/@types/semver": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
"integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
"license": "MIT"
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -2544,6 +2851,30 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/algoliasearch": {
"version": "5.24.0",
"resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.24.0.tgz",
"integrity": "sha512-CkaUygzZ91Xbw11s0CsHMawrK3tl+Ue57725HGRgRzKgt2Z4wvXVXRCtQfvzh8K7Tp4Zp7f1pyHAtMROtTJHxg==",
"license": "MIT",
"dependencies": {
"@algolia/client-abtesting": "5.24.0",
"@algolia/client-analytics": "5.24.0",
"@algolia/client-common": "5.24.0",
"@algolia/client-insights": "5.24.0",
"@algolia/client-personalization": "5.24.0",
"@algolia/client-query-suggestions": "5.24.0",
"@algolia/client-search": "5.24.0",
"@algolia/ingestion": "1.24.0",
"@algolia/monitoring": "1.24.0",
"@algolia/recommend": "5.24.0",
"@algolia/requester-browser-xhr": "5.24.0",
"@algolia/requester-fetch": "5.24.0",
"@algolia/requester-node-http": "5.24.0"
},
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -7557,6 +7888,16 @@
"postcss": "^8.2.1"
}
},
"node_modules/preact": {
"version": "10.26.6",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.26.6.tgz",
"integrity": "sha512-5SRRBinwpwkaD+OqlBDeITlRgvd8I8QlxHJw9AxSdMNV6O+LodN9nUyYGpSF7sadHjs6RzeFShMexC6DbtWr9g==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -8194,6 +8535,13 @@
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"license": "MIT"
},
"node_modules/search-insights": {
"version": "2.17.3",
"resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
"integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
"license": "MIT",
"peer": true
},
"node_modules/section-matter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
@@ -8211,7 +8559,6 @@
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"devOptional": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"

View File

@@ -6,16 +6,21 @@
"scripts": {
"dev": "next dev --turbopack",
"fetch-repo-docs": "tsx scripts/fetch-repo-docs.ts",
"fetch-downloads-info": "tsx scripts/fetch-downloads-info.ts",
"clean": "rm -rf generated out .next",
"build": "next build",
"build-all": "npm run clean && npm run fetch-repo-docs && npm run fetch-downloads-info && next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@docsearch/js": "^3.9.0",
"@mantine/code-highlight": "^8.0.0",
"@mantine/core": "^8.0.0",
"@mantine/hooks": "^8.0.0",
"@mantine/spotlight": "^8.0.0",
"@tabler/icons-react": "^3.31.0",
"@types/semver": "^7.7.0",
"gray-matter": "^4.0.3",
"hast-util-from-html": "^2.0.3",
"hast-util-select": "^6.0.4",
@@ -29,6 +34,7 @@
"rehype-slug": "^6.0.0",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"semver": "^7.7.1",
"shiki": "^3.4.0"
},
"devDependencies": {

View File

@@ -0,0 +1,177 @@
import { octokit } from "./githubClient";
import { GetResponseDataTypeFromEndpointMethod } from "@octokit/types";
import * as fs from "fs";
import * as path from "path";
import docsConfig from "../docs-config";
import { Downloads, Release, Binary } from "@/downloads-metadata-types";
import { compareFullVersion, filterUnique, majorMinor } from "./utils";
const OUTDIR = "./generated";
const assetChecksums: { [releaseID: string]: { [fileName: string]: string } } =
{};
type OctokitRelease = GetResponseDataTypeFromEndpointMethod<
typeof octokit.rest.repos.listReleases
>[number];
const downloads: Downloads = {
repos: [],
operatingSystems: [],
architectures: [],
releases: [],
};
const getBinaries = (r: OctokitRelease) => {
const binaries = r.assets
.filter(
(a) =>
(a.name.endsWith(".tar.gz") || a.name.endsWith(".zip")) &&
!a.name.includes("-web-ui-")
)
.map((a): Binary => {
const baseName = a.name.replace(/(\.tar\.gz|\.zip)$/, "");
const lastPart = baseName.split(".").slice(-1)[0];
const [os, arch] = lastPart.split("-");
return {
name: a.name,
checksum: assetChecksums[r.id][a.name],
os,
arch,
url: a.browser_download_url,
sizeBytes: a.size,
};
});
const grouped = Object.groupBy(binaries, (b) => `${b.os}/${b.arch}`);
// Within each group, sort by name and then return the last one.
const sortedBinaries = Object.values(grouped).map((group) => {
const sorted = group!.sort((a, b) => a.name.localeCompare(b.name));
return sorted[sorted.length - 1];
});
return sortedBinaries;
};
for (const repoName of docsConfig.downloads.repos) {
console.group(`Fetching downloads info for ${repoName}`);
// Fetch repo base information.
console.log(`Fetching repo info for ${repoName}`);
const repoInfo = await octokit.rest.repos.get({
owner: docsConfig.downloads.owner,
repo: repoName,
});
// Fetch releases information for the repo.
console.log(`Fetching releases info for ${repoName}`);
const releasesInfo = await octokit.rest.repos.listReleases({
owner: docsConfig.downloads.owner,
repo: repoName,
});
releasesInfo.data
.sort((a, b) => compareFullVersion(a.tag_name, b.tag_name))
.reverse();
// Select the relevant stable, pre-release, and LTS versions to show.
const preReleases: string[] = [];
const stableReleases: string[] = [];
const shownReleases: OctokitRelease[] = [];
for (const r of releasesInfo.data) {
const version = majorMinor(r.tag_name);
if (r.prerelease) {
if (!preReleases.includes(version) && stableReleases.length === 0) {
shownReleases.push(r);
preReleases.push(version);
}
} else if (
docsConfig.ltsVersions[repoName]?.includes(version) &&
!stableReleases.includes(version)
) {
shownReleases.push(r);
stableReleases.push(version);
} else if (stableReleases.length === 0) {
shownReleases.push(r);
stableReleases.push(version);
}
}
for (const r of shownReleases) {
// Fetch and store checksums for each release.
const checksumsFile = r.assets.find((a) => a.name === "sha256sums.txt");
if (!checksumsFile) {
console.warn(
`No sha256sums.txt asset found for release ${r.tag_name} in ${repoName}`
);
continue;
}
const downloadURL = checksumsFile.browser_download_url;
assetChecksums[r.id] = {};
const response = await fetch(downloadURL);
if (!response.ok) {
throw new Error(
`Failed to fetch checksums for release ${r.tag_name} in ${repoName}: ${response.statusText}`
);
}
const checksums = await response.text();
for (const line of checksums.split("\n")) {
const [checksum, fileName] = line.split(/\s+/);
if (fileName) {
assetChecksums[r.id][fileName] = checksum;
}
}
}
downloads.repos.push({
name: repoInfo.data.name,
fullName: repoInfo.data.full_name,
description: repoInfo.data.description || "",
url: repoInfo.data.html_url,
releases: shownReleases.map(
(r): Release => ({
id: r.id,
name: r.name || "",
url: r.html_url,
prerelease: r.prerelease,
ltsRelease: docsConfig.ltsVersions[repoName]?.includes(
majorMinor(r.tag_name)
),
majorMinor: majorMinor(r.tag_name),
binaries: getBinaries(r),
})
),
});
console.groupEnd();
}
downloads.operatingSystems = downloads.repos
.flatMap((repo) =>
repo.releases
.flatMap((release) => release.binaries)
.flatMap((binary) => binary.os)
)
.filter(filterUnique)
.sort();
downloads.architectures = downloads.repos
.flatMap((repo) =>
repo.releases
.flatMap((release) => release.binaries)
.flatMap((binary) => binary.arch)
)
.filter(filterUnique)
.sort();
console.log(`Writing downloads metadata to ${OUTDIR}/downloads-metadata.json`);
fs.writeFileSync(
path.join(OUTDIR, "downloads-metadata.json"),
JSON.stringify(downloads, null, 2)
);

View File

@@ -1,4 +1,3 @@
import { Octokit } from "octokit";
import { execSync } from "child_process";
import * as fs from "fs";
import * as path from "path";
@@ -10,16 +9,11 @@ import {
RepoDocMetadata,
} from "@/docs-collection-types";
import matter from "gray-matter";
import dotenv from "dotenv";
dotenv.config();
import { octokit } from "./githubClient";
import { compareFullVersion, filterUnique, majorMinor } from "./utils";
const OUTDIR = "./generated";
const octokit = new Octokit({
auth: `${process.env.GITHUB_TOKEN}`,
});
const docsCollection: DocsCollection = {};
const allRepoVersions: AllRepoVersions = {};
@@ -130,33 +124,14 @@ const fetchRepoDocs = async ({
}
}
// We still need to sort the releases by version number, as e.g. "2.53.4"
// was released after "3.2.1".
//
// Sorting by major + minor should be sufficient, as patch versions and
// other suffixes should be in the expected order already when sorting by
// release date.
allReleaseTags
.sort((a, b) => {
const [majorA, minorA] = a.replace(/^v/, "").split(".").map(Number);
const [majorB, minorB] = b.replace(/^v/, "").split(".").map(Number);
return majorA === majorB ? minorA - minorB : majorA - majorB;
})
.reverse();
function onlyUnique(value: string, index: number, array: string[]) {
return array.indexOf(value) === index;
}
// "v3.4.1" -> "3.4"
function shortVersion(version: string) {
return version.replace(/^v/, "").split(".").slice(0, 2).join(".");
}
// was released after "3.2.1"..
allReleaseTags.sort(compareFullVersion).reverse();
// Get all <major>.<minor> versions, regardless of the patch version.
const allVersions = allReleaseTags
.filter((tag) => tag.startsWith("v")) // Ignore prehistoric release tags like "0.1.0"
.map((tag) => shortVersion(tag))
.filter(onlyUnique); // Remove dupes (e.g. "3.4.0" and "3.4.1" both become "3.4")
.map((tag) => majorMinor(tag))
.filter(filterUnique); // Remove dupes (e.g. "3.4.0" and "3.4.1" both become "3.4")
// First, get the last 10 versions, regardless of the major version.
const recentVersions = allVersions.slice(0, minNumVersions);
@@ -177,7 +152,7 @@ const fetchRepoDocs = async ({
if (!latestTag) {
throw new Error(`No latest version found for ${owner}/${repo}.`);
}
const latestVersion = shortVersion(latestTag);
const latestVersion = majorMinor(latestTag);
// Store metadata about the repo and its versions.
if (!allRepoVersions[owner]) {

8
scripts/githubClient.ts Normal file
View File

@@ -0,0 +1,8 @@
import dotenv from "dotenv";
import { Octokit } from "octokit";
dotenv.config();
export const octokit = new Octokit({
auth: `${process.env.GITHUB_TOKEN}`,
});

15
scripts/utils.ts Normal file
View File

@@ -0,0 +1,15 @@
import { compare } from "semver";
// Takes a full Prometheus tag / version string and returns the major and minor version.
// "v3.4.0-rc.0" -> "3.4"
export const majorMinor = (version: string) => {
return version.replace(/^v/, "").split(".").slice(0, 2).join(".");
};
export const compareFullVersion = (a: string, b: string) => {
return compare(a.replace(/^v/, ""), b.replace(/^v/, ""));
};
export function filterUnique(value: string, index: number, array: string[]) {
return array.indexOf(value) === index;
}

9
src/app/blog/page.tsx Normal file
View File

@@ -0,0 +1,9 @@
import { Title } from "@mantine/core";
export default function BlogPage() {
return (
<>
<Title order={1}>Blog</Title>Under construction - stay tuned.
</>
);
}

View File

@@ -0,0 +1,9 @@
import { Title } from "@mantine/core";
export default function CommunityPage() {
return (
<>
<Title order={1}>Community</Title>Under construction - stay tuned.
</>
);
}

View File

@@ -10,6 +10,7 @@ import rehypeShiki from "@shikijs/rehype";
import { IconLink } from "@tabler/icons-react";
import { docsCollection } from "@/docs-collection";
import {
em,
Table,
TableTbody,
TableTd,
@@ -40,8 +41,15 @@ export async function generateStaticParams() {
return params;
}
const h = (order: 1 | 2 | 3 | 4 | 5 | 6) => (props: TitleProps) =>
<Title order={order} {...props} />;
const h = (order: 1 | 2 | 3 | 4 | 5 | 6) => {
const HeadingComponent = (props: TitleProps) => (
<Title order={order} id={props.id}>
{props.children}
</Title>
);
HeadingComponent.displayName = `Heading${order}`;
return HeadingComponent;
};
export default async function DocsPage({
params,
@@ -56,152 +64,159 @@ export default async function DocsPage({
const markdown = await fs.readFile(docMeta.filePath, "utf-8");
return (
<div className="markdown-content">
<MarkdownAsync
remarkPlugins={[remarkFrontmatter, remarkGfm]}
rehypePlugins={[
rehypeSlug,
[
rehypeAutolinkHeadings,
{
content: { type: "text", value: "<replaceme>" },
// Don't link top-level page headings (h1).
test: (el) => el.tagName !== "h1",
<MarkdownAsync
remarkPlugins={[remarkFrontmatter, remarkGfm]}
rehypePlugins={[
rehypeSlug,
() =>
rehypeAutolinkHeadings({
properties: {
className: ["header-auto-link"],
},
],
[
rehypeShiki,
{
// or `theme` for a single theme
themes: {
light: "github-light",
dark: "vitesse-dark",
},
behavior: "prepend",
// Don't link top-level page headings (h1).
test: (el) => el.tagName !== "h1",
}),
[
rehypeShiki,
{
// or `theme` for a single theme
themes: {
light: "github-light",
dark: "vitesse-dark",
},
],
// Important: this has to run after rehypeSlug, since it
// relies on the headers to already have IDs.
rehypeConfigLinker,
]}
components={{
a: (props) => {
if (
props.node?.children &&
props.node.children[0].type === "text" &&
props.node.children[0].value === "<replaceme>"
) {
return (
<a {...props} className="header-auto-link">
<IconLink size={16} />
</a>
);
}
const href = props.href;
if (!href || docMeta.type === "local-doc") {
return <a {...props} />;
}
let normalizedHref = href;
if (href.startsWith(SITE_URL)) {
// Remove the "https://prometheus.io" from links that start with it.
normalizedHref = href.slice(SITE_URL.length);
} else if (href.startsWith("/")) {
// Turn "/<path>" into "https://github.com/prometheus/prometheus/blob/release-3.3.0/<path>"
normalizedHref = `https://github.com/prometheus/prometheus/blob/release-${docMeta.version}${href}`;
} else if (href.includes(".md") && !isAbsoluteUrl(href)) {
// Turn "foo/bar/baz.md" into "../foo/bar/baz" for relative links between Markdown pages.
normalizedHref = `${href.replace(/\.md($|#)/, "$1")}`;
}
return <a href={normalizedHref}>{props.children}</a>;
},
img: (props) => {
const src = props.src;
if (
!src ||
typeof src !== "string" ||
isAbsoluteUrl(src) ||
docMeta.type === "local-doc"
) {
return <img {...props} />;
}
return <img {...props} src={`${docMeta.assetsRoot}/${src}`} />;
},
pre: (props) => {
const firstChild = props.node?.children[0];
if (
!firstChild ||
firstChild?.type !== "element" ||
firstChild?.tagName !== "code"
) {
return <pre>{props.children}</pre>;
}
],
// Important: this has to run after rehypeSlug, since it
// relies on the headers to already have IDs.
rehypeConfigLinker,
]}
components={{
a: (props) => {
// Replace header auto-links with a custom link icon.
const { children, node: _node, ...rest } = props;
if (rest.className === "header-auto-link") {
return (
<pre
style={{
fontSize: 14,
backgroundColor: "var(--mantine-color-gray-0)",
lineHeight: 1.7,
display: "block",
padding: "1em",
borderRadius: "0.5em",
overflow: "auto",
}}
>
{props.children}
</pre>
<a {...rest}>
<IconLink size={em(14)} />
</a>
);
},
h1: h(1),
h2: h(2),
h3: h(3),
h4: h(4),
h5: h(5),
h6: h(6),
table: (props) => (
<Table withColumnBorders withTableBorder highlightOnHover>
{props.children}
</Table>
),
th: TableTh,
td: TableTd,
tr: TableTr,
thead: TableThead,
tbody: TableTbody,
// For <pre> tags that contain <code> tags, we need to extract the content
// of the <code> tag and pass it to a <CodeHighlight> Mantine component. If it's
// a <pre> tag that doesn't contain a <code> tag, we just render it as is.
// pre: (props) => {
// const firstChild = props.node?.children[0];
// if (
// firstChild?.type === "element" &&
// firstChild?.tagName === "code"
// ) {
// const contentElement = firstChild.children[0];
// if (contentElement.type !== "text") {
// throw new Error("Code content is not text");
// }
// const content = contentElement.value;
// const language = firstChild.properties?.className?.[0]?.replace(
// "language-",
// ""
// );
}
// return (
// <CodeHighlight code={content} language={language || "yaml"} />
// );
// } else {
// return <pre {...props} />;
// }
// },
}}
>
{markdown}
</MarkdownAsync>
</div>
// For local docs, keep links as is.
const href = props.href;
if (!href || docMeta.type === "local-doc") {
return <a {...rest}>{children}</a>;
}
// For external docs, do some postprocessing on the hrefs to make
// sure they point to the right place.
let normalizedHref = href;
if (href.startsWith(SITE_URL)) {
// Remove the "https://prometheus.io" from links that start with it.
normalizedHref = href.slice(SITE_URL.length);
} else if (href.startsWith("/")) {
// Turn "/<path>" into e.g. "https://github.com/prometheus/prometheus/blob/release-3.3.0/<path>"
normalizedHref = `https://github.com/prometheus/prometheus/blob/release-${docMeta.version}${href}`;
} else if (href.includes(".md") && !isAbsoluteUrl(href)) {
// Turn "foo/bar/baz.md" into "foo/bar/baz" for relative links between Markdown pages.
normalizedHref = `${href.replace(/\.md($|#)/, "$1")}`;
}
return (
<a {...rest} href={normalizedHref}>
{children}
</a>
);
},
img: (props) => {
const { src, node: _node, ...rest } = props;
if (
!src ||
typeof src !== "string" ||
isAbsoluteUrl(src) ||
docMeta.type === "local-doc"
) {
// eslint-disable-next-line jsx-a11y/alt-text
return <img {...rest} src={src} />;
}
// eslint-disable-next-line jsx-a11y/alt-text
return <img {...rest} src={`${docMeta.assetsRoot}/${src}`} />;
},
pre: (props) => {
const firstChild = props.node?.children[0];
if (
!firstChild ||
firstChild?.type !== "element" ||
firstChild?.tagName !== "code"
) {
return <pre>{props.children}</pre>;
}
return (
<pre
style={{
fontSize: 14,
backgroundColor:
"light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6))",
lineHeight: 1.7,
display: "block",
padding: "1em",
borderRadius: "0.5em",
overflow: "auto",
}}
>
{props.children}
</pre>
);
},
h1: h(1),
h2: h(2),
h3: h(3),
h4: h(4),
h5: h(5),
h6: h(6),
table: (props) => (
<Table withColumnBorders withTableBorder highlightOnHover>
{props.children}
</Table>
),
th: TableTh,
td: TableTd,
tr: TableTr,
thead: TableThead,
tbody: TableTbody,
// For <pre> tags that contain <code> tags, we need to extract the content
// of the <code> tag and pass it to a <CodeHighlight> Mantine component. If it's
// a <pre> tag that doesn't contain a <code> tag, we just render it as is.
// pre: (props) => {
// const firstChild = props.node?.children[0];
// if (
// firstChild?.type === "element" &&
// firstChild?.tagName === "code"
// ) {
// const contentElement = firstChild.children[0];
// if (contentElement.type !== "text") {
// throw new Error("Code content is not text");
// }
// const content = contentElement.value;
// const language = firstChild.properties?.className?.[0]?.replace(
// "language-",
// ""
// );
// return (
// <CodeHighlight code={content} language={language || "yaml"} />
// );
// } else {
// return <pre {...props} />;
// }
// },
}}
>
{markdown}
</MarkdownAsync>
);
}

View File

@@ -7,15 +7,15 @@ import {
RepoDocMetadata,
} from "@/docs-collection-types";
import {
Container,
Group,
Box,
List,
ListItem,
Text,
Select,
NavLink,
Alert,
ScrollAreaAutosize,
Button,
Popover,
Text,
} from "@mantine/core";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
@@ -33,12 +33,13 @@ import {
IconFileDescription,
IconProps,
IconInfoCircle,
IconVersions,
IconTag,
IconMenu2,
} from "@tabler/icons-react";
import { ReactElement } from "react";
import { ReactElement, useEffect, useRef } from "react";
import TOC from "@/components/TOC";
const iconMap: Record<string, React.ComponentType<any>> = {
const iconMap: Record<string, React.ComponentType<IconProps>> = {
flask: IconFlask,
server: IconServer,
code: IconCode,
@@ -52,10 +53,7 @@ const iconMap: Record<string, React.ComponentType<any>> = {
"file-description": IconFileDescription,
};
export function NavIcon({
iconName,
...props
}: { iconName: string } & IconProps) {
function NavIcon({ iconName, ...props }: { iconName: string } & IconProps) {
const Icon = iconMap[iconName];
return Icon ? (
<Icon {...props} color="var(--mantine-primary-color-4)" />
@@ -203,9 +201,11 @@ function buildRecursiveNav(
const navIcon =
node.document.type === "local-doc" && node.document.navIcon;
const active = currentPageSlug.startsWith(node.path);
return (
<NavLink
defaultOpened={active || undefined}
key={node.path}
href="#required-for-focus"
label={node.document.title}
@@ -217,13 +217,7 @@ function buildRecursiveNav(
}
ff={level === 0 ? "var(--font-inter)" : undefined}
fw={level === 0 ? 500 : undefined}
c={level === 0 ? "black" : "gray.7"}
style={{ borderRadius: 2.5 }}
// style={
// level === 1
// ? { borderLeft: "1px solid var(--mantine-color-gray-3)" }
// : {}
// }
>
{level === 0 && repoVersions && (
<Select
@@ -279,17 +273,15 @@ function buildRecursiveNav(
label={node.document.title}
href={`/docs/${node.path}`}
style={{ borderRadius: 2.5 }}
c={active ? undefined : "gray.7"}
// style={
// level === 1
// ? { borderLeft: "1px solid var(--mantine-color-gray-3)" }
// : {}
// }
/>
);
});
}
const breadcrumbs = (pageSlug: string, docsTree: DocsTree[]) => {
const segments = pageSlug.split("/").filter(Boolean);
};
function compareVersions(a: string, b: string): number {
const [majorA, minorA] = a.split(".").map(Number);
const [majorB, minorB] = b.split(".").map(Number);
@@ -309,6 +301,13 @@ export default function DocsLayout({
const docsTree = buildDocsTree(docsCollection);
const pageSlug = usePathname().replace(/^\/docs\//, "");
const currentPage = docsCollection[pageSlug];
const reinitializeTOCRef = useRef(() => {});
const bc = breadcrumbs(pageSlug, docsTree);
useEffect(() => {
reinitializeTOCRef.current();
}, [pageSlug]);
let alert: ReactElement | null = null;
if (currentPage.type === "repo-doc") {
@@ -348,16 +347,75 @@ export default function DocsLayout({
}
return (
<Container size="lg">
<Group wrap="nowrap" align="flex-start" gap={80}>
<Box w={250} flex="0 0 auto" mih={300}>
{buildRecursiveNav(docsTree, pageSlug, router)}
<>
{/* The mobile main nav */}
<Popover position="bottom" withArrow shadow="md">
<Popover.Target>
<Button
hiddenFrom="sm"
variant="outline"
color="gray"
mb="lg"
leftSection={<IconMenu2 />}
>
Show nav
</Button>
</Popover.Target>
<Popover.Dropdown mah="calc(100vh - var(--header-height))">
<ScrollAreaAutosize mah="calc(80vh - var(--header-height))">
{buildRecursiveNav(docsTree, pageSlug, router)}
</ScrollAreaAutosize>
</Popover.Dropdown>
</Popover>
<Group wrap="nowrap" align="flex-start" gap={50}>
{/* The left-hand side main nav */}
<Box
w={250}
flex="0 0 auto"
mih={300}
pos="sticky"
top="calc(var(--header-height) + var(--header-to-content-margin))"
visibleFrom="sm"
style={{
borderRight:
"1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-gray-7))",
}}
>
<ScrollAreaAutosize mah="calc(100vh - var(--header-height))">
<Box pr="xs">{buildRecursiveNav(docsTree, pageSlug, router)}</Box>
</ScrollAreaAutosize>
</Box>
<Box miw={0}>
{/* The main docs page content */}
<Box miw={0} className="docs-content">
{alert}
{children}
</Box>
{/* The right-hand-side table of contents for headings
within the current document */}
<Box
w="fit-content"
maw={230}
flex="0 0 auto"
pos="sticky"
top="calc(var(--header-height) + var(--header-to-content-margin))"
visibleFrom="md"
>
<Text mb="sm" c="dimmed" fw={600} fz="sm">
On this page
</Text>
<ScrollAreaAutosize mah="calc(100vh - var(--header-height))">
<TOC
reinitializeRef={reinitializeTOCRef}
scrollSpyOptions={{
selector:
".docs-content :is(h2, h3), .docs-content h1:not(:first-of-type)",
}}
/>
</ScrollAreaAutosize>
</Box>
</Group>
</Container>
</>
);
}

190
src/app/download/page.tsx Normal file
View File

@@ -0,0 +1,190 @@
"use client";
import TOC from "@/components/TOC";
import { downloadsMetadata } from "@/downloads-metadata";
import {
Anchor,
Badge,
Box,
Card,
Group,
Select,
Stack,
Table,
TableTd,
TableTh,
TableThead,
TableTr,
Title,
} from "@mantine/core";
import { IconBrandGithub } from "@tabler/icons-react";
import Link from "next/link";
import React, { useState } from "react";
export default function DownloadPage() {
const [os, setOs] = useState("popular");
const [arch, setArch] = useState("popular");
const osList =
os === "all"
? downloadsMetadata.operatingSystems
: os === "popular"
? ["linux", "windows", "darwin"]
: [os];
const archList =
arch === "all"
? downloadsMetadata.architectures
: arch === "popular"
? ["amd64", "arm64"]
: [arch];
return (
<>
<Title order={1}>Download</Title>
<Group wrap="nowrap" align="flex-start">
<Box>
<p>
We provide precompiled binaries and{" "}
<Anchor href="https://hub.docker.com/r/prom/" target="_blank">
Docker images
</Anchor>{" "}
for most officially maintained Prometheus components. If a component
is not listed here, check the respective repository on Github for
further instructions.
</p>
<p>
There is also a constantly growing number of independently
maintained exporters listed at{" "}
<Link href="/docs/instrumenting/exporters/">
Exporters and integrations
</Link>
.
</p>
</Box>
<TOC
scrollSpyOptions={{
selector: "h2",
}}
/>
</Group>
<Stack mt="xl" gap="md">
<Group>
<Select
label="Operating System"
placeholder="Select OS"
maxDropdownHeight={300}
data={[
{ group: "Group", items: ["all", "popular"] },
{
group: "Specific",
items: downloadsMetadata.operatingSystems,
},
]}
value={os}
onChange={(value) => {
console.log(value);
setOs(value || "all");
}}
/>
<Select
label="Architecture"
placeholder="Select Architecture"
maxDropdownHeight={300}
data={[
{ group: "Group", items: ["all", "popular"] },
{ group: "Specific", items: downloadsMetadata.architectures },
]}
value={arch}
onChange={(value) => {
setArch(value || "all");
}}
/>
</Group>
{downloadsMetadata.repos.map((repo) => (
// "overflow: unset" is needed, since otherwise "overflow: hidden"
// on the Card breaks the scroll-margin-top of the Title / h2, and
// the title ends up under the sticky header.
<Card key={repo.name} withBorder style={{ overflow: "unset" }}>
<Title order={2} mt={0} mb="xs" id={repo.name}>
{repo.name}
</Title>
<Group justify="space-between" mb="xs" align="flex-end">
{repo.description}
<Anchor href={repo.url} target="_blank">
<Group gap={5} align="center">
<IconBrandGithub size="1em" /> {repo.fullName}
</Group>
</Anchor>
</Group>
<Table withColumnBorders withRowBorders withTableBorder fz="sm">
{repo.releases.map((release) => (
<React.Fragment key={release.id}>
<TableThead>
<TableTr>
<TableTd colSpan={5}>
<Group justify="space-between" align="center">
<Group gap="xs">
<strong>{release.name}</strong>
{release.prerelease ? (
<Badge size="sm" color="yellow">
Pre-release
</Badge>
) : release.ltsRelease ? (
<Badge size="sm" color="blue">
LTS
</Badge>
) : (
<Badge size="sm" color="green">
Latest
</Badge>
)}
</Group>
<a href={release.url}>Release notes</a>
</Group>
</TableTd>
</TableTr>
<TableTr>
<TableTh>File name</TableTh>
<TableTh>OS</TableTh>
<TableTh>Arch</TableTh>
<TableTh>Size</TableTh>
<TableTh>SHA256 Checksum</TableTh>
</TableTr>
</TableThead>
{release.binaries
.filter(
(b) =>
osList.includes(b.os) &&
archList.includes(b.arch) &&
(b.arch === "amd64" ||
(b.os === "darwin" && b.arch === "arm64"))
)
.map((binary) => (
<TableTr key={binary.name}>
<TableTd>
<a className="download" href={binary.url}>
{binary.name}
</a>
</TableTd>
<TableTd>{binary.os}</TableTd>
<TableTd>{binary.arch}</TableTd>
<TableTd>
{(binary.sizeBytes / 1024 / 1024).toFixed(2)} MiB
</TableTd>
<TableTd fz="xs">{binary.checksum}</TableTd>
</TableTr>
))}
</React.Fragment>
))}
</Table>
</Card>
))}
</Stack>
</>
);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,21 +1,10 @@
:is(h1, h2, h3, h4, h5, h6) > a {
position: absolute;
transform: translateX(-130%);
text-decoration: none;
opacity: 0;
color: var(--mantine-color-gray-6);
&:hover {
opacity: 1;
}
:root {
--header-height: 72px;
--header-to-content-margin: var(--mantine-spacing-xl);
}
:is(h1, h2, h3, h4, h5, h6):hover > a {
opacity: 1;
}
:is(h1, h2, h3, h4, h5, h6) a:hover {
color: var(--mantine-color-gray-8);
html {
scroll-behavior: smooth;
}
h1,
@@ -27,11 +16,41 @@ h6 {
margin-top: calc(var(--mantine-spacing-xl) * 1.2);
margin-bottom: calc(var(--mantine-spacing-md) * 1.2);
scroll-margin-top: calc(
var(--header-height) + var(--header-to-content-margin)
);
&:is(h1) {
margin-top: 0;
}
}
.docs-content a {
color: var(--mantine-color-blue-8);
text-decoration: none;
font-weight: 500;
&:hover {
color: var(--mantine-color-blue-6);
text-decoration: underline;
}
}
a.header-auto-link {
position: absolute;
transform: translate(-140%, 5%);
opacity: 0;
color: var(--mantine-color-gray-6);
&:hover {
color: var(--mantine-primary-color-filled);
}
}
*:hover > .header-auto-link {
opacity: 1;
}
pre > code a {
color: #337ab7;
font-style: italic;
@@ -43,9 +62,17 @@ pre > code a {
}
}
.invertInDarkMode,
pre > code {
filter: light-dark("", invert(1));
}
:not(pre) > code {
background-color: var(--mantine-color-gray-1);
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-5)
);
font-size: 0.9em;
padding: 0.1em 0.2em;
padding: 0.1em 0.3em;
border-radius: 0.3em;
}

50
src/app/icon.svg Normal file
View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="115.333px"
height="114px"
viewBox="0 0 115.333 114"
enable-background="new 0 0 115.333 114"
xml:space="preserve"
sodipodi:docname="prometheus_logo_orange.svg"
inkscape:version="0.92.1 r15371"><metadata
id="metadata4495"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs4493" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1484"
inkscape:window-height="886"
id="namedview4491"
showgrid="false"
inkscape:zoom="5.2784901"
inkscape:cx="60.603667"
inkscape:cy="60.329656"
inkscape:window-x="54"
inkscape:window-y="7"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" /><g
id="Layer_2" /><path
style="fill:#e6522c;fill-opacity:1"
inkscape:connector-curvature="0"
id="path4486"
d="M 56.667,0.667 C 25.372,0.667 0,26.036 0,57.332 c 0,31.295 25.372,56.666 56.667,56.666 31.295,0 56.666,-25.371 56.666,-56.666 0,-31.296 -25.372,-56.665 -56.666,-56.665 z m 0,106.055 c -8.904,0 -16.123,-5.948 -16.123,-13.283 H 72.79 c 0,7.334 -7.219,13.283 -16.123,13.283 z M 83.297,89.04 H 30.034 V 79.382 H 83.298 V 89.04 Z M 83.106,74.411 H 30.186 C 30.01,74.208 29.83,74.008 29.66,73.802 24.208,67.182 22.924,63.726 21.677,60.204 c -0.021,-0.116 6.611,1.355 11.314,2.413 0,0 2.42,0.56 5.958,1.205 -3.397,-3.982 -5.414,-9.044 -5.414,-14.218 0,-11.359 8.712,-21.285 5.569,-29.308 3.059,0.249 6.331,6.456 6.552,16.161 3.252,-4.494 4.613,-12.701 4.613,-17.733 0,-5.21 3.433,-11.262 6.867,-11.469 -3.061,5.045 0.793,9.37 4.219,20.099 1.285,4.03 1.121,10.812 2.113,15.113 C 63.797,33.534 65.333,20.5 71,16 c -2.5,5.667 0.37,12.758 2.333,16.167 3.167,5.5 5.087,9.667 5.087,17.548 0,5.284 -1.951,10.259 -5.242,14.148 3.742,-0.702 6.326,-1.335 6.326,-1.335 l 12.152,-2.371 c 10e-4,-10e-4 -1.765,7.261 -8.55,14.254 z" /></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -17,9 +17,14 @@ import {
// https://mantine.dev/styles/mantine-styles/#css-layers.
import "@mantine/core/styles.layer.css";
import "@mantine/code-highlight/styles.layer.css";
import "@mantine/spotlight/styles.layer.css";
import "./globals.css";
import { Header } from "@/components/Header";
import { theme } from "@/theme";
// import docsearch from "@docsearch/js";
import "@docsearch/css";
// import { useEffect } from "react";
const interFont = Inter({
variable: "--font-inter",
@@ -36,6 +41,15 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
// useEffect(() => {
// docsearch({
// container: "#docsearch",
// appId: "prometheus",
// indexName: "prometheus",
// apiKey: "48ac0b7924908a1fd40b1cb18b402ba1",
// });
// }, []);
return (
<html lang="en" {...mantineHtmlProps} className={interFont.variable}>
<head>
@@ -44,20 +58,33 @@ export default function RootLayout({
<body>
<MantineProvider theme={theme}>
<Header />
{children}
<Space h={50} />
<footer style={{ backgroundColor: "var(--mantine-color-gray-0)" }}>
<Container size="lg" p="xl">
{/* <div id="docsearch" /> */}
<Container
size="xl"
mt="xl"
mih="calc(100vh - var(--header-height) - var(--header-to-content-margin))"
>
{children}
<Space h={50} />
</Container>
<footer
style={{
backgroundColor:
"light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-9))",
}}
>
<Container size="xl" p="xl">
<Group h={100}>
<Text c="dimmed" fz="sm">
&copy; Prometheus Authors 2014-2024 | Documentation
Distributed under CC-BY-4.0
&copy; Prometheus Authors 2014-{new Date().getFullYear()} |
Documentation Distributed under CC-BY-4.0
</Text>
<Text c="dimmed" fz="sm">
&copy; 2024 The Linux Foundation. All rights reserved. The
Linux Foundation has registered trademarks and uses
trademarks. For a list of trademarks of The Linux Foundation,
please see our{" "}
&copy; {new Date().getFullYear()} The Linux Foundation. All
rights reserved. The Linux Foundation has registered
trademarks and uses trademarks. For a list of trademarks of
The Linux Foundation, please see our{" "}
<Anchor
inherit
href="https://www.linuxfoundation.org/trademark-usage"

View File

@@ -1,12 +1,14 @@
import NextImage from "next/image";
import { Image } from "@mantine/core";
import { Box, Image } from "@mantine/core";
import classes from "@/components/FeaturesCards.module.css";
import { FeaturesCards } from "@/components/FeaturesCards";
import { Hero } from "@/components/Hero";
import { UserLogos } from "@/components/UserLogos";
import { Space, Title, Group, Anchor, Text } from "@mantine/core";
import cncfLogo from "../assets/cncf-logo.svg";
import cncfLogoLightMode from "../assets/cncf-logo.svg";
import cncfLogoDarkMode from "../assets/cncf-logo-white.svg";
import githubLogo from "../assets/github-logo.svg";
import { GitHubStars } from "@/components/GitHubStars";
export default function Home() {
return (
@@ -21,56 +23,61 @@ export default function Home() {
component={NextImage}
src={githubLogo}
style={{ height: 40, width: 40 }}
className="invertInDarkMode"
alt="GitHub logo"
/>{" "}
Open Source
</Group>
</Title>
<Text c="dimmed" className={classes.description} ta="center" mt="md">
Prometheus is 100% open source and community-driven. All components are
available under the{" "}
<Anchor href="http://www.apache.org/licenses/LICENSE-2.0">
Apache 2 License
</Anchor>{" "}
on <Anchor href="https://github.com/prometheus">GitHub</Anchor>.
<iframe
src="https://ghbtns.com/github-btn.html?user=prometheus&repo=prometheus&type=star&count=true&size=large"
scrolling="0"
style={{
width: 200,
height: 30,
margin: "auto",
display: "block",
marginTop: 20,
marginBottom: 20,
border: 0,
}}
></iframe>
</Text>
<Box className={classes.description}>
<Text c="dimmed" ta="center" mt="md">
Prometheus is 100% open source and community-driven. All components
are available under the{" "}
<Anchor href="http://www.apache.org/licenses/LICENSE-2.0">
Apache 2 License
</Anchor>{" "}
on <Anchor href="https://github.com/prometheus">GitHub</Anchor>.
</Text>
<GitHubStars />
</Box>
<Title order={2} className={classes.title} mt={80}>
<Group justify="center">Open Governance</Group>
</Title>
<Text c="dimmed" className={classes.description} ta="center" mt="md">
Prometheus is a{" "}
<Anchor href="https://cncf.io/">
Cloud Native Computing Foundation
</Anchor>{" "}
graduated project.
<Image
component={NextImage}
mt="md"
m="auto"
w="auto"
src={cncfLogo}
alt="CNCF logo"
className={classes.cncfLogo}
style={{
objectFit: "fill",
}}
/>
</Text>
<Box className={classes.description}>
<Title order={2} className={classes.title} mt={80}>
<Group justify="center">Open Governance</Group>
</Title>
<Text c="dimmed" ta="center" mt="md">
Prometheus is a{" "}
<Anchor href="https://cncf.io/">
Cloud Native Computing Foundation
</Anchor>{" "}
graduated project.
</Text>
<Box mt="md">
<a href="https://cncf.io/" target="_blank">
<Image
darkHidden
component={NextImage}
src={cncfLogoLightMode}
alt="CNCF logo"
style={{
objectFit: "fill",
}}
/>
<Image
lightHidden
component={NextImage}
src={cncfLogoDarkMode}
alt="CNCF logo"
style={{
objectFit: "fill",
opacity: 0.8,
}}
/>
</a>
</Box>
</Box>
</>
);
}

View File

@@ -0,0 +1,10 @@
import { Title } from "@mantine/core";
export default function SupportTrainingPage() {
return (
<>
<Title order={1}>Support and Training</Title>Under construction - stay
tuned.
</>
);
}

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 399.1 76.1" style="enable-background:new 0 0 399.1 76.1;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_00000101819250155371233590000014564074804978075571_);}
.st1{fill:#FFFFFF;}
.st2{fill:#0086FF;}
.st3{fill:#93EAFF;}
</style>
<g>
<defs>
<rect id="SVGID_1_" x="7.7" y="6.8" width="383.9" height="60.9"/>
</defs>
<clipPath id="SVGID_00000085247321625283493830000016876323681948451229_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g style="clip-path:url(#SVGID_00000085247321625283493830000016876323681948451229_);">
<g>
<path class="st1" d="M98.9,33.4c1.5,0,2.9-0.3,4.3-0.9c1.3-0.6,2.5-1.6,3.4-2.8l4.1,4.2c-3.2,3.6-6.9,5.4-11.3,5.4
c-2,0.1-3.9-0.2-5.8-1c-1.8-0.7-3.5-1.8-5-3.1c-1.4-1.3-2.5-3-3.2-4.7c-0.7-1.8-1.1-3.7-1-5.6c-0.1-1.9,0.3-3.9,1-5.7
c0.7-1.8,1.8-3.4,3.2-4.8c1.5-1.4,3.3-2.5,5.2-3.2c1.9-0.7,4-1,6.1-0.9c2.1,0.1,4.1,0.6,6,1.5c1.9,0.9,3.5,2.2,4.9,3.8l-3.9,4.5
c-0.9-1.2-2-2.1-3.3-2.7c-1.3-0.6-2.7-1-4.2-1c-2.2,0-4.4,0.8-6.1,2.3c-0.9,0.8-1.5,1.8-2,2.9c-0.4,1.1-0.6,2.3-0.6,3.4
c-0.1,1.2,0.1,2.3,0.5,3.4c0.4,1.1,1,2.1,1.9,2.9C94.7,32.6,96.8,33.4,98.9,33.4L98.9,33.4z M115.5,38.9V10.7h6.3v22.6h12.1v5.6
H115.5z M161.5,35c-2.9,2.7-6.6,4.2-10.6,4.2s-7.7-1.5-10.6-4.2c-1.4-1.3-2.5-2.9-3.2-4.7c-0.7-1.8-1.1-3.7-1.1-5.6
c-0.1-1.9,0.3-3.9,1-5.6c0.7-1.8,1.8-3.4,3.2-4.7c2.9-2.7,6.6-4.2,10.6-4.2s7.7,1.5,10.6,4.2c1.4,1.3,2.5,2.9,3.2,4.7
c0.7,1.8,1.1,3.7,1,5.6c0.1,1.9-0.3,3.9-1,5.6C164,32.1,162.9,33.7,161.5,35z M159.3,24.7c0-2.4-0.9-4.7-2.5-6.5
c-0.8-0.8-1.7-1.5-2.7-2c-1-0.5-2.2-0.7-3.3-0.7c-1.1,0-2.2,0.2-3.3,0.7c-1,0.5-2,1.1-2.7,2c-1.6,1.8-2.5,4.1-2.5,6.5
c0,2.4,0.9,4.7,2.5,6.5c0.8,0.8,1.7,1.5,2.7,2c1,0.5,2.2,0.7,3.3,0.7c1.1,0,2.2-0.2,3.3-0.7c1-0.5,2-1.1,2.7-2
c0.8-0.9,1.5-1.9,1.9-3C159.2,27,159.4,25.9,159.3,24.7z M178.6,31.7c0.5,0.7,1.2,1.2,1.9,1.5c0.7,0.3,1.6,0.5,2.4,0.5
c0.8,0,1.6-0.1,2.3-0.5c0.7-0.3,1.4-0.9,1.8-1.5c1.1-1.6,1.6-3.4,1.5-5.3V10.8h6.3v15.8c0,4.1-1.1,7.2-3.4,9.4
c-1.2,1.1-2.5,2-4,2.5c-1.5,0.6-3.1,0.8-4.7,0.8c-1.6,0-3.2-0.2-4.7-0.8c-1.5-0.6-2.9-1.4-4-2.5c-2.3-2.2-3.4-5.3-3.4-9.4V10.8
h6.3v15.6C176.9,28.3,177.5,30.2,178.6,31.7z M223.1,14.4c2.7,2.5,4.1,5.9,4.1,10.3s-1.3,7.9-3.9,10.5c-2.6,2.6-6.7,3.8-12,3.8
h-9.8V10.7h10C216.5,10.7,220.4,11.9,223.1,14.4z M218.5,31.2c1.5-1.4,2.3-3.6,2.3-6.4s-0.8-4.9-2.3-6.4s-3.9-2.3-7.1-2.3h-3.5
v17.2h4C214.3,33.5,216.7,32.8,218.5,31.2z M263.1,10.7h6.3v28.3h-6.3l-13.5-17.7v17.7h-6.3V10.7h5.9l13.9,18.2V10.7z
M296.5,38.9l-2.7-6.1h-11.9l-2.7,6.1h-6.8l12.2-28.3h6.1L303,38.9H296.5z M288,19.1l-3.5,8.2h7L288,19.1z M316.5,16.2V39h-6.3
V16.2h-8v-5.4h22.4v5.4C324.6,16.2,316.5,16.2,316.5,16.2z M329,10.7h6.3v28.3H329C329,38.9,329,10.7,329,10.7z M352.8,28.7
l7.2-18h6.9l-11.3,28.3h-5.3l-11.3-28.3h6.9L352.8,28.7z M390.5,10.7v5.6h-14.1v5.8h12.7v5.4h-12.7v5.9H391V39h-20.8V10.8
L390.5,10.7C390.5,10.8,390.5,10.7,390.5,10.7z M91.6,63c0.8,0,1.6-0.2,2.4-0.5c0.7-0.4,1.4-0.9,1.9-1.6l2.3,2.4
c-0.8,0.9-1.7,1.7-2.9,2.2c-1.1,0.5-2.3,0.8-3.5,0.8c-1.1,0-2.2-0.1-3.2-0.5c-1-0.4-2-1-2.8-1.8c-0.8-0.7-1.4-1.6-1.8-2.6
c-0.4-1-0.6-2.1-0.6-3.2c0-1.1,0.2-2.2,0.6-3.2c0.4-1,1-1.9,1.8-2.7c0.8-0.8,1.7-1.4,2.7-1.8c1-0.4,2.1-0.6,3.2-0.6
c1.2,0,2.5,0.2,3.6,0.7c1.1,0.5,2.1,1.3,3,2.2l-2.2,2.5c-0.5-0.7-1.1-1.2-1.8-1.6c-0.7-0.4-1.5-0.5-2.4-0.5
c-1.3,0-2.5,0.5-3.4,1.3c-0.5,0.4-0.9,1-1.1,1.6c-0.2,0.6-0.4,1.3-0.3,1.9c0,0.6,0.1,1.3,0.3,1.9c0.2,0.6,0.6,1.2,1,1.6
c0.4,0.4,0.9,0.8,1.5,1S91,63,91.6,63L91.6,63z M113.9,63.9c-1.6,1.5-3.7,2.4-5.9,2.4c-1.1,0-2.2-0.2-3.2-0.6
c-1-0.4-1.9-1-2.7-1.8c-1.5-1.5-2.4-3.6-2.4-5.8s0.9-4.3,2.4-5.8c1.6-1.5,3.7-2.4,5.9-2.4c1.1,0,2.2,0.2,3.2,0.6s1.9,1,2.7,1.8
c1.5,1.5,2.4,3.6,2.4,5.8S115.4,62.4,113.9,63.9z M112.8,58.1c0-1.3-0.4-2.6-1.3-3.6c-0.4-0.5-0.9-0.8-1.5-1.1
c-0.6-0.3-1.2-0.4-1.8-0.4c-0.6,0-1.3,0.1-1.8,0.4c-0.6,0.3-1.1,0.7-1.5,1.2c-0.5,0.5-0.8,1-1,1.7c-0.2,0.6-0.3,1.3-0.3,1.9
c0,1.3,0.5,2.6,1.3,3.6c0.4,0.5,0.9,0.8,1.5,1.1c0.6,0.3,1.2,0.4,1.8,0.4c0.6,0,1.3-0.1,1.8-0.4c0.6-0.3,1.1-0.7,1.5-1.2
C112.3,60.8,112.8,59.5,112.8,58.1L112.8,58.1z M133.5,56.1l-4.3,8.7h-2.1l-4.3-8.7v10h-3.5V50.3h4.8l4.1,8.7l4.1-8.7h4.8v15.9
h-3.5L133.5,56.1L133.5,56.1z M151.9,51.8c0.6,0.5,1.1,1.2,1.4,2c0.3,0.8,0.4,1.6,0.3,2.4c0,2-0.6,3.4-1.7,4.3
c-1.1,1-2.9,1.3-5.2,1.3h-2.1v4.4H141V50.3h5.6C149,50.3,150.7,50.8,151.9,51.8z M149.3,58c0.5-0.6,0.7-1.3,0.7-2.1
c0-0.4,0-0.7-0.2-1.1c-0.2-0.3-0.4-0.6-0.7-0.8c-0.8-0.4-1.7-0.6-2.6-0.6h-2v5.3h2.4c0.4,0,0.9,0,1.3-0.1
C148.6,58.4,149,58.2,149.3,58z M160.6,62c0.3,0.4,0.6,0.6,1.1,0.8c0.4,0.2,0.9,0.3,1.3,0.3c0.5,0,0.9-0.1,1.3-0.3
c0.4-0.2,0.8-0.5,1.1-0.8c0.6-0.9,0.9-2,0.9-3v-8.8h3.5v8.8c0.1,1-0.1,1.9-0.4,2.9c-0.3,0.9-0.8,1.8-1.5,2.5
c-1.3,1.2-3.1,1.8-4.9,1.8c-1.8,0-3.5-0.7-4.8-1.9c-0.7-0.7-1.2-1.6-1.5-2.5c-0.3-0.9-0.5-1.9-0.4-2.9v-8.8h3.5v8.8
C159.6,60,159.9,61.1,160.6,62z M180.1,53.4v12.7h-3.5V53.4h-4.5v-3h12.6v3C184.6,53.4,180.1,53.4,180.1,53.4z M187.2,50.3h3.5
v15.9h-3.5C187.2,66.2,187.2,50.3,187.2,50.3z M205.7,50.3h3.5v15.9h-3.5l-7.5-9.9v9.9h-3.5V50.3h3.3l7.8,10.2L205.7,50.3
C205.8,50.3,205.7,50.3,205.7,50.3z M223.5,58.1h3.5v5.6c-0.8,0.9-1.9,1.6-3,2c-1.1,0.5-2.4,0.7-3.6,0.6c-2.2,0-4.3-0.8-5.9-2.3
c-0.8-0.7-1.4-1.6-1.8-2.6c-0.4-1-0.6-2.1-0.6-3.2c0-1.1,0.2-2.2,0.6-3.2c0.4-1,1-1.9,1.8-2.7s1.7-1.4,2.7-1.8
c1-0.4,2.1-0.6,3.2-0.6c2.2,0,4.3,0.8,5.9,2.3l-1.8,2.7c-0.5-0.6-1.2-1-2-1.2c-0.6-0.2-1.3-0.4-1.9-0.4c-1.3,0-2.5,0.5-3.4,1.3
c-0.5,0.5-0.9,1-1.1,1.7s-0.4,1.3-0.3,2c0,1.3,0.4,2.6,1.3,3.6c0.4,0.4,0.9,0.8,1.4,1c0.5,0.2,1.1,0.3,1.7,0.3
c1.1,0.1,2.1-0.2,3-0.7v-4.5H223.5z M247,50.3v3.1h-7.3v3.4h6.9V60h-6.9v6.2h-3.5V50.3C236.1,50.3,247,50.3,247,50.3z
M263.4,63.9c-1.6,1.5-3.7,2.4-5.9,2.4c-1.1,0-2.2-0.2-3.2-0.6c-1-0.4-1.9-1-2.7-1.8c-1.5-1.5-2.4-3.6-2.4-5.8s0.9-4.3,2.4-5.8
c1.6-1.5,3.7-2.4,5.9-2.4c1.1,0,2.2,0.2,3.2,0.6s1.9,1,2.7,1.8c1.5,1.5,2.4,3.6,2.4,5.8S264.9,62.4,263.4,63.9z M262.1,58.1
c0-1.3-0.4-2.6-1.3-3.6c-0.4-0.5-0.9-0.8-1.5-1.1c-0.6-0.3-1.2-0.4-1.8-0.4c-0.6,0-1.3,0.1-1.8,0.4c-0.6,0.3-1.1,0.7-1.5,1.2
c-0.5,0.5-0.8,1-1,1.7s-0.3,1.3-0.3,1.9c0,1.3,0.5,2.6,1.3,3.6c0.4,0.5,0.9,0.8,1.5,1.1c0.6,0.3,1.2,0.4,1.8,0.4
c0.6,0,1.3-0.1,1.8-0.4c0.6-0.3,1.1-0.7,1.5-1.2c0.5-0.5,0.8-1,1-1.7S262.2,58.8,262.1,58.1L262.1,58.1z M273,62
c0.3,0.4,0.6,0.6,1.1,0.8c0.4,0.2,0.9,0.3,1.3,0.3s0.9-0.1,1.3-0.3c0.4-0.2,0.8-0.5,1.1-0.8c0.6-0.9,0.9-2,0.9-3v-8.8h3.5v8.8
c0.1,1-0.1,1.9-0.4,2.9c-0.3,0.9-0.8,1.8-1.5,2.5c-1.3,1.2-3.1,1.8-4.9,1.8c-1.8,0-3.5-0.7-4.8-1.9c-0.7-0.7-1.2-1.6-1.5-2.5
c-0.3-0.9-0.5-1.9-0.4-2.9v-8.8h3.5v8.8C272,60,272.3,61.2,273,62z M296.9,50.3h3.5v15.9h-3.5l-7.5-9.9v9.9h-3.5V50.3h3.3
l7.8,10.2L296.9,50.3C297,50.3,296.9,50.3,296.9,50.3z M316.4,52.4c0.8,0.7,1.4,1.7,1.8,2.7s0.6,2.1,0.5,3.1
c0.1,1.1-0.1,2.1-0.5,3.1c-0.4,1-1,1.9-1.7,2.7c-1.4,1.4-3.7,2.2-6.8,2.2h-5.4V50.3h5.6C312.8,50.3,315,51,316.4,52.4z
M313.8,61.9c0.4-0.5,0.8-1,1-1.6c0.2-0.6,0.3-1.3,0.3-1.9c0-0.7-0.1-1.3-0.3-1.9s-0.6-1.2-1-1.7c-0.6-0.5-1.2-0.8-1.9-1
s-1.4-0.3-2.1-0.2h-2v9.6h2.3C311.4,63.1,312.8,62.7,313.8,61.9z M332.6,66.1l-1.4-3.4h-6.7l-1.4,3.4h-3.8l6.9-15.9h3.4l6.9,15.9
H332.6z M327.8,55l-2,4.6h4L327.8,55z M343.8,53.4v12.7h-3.5V53.4h-4.6v-3h12.6v3C348.3,53.4,343.8,53.4,343.8,53.4z M350.8,50.3
h3.5v15.9h-3.5C350.8,66.2,350.8,50.3,350.8,50.3z M371.6,63.9c-1.6,1.5-3.7,2.4-5.9,2.4c-1.1,0-2.2-0.2-3.2-0.6s-1.9-1-2.7-1.8
c-1.5-1.5-2.4-3.6-2.4-5.8s0.9-4.3,2.4-5.8c1.6-1.5,3.7-2.4,5.9-2.4c1.1,0,2.2,0.2,3.2,0.6c1,0.4,1.9,1,2.7,1.8
c1.5,1.5,2.4,3.6,2.4,5.8S373.1,62.4,371.6,63.9z M370.5,58.1c0-1.3-0.5-2.6-1.3-3.6c-0.4-0.5-0.9-0.8-1.5-1.1
c-0.6-0.3-1.2-0.4-1.8-0.4c-0.6,0-1.3,0.1-1.8,0.4c-0.6,0.3-1.1,0.7-1.5,1.2c-0.5,0.5-0.8,1-1,1.7s-0.3,1.3-0.3,1.9
c0,1.3,0.5,2.6,1.3,3.6c0.4,0.5,0.9,0.8,1.5,1.1c0.6,0.3,1.2,0.4,1.8,0.4c0.6,0,1.3-0.1,1.8-0.4c0.6-0.3,1.1-0.7,1.5-1.2
C370,60.8,370.5,59.5,370.5,58.1z M388.1,50.3h3.5v15.9h-3.5l-7.5-9.9v9.9H377V50.3h3.3l7.8,10.2
C388.2,60.5,388.1,50.3,388.1,50.3z"/>
</g>
</g>
<g style="clip-path:url(#SVGID_00000085247321625283493830000016876323681948451229_);">
<path class="st2" d="M177.5-49.3h-8.7v20.3h20.3v-8.7h-11.6V-49.3z"/>
<path class="st2" d="M221.1-49.2v11.5h-11.6v8.7h20.3v-20.3L221.1-49.2L221.1-49.2z"/>
<path class="st2" d="M168.9-69.5h8.8l-0.1-0.1v-11.5h11.6v-8.7h-20.3V-69.5z"/>
<path class="st2" d="M209.5-89.8v8.7h11.6v11.6h8.7v-20.3C229.8-89.8,209.5-89.8,209.5-89.8z"/>
<path class="st3" d="M208.4-69.5l-11.6-11.6h12.7v-8.7h-20.4v8.7l11.6,11.6H208.4z"/>
<path class="st3" d="M197.9-49.3h-7.6l9.6,9.6l1.9,2h-12.7v8.7h20.4v-8.8l-5.8-5.7L197.9-49.3z"/>
<path class="st3" d="M221.1-69.5v12.6l-2-2l-9.6-9.6v7.7l5.7,5.7l5.8,5.8h8.8v-20.2H221.1L221.1-69.5z"/>
<path class="st3" d="M189.1-58l-11.5-11.5h-8.8v20.2h8.7v-12.6l11.6,11.6V-58z"/>
</g>
</g>
<g>
<path class="st2" d="M16.3,47.3H7.7v20.3h20.3v-8.7H16.3V47.3z"/>
<path class="st2" d="M59.9,47.4v11.5H48.3v8.7h20.3V47.3L59.9,47.4L59.9,47.4z"/>
<path class="st2" d="M7.7,27.1h8.8L16.3,27V15.5h11.6V6.8H7.7V27.1z"/>
<path class="st2" d="M48.3,6.8v8.7h11.6v11.6h8.7V6.8C68.6,6.8,48.3,6.8,48.3,6.8z"/>
<path class="st3" d="M47.2,27.1L35.5,15.5h12.7V6.8H27.9v8.7l11.6,11.6H47.2z"/>
<path class="st3" d="M36.7,47.3h-7.6l9.6,9.6l1.9,2H27.9v8.7h20.4v-8.8l-5.8-5.7L36.7,47.3z"/>
<path class="st3" d="M59.9,27.1v12.6l-2-2l-9.6-9.6v7.7l5.7,5.7l5.8,5.8h8.8V27.1H59.9L59.9,27.1z"/>
<path class="st3" d="M27.9,38.6L16.4,27.1H7.7v20.2h8.7V34.7l11.6,11.6V38.6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -6,7 +6,7 @@
<g id="Layer_2">
</g>
<g>
<path fill="#EEEEEE" d="M56.667,0.667C25.372,0.667,0,26.036,0,57.332c0,31.295,25.372,56.666,56.667,56.666
<path fill="#e64a22" d="M56.667,0.667C25.372,0.667,0,26.036,0,57.332c0,31.295,25.372,56.666,56.667,56.666
s56.666-25.371,56.666-56.666C113.333,26.036,87.961,0.667,56.667,0.667z M56.667,106.722c-8.904,0-16.123-5.948-16.123-13.283
H72.79C72.79,100.773,65.571,106.722,56.667,106.722z M83.297,89.04H30.034v-9.658h53.264V89.04z M83.106,74.411h-52.92
c-0.176-0.203-0.356-0.403-0.526-0.609c-5.452-6.62-6.736-10.076-7.983-13.598c-0.021-0.116,6.611,1.355,11.314,2.413

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -27,12 +27,12 @@
border: rem(1px) solid
light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
cursor: pointer;
transition: border-color 100ms ease, background-color 500ms ease;
transition: border-color 100ms ease, background-color 250ms ease;
}
.card:hover {
border-color: var(--mantine-primary-color-filled);
background-color: var(--mantine-primary-color-0);
background-color: var(--mantine-primary-color-light);
}
.cardTitle {

View File

@@ -17,44 +17,50 @@ import {
IconAffiliate,
} from "@tabler/icons-react";
import classes from "./FeaturesCards.module.css";
import { theme } from "@/theme";
import Link from "next/link";
const mockdata = [
const features = [
{
title: "Dimensional data model",
description:
"Prometheus models time series in a flexible dimensional data model. Time series are identified by a metric name and a set of key-value pairs.",
icon: IconChartGridDots,
link: "/docs/concepts/data_model/",
},
{
title: "Powerful queries",
description:
"The PromQL query language allows you to query, correlate, and transform your time series data in powerful ways for visualizations, alerts, and more.",
icon: IconDatabaseSearch,
link: "/docs/prometheus/latest/querying/basics/",
},
{
title: "Precise alerting",
description:
"Alerting rules are based on PromQL and make full use of the dimensional data model. A separate Alertmanager component handles notifications and silencing.",
icon: IconBell,
link: "/docs/alerting/latest/overview/",
},
{
title: "Simple operation",
description:
"Prometheus servers operate independently and only rely on local storage. Developed in Go, the statically linked binaries are easy to deploy across various environments.",
icon: IconRun,
link: "/docs/prometheus/latest/configuration/configuration/",
},
{
title: "Instrumentation libraries",
description:
"Prometheus provides a large number of official and community-contributed metrics instrumentation libraries that cover most major languages.",
icon: IconGauge,
link: "/docs/instrumenting/clientlibs/",
},
{
title: "Ubiquitous integrations",
description:
"Prometheus comes with hundreds of official and community-contributed integrations that allow you to easily extract metrics from existing systems.",
icon: IconAffiliate,
link: "/docs/instrumenting/exporters/",
},
// {
// title: "Efficient storage",
@@ -71,19 +77,20 @@ const mockdata = [
];
export function FeaturesCards() {
// const theme = useMantineTheme();
const features = mockdata.map((feature) => (
const featureCards = features.map((feature) => (
<Card
key={feature.title}
component={Link}
href={feature.link}
shadow="md"
radius="md"
className={classes.card}
padding="xl"
>
<feature.icon
style={{ width: rem(50), height: rem(50) }}
stroke={2}
color={theme.colors!.prometheusColor![6]}
style={{ width: rem(40), height: rem(40) }}
stroke={1.5}
color="var(--mantine-primary-color-filled)"
/>
<Text fz="lg" fw={500} className={classes.cardTitle} mt="md">
{feature.title}
@@ -96,8 +103,8 @@ export function FeaturesCards() {
return (
<Container size="lg" pb={90}>
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="xl" my={50}>
{features}
<SimpleGrid cols={{ base: 1, xs: 2, sm: 3 }} spacing="xl" my={50}>
{featureCards}
</SimpleGrid>
<Group justify="center" mt={120}>
<Badge variant="filled" size="lg">

View File

@@ -0,0 +1,38 @@
"use client";
import { Button, NumberFormatter, Pill, Stack } from "@mantine/core";
import { IconBrandGithub } from "@tabler/icons-react";
import { useEffect, useState } from "react";
export function GitHubStars() {
const [stars, setStars] = useState<number | null>(null);
useEffect(() => {
fetch("https://api.github.com/repos/prometheus/prometheus")
.then((res) => res.json())
.then((data) => setStars(data.stargazers_count));
}, []);
return (
<Stack align="center" gap="lg" my="lg">
<Button
component="a"
href="https://github.com/prometheus/prometheus"
target="_blank"
size="lg"
variant="light"
leftSection={<IconBrandGithub />}
w="fit-content"
>
Star us on GitHub
</Button>
<Pill fw="bold" size="md">
{stars ? (
<NumberFormatter value={stars} thousandSeparator suffix=" stars" />
) : (
"Loading stars..."
)}
</Pill>
</Stack>
);
}

View File

@@ -1,19 +1,20 @@
.header {
height: rem(72px);
margin-bottom: rem(60px);
/* background-color: var(--mantine-color-body); */
/* background-color: var(--mantine-color-gray-7); */
/* background-color: #3e4a56; */
/* background-color: #2d3b48; */
background-color: #28313a;
/* border-bottom: rem(1px) solid
light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); */
padding-left: var(--mantine-spacing-md);
padding-right: var(--mantine-spacing-md);
height: var(--header-height);
/* padding-left: var(--mantine-spacing-md);
padding-right: var(--mantine-spacing-md); */
position: sticky;
top: 0;
background-color: color-mix(
in srgb,
var(--mantine-color-body),
transparent 15%
);
backdrop-filter: blur(5px);
z-index: 1000;
}
.inner {
height: rem(72px);
height: var(--header-height);
display: flex;
justify-content: space-between;
align-items: center;
@@ -25,11 +26,14 @@
padding: rem(8px) rem(12px);
border-radius: var(--mantine-radius-sm);
text-decoration: none;
color: var(--mantine-color-gray-2);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-3));
font-size: var(--mantine-font-size-sm);
font-weight: 500;
@mixin hover {
background-color: var(--mantine-color-dark-6);
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-5)
);
}
}

View File

@@ -1,12 +1,27 @@
import { Group, Burger, rem, Text, Container, TextInput } from "@mantine/core";
import {
Group,
Burger,
rem,
Text,
Container,
TextInput,
ActionIcon,
} from "@mantine/core";
import Image from "next/image";
import { useDisclosure } from "@mantine/hooks";
import { IconSearch } from "@tabler/icons-react";
import {
IconDashboard,
IconFileText,
IconHome,
IconSearch,
} from "@tabler/icons-react";
import prometheusLogo from "../assets/prometheus-logo.svg";
import classes from "./Header.module.css";
import { FC } from "react";
import githubLogo from "../assets/github-logo.svg";
import Link from "next/link";
import { ThemeSelector } from "./ThemeSelector";
import { Spotlight, SpotlightActionData, spotlight } from "@mantine/spotlight";
const links = [
{ link: "/docs/introduction/overview", label: "Docs" },
@@ -16,6 +31,30 @@ const links = [
{ link: "/blog", label: "Blog" },
];
const actions: SpotlightActionData[] = [
{
id: "home",
label: "Home",
description: "Get to home page",
onClick: () => console.log("Home"),
leftSection: <IconHome size={24} stroke={1.5} />,
},
{
id: "dashboard",
label: "Dashboard",
description: "Get full information about current system status",
onClick: () => console.log("Dashboard"),
leftSection: <IconDashboard size={24} stroke={1.5} />,
},
{
id: "documentation",
label: "Documentation",
description: "Visit documentation to lean more about all features",
onClick: () => console.log("Documentation"),
leftSection: <IconFileText size={24} stroke={1.5} />,
},
];
export const Header: FC = () => {
const [opened, { toggle }] = useDisclosure(false);
@@ -27,71 +66,109 @@ export const Header: FC = () => {
return (
<header className={classes.header}>
<Container size="lg">
<Container size="xl">
<div className={classes.inner}>
<Link href="/" style={{ textDecoration: "none" }}>
<Group>
{/* Logo + Text */}
<Link href="/" style={{ textDecoration: "none", color: "inherit" }}>
<Group wrap="nowrap" align="center">
<Image src={prometheusLogo} height={32} alt="Prometheus logo" />
<Text fz={25} ff="Lato Light" c="white">
<Text
fz={25}
ff="Lato Light"
c="light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-0))"
>
Prometheus
</Text>
</Group>
</Link>
{/* Menu items + search */}
<Group align="center">
<Group ml={50} gap={5} className={classes.links} visibleFrom="sm">
<Group gap={5} visibleFrom="sm" align="center">
{items}
</Group>
<TextInput
className={classes.search}
placeholder="Search"
w={250}
mx="lg"
leftSection={
<IconSearch
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
rightSection={
<Text
size="xs"
mx={5}
p={6}
fw={700}
c="dark.1"
// bg="#394855"
bg="#56697a"
lh={1}
style={{ borderRadius: "0.25em" }}
>
Ctrl + K
</Text>
}
rightSectionWidth="fit-content"
visibleFrom="xs"
styles={{
input: {
background: "#394855",
borderColor: "transparent",
color: "white",
},
}}
/>
<a href="https://github.com/prometheus" target="_blank">
<Image
src={githubLogo}
style={{
height: 20,
width: 20,
filter: "invert(1)",
verticalAlign: "middle",
}}
alt="GitHub Logo"
<Group visibleFrom="md" gap="xs">
<TextInput
placeholder="Search"
w={220}
mx="lg"
leftSection={
<IconSearch
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
rightSection={
<Text
size="xs"
mx={5}
p={6}
fw={700}
bg="light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-7))"
lh={1}
style={{ borderRadius: "0.25em" }}
>
Ctrl + K
</Text>
}
onClick={spotlight.open}
rightSectionWidth="fit-content"
visibleFrom="lg"
/>
</a>
<ActionIcon
hiddenFrom="lg"
color="gray"
variant="subtle"
onClick={spotlight.open}
>
<IconSearch
{...{
style: {
width: rem(20),
height: rem(20),
display: "block",
},
stroke: 2,
}}
/>
</ActionIcon>
<ThemeSelector />
<ActionIcon
component="a"
href="https://github.com/prometheus"
target="_blank"
color="gray"
variant="subtle"
>
<Image
src={githubLogo}
style={{
height: 20,
width: 20,
opacity: 0.9,
verticalAlign: "middle",
}}
className="invertInDarkMode"
alt="GitHub Logo"
/>
</ActionIcon>
{/* <a href="https://github.com/prometheus" target="_blank">
<Image
src={githubLogo}
style={{
height: 20,
width: 20,
opacity: 0.9,
verticalAlign: "middle",
}}
className="invertInDarkMode"
alt="GitHub Logo"
/>
</a> */}
</Group>
<Burger
opened={opened}
onClick={toggle}
@@ -102,6 +179,15 @@ export const Header: FC = () => {
</Group>
</div>
</Container>
<Spotlight
actions={actions}
nothingFound="Nothing found..."
highlightQuery
searchProps={{
leftSection: <IconSearch size={20} stroke={1.5} />,
placeholder: "Search...",
}}
/>
</header>
);
};

View File

@@ -1,12 +1,7 @@
.wrapper {
position: relative;
padding-top: rem(80px);
margin-top: clamp(0px, 5vw, rem(80px));
padding-bottom: rem(60px);
@media (max-width: $mantine-breakpoint-sm) {
padding-top: rem(80px);
padding-bottom: rem(60px);
}
}
.inner {
@@ -30,14 +25,20 @@
.title {
text-align: center;
font-weight: 800;
font-size: rem(40px);
/* font-size: rem(40px); */
letter-spacing: -1px;
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
margin-bottom: var(--mantine-spacing-xs);
font-family: Greycliff CF, var(--mantine-font-family);
/* font-family: Greycliff CF, var(--mantine-font-family); */
font-size: clamp(rem(35px), 4vw, rem(50px));
/* Width of 35 chars explicitly chosen to fit "Open source metrics and monitoring for [...]" first line */
width: min(30ch, 90vw);
font-weight: 600;
margin: 0 auto;
margin-bottom: var(--mantine-spacing-xl);
@media (max-width: $mantine-breakpoint-xs) {
font-size: rem(28px);
text-align: left;
}
}
@@ -48,35 +49,23 @@
.description {
text-align: center;
font-size: clamp(
var(--mantine-font-size-lg),
2vw,
calc(var(--mantine-font-size-xl) * 1.1)
);
width: min(60ch, 85vw);
margin: 0 auto;
margin-bottom: var(--mantine-spacing-xl);
@media (max-width: $mantine-breakpoint-xs) {
text-align: left;
font-size: var(--mantine-font-size-md);
/* font-size: var(--mantine-font-size-md); */
}
}
.controls {
margin-top: var(--mantine-spacing-lg);
display: flex;
justify-content: center;
@media (max-width: $mantine-breakpoint-xs) {
flex-direction: column;
}
}
.control {
&:not(:first-of-type) {
margin-left: var(--mantine-spacing-md);
}
@media (max-width: $mantine-breakpoint-xs) {
height: rem(42px);
font-size: var(--mantine-font-size-md);
&:not(:first-of-type) {
margin-top: var(--mantine-spacing-md);
margin-left: 0;
}
}
.buttons {
/* transform: scale(clamp(1, calc(100vw / 1920), 1.2)); */
transform: scale(calc(100vw / 1920)); /* Assume 1920 is your base width */
transform-origin: top left;
}

View File

@@ -1,7 +1,8 @@
import { Title, Text, Button, Container } from "@mantine/core";
import { Title, Text, Button, Container, Group } from "@mantine/core";
import { Dots } from "./Dots";
import classes from "./Hero.module.css";
import { IconDownload } from "@tabler/icons-react";
import Link from "next/link";
export function Hero() {
return (
@@ -12,56 +13,39 @@ export function Hero() {
<Dots className={classes.dots} style={{ right: 0, top: 60 }} />
<div className={classes.inner}>
{/* <Container p={0} size={800}>
<Title className={classes.title}>
The leading{" "}
<Text component="span" className={classes.highlight} inherit>
metrics and monitoring
</Text>{" "}
solution
</Title>
</Container> */}
{/* <Container p={0} size={800}>
<Title className={classes.title}>
Open source{" "}
<Text component="span" className={classes.highlight} inherit>
metrics and monitoring
</Text>{" "}
for your systems and services
</Title>
</Container> */}
<Container p={0} size={800}>
<Title className={classes.title}>
Open source{" "}
<Text component="span" className={classes.highlight} inherit>
metrics and monitoring
</Text>{" "}
for your systems and services
</Title>
</Container>
<Title className={classes.title}>
Open source{" "}
<Text component="span" className={classes.highlight} inherit>
metrics and monitoring
</Text>{" "}
for your systems and services
</Title>
<Container p={0} size={600} my="xl">
<Text size="lg" c="dimmed" className={classes.description}>
Monitor your applications, systems, and services with the leading
open source monitoring solution. Instrument, collect, store, and
query your metrics for alerting, dashboarding, and other use cases.
</Text>
</Container>
<Text c="dimmed" className={classes.description}>
Monitor your applications, systems, and services with the leading open
source monitoring solution. Instrument, collect, store, and query your
metrics for alerting, dashboarding, and other use cases.
</Text>
<div className={classes.controls}>
<Button className={classes.control} size="lg">
<Group gap="md" justify="center" className={classes.buttons}>
<Button
component={Link}
href="/docs/prometheus/latest/getting_started/"
size="lg"
w={{ base: "100%", xs: "fit-content" }}
>
Get started
</Button>
<Button
className={classes.control}
size="lg"
variant="default"
color="gray"
size="lg"
w={{ base: "100%", xs: "fit-content" }}
leftSection={<IconDownload />}
>
Download
</Button>
</div>
</Group>
</div>
</Container>
);

28
src/components/TOC.tsx Normal file
View File

@@ -0,0 +1,28 @@
import { TableOfContents, TableOfContentsProps } from "@mantine/core";
export default function TOC(props: TableOfContentsProps) {
return (
<TableOfContents
pr="xs"
size="sm"
c="dimmed"
minDepthToOffset={2}
depthOffset={30}
variant="light"
getControlProps={({ active, data }) => ({
component: "a",
href: `#${data.id}`,
children: data.value,
style: {
borderLeftStyle: "solid",
borderLeftWidth: active ? 2 : 1,
borderLeftColor: active
? "var(--mantine-color-primary-filled)"
: "light-dark(var(--mantine-color-gray-3), var(--mantine-color-gray-7))",
},
})}
radius={0}
{...props}
/>
);
}

View File

@@ -0,0 +1,50 @@
import { useMantineColorScheme, rem, ActionIcon } from "@mantine/core";
import { IconBrightnessFilled, IconSun, IconMoon } from "@tabler/icons-react";
import { FC } from "react";
export const ThemeSelector: FC = () => {
const { colorScheme, setColorScheme } = useMantineColorScheme();
const iconProps = {
style: { width: rem(20), height: rem(20), display: "block" },
stroke: 1.5,
};
return (
<ActionIcon
suppressHydrationWarning
color="gray"
variant="subtle"
title={`Switch to ${
colorScheme === "light"
? "dark"
: colorScheme === "dark"
? "browser-preferred"
: "light"
} theme`}
aria-label={`Switch to ${
colorScheme === "light"
? "dark"
: colorScheme === "dark"
? "browser-preferred"
: "light"
} theme`}
size={32}
onClick={() =>
setColorScheme(
colorScheme === "light"
? "dark"
: colorScheme === "dark"
? "auto"
: "light"
)
}
>
{colorScheme === "light" ? (
<IconSun suppressHydrationWarning {...iconProps} />
) : colorScheme === "dark" ? (
<IconMoon suppressHydrationWarning {...iconProps} />
) : (
<IconBrightnessFilled suppressHydrationWarning {...iconProps} />
)}
</ActionIcon>
);
};

View File

@@ -2,6 +2,7 @@ export type DocsConfig = {
localMarkdownSources: LocalMarkdownSource[];
githubMarkdownSources: GithubMarkdownSource[];
ltsVersions: LTSConfig;
downloads: DownloadConfig;
};
export type GithubMarkdownSource = {
@@ -20,3 +21,8 @@ export type LocalMarkdownSource = {
export type LTSConfig = {
[repo: string]: string[];
};
export type DownloadConfig = {
owner: string;
repos: string[];
};

View File

@@ -0,0 +1,33 @@
export type Downloads = {
repos: Repo[];
operatingSystems: string[];
architectures: string[];
releases: Release[];
};
export type Repo = {
name: string;
fullName: string;
description: string;
url: string;
releases: Release[];
};
export type Release = {
id: number;
name: string;
url: string;
prerelease: boolean;
ltsRelease: boolean;
majorMinor: string;
binaries: Binary[];
};
export type Binary = {
name: string;
checksum: string;
os: string;
arch: string;
url: string;
sizeBytes: number;
};

View File

@@ -0,0 +1,4 @@
import downloadsMetadataJson from "../generated/downloads-metadata.json";
import { Downloads } from "./downloads-metadata-types";
export const downloadsMetadata = downloadsMetadataJson as Downloads;

View File

@@ -73,7 +73,6 @@ export default function rehypeConfigLinker() {
);
changed = true;
}
console.log(`Matched for ${anchor} with ${html}, changed ${changed}`);
});
if (changed) {

View File

@@ -17,6 +17,7 @@ export const theme = createTheme({
colors: {
prometheusColor,
},
black: "var(--mantine-color-gray-8)",
primaryColor: "prometheusColor",
headings: {
fontFamily: "var(--font-inter)",