diff --git a/docs/app/global.css b/docs/app/global.css index 48e47bc..f415641 100644 --- a/docs/app/global.css +++ b/docs/app/global.css @@ -1,4 +1,5 @@ -@import 'tailwindcss'; -@import 'fumadocs-ui/css/neutral.css'; -@import 'fumadocs-ui/css/ocean.css'; -@import 'fumadocs-ui/css/preset.css'; +@import "tailwindcss"; +@import "fumadocs-ui/css/neutral.css"; +@import "fumadocs-ui/css/ocean.css"; +@import "fumadocs-ui/css/preset.css"; +@import "tw-animate-css"; diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx index 5b62bf5..9d8e16f 100644 --- a/docs/app/layout.tsx +++ b/docs/app/layout.tsx @@ -2,6 +2,7 @@ import "@/app/global.css"; import { RootProvider } from "fumadocs-ui/provider"; import localFont from "next/font/local"; import Script from "next/script"; +import { Toaster } from "@/components/ui/sonner"; const inter = localFont({ src: "../lib/inter.ttf" }); @@ -18,6 +19,7 @@ export default function Layout({ children }: LayoutProps<"/">) { data-web-vitals="true" strategy="afterInteractive" /> + ); diff --git a/docs/bun.lock b/docs/bun.lock index 9eb200d..3c1d10d 100644 --- a/docs/bun.lock +++ b/docs/bun.lock @@ -8,17 +8,20 @@ "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "fumadocs-core": "15.8.1", "fumadocs-mdx": "12.0.1", "fumadocs-ui": "15.8.1", - "lucide-react": "^0.544.0", + "lucide-react": "^0.545.0", "next": "15.5.4", + "next-themes": "^0.4.6", "react": "^19.1.1", "react-dom": "^19.1.1", + "sonner": "^2.0.7", "tailwind-merge": "^3.3.1", }, "devDependencies": { - "@biomejs/biome": "2.2.5", + "@biomejs/biome": "2.2.6", "@tailwindcss/postcss": "^4.1.13", "@types/mdx": "^2.0.13", "@types/node": "24.5.2", @@ -26,6 +29,7 @@ "@types/react-dom": "^19.1.9", "postcss": "^8.5.6", "tailwindcss": "^4.1.13", + "tw-animate-css": "^1.4.0", "typescript": "^5.9.2", }, }, @@ -33,23 +37,23 @@ "packages": { "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@biomejs/biome": ["@biomejs/biome@2.2.5", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.2.5", "@biomejs/cli-darwin-x64": "2.2.5", "@biomejs/cli-linux-arm64": "2.2.5", "@biomejs/cli-linux-arm64-musl": "2.2.5", "@biomejs/cli-linux-x64": "2.2.5", "@biomejs/cli-linux-x64-musl": "2.2.5", "@biomejs/cli-win32-arm64": "2.2.5", "@biomejs/cli-win32-x64": "2.2.5" }, "bin": { "biome": "bin/biome" } }, "sha512-zcIi+163Rc3HtyHbEO7CjeHq8DjQRs40HsGbW6vx2WI0tg8mYQOPouhvHSyEnCBAorfYNnKdR64/IxO7xQ5faw=="], + "@biomejs/biome": ["@biomejs/biome@2.2.6", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.2.6", "@biomejs/cli-darwin-x64": "2.2.6", "@biomejs/cli-linux-arm64": "2.2.6", "@biomejs/cli-linux-arm64-musl": "2.2.6", "@biomejs/cli-linux-x64": "2.2.6", "@biomejs/cli-linux-x64-musl": "2.2.6", "@biomejs/cli-win32-arm64": "2.2.6", "@biomejs/cli-win32-x64": "2.2.6" }, "bin": { "biome": "bin/biome" } }, "sha512-yKTCNGhek0rL5OEW1jbLeZX8LHaM8yk7+3JRGv08my+gkpmtb5dDE+54r2ZjZx0ediFEn1pYBOJSmOdDP9xtFw=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.2.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MYT+nZ38wEIWVcL5xLyOhYQQ7nlWD0b/4mgATW2c8dvq7R4OQjt/XGXFkXrmtWmQofaIM14L7V8qIz/M+bx5QQ=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.2.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UZPmn3M45CjTYulgcrFJFZv7YmK3pTxTJDrFYlNElT2FNnkkX4fsxjExTSMeWKQYoZjvekpH5cvrYZZlWu3yfA=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.2.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-FLIEl73fv0R7dI10EnEiZLw+IMz3mWLnF95ASDI0kbx6DDLJjWxE5JxxBfmG+udz1hIDd3fr5wsuP7nwuTRdAg=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.2.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-HOUIquhHVgh/jvxyClpwlpl/oeMqntlteL89YqjuFDiZ091P0vhHccwz+8muu3nTyHWM5FQslt+4Jdcd67+xWQ=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.2.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-5DjiiDfHqGgR2MS9D+AZ8kOfrzTGqLKywn8hoXpXXlJXIECGQ32t+gt/uiS2XyGBM2XQhR6ztUvbjZWeccFMoQ=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.2.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-BpGtuMJGN+o8pQjvYsUKZ+4JEErxdSmcRD/JG3mXoWc6zrcA7OkuyGFN1mDggO0Q1n7qXxo/PcupHk8gzijt5g=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.2.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Ov2wgAFwqDvQiESnu7b9ufD1faRa+40uwrohgBopeY84El2TnBDoMNXx6iuQdreoFGjwW8vH6k68G21EpNERw=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.2.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-TjCenQq3N6g1C+5UT3jE1bIiJb5MWQvulpUngTIpFsL4StVAUXucWD0SL9MCW89Tm6awWfeXBbZBAhJwjyFbRQ=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.2.5", "", { "os": "linux", "cpu": "x64" }, "sha512-fq9meKm1AEXeAWan3uCg6XSP5ObA6F/Ovm89TwaMiy1DNIwdgxPkNwxlXJX8iM6oRbFysYeGnT0OG8diCWb9ew=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.2.6", "", { "os": "linux", "cpu": "x64" }, "sha512-1HaM/dpI/1Z68zp8ZdT6EiBq+/O/z97a2AiHMl+VAdv5/ELckFt9EvRb8hDHpk8hUMoz03gXkC7VPXOVtU7faA=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.2.5", "", { "os": "linux", "cpu": "x64" }, "sha512-AVqLCDb/6K7aPNIcxHaTQj01sl1m989CJIQFQEaiQkGr2EQwyOpaATJ473h+nXDUuAcREhccfRpe/tu+0wu0eQ=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.2.6", "", { "os": "linux", "cpu": "x64" }, "sha512-1ZcBux8zVM3JhWN2ZCPaYf0+ogxXG316uaoXJdgoPZcdK/rmRcRY7PqHdAos2ExzvjIdvhQp72UcveI98hgOog=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.2.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-xaOIad4wBambwJa6mdp1FigYSIF9i7PCqRbvBqtIi9y29QtPVQ13sDGtUnsRoe6SjL10auMzQ6YAe+B3RpZXVg=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.2.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-h3A88G8PGM1ryTeZyLlSdfC/gz3e95EJw9BZmA6Po412DRqwqPBa2Y9U+4ZSGUAXCsnSQE00jLV8Pyrh0d+jQw=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.2.5", "", { "os": "win32", "cpu": "x64" }, "sha512-F/jhuXCssPFAuciMhHKk00xnCAxJRS/pUzVfXYmOMUp//XW7mO6QeCjsjvnm8L4AO/dG2VOB0O+fJPiJ2uXtIw=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.2.6", "", { "os": "win32", "cpu": "x64" }, "sha512-yx0CqeOhPjYQ5ZXgPfu8QYkgBhVJyvWe36as7jRuPrKPO5ylVDfwVtPQ+K/mooNTADW0IhxOZm3aPu16dP8yNQ=="], "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], @@ -495,7 +499,7 @@ "lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="], - "lucide-react": ["lucide-react@0.544.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw=="], + "lucide-react": ["lucide-react@0.545.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw=="], "magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], @@ -689,6 +693,8 @@ "shiki": ["shiki@3.13.0", "", { "dependencies": { "@shikijs/core": "3.13.0", "@shikijs/engine-javascript": "3.13.0", "@shikijs/engine-oniguruma": "3.13.0", "@shikijs/langs": "3.13.0", "@shikijs/themes": "3.13.0", "@shikijs/types": "3.13.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g=="], + "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], + "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -721,6 +727,8 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], + "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], "undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="], diff --git a/docs/components.json b/docs/components.json new file mode 100644 index 0000000..f8e41b5 --- /dev/null +++ b/docs/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "app/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/docs/components/builder-sections/ckan-extensions.tsx b/docs/components/builder-sections/ckan-extensions.tsx new file mode 100644 index 0000000..0847d3c --- /dev/null +++ b/docs/components/builder-sections/ckan-extensions.tsx @@ -0,0 +1,107 @@ +import defaultMdxComponents from "fumadocs-ui/mdx"; +import { SailboatIcon, TerminalSquareIcon } from "lucide-react"; +import { Config, selectedCardClasses } from "../builder"; +import { toast } from "sonner"; + +const getExtensionClassName = (config: Config, extensionName: string) => { + return config.extensions.includes(extensionName) ? selectedCardClasses : ""; +}; + +const updateExtensions = ( + config: Config, + setConfig: any, + extensions: string[] | string, + mode?: "add" | "remove", +) => { + const extensionsArray = Array.isArray(extensions) ? extensions : [extensions]; + if (mode === "add") { + setConfig({ + ...config, + extensions: [...new Set([...config.extensions, ...extensionsArray])], + }); + return; + } + for (const extensionName of extensionsArray) { + if (config.extensions.includes(extensionName)) + setConfig({ + ...config, + extensions: config.extensions.filter( + (extension) => extension !== extensionName, + ), + }); + else if (!config.extensions.includes(extensionName)) + setConfig({ + ...config, + extensions: [...config.extensions, extensionName], + }); + } +}; + +export default function CKANExtensionsBuilderSection({ + config, + setConfig, +}: { + config: Config; + setConfig: any; +}) { + const { Card, Cards } = defaultMdxComponents; + + return ( + <> +

CKAN extensions

+ + } + title="ckanext-scheming" + onClick={() => { + if ( + config.extensions.includes("DataPusher+") && + config.extensions.includes("ckanext-scheming") + ) { + toast.error( + "You cannot remove the ckanext-scheming extension because the DataPusher+ extension depends on it.", + ); + return; + } + updateExtensions(config, setConfig, "ckanext-scheming"); + }} + > + } + title="DataStore" + onClick={() => { + if ( + config.extensions.includes("DataPusher+") && + config.extensions.includes("DataStore") + ) { + toast.error( + "You cannot remove the DataStore extension because the DataPusher+ extension depends on it.", + ); + return; + } + updateExtensions(config, setConfig, "DataStore"); + }} + > + } + title="DataPusher+" + onClick={() => { + if (config.extensions.includes("DataPusher+")) { + updateExtensions(config, setConfig, "DataPusher+"); + } else { + updateExtensions( + config, + setConfig, + ["DataPusher+", "ckanext-scheming", "DataStore"], + "add", + ); + } + }} + > + + + ); +} diff --git a/docs/components/builder-sections/ckan-version.tsx b/docs/components/builder-sections/ckan-version.tsx new file mode 100644 index 0000000..2348d8b --- /dev/null +++ b/docs/components/builder-sections/ckan-version.tsx @@ -0,0 +1,39 @@ +import defaultMdxComponents from "fumadocs-ui/mdx"; +import { SailboatIcon } from "lucide-react"; +import { selectedCardClasses } from "../builder"; + +export default function CKANVersionBuilderSection({ config, setConfig }: any) { + const { Card, Cards } = defaultMdxComponents; + + return ( + <> +

CKAN version

+ + } + title="2.11.3" + className={ + config.ckanVersion === "2.11.3" + ? selectedCardClasses + : "cursor-pointer" + } + onClick={() => { + setConfig({ ...config, ckanVersion: "2.11.3" }); + }} + > + } + title="2.10.8" + className={ + config.ckanVersion === "2.10.8" + ? selectedCardClasses + : "cursor-pointer" + } + onClick={() => { + setConfig({ ...config, ckanVersion: "2.10.8" }); + }} + > + + + ); +} diff --git a/docs/components/builder-sections/features.tsx b/docs/components/builder-sections/features.tsx new file mode 100644 index 0000000..456c4c0 --- /dev/null +++ b/docs/components/builder-sections/features.tsx @@ -0,0 +1,48 @@ +import defaultMdxComponents from "fumadocs-ui/mdx"; +import { SailboatIcon, TerminalSquareIcon } from "lucide-react"; +import { Config, selectedCardClasses } from "../builder"; + +const getFeatureClassName = (config: Config, featureName: string) => { + return config.features.includes(featureName) ? selectedCardClasses : ""; +}; + +const updateFeatures = ( + config: Config, + setConfig: any, + featureName: string, +) => { + if (config.features.includes(featureName)) + setConfig({ + ...config, + features: config.features.filter((feature) => feature !== featureName), + }); + else setConfig({ ...config, features: [...config.features, featureName] }); +}; + +export default function FeaturesBuilderSection({ + config, + setConfig, +}: { + config: Config; + setConfig: any; +}) { + const { Card, Cards } = defaultMdxComponents; + + return ( + <> +

Features

+ + } + title="Enable SSH" + onClick={() => { + updateFeatures(config, setConfig, "enable-ssh"); + }} + > + Installs the openssh-server package. + + + + ); +} diff --git a/docs/components/builder-sections/presets.tsx b/docs/components/builder-sections/presets.tsx new file mode 100644 index 0000000..444652b --- /dev/null +++ b/docs/components/builder-sections/presets.tsx @@ -0,0 +1,63 @@ +import { Config, selectedCardClasses } from "../builder"; +import { BarChartBigIcon, SailboatIcon } from "lucide-react"; +import defaultMdxComponents from "fumadocs-ui/mdx"; + +export default function PresetsBuilderSection({ + config, + setConfig, +}: { + config: Config; + setConfig: any; +}) { + const { Card, Cards } = defaultMdxComponents; + + return ( + <> +

Presets

+ + } + title="CKAN-only" + onClick={() => { + setConfig({ + ...config, + preset: "ckan-only", + extensions: [], + features: [], + }); + }} + > + Installs CKAN with ckan-compose. No CKAN extensions and extra features + are installed. + + } + title="datHere Default" + onClick={() => { + setConfig({ + ...config, + preset: "dathere-default", + ckanVersion: "2.11.3", + extensions: ["ckanext-scheming", "DataStore", "DataPusher+"], + features: ["enable-ssh"], + }); + }} + > + datHere's default preset featuring the DataPusher+ extension. + + + + ); +} diff --git a/docs/components/builder.tsx b/docs/components/builder.tsx index 32cca5d..94962f4 100644 --- a/docs/components/builder.tsx +++ b/docs/components/builder.tsx @@ -8,23 +8,60 @@ import { SailboatIcon, TerminalSquareIcon, } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import PresetsBuilderSection from "./builder-sections/presets"; +import CKANVersionBuilderSection from "./builder-sections/ckan-version"; +import CKANExtensionsBuilderSection from "./builder-sections/ckan-extensions"; +import FeaturesBuilderSection from "./builder-sections/features"; -type Config = { +export type Config = { preset: string | undefined; ckanVersion: string; extensions: string[]; + features: string[]; }; +export const selectedCardClasses = + "bg-blue-100 dark:bg-blue-950 border-blue-300 dark:border-blue-900 border-2"; + export default function Builder() { const { Card, Cards } = defaultMdxComponents; const [command, setCommand] = useState("./ckan-devstaller"); const [config, setConfig] = useState({ - preset: undefined, + preset: "ckan-only", ckanVersion: "2.11.3", extensions: [], + features: [], }); + // Update command string when user changes configuration + useEffect(() => { + let presetString = ""; + if (config.extensions.length === 0 && config.features.length === 0) + presetString = ` \\\n--preset ckan-only`; + else if ( + config.ckanVersion === "2.11.3" && + config.extensions.includes("DataPusher+") && + config.extensions.includes("ckanext-scheming") && + config.extensions.includes("DataStore") && + config.features.includes("enable-ssh") + ) + presetString = ` \\\n--preset dathere-default`; + const ckanVersionString = `--ckan-version ${config.ckanVersion}`; + const extensionsString = + config.extensions.length > 0 + ? ` \\\n--extensions ${config.extensions.join(" ")}` + : undefined; + const featuresString = + config.features.length > 0 + ? ` \\\n--features ${config.features.join(" ")}` + : undefined; + setCommand( + `./ckan-devstaller${presetString} \\ +${ckanVersionString}${extensionsString ? extensionsString : ""}${featuresString ? featuresString : ""}`, + ); + }, [config]); + return (
@@ -35,72 +72,38 @@ export default function Builder() {

Selected configuration

- CKAN version: 2.11.3 + CKAN version: {config.ckanVersion}

- Extensions: -
    -
  • DataStore
  • -
  • ckanext-scheming
  • -
  • DataPusher+
  • -
- Extra features: -
    -
  • Enable SSH
  • -
+ {config.extensions.length > 0 && ( + <> + Extensions: +
    + {config.extensions.map((extension) => ( +
  • {extension}
  • + ))} +
+ + )} + {config.features.length > 0 && ( + <> + Features: +
    + {config.features.map((feature) => ( +
  • {feature}
  • + ))} +
+ + )}

Configuration options

-

Presets

- - } - title="CKAN-only" - > - Installs CKAN with ckan-compose. - - } title="CKAN and the DataStore extension"> - Installs CKAN and the DataStore extension. - - } title="datHere Default"> - Installs CKAN, the DataStore extension, the ckanext-scheming - extension, and the DataPusher+ extension. - - -

