fix: address assistant review feedback

This commit is contained in:
ajnart committed 2026-08-02 16:45:14 +02:00
1 parent cf6aefa48a
commit 8a2375b3ef
28 files changed
+351 -58

No files matched your search

@@ -6,7 +6,7 @@ import { useDebouncedValue } from "@mantine/hooks";
import { IconCheck } from "@tabler/icons-react";
import { translateIfNecessary } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import type { CommonWidgetInputProps } from "./common";
import { useWidgetInputTranslation } from "./common";
@@ -19,16 +19,17 @@ export interface DynamicSelectOption {
export const WidgetDynamicSelectInput = ({ property, kind, options }: CommonWidgetInputProps<"dynamicSelect">) => {
const t = useI18n();
const tSelect = useScopedI18n("widget.dynamicSelect");
const tWidget = useWidgetInputTranslation(kind, property);
const form = useFormContext();
const inputProps = form.getInputProps(`options.${property}`);
const [search, setSearch] = useState("");
const [debouncedSearch] = useDebouncedValue(search, 300);
const { isPending, options: selectOptions } = options.useOptions(
debouncedSearch,
form.values.integrationIds,
form.values.options,
);
const {
isPending,
isError = false,
options: selectOptions,
} = options.useOptions(debouncedSearch, form.values.integrationIds, form.values.options);
const currentOption = inputProps.value as DynamicSelectOption | null;
const onChange = inputProps.onChange as (value: DynamicSelectOption | null) => void;
@@ -71,7 +72,7 @@ export const WidgetDynamicSelectInput = ({ property, kind, options }: CommonWidg
searchValue={search}
onSearchChange={setSearch}
placeholder={tWidget("placeholder")}
nothingFoundMessage={t("common.noResults")}
nothingFoundMessage={tSelect("noResults")}
leftSection={isPending && <Loader size="xs" />}
renderOption={({ option, checked }) => {
return (
@@ -92,6 +93,8 @@ export const WidgetDynamicSelectInput = ({ property, kind, options }: CommonWidg
description={options.withDescription ? tWidget("description") : undefined}
searchable
{...inputProps}
disabled={isError}
error={isError ? tSelect("loadError") : inputProps.error}
value={currentOption === null ? null : currentOption.value}
onChange={(selectedValue: string | null) => {
if (selectedValue === null) {
+4 -4
View File
@@ -3,14 +3,14 @@
import { Center, Stack, Text, ThemeIcon } from "@mantine/core";
import { IconRobot } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
import { useScopedI18n } from "@homarr/translation/client";
import type { WidgetComponentProps } from "../definition";
import { useAssistantWidgetRenderer } from "./context";
export default function AssistantWidget(props: WidgetComponentProps<"assistant">) {
const Renderer = useAssistantWidgetRenderer();
const t = useI18n();
const t = useScopedI18n("widget.assistant.unavailable");
if (Renderer) return <Renderer {...props} />;
@@ -21,10 +21,10 @@ export default function AssistantWidget(props: WidgetComponentProps<"assistant">
<IconRobot size={20} />
</ThemeIcon>
<Text size="sm" fw={600}>
{t("widget.assistant.unavailable.title")}
{t("title")}
</Text>
<Text size="xs" c="dimmed">
{t("widget.assistant.unavailable.description")}
{t("description")}
</Text>
</Stack>
</Center>
+2 -1
View File
@@ -21,10 +21,11 @@ export const { definition, componentLoader } = createWidgetDefinition("assistant
conversation: factory.dynamicSelect({
withDescription: true,
useOptions(query) {
const { data: threads = [], isPending } = clientApi.assistant.listThreads.useQuery();
const { data: threads = [], isPending, isError } = clientApi.assistant.listThreads.useQuery();
const normalizedQuery = query.trim().toLocaleLowerCase();
return {
isPending,
isError,
options: threads
.filter((thread) => {
if (normalizedQuery.length === 0) return true;
+1
View File
@@ -58,6 +58,7 @@ interface DynamicSelectInput extends CommonInput<DynamicSelectOption | null> {
options: Record<string, unknown>,
) => {
isPending: boolean;
isError?: boolean;
options: DynamicSelectOption[];
};
}