Files
homarr/packages/widgets/src/_inputs/widget-integration-select-input.tsx
T
Thomas Camlong 5078c300f8 fix(widgets): race conditions in useLiveStats and stale value in integration select
- Add generation guard to prevent late SSE events from writing stale
  data after systemId/integration changes
- Sort integrationIds for stable key (avoids unnecessary resubscribes)
- Include integrationKey and systemId in flush interval deps
- Preserve current form value in WidgetIntegrationSelectInput when it's
  missing from loaded options (matches WidgetDynamicSelectInput pattern)
2026-06-16 17:59:41 +02:00

54 lines
1.7 KiB
TypeScript

"use client";
import { Select, Text } from "@mantine/core";
import { useScopedI18n } from "@homarr/translation/client";
import type { CommonWidgetInputProps } from "./common";
import { useWidgetInputTranslation } from "./common";
import { useFormContext } from "./form";
const useIntegrationSelectTranslation = () => useScopedI18n("widget.integrationSelect");
export const WidgetIntegrationSelectInput = ({
property,
kind,
options,
}: CommonWidgetInputProps<"integrationSelect">) => {
const t = useIntegrationSelectTranslation();
const tInput = useWidgetInputTranslation(kind, property);
const form = useFormContext();
const integrationIds = form.values.integrationIds as string[];
const { data: selectData = [], isPending, isError } = options.useOptions(integrationIds);
const currentValue = form.getInputProps(`options.${property}`).value as string;
const data =
currentValue && !selectData.some((opt) => opt.value === currentValue)
? [...selectData, { value: currentValue, label: currentValue }]
: selectData;
if (integrationIds.length === 0) {
return (
<Text size="sm" c="dimmed">
{t("configureIntegrationFirst")}
</Text>
);
}
return (
<Select
label={tInput("label")}
description={options.withDescription ? tInput("description") : undefined}
placeholder={(isPending && t("loading")) || t("placeholder")}
clearable={options.clearable}
searchable={options.searchable}
nothingFoundMessage={t("noResults")}
data={data}
disabled={isError}
error={(isError && t("loadError")) || undefined}
{...form.getInputProps(`options.${property}`)}
/>
);
};