From 4908a15c6086da5ed0d3d0a97fac20aa63622d39 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 28 Sep 2024 13:53:20 +0200 Subject: [PATCH 1/7] feat(spotlight): add search settings link --- packages/spotlight/src/components/spotlight.tsx | 14 +++++++++++++- packages/translation/src/lang/en.ts | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/spotlight/src/components/spotlight.tsx b/packages/spotlight/src/components/spotlight.tsx index c9c9c2904..a2468d0ab 100644 --- a/packages/spotlight/src/components/spotlight.tsx +++ b/packages/spotlight/src/components/spotlight.tsx @@ -1,10 +1,12 @@ "use client"; import { useMemo, useRef, useState } from "react"; -import { ActionIcon, Center, Group, Kbd } from "@mantine/core"; +import Link from "next/link"; +import { ActionIcon, Anchor, Center, Group, Kbd } from "@mantine/core"; import { Spotlight as MantineSpotlight } from "@mantine/spotlight"; import { IconSearch, IconX } from "@tabler/icons-react"; +import { useSession } from "@homarr/auth/client"; import type { TranslationObject } from "@homarr/translation"; import { useI18n } from "@homarr/translation/client"; @@ -21,6 +23,7 @@ export const Spotlight = () => { const t = useI18n(); const inputRef = useRef(null); const activeMode = useMemo(() => searchModes.find((searchMode) => searchMode.modeKey === mode), [mode]); + const { data: session } = useSession(); if (!activeMode) { return null; @@ -113,6 +116,15 @@ export const Spotlight = () => { /> )} + {session ? ( + + + + {t("search.settings")} + + + + ) : null} ); }; diff --git a/packages/translation/src/lang/en.ts b/packages/translation/src/lang/en.ts index e1248959b..fdf1b2670 100644 --- a/packages/translation/src/lang/en.ts +++ b/packages/translation/src/lang/en.ts @@ -2054,6 +2054,7 @@ export default { search: { placeholder: "Search for anything", nothingFound: "Nothing found", + settings: "Search settings", error: { fetch: "An error occurred while fetching data", }, @@ -2293,5 +2294,6 @@ export default { }, }, }, + engine: {}, }, } as const; From 87fdc33006f0b37782734648fda3881d8730b5d8 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 28 Sep 2024 16:08:54 +0200 Subject: [PATCH 2/7] feat(search-engine): add to manage pages --- .../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 | 28 + .../new/_search-engine-new-form.tsx | 53 + .../manage/search-engines/new/page.tsx | 22 + .../[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 | 79 + .../migrations/mysql/0008_far_lifeguard.sql | 9 + .../migrations/mysql/meta/0008_snapshot.json | 1598 +++++++++++++++++ .../db/migrations/mysql/meta/_journal.json | 9 +- .../db/migrations/sqlite/0008_third_thor.sql | 8 + .../migrations/sqlite/meta/0008_snapshot.json | 1510 ++++++++++++++++ .../db/migrations/sqlite/meta/_journal.json | 9 +- packages/db/schema/mysql.ts | 9 + packages/db/schema/sqlite.ts | 9 + .../src/modes/page/pages-search-group.tsx | 7 + packages/translation/src/lang/en.ts | 88 +- packages/validation/src/app.ts | 3 - packages/validation/src/form/i18n.ts | 2 +- packages/validation/src/group.ts | 13 +- packages/validation/src/index.ts | 7 + packages/validation/src/search-engine.ts | 20 + packages/validation/src/shared.ts | 10 + 29 files changed, 3814 insertions(+), 29 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/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 ( +
+ + + + + + + + + + + +