feat: add pi hole summary integration (#521)

* feat: add pi hole summary integration

* feat: add pi hole summary widget

* fix: type issues with integrations and integrationIds

* feat: add middleware for integrations and improve cache redis channel

* feat: add error boundary for widgets

* fix: broken lock file

* fix: format format issues

* fix: typecheck issue

* fix: deepsource issues

* fix: widget sandbox without error boundary

* chore: address pull request feedback

* chore: remove todo comment and created issue

* fix: format issues

* fix: deepsource issue
This commit is contained in:
Meier Lukas
2024-05-26 17:13:34 +02:00
committed by GitHub
parent 96c71aed6e
commit d57b771a17
45 changed files with 902 additions and 124 deletions

View File

@@ -1,11 +1,12 @@
import type { LoaderComponent } from "next/dynamic";
import type { DefaultErrorData } from "@trpc/server/unstable-core-do-not-import";
import type { IntegrationKind, WidgetKind } from "@homarr/definitions";
import type { stringOrTranslation } from "@homarr/translation";
import type { TablerIcon } from "@homarr/ui";
import type { WidgetImports } from ".";
import type { inferOptionsFromDefinition, WidgetOptionsRecord } from "./options";
import type { IntegrationSelectOption } from "./widget-integration-select";
type ServerDataLoader<TKind extends WidgetKind> = () => Promise<{
default: (props: WidgetProps<TKind>) => Promise<Record<string, unknown>>;
@@ -64,11 +65,20 @@ export interface WidgetDefinition {
icon: TablerIcon;
supportedIntegrations?: IntegrationKind[];
options: WidgetOptionsRecord;
errors?: Partial<
Record<
DefaultErrorData["code"],
{
icon: TablerIcon;
message: stringOrTranslation;
}
>
>;
}
export interface WidgetProps<TKind extends WidgetKind> {
options: inferOptionsFromDefinition<WidgetOptionsRecordOf<TKind>>;
integrations: inferIntegrationsFromDefinition<WidgetImports[TKind]["definition"]>;
integrationIds: string[];
}
type inferServerDataForKind<TKind extends WidgetKind> = WidgetImports[TKind] extends {
@@ -87,19 +97,4 @@ export type WidgetComponentProps<TKind extends WidgetKind> = WidgetProps<TKind>
height: number;
};
type inferIntegrationsFromDefinition<TDefinition extends WidgetDefinition> = TDefinition extends {
supportedIntegrations: infer TSupportedIntegrations;
} // check if definition has supportedIntegrations
? TSupportedIntegrations extends IntegrationKind[] // check if supportedIntegrations is an array of IntegrationKind
? IntegrationSelectOptionFor<TSupportedIntegrations[number]>[] // if so, return an array of IntegrationSelectOptionFor
: IntegrationSelectOption[] // otherwise, return an array of IntegrationSelectOption without specifying the kind
: IntegrationSelectOption[];
interface IntegrationSelectOptionFor<TIntegration extends IntegrationKind> {
id: string;
name: string;
url: string;
kind: TIntegration[number];
}
export type WidgetOptionsRecordOf<TKind extends WidgetKind> = WidgetImports[TKind]["definition"]["options"];