{t("connection.reconnecting", { attempt: state.attempt ?? 1 })}
- ) : ( + ) : presentation.hint ? ({t(presentation.hint)}
- )} + ) : null} {state.blocked ? (diff --git a/frontend/src/components/views/ConnectionsView.tsx b/frontend/src/components/views/ConnectionsView.tsx index 7c70901..d1b1ecf 100644 --- a/frontend/src/components/views/ConnectionsView.tsx +++ b/frontend/src/components/views/ConnectionsView.tsx @@ -192,7 +192,10 @@ function ConnectionsView({ connected, rules, profiles }: ConnectionsViewProps) { -
{rows.length === 0 ? t("connections.none") : t("connections.noMatch")} @@ -202,7 +205,7 @@ function ConnectionsView({ connected, rules, profiles }: ConnectionsViewProps) { // app and rule under it, then the server, with the data // on the right. Five columns left a phone a word per cell.
| {t("connections.col.site")} | {t("connections.col.app")} | diff --git a/frontend/src/components/views/RoutingView.tsx b/frontend/src/components/views/RoutingView.tsx index 19983c6..11058f9 100644 --- a/frontend/src/components/views/RoutingView.tsx +++ b/frontend/src/components/views/RoutingView.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import toast from "react-hot-toast"; -import { Download, FileUp, Globe2, Landmark, Link2, Loader2, Redo2, RefreshCw, Server, StickyNote, Trash2, Puzzle, Undo2, Upload, Plus } from "lucide-react"; +import { Download, FileUp, Globe2, Info, Landmark, Link2, Loader2, Redo2, RefreshCw, Server, StickyNote, Trash2, Puzzle, Undo2, Upload, Plus } from "lucide-react"; import { Background, BackgroundVariant, @@ -40,6 +40,7 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { errorMessage, invoke } from "@/lib/backend"; import { MessageKey, useT } from "@/lib/i18n"; import { cn } from "@/lib/utils"; @@ -55,10 +56,10 @@ import { RuleListStatus, } from "@/types"; +// Domain patterns are added as a domains card, switched to patterns there. const SOURCE_KINDS: RoutingKind[] = [ "apps", "domains", - "domain_regex", "ip", "port", "protocol", @@ -70,6 +71,59 @@ const SOURCE_KINDS: RoutingKind[] = [ ]; const ACTIONS: RoutingAction[] = ["proxy", "direct", "block", "drop"]; +/** + * Destinations that can be taken off the canvas while nothing goes to them: + * many setups never block or drop anything, and the two cards only take room. + * Which ones are hidden is how this device shows the canvas, not part of the + * routing, so it is kept here rather than in the settings. + */ +const HIDEABLE_ACTIONS: RoutingAction[] = ["block", "drop"]; +const HIDDEN_ACTIONS_KEY = "nugget.routing.hiddenActions"; + +function useHiddenActions() { + const [hidden, setHidden] = useState
|---|