Feature: Linkwarden service widget (#3836)

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
PyrokineticDarkElf 2024-08-09 22:19:06 +01:00 committed by GitHub
parent b9b7c482d4
commit 4d38222ba0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 107 additions and 3 deletions

View file

@ -35,9 +35,16 @@ export default async function credentialedProxyHandler(req, res, map) {
} else if (widget.type === "gotify") {
headers["X-gotify-Key"] = `${widget.key}`;
} else if (
["authentik", "cloudflared", "ghostfolio", "mealie", "tailscale", "tandoor", "pterodactyl"].includes(
widget.type,
)
[
"authentik",
"cloudflared",
"ghostfolio",
"linkwarden",
"mealie",
"tailscale",
"tandoor",
"pterodactyl",
].includes(widget.type)
) {
headers.Authorization = `Bearer ${widget.key}`;
} else if (widget.type === "truenas") {

View file

@ -54,6 +54,7 @@ const components = {
komga: dynamic(() => import("./komga/component")),
kopia: dynamic(() => import("./kopia/component")),
lidarr: dynamic(() => import("./lidarr/component")),
linkwarden: dynamic(() => import("./linkwarden/component")),
mastodon: dynamic(() => import("./mastodon/component")),
mealie: dynamic(() => import("./mealie/component")),
medusa: dynamic(() => import("./medusa/component")),

View file

@ -0,0 +1,55 @@
import React, { useState, useEffect } from "react";
import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { widget } = service;
const [stats, setStats] = useState({
totalLinks: null,
collections: { total: null },
tags: { total: null },
});
const { data: collectionsStatsData, error: collectionsStatsError } = useWidgetAPI(widget, "collections");
const { data: tagsStatsData, error: tagsStatsError } = useWidgetAPI(widget, "tags");
useEffect(() => {
if (collectionsStatsData?.response && tagsStatsData?.response) {
setStats({
// eslint-disable-next-line no-underscore-dangle
totalLinks: collectionsStatsData.response.reduce((sum, collection) => sum + (collection._count?.links || 0), 0),
collections: {
total: collectionsStatsData.response.length,
},
tags: {
total: tagsStatsData.response.length,
},
});
}
}, [collectionsStatsData, tagsStatsData]);
if (collectionsStatsError || tagsStatsError) {
return <Container service={service} error={collectionsStatsError || tagsStatsError} />;
}
if (!tagsStatsData || !collectionsStatsData) {
return (
<Container service={service}>
<Block label="linkwarden.links" />
<Block label="linkwarden.collections" />
<Block label="linkwarden.tags" />
</Container>
);
}
return (
<Container service={service}>
<Block label="linkwarden.links" value={stats.totalLinks} />
<Block label="linkwarden.collections" value={stats.collections.total} />
<Block label="linkwarden.tags" value={stats.tags.total} />
</Container>
);
}

View file

@ -0,0 +1,17 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = {
api: "{url}/api/v1/{endpoint}",
proxyHandler: credentialedProxyHandler,
mappings: {
collections: {
endpoint: "collections",
},
tags: {
endpoint: "tags",
},
},
};
export default widget;

View file

@ -46,6 +46,7 @@ import kavita from "./kavita/widget";
import komga from "./komga/widget";
import kopia from "./kopia/widget";
import lidarr from "./lidarr/widget";
import linkwarden from "./linkwarden/widget";
import mastodon from "./mastodon/widget";
import mealie from "./mealie/widget";
import medusa from "./medusa/widget";
@ -167,6 +168,7 @@ const widgets = {
komga,
kopia,
lidarr,
linkwarden,
mastodon,
mealie,
medusa,