fix: change nodeList to existingTags

This commit is contained in:
Meow
2025-11-09 01:19:59 -05:00
parent c3e07e4e10
commit 5090733013
6 changed files with 30 additions and 28 deletions
@@ -9,7 +9,7 @@ import { ExpiryTag } from '~/components/tags/Expiry';
import { HeadplaneAgentTag } from '~/components/tags/HeadplaneAgent';
import { SubnetTag } from '~/components/tags/Subnet';
import { TailscaleSSHTag } from '~/components/tags/TailscaleSSH';
import type { Machine, User } from '~/types';
import type { User } from '~/types';
import cn from '~/utils/cn';
import * as hinfo from '~/utils/host-info';
import { PopulatedNode } from '~/utils/node-info';
@@ -22,7 +22,7 @@ interface Props {
isAgent?: boolean;
magic?: string;
isDisabled?: boolean;
nodeList?: Machine[];
existingTags?: string[];
}
export default function MachineRow({
@@ -31,7 +31,7 @@ export default function MachineRow({
isAgent,
magic,
isDisabled,
nodeList,
existingTags,
}: Props) {
const uiTags = useMemo(() => {
const tags = uiTagsForNode(node, isAgent);
@@ -148,10 +148,10 @@ export default function MachineRow({
</td>
<td className="py-2 pr-0.5">
<MenuOptions
existingTags={existingTags}
isDisabled={isDisabled}
magic={magic}
node={node}
nodeList={nodeList}
users={users}
/>
</td>
+4 -4
View File
@@ -2,7 +2,7 @@ import { Cog, Ellipsis, SquareTerminal } from 'lucide-react';
import { useState } from 'react';
import Button from '~/components/Button';
import Menu from '~/components/Menu';
import type { Machine, User } from '~/types';
import type { User } from '~/types';
import cn from '~/utils/cn';
import { PopulatedNode } from '~/utils/node-info';
import Delete from '../dialogs/delete';
@@ -18,7 +18,7 @@ interface MenuProps {
magic?: string;
isFullButton?: boolean;
isDisabled?: boolean;
nodeList?: Machine[];
existingTags?: string[];
}
type Modal = 'rename' | 'expire' | 'remove' | 'routes' | 'move' | 'tags' | null;
@@ -29,7 +29,7 @@ export default function MachineMenu({
users,
isFullButton,
isDisabled,
nodeList,
existingTags,
}: MenuProps) {
const [modal, setModal] = useState<Modal>(null);
const supportsTailscaleSSH =
@@ -77,9 +77,9 @@ export default function MachineMenu({
)}
{modal === 'tags' && (
<Tags
existingTags={existingTags}
isOpen={modal === 'tags'}
machine={node}
nodeList={nodeList}
setIsOpen={(isOpen) => {
if (!isOpen) setModal(null);
}}
+3 -9
View File
@@ -12,14 +12,14 @@ interface TagsProps {
machine: Machine;
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
nodeList?: Machine[];
existingTags?: string[];
}
export default function Tags({
machine,
isOpen,
setIsOpen,
nodeList,
existingTags,
}: TagsProps) {
const [tags, setTags] = useState(machine.forcedTags);
const [tag, setTag] = useState('tag:');
@@ -28,13 +28,7 @@ export default function Tags({
}, [tag, tags]);
const validNodeTags = useMemo(() => {
if (!nodeList?.length) return [];
const allNodeTags = Array.from(
new Set(
nodeList.flatMap((node) => [...node.validTags, ...node.forcedTags]),
),
).sort();
return allNodeTags.filter((nodeTag) => !tags.includes(nodeTag));
return existingTags?.filter((nodeTag) => !tags.includes(nodeTag)) || [];
}, [tags]);
return (
+6 -9
View File
@@ -10,7 +10,7 @@ import StatusCircle from '~/components/StatusCircle';
import Tooltip from '~/components/Tooltip';
import cn from '~/utils/cn';
import { getOSInfo, getTSVersion } from '~/utils/host-info';
import { mapNodes } from '~/utils/node-info';
import { mapNodes, sortNodeTags } from '~/utils/node-info';
import type { Route } from './+types/machine';
import { mapTagsToComponents, uiTagsForNode } from './components/machine-row';
import MenuOptions from './components/menu';
@@ -35,11 +35,8 @@ export async function loader({ request, params, context }: Route.LoaderArgs) {
}
const api = context.hsApi.getRuntimeClient(session.api_key);
const [node, users, allNodes] = await Promise.all([
api.getNode(params.id),
api.getUsers(),
api.getNodes(),
]);
const [nodes, users] = await Promise.all([api.getNodes(), api.getUsers()]);
const node = nodes.find((node) => node.id === params.id);
const lookup = await context.agents?.lookup([node.nodeKey]);
const [enhancedNode] = mapNodes([node], lookup);
@@ -54,14 +51,14 @@ export async function loader({ request, params, context }: Route.LoaderArgs) {
magic,
agent: context.agents?.agentID(),
stats: lookup?.[enhancedNode.nodeKey],
nodeList: allNodes,
existingTags: sortNodeTags(nodes),
};
}
export const action = machineAction;
export default function Page({
loaderData: { node, tags, users, magic, agent, stats, nodeList },
loaderData: { node, tags, users, magic, agent, stats, existingTags },
}: Route.ComponentProps) {
const [showRouting, setShowRouting] = useState(false);
@@ -90,10 +87,10 @@ export default function Page({
<StatusCircle className="w-4 h-4" isOnline={node.online} />
</span>
<MenuOptions
existingTags={existingTags}
isFullButton
magic={magic}
node={node}
nodeList={nodeList}
users={users}
/>
</div>
+2 -2
View File
@@ -4,7 +4,7 @@ import Link from '~/components/Link';
import Tooltip from '~/components/Tooltip';
import { Capabilities } from '~/server/web/roles';
import cn from '~/utils/cn';
import { mapNodes } from '~/utils/node-info';
import { mapNodes, sortNodeTags } from '~/utils/node-info';
import type { Route } from './+types/overview';
import MachineRow from './components/machine-row';
import NewMachine from './dialogs/new';
@@ -126,6 +126,7 @@ export default function Page({ loaderData }: Route.ComponentProps) {
>
{loaderData.populatedNodes.map((node) => (
<MachineRow
existingTags={sortNodeTags(loaderData.nodes)}
isAgent={
loaderData.agent ? loaderData.agent === node.nodeKey : undefined
}
@@ -138,7 +139,6 @@ export default function Page({ loaderData }: Route.ComponentProps) {
key={node.id}
magic={loaderData.magic}
node={node}
nodeList={loaderData.nodes}
users={loaderData.users}
/>
))}
+11
View File
@@ -52,3 +52,14 @@ export function mapNodes(
};
});
}
export function sortNodeTags(nodes: Machine[]): string[] {
return Array.from(
new Set(
nodes.flatMap(({ validTags, forcedTags }) => [
...validTags,
...forcedTags,
]),
),
).sort();
}