mirror of
https://github.com/gethomepage/homepage.git
synced 2026-03-30 23:02:39 -07:00
Chore: merge Overseerr into Seerr, add aliases (#6330)
This commit is contained in:
@@ -101,7 +101,6 @@ You can also find a list of all available service widgets in the sidebar navigat
|
||||
- [OpenMediaVault](openmediavault.md)
|
||||
- [OpenWRT](openwrt.md)
|
||||
- [OPNsense](opnsense.md)
|
||||
- [Overseerr](overseerr.md)
|
||||
- [PaperlessNGX](paperlessngx.md)
|
||||
- [Peanut](peanut.md)
|
||||
- [pfSense](pfsense.md)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
title: Overseerr
|
||||
description: Overseerr Widget Configuration
|
||||
---
|
||||
|
||||
Learn more about [Overseerr](https://github.com/sct/overseerr).
|
||||
|
||||
Find your API key under `Settings > General`.
|
||||
|
||||
Allowed fields: `["pending", "approved", "available", "processing"]`.
|
||||
|
||||
```yaml
|
||||
widget:
|
||||
type: overseerr
|
||||
url: http://overseerr.host.or.ip
|
||||
key: apikeyapikeyapikeyapikeyapikey
|
||||
```
|
||||
@@ -7,9 +7,9 @@ Learn more about [Seerr](https://github.com/seerr-team/seerr).
|
||||
|
||||
Find your API key under `Settings > General > API Key`.
|
||||
|
||||
_Note that Jellyseerr was merged with Overseerr and renamed Seerr. Use `type: seerr` (legacy `type: jellyseerr` is aliased)._
|
||||
_Jellyseerr and Overseerr merged into Seerr. Use `type: seerr` (legacy `type: jellyseerr` and `type: overseerr` are aliased)._
|
||||
|
||||
Allowed fields: `["pending", "approved", "available", "completed", "issues"]`.
|
||||
Allowed fields: `["pending", "approved", "available", "completed", "processing", "issues"]`.
|
||||
Default fields: `["pending", "approved", "completed"]`.
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -124,7 +124,6 @@ nav:
|
||||
- widgets/services/openmediavault.md
|
||||
- widgets/services/opnsense.md
|
||||
- widgets/services/openwrt.md
|
||||
- widgets/services/overseerr.md
|
||||
- widgets/services/pangolin.md
|
||||
- widgets/services/paperlessngx.md
|
||||
- widgets/services/peanut.md
|
||||
|
||||
@@ -294,13 +294,8 @@
|
||||
"approved": "Approved",
|
||||
"available": "Available",
|
||||
"completed": "Completed",
|
||||
"issues": "Open Issues"
|
||||
},
|
||||
"overseerr": {
|
||||
"pending": "Pending",
|
||||
"processing": "Processing",
|
||||
"approved": "Approved",
|
||||
"available": "Available"
|
||||
"issues": "Open Issues"
|
||||
},
|
||||
"netalertx": {
|
||||
"total": "Total",
|
||||
|
||||
@@ -9,6 +9,8 @@ import { buildHighlightConfig } from "utils/highlights";
|
||||
const ALIASED_WIDGETS = {
|
||||
pialert: "netalertx",
|
||||
hoarder: "karakeep",
|
||||
jellyseerr: "seerr",
|
||||
overseerr: "seerr",
|
||||
};
|
||||
|
||||
export default function Container({ error = false, children, service }) {
|
||||
|
||||
@@ -58,6 +58,26 @@ describe("components/services/widget/container", () => {
|
||||
expect(screen.getByTestId("karakeep.count")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("supports seerr aliases when filtering (jellyseerr/overseerr -> seerr)", () => {
|
||||
renderWithProviders(
|
||||
<Container service={{ widget: { type: "jellyseerr", fields: ["pending"] } }}>
|
||||
<Dummy label="seerr.pending" />
|
||||
</Container>,
|
||||
{ settings: {} },
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("seerr.pending")).toBeInTheDocument();
|
||||
|
||||
renderWithProviders(
|
||||
<Container service={{ widget: { type: "overseerr", fields: ["processing"] } }}>
|
||||
<Dummy label="seerr.processing" />
|
||||
</Container>,
|
||||
{ settings: {} },
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("seerr.processing")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("returns null when errors are hidden via settings.hideErrors", () => {
|
||||
const { container } = renderWithProviders(
|
||||
<Container error="nope" service={{ widget: { type: "omada", hide_errors: false } }}>
|
||||
|
||||
@@ -97,7 +97,7 @@ const components = {
|
||||
ombi: dynamic(() => import("./ombi/component")),
|
||||
opendtu: dynamic(() => import("./opendtu/component")),
|
||||
opnsense: dynamic(() => import("./opnsense/component")),
|
||||
overseerr: dynamic(() => import("./overseerr/component")),
|
||||
overseerr: dynamic(() => import("./seerr/component")),
|
||||
openmediavault: dynamic(() => import("./openmediavault/component")),
|
||||
openwrt: dynamic(() => import("./openwrt/component")),
|
||||
paperlessngx: dynamic(() => import("./paperlessngx/component")),
|
||||
|
||||
@@ -8,7 +8,6 @@ const MAX_ALLOWED_FIELDS = 4;
|
||||
|
||||
export default function Component({ service }) {
|
||||
const { widget } = service;
|
||||
|
||||
widget.fields = widget?.fields?.length ? widget.fields.slice(0, MAX_ALLOWED_FIELDS) : seerrDefaultFields;
|
||||
const isIssueEnabled = widget.fields.includes("issues");
|
||||
|
||||
@@ -21,11 +20,12 @@ export default function Component({ service }) {
|
||||
if (!statsData || (isIssueEnabled && !issueData)) {
|
||||
return (
|
||||
<Container service={service}>
|
||||
<Block label="seerr.pending" />
|
||||
<Block label="seerr.approved" />
|
||||
<Block label="seerr.available" />
|
||||
<Block label="seerr.completed" />
|
||||
<Block label="seerr.issues" />
|
||||
<Block field="seerr.pending" label="seerr.pending" />
|
||||
<Block field="seerr.approved" label="seerr.approved" />
|
||||
<Block field="seerr.available" label="seerr.available" />
|
||||
<Block field="seerr.completed" label="seerr.completed" />
|
||||
<Block field="seerr.processing" label="seerr.processing" />
|
||||
<Block field="seerr.issues" label="seerr.issues" />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -38,11 +38,12 @@ export default function Component({ service }) {
|
||||
|
||||
return (
|
||||
<Container service={service}>
|
||||
<Block label="seerr.pending" value={statsData.pending} />
|
||||
<Block label="seerr.approved" value={statsData.approved} />
|
||||
<Block label="seerr.available" value={statsData.available} />
|
||||
<Block label="seerr.completed" value={statsData.completed} />
|
||||
<Block label="seerr.issues" value={`${issueData?.open} / ${issueData?.total}`} />
|
||||
<Block field="seerr.pending" label="seerr.pending" value={statsData.pending} />
|
||||
<Block field="seerr.approved" label="seerr.approved" value={statsData.approved} />
|
||||
<Block field="seerr.available" label="seerr.available" value={statsData.available} />
|
||||
<Block field="seerr.completed" label="seerr.completed" value={statsData.completed} />
|
||||
<Block field="seerr.processing" label="seerr.processing" value={statsData.processing} />
|
||||
<Block field="seerr.issues" label="seerr.issues" value={`${issueData?.open} / ${issueData?.total}`} />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,59 @@ describe("widgets/seerr/component", () => {
|
||||
expect(screen.getByText("seerr.approved")).toBeInTheDocument();
|
||||
expect(screen.getByText("seerr.completed")).toBeInTheDocument();
|
||||
expect(screen.queryByText("seerr.available")).toBeNull();
|
||||
expect(screen.queryByText("seerr.processing")).toBeNull();
|
||||
expect(screen.queryByText("seerr.issues")).toBeNull();
|
||||
});
|
||||
|
||||
it("supports jellyseerr as a legacy alias to seerr", () => {
|
||||
useWidgetAPI
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }) // request/count
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }); // issue/count disabled (endpoint = "")
|
||||
|
||||
const service = { widget: { type: "jellyseerr", url: "http://x" } };
|
||||
const { container } = renderWithProviders(<Component service={service} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(service.widget.fields).toEqual(seerrDefaultFields);
|
||||
expect(useWidgetAPI.mock.calls[1][1]).toBe("");
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(3);
|
||||
expect(screen.getByText("seerr.pending")).toBeInTheDocument();
|
||||
expect(screen.getByText("seerr.approved")).toBeInTheDocument();
|
||||
expect(screen.getByText("seerr.completed")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("supports overseerr as a legacy alias with the same default fields", () => {
|
||||
useWidgetAPI
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }) // request/count
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }); // issue/count disabled (endpoint = "")
|
||||
|
||||
const service = { widget: { type: "overseerr", url: "http://x" } };
|
||||
const { container } = renderWithProviders(<Component service={service} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(service.widget.fields).toEqual(seerrDefaultFields);
|
||||
expect(useWidgetAPI.mock.calls[1][1]).toBe("");
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(3);
|
||||
expect(screen.getByText("seerr.pending")).toBeInTheDocument();
|
||||
expect(screen.getByText("seerr.approved")).toBeInTheDocument();
|
||||
expect(screen.getByText("seerr.completed")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps processing as a separate optional field", () => {
|
||||
useWidgetAPI
|
||||
.mockReturnValueOnce({ data: { pending: 1, processing: 2, approved: 3, available: 4 }, error: undefined })
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }); // issue/count disabled (endpoint = "")
|
||||
|
||||
const service = {
|
||||
widget: { type: "overseerr", url: "http://x", fields: ["pending", "processing", "approved", "available"] },
|
||||
};
|
||||
const { container } = renderWithProviders(<Component service={service} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(useWidgetAPI.mock.calls[1][1]).toBe("");
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(4);
|
||||
expect(screen.getByText("seerr.processing")).toBeInTheDocument();
|
||||
expect(screen.getByText("2")).toBeInTheDocument();
|
||||
expect(screen.queryByText("seerr.completed")).toBeNull();
|
||||
});
|
||||
|
||||
it("renders issues when enabled (and calls the issue/count endpoint)", () => {
|
||||
useWidgetAPI
|
||||
.mockReturnValueOnce({ data: { pending: 1, approved: 2, available: 3, completed: 4 }, error: undefined })
|
||||
|
||||
@@ -90,7 +90,6 @@ import opendtu from "./opendtu/widget";
|
||||
import openmediavault from "./openmediavault/widget";
|
||||
import openwrt from "./openwrt/widget";
|
||||
import opnsense from "./opnsense/widget";
|
||||
import overseerr from "./overseerr/widget";
|
||||
import pangolin from "./pangolin/widget";
|
||||
import paperlessngx from "./paperlessngx/widget";
|
||||
import peanut from "./peanut/widget";
|
||||
@@ -244,7 +243,7 @@ const widgets = {
|
||||
ombi,
|
||||
opendtu,
|
||||
opnsense,
|
||||
overseerr,
|
||||
overseerr: seerr,
|
||||
openmediavault,
|
||||
openwrt,
|
||||
paperlessngx,
|
||||
|
||||
Reference in New Issue
Block a user