feat!: release v2 (#6545)

Co-authored-by: Artur <145776561+arturict@users.noreply.github.com>
Co-authored-by: arturict <arturict@users.noreply.github.com>
Co-authored-by: Thomas <thomas@ajnart.fr>
Co-authored-by: Afonso Jorge Ramos <afonsojorgeramos@gmail.com>
Co-authored-by: Danura30082 <danura30082+github@gmail.com>
Co-authored-by: Kushie <122986913+kushiemoon-dev@users.noreply.github.com>
Co-authored-by: ajnart <thomas@ajnart.fr>
Co-authored-by: ajnart <thomas@ajnart.dev>
Co-authored-by: chenjun <chenjun@foxmail.com>
Co-authored-by: Wikibear <wikibear@users.noreply.github.com>
Co-authored-by: Bergasha <bergasha@gmail.com>
Co-authored-by: leafyelin <43306196+leafyelin@users.noreply.github.com>
Co-authored-by: Lucas Araujo <lucas.lra@gmail.com>
Co-authored-by: GreenMonito <86085570+GreenMonito@users.noreply.github.com>
Co-authored-by: Nerdy-Technician <roffo@nerdy-technician.social>
Co-authored-by: Jun <34545896+jcstrong@users.noreply.github.com>
Co-authored-by: Edmond Abraham <54119952+gitedmond@users.noreply.github.com>
Co-authored-by: thrawnx <tight.bulb9384@fastmail.com>
Co-authored-by: Chris <58918656+nordada@users.noreply.github.com>
Co-authored-by: yi111 <153097222+Yi-111-a@users.noreply.github.com>
Co-authored-by: Yanis <naamaneyanis@gmail.com>
Co-authored-by: Wikibear <me@sej.de>
Co-authored-by: alessiottavo <93441886+alessiottavo@users.noreply.github.com>
This commit is contained in:
3286 files changed
+284386 -139176

No files matched your search

@@ -5,7 +5,7 @@ export const BoardTourGate = async ({ enabled, children }: PropsWithChildren<{ e
// Native server-side import keeps the completed-user client graph lean while
// giving first-time users one stable board tree instead of swapping a
// Suspense fallback after GridStack has mounted.
// Suspense fallback after the board grid has mounted.
const { BoardTourProvider } = await import("./board-tour");
return <BoardTourProvider>{children}</BoardTourProvider>;
};
@@ -7,7 +7,7 @@ import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour";
import { clientApi } from "@homarr/api/client";
import { useRequiredBoard } from "@homarr/boards/context";
import { createDocumentationLink } from "@homarr/definitions";
import { useScopedI18n } from "@homarr/translation/client";
import { useI18n } from "@homarr/translation/client";
import { useBoardPermissions } from "~/components/board/permissions/client";
import { TourTargetsProvider } from "~/components/layout/header/tour-target";
@@ -15,7 +15,7 @@ import { TourShell } from "./tour-shell";
import { TourStepContent } from "./tour-step-content";
export const BoardTourProvider = ({ children }: PropsWithChildren) => {
const t = useScopedI18n("onboardingTour.board");
const t = useI18n("onboardingTour.board");
const board = useRequiredBoard();
const { hasChangeAccess } = useBoardPermissions(board);
const [started, setStarted] = useState(true);
@@ -66,16 +66,6 @@ export const BoardTourProvider = ({ children }: PropsWithChildren) => {
/>
),
},
{
id: "board-switcher",
title: t("switcher.title"),
content: (
<TourStepContent
description={t("switcher.description")}
documentationHref={createDocumentationLink("/docs/management/boards")}
/>
),
},
{
id: "board-user-menu",
title: t("userMenu.title"),
@@ -93,7 +83,7 @@ export const BoardTourProvider = ({ children }: PropsWithChildren) => {
return (
<TourTargetsProvider enabled={started}>
<TourShell steps={steps} started={started} onEnd={handleEnd} position={{ base: "bottom", sm: "left" }}>
<TourShell steps={steps} started={started} onEnd={handleEnd} position={{ base: "bottom", md: "left" }}>
{children}
</TourShell>
</TourTargetsProvider>
@@ -4,7 +4,6 @@ import type { PropsWithChildren } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import type { OnboardingTourFocusRevealProps, OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour";
import { useMediaQuery } from "@mantine/hooks";
import {
IconAffiliateFilled,
IconAppsFilled,
@@ -15,7 +14,8 @@ import {
import { clientApi } from "@homarr/api/client";
import { createDocumentationLink } from "@homarr/definitions";
import { useScopedI18n } from "@homarr/translation/client";
import { useI18n } from "@homarr/translation/client";
import { useIsMobile } from "@homarr/ui/hooks";
import { TourTargetsProvider } from "~/components/layout/header/tour-target";
import { TourShell } from "./tour-shell";
@@ -46,9 +46,9 @@ const usersStepFocusRevealProps: OnboardingTourFocusRevealProps = {
};
export const ManageTourProvider = ({ children, isAdmin }: ManageTourProviderProps) => {
const t = useScopedI18n("onboardingTour.manage");
const t = useI18n("onboardingTour.manage");
const { mutate: completeTour } = clientApi.user.completeTour.useMutation();
const isMobile = useMediaQuery("(max-width: 48em)");
const isMobile = useIsMobile();
const pathname = usePathname();
const router = useRouter();
@@ -8,10 +8,9 @@ import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour";
import { Button, Center, Group, Image, Kbd, Text } from "@mantine/core";
import type { FloatingPosition } from "@mantine/core";
import { useSettings } from "@homarr/settings";
import { useI18n } from "@homarr/translation/client";
import { homarrLogoPath } from "~/components/layout/logo/homarr-logo";
interface TourShellProps extends PropsWithChildren {
steps: OnboardingTourStep[];
started: boolean;
@@ -77,7 +76,9 @@ const TourDoneButton = ({ label, onClick }: TourDoneButtonProps) => {
};
export const TourShell = ({ steps, started, onEnd, stepRoutes, position, children }: TourShellProps) => {
const t = useI18n();
const tCommon = useI18n("common.action");
const tTour = useI18n("onboardingTour");
const { branding } = useSettings();
const router = useRouter();
const forwardActionRef = useRef<(() => void) | null>(null);
@@ -144,7 +145,13 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre
</Group>
{stepIndexFromController(controller) === 0 && (
<Center py="xs">
<Image src={homarrLogoPath} alt="Homarr" w={64} h={64} fit="contain" />
<Image
src={branding.logoImageUrl ?? "/logo/logo.png"}
alt={`${branding.appName} logo`}
w={64}
h={64}
fit="contain"
/>
</Center>
)}
</>
@@ -154,11 +161,11 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre
const action = bindForwardAction(controller, () => {
navigateAndAdvance(controller.currentStep?.id, nextStep?.id, () => controller.nextStep());
});
return <TourForwardButton label={t("onboardingTour.next")} onClick={action} />;
return <TourForwardButton label={tCommon("next")} onClick={action} />;
}}
endStepNavigation={(controller) => {
const action = bindForwardAction(controller, () => controller.endTour());
return <TourDoneButton label={t("onboardingTour.done")} onClick={action} />;
return <TourDoneButton label={tTour("done")} onClick={action} />;
}}
prevStepNavigation={(controller) => (
<Button
@@ -169,20 +176,20 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre
navigateAndAdvance(controller.currentStep?.id, prevStep?.id, () => controller.prevStep());
}}
>
{t("onboardingTour.prev")}
{tTour("prev")}
</Button>
)}
skipNavigation={(controller) => (
<Button size="sm" variant="subtle" color="gray" onClick={() => controller.skipTour()}>
{t("onboardingTour.skip")}
{tTour("skip")}
</Button>
)}
withPrevButton
focusRevealProps={{
disableTargetInteraction: true,
popoverProps: {
position: position ?? { base: "bottom", sm: "right" },
width: 420,
position: position ?? { base: "bottom", md: "right" },
width: { base: "calc(100vw - 32px)", md: 420 },
shadow: "xl",
radius: "lg",
middlewares: { shift: { padding: 16 }, flip: true },
@@ -13,7 +13,7 @@ interface TourStepContentProps {
}
export const TourStepContent = ({ description, documentationHref, icon }: TourStepContentProps) => {
const t = useI18n();
const t = useI18n("onboardingTour");
return (
<Stack gap="sm">
@@ -31,7 +31,7 @@ export const TourStepContent = ({ description, documentationHref, icon }: TourSt
<Anchor href={documentationHref} target="_blank" size="xs" fw={500}>
<Group gap={4} wrap="nowrap">
<IconExternalLink size={14} />
{t("onboardingTour.learnMore")}
{t("learnMore")}
</Group>
</Anchor>
</Stack>