feat: add improved search (#1051)
* feat: add improved search * wip: add support for sorting, rename use-options to use-query-options, add use-options for local usage, add pages search group * feat: add help links from manage layout to help search mode * feat: add additional search engines * feat: add group search details * refactor: improve users search group type * feat: add apps search group, add disabled search interaction * feat: add integrations and boards for search * wip: hook issue with react * fix: hook issue regarding actions and interactions * chore: address pull request feedback * fix: format issues * feat: add additional global actions to search * chore: remove unused code * fix: search engine short key * fix: typecheck issues * fix: deepsource issues * fix: eslint issue * fix: lint issues * fix: unordered dependencies * chore: address pull request feedback
This commit is contained in:
56
packages/spotlight/src/lib/interaction.ts
Normal file
56
packages/spotlight/src/lib/interaction.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { MaybePromise } from "@homarr/common/types";
|
||||
import type { TranslationObject } from "@homarr/translation";
|
||||
|
||||
import type { CreateChildrenOptionsProps } from "./children";
|
||||
|
||||
const createSearchInteraction = <TType extends string>(type: TType) => ({
|
||||
optionsType: <TOption extends Record<string, unknown>>() => ({ type, _inferOptions: {} as TOption }),
|
||||
});
|
||||
|
||||
// This is used to define search interactions with their options
|
||||
const searchInteractions = [
|
||||
createSearchInteraction("link").optionsType<{ href: string; newTab?: boolean }>(),
|
||||
createSearchInteraction("javaScript").optionsType<{ onSelect: () => MaybePromise<void> }>(),
|
||||
createSearchInteraction("mode").optionsType<{ mode: keyof TranslationObject["search"]["mode"] }>(),
|
||||
createSearchInteraction("children").optionsType<{
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
useActions: CreateChildrenOptionsProps<any>["useActions"];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
detailComponent: CreateChildrenOptionsProps<any>["detailComponent"];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
option: any;
|
||||
}>(),
|
||||
] as const;
|
||||
|
||||
// Union of all search interactions types
|
||||
export type SearchInteraction = (typeof searchInteractions)[number]["type"];
|
||||
|
||||
// Infer the options for the specified search interaction
|
||||
export type inferSearchInteractionOptions<TInteraction extends SearchInteraction> = Extract<
|
||||
(typeof searchInteractions)[number],
|
||||
{ type: TInteraction }
|
||||
>["_inferOptions"];
|
||||
|
||||
// Infer the search interaction definition (type + options) for the specified search interaction
|
||||
export type inferSearchInteractionDefinition<TInteraction extends SearchInteraction> = {
|
||||
[interactionKey in TInteraction]: { type: interactionKey } & inferSearchInteractionOptions<interactionKey>;
|
||||
}[TInteraction];
|
||||
|
||||
// Type used for helper functions to define basic search interactions
|
||||
type SearchInteractions = {
|
||||
[optionKey in SearchInteraction]: <TOption extends Record<string, unknown>>(
|
||||
callback: (option: TOption, query: string) => inferSearchInteractionOptions<optionKey>,
|
||||
) => (option: TOption, query: string) => inferSearchInteractionDefinition<optionKey>;
|
||||
};
|
||||
|
||||
// Helper functions to define basic search interactions
|
||||
export const interaction = searchInteractions.reduce((acc, interaction) => {
|
||||
return {
|
||||
...acc,
|
||||
[interaction.type]: <TOption extends Record<string, unknown>>(
|
||||
callback: (option: TOption, query: string) => inferSearchInteractionOptions<SearchInteraction>,
|
||||
) => {
|
||||
return (option: TOption, query: string) => ({ type: interaction.type, ...callback(option, query) });
|
||||
},
|
||||
};
|
||||
}, {} as SearchInteractions);
|
||||
Reference in New Issue
Block a user