CKAN version

- - } title="2.11.3"> - } title="2.10.8"> - } - title="Install a different version" - > - } - title="Clone from remote Git repository" - > - -

CKAN extensions

- - } title="ckanext-scheming"> - } title="ckanext-gztr"> - } title="DataStore"> - } title="DataPusher+"> - } title="ckanext-spatial"> - } title="Custom extension"> - -

Extra features

- - } title="Enable SSH"> - Installs openssh-server and net-tools. - - } title="Run a Bash script"> - Run a Bash script before or after any step during the installation. - - + + + +
); diff --git a/docs/components/ui/sonner.tsx b/docs/components/ui/sonner.tsx new file mode 100644 index 0000000..331836d --- /dev/null +++ b/docs/components/ui/sonner.tsx @@ -0,0 +1,40 @@ +"use client"; + +import { + CircleCheckIcon, + InfoIcon, + Loader2Icon, + OctagonXIcon, + TriangleAlertIcon, +} from "lucide-react"; +import { useTheme } from "next-themes"; +import { Toaster as Sonner, ToasterProps } from "sonner"; + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme(); + + return ( + , + info: , + warning: , + error: , + loading: , + }} + style={ + { + "--normal-bg": "var(--popover)", + "--normal-text": "var(--popover-foreground)", + "--normal-border": "var(--border)", + "--border-radius": "var(--radius)", + } as React.CSSProperties + } + {...props} + /> + ); +}; + +export { Toaster }; diff --git a/docs/lib/utils.ts b/docs/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/docs/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/docs/package.json b/docs/package.json index 812b351..a13a8ad 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,17 +15,20 @@ "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "fumadocs-core": "15.8.1", "fumadocs-mdx": "12.0.1", "fumadocs-ui": "15.8.1", - "lucide-react": "^0.544.0", + "lucide-react": "^0.545.0", "next": "15.5.4", + "next-themes": "^0.4.6", "react": "^19.1.1", "react-dom": "^19.1.1", + "sonner": "^2.0.7", "tailwind-merge": "^3.3.1" }, "devDependencies": { - "@biomejs/biome": "2.2.5", + "@biomejs/biome": "2.2.6", "@tailwindcss/postcss": "^4.1.13", "@types/mdx": "^2.0.13", "@types/node": "24.5.2", @@ -33,6 +36,7 @@ "@types/react-dom": "^19.1.9", "postcss": "^8.5.6", "tailwindcss": "^4.1.13", + "tw-animate-css": "^1.4.0", "typescript": "^5.9.2" } } \ No newline at end of file