feat: read all packages on about page (#391)
This commit is contained in:
@@ -47,6 +47,7 @@
|
|||||||
"chroma-js": "^2.4.2",
|
"chroma-js": "^2.4.2",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"glob": "^10.3.12",
|
||||||
"jotai": "^2.8.0",
|
"jotai": "^2.8.0",
|
||||||
"next": "^14.2.3",
|
"next": "^14.2.3",
|
||||||
"postcss-preset-mantine": "^1.15.0",
|
"postcss-preset-mantine": "^1.15.0",
|
||||||
@@ -60,10 +61,10 @@
|
|||||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||||
|
"@types/chroma-js": "2.4.4",
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@types/react": "^18.3.1",
|
"@types/react": "^18.3.1",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/chroma-js": "2.4.4",
|
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconLanguage, IconLibrary, IconUsers } from "@tabler/icons-react";
|
import { IconLanguage, IconLibrary, IconUsers } from "@tabler/icons-react";
|
||||||
|
import { setStaticParamsLocale } from "next-international/server";
|
||||||
|
|
||||||
import { getScopedI18n } from "@homarr/translation/server";
|
import { getScopedI18n, getStaticParams } from "@homarr/translation/server";
|
||||||
|
|
||||||
import { getPackageAttributes } from "~/versions/package-reader";
|
import { getPackageAttributesAsync } from "~/versions/package-reader";
|
||||||
import logo from "../../../../../public/logo/logo.png";
|
import logo from "../../../../../public/logo/logo.png";
|
||||||
import classes from "./accordion.module.css";
|
import classes from "./accordion.module.css";
|
||||||
|
|
||||||
@@ -29,9 +30,16 @@ export async function generateMetadata() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function AboutPage() {
|
interface PageProps {
|
||||||
|
params: {
|
||||||
|
locale: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function AboutPage({ params: { locale } }: PageProps) {
|
||||||
|
setStaticParamsLocale(locale);
|
||||||
const t = await getScopedI18n("management.page.about");
|
const t = await getScopedI18n("management.page.about");
|
||||||
const attributes = getPackageAttributes();
|
const attributes = await getPackageAttributesAsync();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Center w="100%">
|
<Center w="100%">
|
||||||
@@ -75,15 +83,17 @@ export default async function AboutPage() {
|
|||||||
</AccordionControl>
|
</AccordionControl>
|
||||||
<AccordionPanel>
|
<AccordionPanel>
|
||||||
<List>
|
<List>
|
||||||
{Object.entries(attributes.dependencies).map(([key, value]) => (
|
{Object.entries(attributes.dependencies)
|
||||||
<ListItem key={key}>
|
.sort(([key1], [key2]) => key1.localeCompare(key2))
|
||||||
{value.includes("workspace:") ? (
|
.map(([key, value]) => (
|
||||||
<Text>{key}</Text>
|
<ListItem key={key}>
|
||||||
) : (
|
{value.includes("workspace:") ? (
|
||||||
<a href={`https://www.npmjs.com/package/${key}`}>{key}</a>
|
<Text>{key}</Text>
|
||||||
)}
|
) : (
|
||||||
</ListItem>
|
<a href={`https://www.npmjs.com/package/${key}`}>{key}</a>
|
||||||
))}
|
)}
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
</List>
|
</List>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
@@ -91,3 +101,9 @@ export default async function AboutPage() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function generateStaticParams() {
|
||||||
|
return getStaticParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dynamic = "force-static";
|
||||||
|
|||||||
@@ -1,13 +1,40 @@
|
|||||||
|
import fsPromises from "fs/promises";
|
||||||
|
import { glob } from "glob";
|
||||||
|
|
||||||
import packageJson from "~/../package.json";
|
import packageJson from "~/../package.json";
|
||||||
|
|
||||||
const getPackageVersion = () => packageJson.version;
|
const getPackageVersion = () => packageJson.version;
|
||||||
const getDependencies = (): PackageJsonDependencies => packageJson.dependencies;
|
const getDependenciesAsync = async (): Promise<PackageJsonDependencies> => {
|
||||||
|
const pathNames = await glob("**/package.json", {
|
||||||
|
ignore: "node_modules/**",
|
||||||
|
cwd: "../../",
|
||||||
|
absolute: true,
|
||||||
|
});
|
||||||
|
const packageContents = await Promise.all(
|
||||||
|
pathNames.map(async (path) => await fsPromises.readFile(path, "utf-8")),
|
||||||
|
);
|
||||||
|
const packageDependencies = packageContents
|
||||||
|
.map(
|
||||||
|
(packageContent) =>
|
||||||
|
(JSON.parse(packageContent) as PackageJson).dependencies,
|
||||||
|
)
|
||||||
|
.filter((dependencies) => dependencies !== undefined);
|
||||||
|
|
||||||
export const getPackageAttributes = () => {
|
let dependencies = {};
|
||||||
|
for (const dependenciesOfPackage of packageDependencies) {
|
||||||
|
dependencies = { ...dependencies, ...dependenciesOfPackage };
|
||||||
|
}
|
||||||
|
return dependencies;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPackageAttributesAsync = async () => {
|
||||||
return {
|
return {
|
||||||
version: getPackageVersion(),
|
version: getPackageVersion(),
|
||||||
dependencies: getDependencies(),
|
dependencies: await getDependenciesAsync(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type PackageJsonDependencies = { [key in string]: string };
|
type PackageJsonDependencies = { [key in string]: string };
|
||||||
|
interface PackageJson {
|
||||||
|
dependencies: PackageJsonDependencies | undefined;
|
||||||
|
}
|
||||||
|
|||||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@@ -159,6 +159,9 @@ importers:
|
|||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.4.5
|
specifier: ^16.4.5
|
||||||
version: 16.4.5
|
version: 16.4.5
|
||||||
|
glob:
|
||||||
|
specifier: ^10.3.12
|
||||||
|
version: 10.3.12
|
||||||
jotai:
|
jotai:
|
||||||
specifier: ^2.8.0
|
specifier: ^2.8.0
|
||||||
version: 2.8.0(@types/react@18.3.1)(react@18.3.1)
|
version: 2.8.0(@types/react@18.3.1)(react@18.3.1)
|
||||||
@@ -3521,6 +3524,11 @@ packages:
|
|||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
glob@10.3.12:
|
||||||
|
resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==}
|
||||||
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
glob@7.2.3:
|
glob@7.2.3:
|
||||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||||
|
|
||||||
@@ -4499,6 +4507,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
|
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
|
||||||
|
path-scurry@1.10.2:
|
||||||
|
resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
|
||||||
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
|
||||||
path-type@4.0.0:
|
path-type@4.0.0:
|
||||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -8432,6 +8444,14 @@ snapshots:
|
|||||||
minipass: 7.0.4
|
minipass: 7.0.4
|
||||||
path-scurry: 1.10.1
|
path-scurry: 1.10.1
|
||||||
|
|
||||||
|
glob@10.3.12:
|
||||||
|
dependencies:
|
||||||
|
foreground-child: 3.1.1
|
||||||
|
jackspeak: 2.3.6
|
||||||
|
minimatch: 9.0.4
|
||||||
|
minipass: 7.0.4
|
||||||
|
path-scurry: 1.10.2
|
||||||
|
|
||||||
glob@7.2.3:
|
glob@7.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
fs.realpath: 1.0.0
|
fs.realpath: 1.0.0
|
||||||
@@ -9491,6 +9511,11 @@ snapshots:
|
|||||||
lru-cache: 10.2.0
|
lru-cache: 10.2.0
|
||||||
minipass: 7.0.4
|
minipass: 7.0.4
|
||||||
|
|
||||||
|
path-scurry@1.10.2:
|
||||||
|
dependencies:
|
||||||
|
lru-cache: 10.2.0
|
||||||
|
minipass: 7.0.4
|
||||||
|
|
||||||
path-type@4.0.0: {}
|
path-type@4.0.0: {}
|
||||||
|
|
||||||
pathe@1.1.2: {}
|
pathe@1.1.2: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user