feat(apps): remove url variables (#1771)

This commit is contained in:
Meier Lukas
2024-12-24 14:16:24 +01:00
committed by GitHub
parent 425359be02
commit 8df398c3c7
11 changed files with 41 additions and 80 deletions

View File

@@ -6,7 +6,6 @@ import { IconBox, IconPencil } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { parseAppHrefWithVariablesServer } from "@homarr/common/server";
import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { ManageContainer } from "~/components/manage/manage-container";
@@ -82,8 +81,8 @@ const AppCard = async ({ app }: AppCardProps) => {
</Text>
)}
{app.href && (
<Anchor href={parseAppHrefWithVariablesServer(app.href)} lineClamp={1} size="sm" w="min-content">
{parseAppHrefWithVariablesServer(app.href)}
<Anchor href={app.href} lineClamp={1} size="sm" w="min-content">
{app.href}
</Anchor>
)}
</Stack>

View File

@@ -28,8 +28,7 @@
"@homarr/log": "workspace:^0.1.0",
"dayjs": "^1.11.13",
"next": "^14.2.21",
"react": "^19.0.0",
"tldts": "^6.1.69"
"react": "^19.0.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -1,23 +0,0 @@
import * as tldts from "tldts";
const safeParseTldts = (url: string) => {
try {
return tldts.parse(url);
} catch {
return null;
}
};
export const parseAppHrefWithVariables = <TInput extends string | null>(url: TInput, currentHref: string): TInput => {
if (!url || url.length === 0) return url;
const tldtsResult = safeParseTldts(currentHref);
const urlObject = new URL(currentHref);
return url
.replaceAll("[homarr_base]", `${urlObject.protocol}//${urlObject.hostname}`)
.replaceAll("[homarr_hostname]", tldtsResult?.hostname ?? "")
.replaceAll("[homarr_domain]", tldtsResult?.domain ?? "")
.replaceAll("[homarr_protocol]", urlObject.protocol.replace(":", "")) as TInput;
};

View File

@@ -1,6 +0,0 @@
import { parseAppHrefWithVariables } from "./base";
export const parseAppHrefWithVariablesClient = <TInput extends string | null>(url: TInput): TInput => {
if (typeof window === "undefined") return url;
return parseAppHrefWithVariables(url, window.location.href);
};

View File

@@ -1,8 +0,0 @@
import { headers } from "next/headers";
import { extractBaseUrlFromHeaders } from "../url";
import { parseAppHrefWithVariables } from "./base";
export const parseAppHrefWithVariablesServer = <TInput extends string | null>(url: TInput): TInput => {
return parseAppHrefWithVariables(url, extractBaseUrlFromHeaders(headers()));
};

View File

@@ -1,2 +1 @@
export * from "./app-url/client";
export * from "./revalidate-path-action";

View File

@@ -1,3 +1,2 @@
export * from "./app-url/server";
export * from "./security";
export * from "./encryption";

View File

@@ -7,7 +7,6 @@ import { IconLoader } from "@tabler/icons-react";
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";
@@ -31,26 +30,30 @@ export default function AppWidget({ options, isEditMode }: WidgetComponentProps<
);
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.href
? [
{
id: app.id,
name: app.name,
icon: app.iconUrl,
interaction() {
return {
type: "link",
// We checked above that app.href is defined
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
href: app.href!,
newTab: options.openInNewTab,
};
},
},
]
: [],
[app, options.openInNewTab],
);
return (
<AppLink
href={parseAppHrefWithVariablesClient(app.href ?? "")}
href={app.href ?? undefined}
openInNewTab={options.openInNewTab}
enabled={Boolean(app.href) && !isEditMode}
>
@@ -88,7 +91,7 @@ export default function AppWidget({ options, isEditMode }: WidgetComponentProps<
}
interface AppLinkProps {
href: string;
href: string | undefined;
openInNewTab: boolean;
enabled: boolean;
}

View File

@@ -3,7 +3,6 @@ import { IconCheck, IconX } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { parseAppHrefWithVariablesClient } from "@homarr/common/client";
import { PingDot } from "./ping-dot";
@@ -14,7 +13,7 @@ interface PingIndicatorProps {
export const PingIndicator = ({ href }: PingIndicatorProps) => {
const [ping] = clientApi.widget.app.ping.useSuspenseQuery(
{
url: parseAppHrefWithVariablesClient(href),
url: href,
},
{
refetchOnMount: false,
@@ -25,7 +24,7 @@ export const PingIndicator = ({ href }: PingIndicatorProps) => {
const [pingResult, setPingResult] = useState<RouterOutputs["widget"]["app"]["ping"]>(ping);
clientApi.widget.app.updatedPing.useSubscription(
{ url: parseAppHrefWithVariablesClient(href) },
{ url: href },
{
onData(data) {
setPingResult(data);

View File

@@ -4,7 +4,6 @@ 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";
@@ -19,18 +18,22 @@ export default function BookmarksWidget({ options, width, height, itemId }: Widg
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
.filter((app) => app.href !== null)
.map((app) => ({
id: app.id,
name: app.name,
icon: app.iconUrl,
interaction() {
return {
type: "link",
// We checked above that app.href is defined
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
href: app.href!,
newTab: false,
};
},
})),
[data],
);

3
pnpm-lock.yaml generated
View File

@@ -707,9 +707,6 @@ importers:
react:
specifier: ^19.0.0
version: 19.0.0
tldts:
specifier: ^6.1.69
version: 6.1.69
devDependencies:
'@homarr/eslint-config':
specifier: workspace:^0.2.0