feat: add context specific search and actions (#1570)
This commit is contained in:
@@ -8,6 +8,7 @@ import combineClasses from "clsx";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { parseAppHrefWithVariablesClient } from "@homarr/common/client";
|
||||
import { useRegisterSpotlightContextResults } from "@homarr/spotlight";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
@@ -28,6 +29,24 @@ export default function AppWidget({ options, isEditMode }: WidgetComponentProps<
|
||||
retry: false,
|
||||
},
|
||||
);
|
||||
useRegisterSpotlightContextResults(
|
||||
`app-${app.id}`,
|
||||
[
|
||||
{
|
||||
id: app.id,
|
||||
name: app.name,
|
||||
icon: app.iconUrl,
|
||||
interaction() {
|
||||
return {
|
||||
type: "link",
|
||||
href: parseAppHrefWithVariablesClient(app.href ?? ""),
|
||||
newTab: options.openInNewTab,
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
[app, options.openInNewTab],
|
||||
);
|
||||
|
||||
return (
|
||||
<AppLink
|
||||
|
||||
@@ -4,17 +4,36 @@ import { Anchor, Box, Card, Divider, Flex, Group, Stack, Text, Title, UnstyledBu
|
||||
|
||||
import type { RouterOutputs } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { parseAppHrefWithVariablesClient } from "@homarr/common/client";
|
||||
import { useRegisterSpotlightContextResults } from "@homarr/spotlight";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
import classes from "./bookmark.module.css";
|
||||
|
||||
export default function BookmarksWidget({ options, width, height }: WidgetComponentProps<"bookmarks">) {
|
||||
export default function BookmarksWidget({ options, width, height, itemId }: WidgetComponentProps<"bookmarks">) {
|
||||
const [data] = clientApi.app.byIds.useSuspenseQuery(options.items, {
|
||||
select(data) {
|
||||
return data.sort((appA, appB) => options.items.indexOf(appA.id) - options.items.indexOf(appB.id));
|
||||
},
|
||||
});
|
||||
|
||||
useRegisterSpotlightContextResults(
|
||||
`bookmark-${itemId}`,
|
||||
data.map((app) => ({
|
||||
id: app.id,
|
||||
name: app.name,
|
||||
icon: app.iconUrl,
|
||||
interaction() {
|
||||
return {
|
||||
type: "link",
|
||||
href: parseAppHrefWithVariablesClient(app.href ?? ""),
|
||||
newTab: false,
|
||||
};
|
||||
},
|
||||
})),
|
||||
[data],
|
||||
);
|
||||
|
||||
return (
|
||||
<Stack h="100%" gap="sm" p="sm">
|
||||
<Title order={4} px="0.25rem">
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { Center, Stack, Text, UnstyledButton } from "@mantine/core";
|
||||
import { IconBinaryTree } from "@tabler/icons-react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useRegisterSpotlightContextActions } from "@homarr/spotlight";
|
||||
|
||||
import type { WidgetComponentProps } from "../../definition";
|
||||
import { NoIntegrationSelectedError } from "../../errors";
|
||||
@@ -60,6 +62,27 @@ const InnerComponent = ({ options, integrationId, isEditMode }: InnerComponentPr
|
||||
});
|
||||
}, [integrationId, isEditMode, mutate, options.clickable, options.entityId]);
|
||||
|
||||
useRegisterSpotlightContextActions(
|
||||
`smartHome-entityState-${options.entityId}`,
|
||||
[
|
||||
{
|
||||
id: options.entityId,
|
||||
name: options.displayName,
|
||||
icon: IconBinaryTree,
|
||||
interaction() {
|
||||
return {
|
||||
type: "javaScript",
|
||||
onSelect() {
|
||||
handleClick();
|
||||
},
|
||||
};
|
||||
},
|
||||
disabled: !options.clickable,
|
||||
},
|
||||
],
|
||||
[handleClick, options.clickable, options.displayName, options.entityId],
|
||||
);
|
||||
|
||||
return (
|
||||
<UnstyledButton
|
||||
onClick={handleClick}
|
||||
|
||||
@@ -6,6 +6,8 @@ import { useDisclosure, useTimeout } from "@mantine/hooks";
|
||||
import { IconAutomation, IconCheck } from "@tabler/icons-react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useRegisterSpotlightContextActions } from "@homarr/spotlight";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../../definition";
|
||||
|
||||
@@ -34,6 +36,29 @@ export default function SmartHomeTriggerAutomationWidget({
|
||||
integrationId: integrationIds[0] ?? "",
|
||||
});
|
||||
}, [integrationIds, isEditMode, mutateAsync, options.automationId]);
|
||||
|
||||
const t = useI18n();
|
||||
useRegisterSpotlightContextActions(
|
||||
`smartHome-automation-${options.automationId}`,
|
||||
[
|
||||
{
|
||||
id: options.automationId,
|
||||
name: t("widget.smartHome-executeAutomation.spotlightAction.run", { name: options.displayName }),
|
||||
icon: IconAutomation,
|
||||
interaction() {
|
||||
return {
|
||||
type: "javaScript",
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
async onSelect() {
|
||||
await handleClick();
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
[handleClick, options.automationId, options.displayName],
|
||||
);
|
||||
|
||||
return (
|
||||
<UnstyledButton onClick={handleClick} style={{ cursor: !isEditMode ? "pointer" : "initial" }} w="100%" h="100%">
|
||||
{isShowSuccess && (
|
||||
|
||||
Reference in New Issue
Block a user