From 20048ff5672dc9cc404c7c5170d76c94bbfb9af9 Mon Sep 17 00:00:00 2001
From: vhsdream <67816022+vhsdream@users.noreply.github.com>
Date: Sat, 12 Oct 2024 10:53:02 -0400
Subject: [PATCH] Feature: Vikunja service widget (#4118)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
---
docs/widgets/services/index.md | 1 +
docs/widgets/services/vikunja.md | 18 +++++++
mkdocs.yml | 1 +
public/locales/en/common.json | 6 +++
src/utils/config/service-helpers.js | 6 +++
src/utils/proxy/handlers/credentialed.js | 1 +
src/widgets/components.js | 1 +
src/widgets/vikunja/component.jsx | 68 ++++++++++++++++++++++++
src/widgets/vikunja/widget.js | 27 ++++++++++
src/widgets/widgets.js | 2 +
10 files changed, 131 insertions(+)
create mode 100644 docs/widgets/services/vikunja.md
create mode 100644 src/widgets/vikunja/component.jsx
create mode 100644 src/widgets/vikunja/widget.js
diff --git a/docs/widgets/services/index.md b/docs/widgets/services/index.md
index 3462fef3..91f91d38 100644
--- a/docs/widgets/services/index.md
+++ b/docs/widgets/services/index.md
@@ -128,6 +128,7 @@ You can also find a list of all available service widgets in the sidebar navigat
- [Uptime Kuma](uptime-kuma.md)
- [UptimeRobot](uptimerobot.md)
- [UrBackup](urbackup.md)
+- [Vikunja](vikunja.md)
- [Watchtower](watchtower.md)
- [WGEasy](wgeasy.md)
- [WhatsUpDocker](whatsupdocker.md)
diff --git a/docs/widgets/services/vikunja.md b/docs/widgets/services/vikunja.md
new file mode 100644
index 00000000..94b99055
--- /dev/null
+++ b/docs/widgets/services/vikunja.md
@@ -0,0 +1,18 @@
+---
+title: Vikunja
+description: Vikunja Widget Configuration
+---
+
+Learn more about [Vikunja](https://vikunja.io).
+
+Allowed fields: `["projects", "tasks7d", "tasksOverdue", "tasksInProgress"]`.
+
+A list of the next 5 tasks ordered by due date is disabled by default, but can be enabled with the `enableTaskList` option.
+
+```yaml
+widget:
+ type: vikunja
+ url: http[s]://vikunja.host.or.ip[:port]
+ key: vikunjaapikey
+ enableTaskList: true # optional, defaults to false
+```
diff --git a/mkdocs.yml b/mkdocs.yml
index 1b3afd62..0667e5ea 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -151,6 +151,7 @@ nav:
- widgets/services/uptime-kuma.md
- widgets/services/uptimerobot.md
- widgets/services/urbackup.md
+ - widgets/services/vikunja.md
- widgets/services/watchtower.md
- widgets/services/wgeasy.md
- widgets/services/whatsupdocker.md
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 3aea07eb..384f44be 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -953,5 +953,11 @@
"reminders": "Reminders",
"nextReminder": "Next Reminder",
"none": "None"
+ },
+ "vikunja": {
+ "projects": "Active Projects",
+ "tasks7d": "Tasks Due This Week",
+ "tasksOverdue": "Overdue Tasks",
+ "tasksInProgress": "Tasks In Progress"
}
}
diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js
index 24ba57e2..9d55ce43 100644
--- a/src/utils/config/service-helpers.js
+++ b/src/utils/config/service-helpers.js
@@ -478,6 +478,9 @@ export function cleanServiceGroups(groups) {
// unifi
site,
+ // vikunja
+ enableTaskList,
+
// wgeasy
threshold,
@@ -633,6 +636,9 @@ export function cleanServiceGroups(groups) {
if (type === "lubelogger") {
if (vehicleID !== undefined) cleanedService.widget.vehicleID = parseInt(vehicleID, 10);
}
+ if (type === "vikunja") {
+ if (enableTaskList !== undefined) cleanedService.widget.enableTaskList = !!enableTaskList;
+ }
}
return cleanedService;
diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js
index 39822075..e907912d 100644
--- a/src/utils/proxy/handlers/credentialed.js
+++ b/src/utils/proxy/handlers/credentialed.js
@@ -44,6 +44,7 @@ export default async function credentialedProxyHandler(req, res, map) {
"tailscale",
"tandoor",
"pterodactyl",
+ "vikunja",
].includes(widget.type)
) {
headers.Authorization = `Bearer ${widget.key}`;
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 0a5a815c..62bd479f 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -125,6 +125,7 @@ const components = {
uptimekuma: dynamic(() => import("./uptimekuma/component")),
uptimerobot: dynamic(() => import("./uptimerobot/component")),
urbackup: dynamic(() => import("./urbackup/component")),
+ vikunja: dynamic(() => import("./vikunja/component")),
watchtower: dynamic(() => import("./watchtower/component")),
wgeasy: dynamic(() => import("./wgeasy/component")),
whatsupdocker: dynamic(() => import("./whatsupdocker/component")),
diff --git a/src/widgets/vikunja/component.jsx b/src/widgets/vikunja/component.jsx
new file mode 100644
index 00000000..09704338
--- /dev/null
+++ b/src/widgets/vikunja/component.jsx
@@ -0,0 +1,68 @@
+import { useTranslation } from "next-i18next";
+
+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 { t } = useTranslation();
+ const { widget } = service;
+
+ const { data: projectsData, error: projectsError } = useWidgetAPI(widget, "projects");
+ const { data: tasksData, error: tasksError } = useWidgetAPI(widget, "tasks");
+
+ if (projectsError || tasksError) {
+ return