From 4c9471e6086c354ec4383f22a7b8020c5aa8974d Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Fri, 4 Oct 2024 15:59:08 +0200 Subject: [PATCH] feat(spotlight): add support for custom search-engines (#1200) * feat(spotlight): add search settings link * feat(search-engine): add to manage pages * feat(spotlight): add children option for external search engines * chore: revert search settings * fix: deepsource issue * fix: inconsistent breadcrum placement * chore: address pull request feedback --- .../src/app/[locale]/manage/apps/page.tsx | 2 +- .../nextjs/src/app/[locale]/manage/layout.tsx | 6 + .../[locale]/manage/search-engines/_form.tsx | 73 + .../_search-engine-delete-button.tsx | 55 + .../edit/[id]/_search-engine-edit-form.tsx | 63 + .../manage/search-engines/edit/[id]/page.tsx | 27 + .../new/_search-engine-new-form.tsx | 52 + .../manage/search-engines/new/page.tsx | 21 + .../[locale]/manage/search-engines/page.tsx | 139 ++ packages/api/src/root.ts | 2 + packages/api/src/router/app.ts | 4 +- packages/api/src/router/group.ts | 6 +- .../search-engine/search-engine-router.ts | 85 + .../migrations/mysql/0008_far_lifeguard.sql | 9 + .../migrations/mysql/meta/0008_snapshot.json | 1429 +++++++++++++++++ .../db/migrations/mysql/meta/_journal.json | 7 + .../db/migrations/sqlite/0008_third_thor.sql | 8 + .../migrations/sqlite/meta/0008_snapshot.json | 1367 ++++++++++++++++ .../db/migrations/sqlite/meta/_journal.json | 7 + packages/db/schema/mysql.ts | 9 + packages/db/schema/sqlite.ts | 9 + .../src/components/actions/group-actions.tsx | 6 + .../actions/groups/action-group.tsx | 9 +- .../spotlight/src/components/spotlight.tsx | 7 +- packages/spotlight/src/lib/group.ts | 10 +- .../external/search-engines-search-group.tsx | 133 +- .../src/modes/page/pages-search-group.tsx | 7 + packages/translation/src/lang/en.ts | 97 +- packages/validation/src/app.ts | 3 - packages/validation/src/common.ts | 22 + packages/validation/src/form/i18n.ts | 2 +- packages/validation/src/group.ts | 13 +- packages/validation/src/index.ts | 20 +- packages/validation/src/search-engine.ts | 20 + 34 files changed, 3620 insertions(+), 109 deletions(-) create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/_search-engine-edit-form.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/edit/[id]/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/new/_search-engine-new-form.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/new/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx create mode 100644 packages/api/src/router/search-engine/search-engine-router.ts create mode 100644 packages/db/migrations/mysql/0008_far_lifeguard.sql create mode 100644 packages/db/migrations/mysql/meta/0008_snapshot.json create mode 100644 packages/db/migrations/sqlite/0008_third_thor.sql create mode 100644 packages/db/migrations/sqlite/meta/0008_snapshot.json create mode 100644 packages/validation/src/common.ts create mode 100644 packages/validation/src/search-engine.ts diff --git a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx index 7ddf2816a..11aa2e8eb 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx @@ -105,7 +105,7 @@ const AppNoResults = async () => { {t("app.page.list.noResults.title")} - {t("app.page.list.noResults.description")} + {t("app.page.list.noResults.action")} ); diff --git a/apps/nextjs/src/app/[locale]/manage/layout.tsx b/apps/nextjs/src/app/[locale]/manage/layout.tsx index 58314d65a..b4d1564c4 100644 --- a/apps/nextjs/src/app/[locale]/manage/layout.tsx +++ b/apps/nextjs/src/app/[locale]/manage/layout.tsx @@ -15,6 +15,7 @@ import { IconPlug, IconQuestionMark, IconReport, + IconSearch, IconSettings, IconTool, IconUser, @@ -53,6 +54,11 @@ export default async function ManageLayout({ children }: PropsWithChildren) { href: "/manage/integrations", label: t("items.integrations"), }, + { + icon: IconSearch, + href: "/manage/search-engines", + label: t("items.searchEngies"), + }, { icon: IconUser, label: t("items.users.label"), diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx new file mode 100644 index 000000000..e937cf503 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/search-engines/_form.tsx @@ -0,0 +1,73 @@ +"use client"; + +import Link from "next/link"; +import { Button, Grid, Group, Stack, Textarea, TextInput } from "@mantine/core"; + +import { useZodForm } from "@homarr/form"; +import type { TranslationFunction } from "@homarr/translation"; +import { useI18n } from "@homarr/translation/client"; +import type { z } from "@homarr/validation"; +import { validation } from "@homarr/validation"; + +import { IconPicker } from "~/components/icons/picker/icon-picker"; + +type FormType = z.infer; + +interface SearchEngineFormProps { + submitButtonTranslation: (t: TranslationFunction) => string; + initialValues?: FormType; + handleSubmit: (values: FormType) => void; + isPending: boolean; + disableShort?: boolean; +} + +export const SearchEngineForm = (props: SearchEngineFormProps) => { + const { submitButtonTranslation, handleSubmit, initialValues, isPending, disableShort } = props; + const t = useI18n(); + + const form = useZodForm(validation.searchEngine.manage, { + initialValues: initialValues ?? { + name: "", + short: "", + iconUrl: "", + urlTemplate: "", + description: "", + }, + }); + + return ( +
+ + + + + + + + + + + +