feat(integrations): add mock integration (#3505)

This commit is contained in:
Meier Lukas
2025-07-04 09:49:18 +02:00
committed by GitHub
parent 350a531d32
commit 58d5b14c51
73 changed files with 1049 additions and 156 deletions

View File

@@ -5,6 +5,7 @@ import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import { clientApi } from "@homarr/api/client";
import type { IntegrationKind } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import type { WidgetComponentProps } from "../definition";
@@ -13,21 +14,25 @@ import { SystemHealthMonitoring } from "./system-health";
dayjs.extend(duration);
const isClusterIntegration = (integration: { kind: IntegrationKind }) =>
integration.kind === "proxmox" || integration.kind === "mock";
export default function HealthMonitoringWidget(props: WidgetComponentProps<"healthMonitoring">) {
const [integrations] = clientApi.integration.byIds.useSuspenseQuery(props.integrationIds);
const t = useI18n();
const proxmoxIntegrationId = integrations.find((integration) => integration.kind === "proxmox")?.id;
const clusterIntegrationId = integrations.find(isClusterIntegration)?.id;
if (!proxmoxIntegrationId) {
if (!clusterIntegrationId) {
return <SystemHealthMonitoring {...props} />;
}
const otherIntegrationIds = integrations
// We want to have the mock integration also in the system tab, so we use it for both
.filter((integration) => integration.kind !== "proxmox")
.map((integration) => integration.id);
if (otherIntegrationIds.length === 0) {
return <ClusterHealthMonitoring {...props} integrationId={proxmoxIntegrationId} />;
return <ClusterHealthMonitoring {...props} integrationId={clusterIntegrationId} />;
}
return (
@@ -45,7 +50,7 @@ export default function HealthMonitoringWidget(props: WidgetComponentProps<"heal
<SystemHealthMonitoring {...props} integrationIds={otherIntegrationIds} />
</Tabs.Panel>
<Tabs.Panel value="cluster">
<ClusterHealthMonitoring integrationId={proxmoxIntegrationId} {...props} />
<ClusterHealthMonitoring integrationId={clusterIntegrationId} {...props} />
</Tabs.Panel>
</Tabs>
</ScrollArea>

View File

@@ -1,5 +1,7 @@
import { IconVideo } from "@tabler/icons-react";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import { createWidgetDefinition } from "../definition";
import { optionsBuilder } from "../options";
@@ -10,5 +12,5 @@ export const { componentLoader, definition } = createWidgetDefinition("mediaServ
showOnlyPlaying: factory.switch({ defaultValue: true, withDescription: true }),
}));
},
supportedIntegrations: ["jellyfin", "plex", "emby"],
supportedIntegrations: getIntegrationKindsByCategory("mediaService"),
}).withDynamicImport(() => import("./component"));

View File

@@ -2,6 +2,7 @@ import { IconTransform } from "@tabler/icons-react";
import { z } from "zod";
import { capitalize } from "@homarr/common";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import { createWidgetDefinition } from "../definition";
import { optionsBuilder } from "../options";
@@ -19,5 +20,5 @@ export const { componentLoader, definition } = createWidgetDefinition("mediaTran
queuePageSize: factory.number({ defaultValue: 10, validate: z.number().min(1).max(30) }),
}));
},
supportedIntegrations: ["tdarr"],
supportedIntegrations: getIntegrationKindsByCategory("mediaTranscoding"),
}).withDynamicImport(() => import("./component"));