Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: multiple widgets per service #4338

Merged
merged 6 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion docs/configs/service-widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Service Widget Configuration

Unless otherwise noted, URLs should not end with a `/` or other API path. Each widget will handle the path on its own.

Each service can have one widget attached to it (often matching the service type, but that's not forced).
Each service can have widgets attached to it (often matching the service type, but that's not forced).

In addition to the href of the service, you can also specify the target location in which to open that link. See [Link Target](settings.md#link-target) for more details.

Expand All @@ -22,6 +22,28 @@ Using Emby as an example, this is how you would attach the Emby service widget.
key: apikeyapikeyapikeyapikeyapikey
```

## Multiple Widgets

Each service can have multiple widgets attached to it. Each widget needs a unique name.

Using Emby as an example, here is how you would attack the Emby service widget alongside an uptime widget.

```yaml
- Emby:
icon: emby.png
href: http://emby.host.or.ip/
description: Movies & TV Shows
widgets:
- Emby:
type: emby
url: http://emby.host.or.ip
key: apikeyapikeyapikeyapikeyapikey
- Uptime:
type: uptimekuma
url: http://uptimekuma.host.or.ip:port
slug: statuspageslug
```

## Field Visibility

Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields.
Expand Down
13 changes: 9 additions & 4 deletions docs/widgets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ Service widgets are used to display the status of a service, often a web service
description: Watch movies and TV shows.
server: localhost
container: plex
widget:
type: tautulli
url: http://172.16.1.1:8181
key: aabbccddeeffgghhiijjkkllmmnnoo
widgets:
- Tautulli:
type: tautulli
url: http://172.16.1.1:8181
key: aabbccddeeffgghhiijjkkllmmnnoo
- UptimeKuma:
type: uptimekuma
url: http://172.16.1.2:8080
slug: aaaaaaabbbbb
```

## Info Widgets
Expand Down
4 changes: 3 additions & 1 deletion src/components/services/item.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ export default function Item({ service, group, useEqualHeights }) {
</div>
)}

{service.widget && <Widget service={service} />}
{service.widgets.map((widget) => (
<Widget widget={widget} service={service} />
))}
</div>
</li>
);
Expand Down
10 changes: 6 additions & 4 deletions src/components/services/widget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ import { useTranslation } from "next-i18next";
import ErrorBoundary from "components/errorboundry";
import components from "widgets/components";

export default function Widget({ service }) {
export default function Widget({ widget, service }) {
const { t } = useTranslation("common");

const ServiceWidget = components[service.widget.type];
const ServiceWidget = components[widget.type];

const fullService = service;
fullService.widget = widget;
if (ServiceWidget) {
return (
<ErrorBoundary>
<ServiceWidget service={service} />
<ServiceWidget service={fullService} />
</ErrorBoundary>
);
}

return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1 service-missing">
<div className="font-thin text-sm">{t("widget.missing_type", { type: service.widget.type })}</div>
<div className="font-thin text-sm">{t("widget.missing_type", { type: widget.type })}</div>
</div>
);
}
4 changes: 2 additions & 2 deletions src/pages/api/services/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const logger = createLogger("servicesProxy");

export default async function handler(req, res) {
try {
const { service, group } = req.query;
const serviceWidget = await getServiceWidget(group, service);
const { service, group, name } = req.query;
const serviceWidget = await getServiceWidget(group, service, name);
let type = serviceWidget?.type;

// exceptions
Expand Down
Loading