mirror of
https://github.com/karl0ss/homepage.git
synced 2025-05-04 22:43:40 +01:00
Feature: Linkwarden service widget (#3836)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
parent
b9b7c482d4
commit
4d38222ba0
@ -55,6 +55,7 @@ You can also find a list of all available service widgets in the sidebar navigat
|
|||||||
- [Komga](komga.md)
|
- [Komga](komga.md)
|
||||||
- [Kopia](kopia.md)
|
- [Kopia](kopia.md)
|
||||||
- [Lidarr](lidarr.md)
|
- [Lidarr](lidarr.md)
|
||||||
|
- [Linkwarden](linkwarden.md)
|
||||||
- [Mastodon](mastodon.md)
|
- [Mastodon](mastodon.md)
|
||||||
- [Mealie](mealie.md)
|
- [Mealie](mealie.md)
|
||||||
- [Medusa](medusa.md)
|
- [Medusa](medusa.md)
|
||||||
|
15
docs/widgets/services/linkwarden.md
Normal file
15
docs/widgets/services/linkwarden.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: Linkwarden
|
||||||
|
description: Linkwarden Widget Configuration
|
||||||
|
---
|
||||||
|
|
||||||
|
Learn more about [Linkwarden](https://linkwarden.app/).
|
||||||
|
|
||||||
|
Allowed fields: `["links", "collections", "tags"]`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
widget:
|
||||||
|
type: linkwarden
|
||||||
|
url: http://linkwarden.host.or.ip
|
||||||
|
key: myApiKeyHere # On your Linkwarden install, go to Settings > Access Tokens. Generate a token.
|
||||||
|
```
|
@ -80,6 +80,7 @@ nav:
|
|||||||
- widgets/services/komga.md
|
- widgets/services/komga.md
|
||||||
- widgets/services/kopia.md
|
- widgets/services/kopia.md
|
||||||
- widgets/services/lidarr.md
|
- widgets/services/lidarr.md
|
||||||
|
- widgets/services/linkwarden.md
|
||||||
- widgets/services/mastodon.md
|
- widgets/services/mastodon.md
|
||||||
- widgets/services/mealie.md
|
- widgets/services/mealie.md
|
||||||
- widgets/services/medusa.md
|
- widgets/services/medusa.md
|
||||||
|
@ -905,5 +905,10 @@
|
|||||||
"cameras": "Cameras",
|
"cameras": "Cameras",
|
||||||
"uptime": "Uptime",
|
"uptime": "Uptime",
|
||||||
"version": "Version"
|
"version": "Version"
|
||||||
|
},
|
||||||
|
"linkwarden": {
|
||||||
|
"links": "Links",
|
||||||
|
"collections": "Collections",
|
||||||
|
"tags": "Tags"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,16 @@ export default async function credentialedProxyHandler(req, res, map) {
|
|||||||
} else if (widget.type === "gotify") {
|
} else if (widget.type === "gotify") {
|
||||||
headers["X-gotify-Key"] = `${widget.key}`;
|
headers["X-gotify-Key"] = `${widget.key}`;
|
||||||
} else if (
|
} 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}`;
|
headers.Authorization = `Bearer ${widget.key}`;
|
||||||
} else if (widget.type === "truenas") {
|
} else if (widget.type === "truenas") {
|
||||||
|
@ -54,6 +54,7 @@ const components = {
|
|||||||
komga: dynamic(() => import("./komga/component")),
|
komga: dynamic(() => import("./komga/component")),
|
||||||
kopia: dynamic(() => import("./kopia/component")),
|
kopia: dynamic(() => import("./kopia/component")),
|
||||||
lidarr: dynamic(() => import("./lidarr/component")),
|
lidarr: dynamic(() => import("./lidarr/component")),
|
||||||
|
linkwarden: dynamic(() => import("./linkwarden/component")),
|
||||||
mastodon: dynamic(() => import("./mastodon/component")),
|
mastodon: dynamic(() => import("./mastodon/component")),
|
||||||
mealie: dynamic(() => import("./mealie/component")),
|
mealie: dynamic(() => import("./mealie/component")),
|
||||||
medusa: dynamic(() => import("./medusa/component")),
|
medusa: dynamic(() => import("./medusa/component")),
|
||||||
|
55
src/widgets/linkwarden/component.jsx
Normal file
55
src/widgets/linkwarden/component.jsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
17
src/widgets/linkwarden/widget.js
Normal file
17
src/widgets/linkwarden/widget.js
Normal 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;
|
@ -46,6 +46,7 @@ import kavita from "./kavita/widget";
|
|||||||
import komga from "./komga/widget";
|
import komga from "./komga/widget";
|
||||||
import kopia from "./kopia/widget";
|
import kopia from "./kopia/widget";
|
||||||
import lidarr from "./lidarr/widget";
|
import lidarr from "./lidarr/widget";
|
||||||
|
import linkwarden from "./linkwarden/widget";
|
||||||
import mastodon from "./mastodon/widget";
|
import mastodon from "./mastodon/widget";
|
||||||
import mealie from "./mealie/widget";
|
import mealie from "./mealie/widget";
|
||||||
import medusa from "./medusa/widget";
|
import medusa from "./medusa/widget";
|
||||||
@ -167,6 +168,7 @@ const widgets = {
|
|||||||
komga,
|
komga,
|
||||||
kopia,
|
kopia,
|
||||||
lidarr,
|
lidarr,
|
||||||
|
linkwarden,
|
||||||
mastodon,
|
mastodon,
|
||||||
mealie,
|
mealie,
|
||||||
medusa,
|
medusa,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user