Feature: Trilium Service widget (#5380)

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
Jon Fuller 2025-06-04 20:29:43 -07:00 committed by GitHub
parent fc99a0d1db
commit 0e96778740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,17 @@
---
title: Trilium
description: Trilium Widget Configuration
---
Learn more about [Trilium](https://github.com/TriliumNext/Notes).
This widget is compatible with [TriliumNext](https://github.com/TriliumNext/Notes) versions >= [v0.94.0](https://github.com/TriliumNext/Notes/releases/tag/v0.94.0).
Find (or create) your ETAPI key under `Options > ETAPI > Create new ETAPI token`.
```yaml
widget:
type: trilium
url: https://trilium.host.or.ip
key: etapi_token
```

View File

@ -359,6 +359,12 @@
"services": "Services",
"middleware": "Middleware"
},
"trilium": {
"version": "Version",
"notesCount": "Notes",
"dbSize": "Database Size",
"unknown": "Unknown"
},
"navidrome": {
"nothing_streaming": "No Active Streams",
"please_wait": "Please Wait"

View File

@ -106,6 +106,8 @@ export default async function credentialedProxyHandler(req, res, map) {
} else {
headers.Authorization = widget.password;
}
} else if (widget.type === "trilium") {
headers.Authorization = widget.key;
} else if (widget.type === "gitlab") {
headers["PRIVATE-TOKEN"] = widget.key;
} else if (widget.type === "speedtest") {

View File

@ -132,6 +132,7 @@ const components = {
tdarr: dynamic(() => import("./tdarr/component")),
traefik: dynamic(() => import("./traefik/component")),
transmission: dynamic(() => import("./transmission/component")),
trilium: dynamic(() => import("./trilium/component")),
tubearchivist: dynamic(() => import("./tubearchivist/component")),
truenas: dynamic(() => import("./truenas/component")),
unifi: dynamic(() => import("./unifi/component")),

View File

@ -0,0 +1,38 @@
import Block from "components/services/widget/block";
import Container from "components/services/widget/container";
import { useTranslation } from "next-i18next";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { data: metricsData, error: metricsError } = useWidgetAPI(widget, "metrics");
if (metricsError) {
return <Container service={service} error={metricsError} />;
}
if (!metricsData) {
return (
<Container service={service}>
<Block label="trilium.version" />
<Block label="trilium.notesCount" />
<Block label="trilium.dbSize" />
</Container>
);
}
const version = metricsData.version?.app;
const notesCount = metricsData.database?.activeNotes || 0;
const databaseSizeBytes = metricsData.statistics?.databaseSizeBytes || 0;
return (
<Container service={service}>
<Block label="trilium.version" value={version ? `v${version}` : t("trilium.unknown")} />
<Block label="trilium.notesCount" value={t("common.number", { value: notesCount })} />
<Block label="trilium.dbSize" value={t("common.bytes", { value: databaseSizeBytes })} />
</Container>
);
}

View File

@ -0,0 +1,15 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = {
api: "{url}/etapi/{endpoint}",
proxyHandler: credentialedProxyHandler,
mappings: {
metrics: {
endpoint: "metrics?format=json",
validate: ["version", "database"],
},
},
};
export default widget;

View File

@ -123,6 +123,7 @@ import tdarr from "./tdarr/widget";
import technitium from "./technitium/widget";
import traefik from "./traefik/widget";
import transmission from "./transmission/widget";
import trilium from "./trilium/widget";
import truenas from "./truenas/widget";
import tubearchivist from "./tubearchivist/widget";
import unifi from "./unifi/widget";
@ -266,6 +267,7 @@ const widgets = {
tdarr,
traefik,
transmission,
trilium,
tubearchivist,
truenas,
unifi,