mirror of
https://github.com/tale/headplane.git
synced 2026-08-05 11:47:41 +00:00
feat: remove octicons icon pack
This commit is contained in:
@@ -21,7 +21,6 @@ export default function Code({ isCopyable, children, className }: CodeProps) {
|
||||
{children}
|
||||
{isCopyable && (
|
||||
<button
|
||||
type="button"
|
||||
className="bottom-0 right-0 absolute"
|
||||
onClick={async (event) => {
|
||||
const text = Array.isArray(children) ? children.join('') : children;
|
||||
@@ -40,6 +39,7 @@ export default function Code({ isCopyable, children, className }: CodeProps) {
|
||||
}
|
||||
}, 1000);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<Check className="h-4.5 w-4.5 p-1 hidden data-copied:block" />
|
||||
<Copy className="h-4.5 w-4.5 p-1 block data-copied:hidden" />
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { AlertIcon } from '@primer/octicons-react';
|
||||
import { AlertCircle } from 'lucide-react';
|
||||
import { isRouteErrorResponse, useRouteError } from 'react-router';
|
||||
import ResponseError from '~/server/headscale/api-error';
|
||||
import cn from '~/utils/cn';
|
||||
import Card from './Card';
|
||||
import Code from './Code';
|
||||
|
||||
interface Props {
|
||||
type?: 'full' | 'embedded';
|
||||
@@ -69,14 +70,16 @@ export function ErrorPopup({ type = 'full' }: Props) {
|
||||
)}
|
||||
>
|
||||
<Card>
|
||||
<div className="flex items-center justify-between">
|
||||
<Card.Title className="text-3xl mb-0">
|
||||
{routing ? error.status : title}
|
||||
</Card.Title>
|
||||
<AlertIcon className="w-12 h-12 text-red-500" />
|
||||
<div className="flex items-center gap-4">
|
||||
<AlertCircle className="w-8 h-8 text-red-500" />
|
||||
<div className="flex justify-between items-center gap-2 w-full">
|
||||
<Card.Title className="text-3xl mb-0">{title}</Card.Title>
|
||||
{routing && <Code className="text-2xl">{`${error.status}`}</Code>}
|
||||
</div>
|
||||
</div>
|
||||
<hr className="my-4 text-headplane-100 dark:text-headplane-800" />
|
||||
<Card.Text
|
||||
className={cn('mt-4 text-lg', routing ? 'font-normal' : 'font-mono')}
|
||||
className={cn('py-4 text-lg', routing ? 'font-normal' : 'font-mono')}
|
||||
>
|
||||
{routing ? error.data : message}
|
||||
</Card.Text>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RepoForkedIcon } from '@primer/octicons-react';
|
||||
import { Split } from 'lucide-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import Chip from '~/components/Chip';
|
||||
import Dialog from '~/components/Dialog';
|
||||
@@ -35,15 +35,15 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
<Dialog.Button>Add nameserver</Dialog.Button>
|
||||
<Dialog.Panel>
|
||||
<Dialog.Title className="mb-4">Add nameserver</Dialog.Title>
|
||||
<input type="hidden" name="action_id" value="add_ns" />
|
||||
<input name="action_id" type="hidden" value="add_ns" />
|
||||
<Input
|
||||
description="Use this IPv4 or IPv6 address to resolve names."
|
||||
isInvalid={isInvalid}
|
||||
isRequired
|
||||
label="Nameserver"
|
||||
description="Use this IPv4 or IPv6 address to resolve names."
|
||||
placeholder="1.2.3.4"
|
||||
name="ns"
|
||||
onChange={setNs}
|
||||
isInvalid={isInvalid}
|
||||
placeholder="1.2.3.4"
|
||||
/>
|
||||
<div className="flex items-center justify-between mt-8">
|
||||
<div className="block">
|
||||
@@ -53,9 +53,9 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
</Dialog.Text>
|
||||
<Tooltip>
|
||||
<Chip
|
||||
text="Split DNS"
|
||||
leftIcon={<RepoForkedIcon className="w-4 h-4 mr-0.5" />}
|
||||
className={cn('inline-flex items-center')}
|
||||
leftIcon={<Split className="w-3 h-3 mr-0.5" />}
|
||||
text="Split DNS"
|
||||
/>
|
||||
<Tooltip.Body>
|
||||
Only clients that support split DNS (Tailscale v1.8 or later
|
||||
@@ -76,9 +76,9 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
<Input
|
||||
isRequired={split === true}
|
||||
label="Domain"
|
||||
placeholder="example.com"
|
||||
name="split_name"
|
||||
onChange={setDomain}
|
||||
placeholder="example.com"
|
||||
/>
|
||||
<Dialog.Text className="text-sm">
|
||||
Only single-label or fully-qualified queries matching this suffix
|
||||
@@ -86,7 +86,7 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
</Dialog.Text>
|
||||
</>
|
||||
) : (
|
||||
<input type="hidden" name="split_name" value="global" />
|
||||
<input name="split_name" type="hidden" value="global" />
|
||||
)}
|
||||
</Dialog.Panel>
|
||||
</Dialog>
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { ChevronDownIcon, CopyIcon } from '@primer/octicons-react';
|
||||
import { ChevronDown, Copy } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import Chip from '~/components/Chip';
|
||||
import Menu from '~/components/Menu';
|
||||
import StatusCircle from '~/components/StatusCircle';
|
||||
import type { User } from '~/types';
|
||||
import cn from '~/utils/cn';
|
||||
import * as hinfo from '~/utils/host-info';
|
||||
|
||||
import { ExitNodeTag } from '~/components/tags/ExitNode';
|
||||
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 { User } from '~/types';
|
||||
import cn from '~/utils/cn';
|
||||
import * as hinfo from '~/utils/host-info';
|
||||
import { PopulatedNode } from '~/utils/node-info';
|
||||
import toast from '~/utils/toast';
|
||||
import MenuOptions from './menu';
|
||||
@@ -47,13 +46,13 @@ export default function MachineRow({
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={node.id}
|
||||
className="group hover:bg-headplane-50 dark:hover:bg-headplane-950"
|
||||
key={node.id}
|
||||
>
|
||||
<td className="pl-0.5 py-2 focus-within:ring-3">
|
||||
<Link
|
||||
to={`/machines/${node.id}`}
|
||||
className={cn('group/link h-full focus:outline-hidden')}
|
||||
to={`/machines/${node.id}`}
|
||||
>
|
||||
<p
|
||||
className={cn(
|
||||
@@ -80,7 +79,7 @@ export default function MachineRow({
|
||||
{node.ipAddresses[0]}
|
||||
<Menu placement="bottom end">
|
||||
<Menu.IconButton className="bg-transparent" label="IP Addresses">
|
||||
<ChevronDownIcon className="w-4 h-4" />
|
||||
<ChevronDown className="w-4 h-4" />
|
||||
</Menu.IconButton>
|
||||
<Menu.Panel
|
||||
onAction={async (key) => {
|
||||
@@ -98,7 +97,7 @@ export default function MachineRow({
|
||||
)}
|
||||
>
|
||||
{ip}
|
||||
<CopyIcon className="w-3 h-3" />
|
||||
<Copy className="w-3 h-3" />
|
||||
</div>
|
||||
</Menu.Item>
|
||||
))}
|
||||
@@ -132,8 +131,8 @@ export default function MachineRow({
|
||||
)}
|
||||
>
|
||||
<StatusCircle
|
||||
isOnline={node.online && !node.expired}
|
||||
className="w-4 h-4"
|
||||
isOnline={node.online && !node.expired}
|
||||
/>
|
||||
<p suppressHydrationWarning>
|
||||
{node.online && !node.expired
|
||||
@@ -144,10 +143,10 @@ export default function MachineRow({
|
||||
</td>
|
||||
<td className="py-2 pr-0.5">
|
||||
<MenuOptions
|
||||
isDisabled={isDisabled}
|
||||
magic={magic}
|
||||
node={node}
|
||||
users={users}
|
||||
magic={magic}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -194,30 +193,30 @@ export function mapTagsToComponents(node: PopulatedNode, uiTags: string[]) {
|
||||
switch (tag) {
|
||||
case 'exit-approved':
|
||||
case 'exit-waiting':
|
||||
return <ExitNodeTag key={tag} isEnabled={tag === 'exit-approved'} />;
|
||||
return <ExitNodeTag isEnabled={tag === 'exit-approved'} key={tag} />;
|
||||
|
||||
case 'subnet-approved':
|
||||
case 'subnet-waiting':
|
||||
return <SubnetTag key={tag} isEnabled={tag === 'subnet-approved'} />;
|
||||
return <SubnetTag isEnabled={tag === 'subnet-approved'} key={tag} />;
|
||||
|
||||
case 'expired':
|
||||
case 'no-expiry':
|
||||
return (
|
||||
<ExpiryTag
|
||||
expiry={node.expiry ?? undefined}
|
||||
key={tag}
|
||||
variant={tag}
|
||||
expiry={node.expiry ?? undefined}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'tailscale-ssh':
|
||||
return <TailscaleSSHTag />;
|
||||
return <TailscaleSSHTag key={tag} />;
|
||||
|
||||
case 'headplane-agent':
|
||||
return <HeadplaneAgentTag />;
|
||||
return <HeadplaneAgentTag key={tag} />;
|
||||
|
||||
default:
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InfoIcon } from '@primer/octicons-react';
|
||||
import { Info } from 'lucide-react';
|
||||
import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router';
|
||||
import { useLoaderData } from 'react-router';
|
||||
import Code from '~/components/Code';
|
||||
@@ -110,7 +110,7 @@ export default function Page() {
|
||||
<p className="uppercase text-xs font-bold">Addresses</p>
|
||||
{data.magic ? (
|
||||
<Tooltip>
|
||||
<InfoIcon className="w-4 h-4" />
|
||||
<Info className="w-4 h-4" />
|
||||
<Tooltip.Body className="font-normal">
|
||||
Since MagicDNS is enabled, you can access devices based on
|
||||
their name and also at{' '}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { ArrowRightIcon } from '@primer/octicons-react';
|
||||
import { Link as RemixLink } from 'react-router';
|
||||
import Button from '~/components/Button';
|
||||
import Link from '~/components/Link';
|
||||
import cn from '~/utils/cn';
|
||||
|
||||
export default function AgentSection() {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col w-2/3">
|
||||
<h1 className="text-2xl font-medium mb-4">Local Agent</h1>
|
||||
<p>
|
||||
Headplane provides a local agent that can be installed on a server to
|
||||
provide additional features including viewing device information and
|
||||
SSH access via the web interface (soon). To learn more about the agent
|
||||
visit the{' '}
|
||||
<Link
|
||||
to="https://github.com/tale/headplane/blob/main/docs/Headplane-Agent.md"
|
||||
name="Headplane Agent Documentation"
|
||||
>
|
||||
Headplane documentation
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
<RemixLink to="/settings/local-agent">
|
||||
<div className={cn('text-lg font-medium flex items-center')}>
|
||||
Manage Agent
|
||||
<ArrowRightIcon className="w-5 h-5 ml-2" />
|
||||
</div>
|
||||
</RemixLink>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import Card from '~/components/Card';
|
||||
import StatusCircle from '~/components/StatusCircle';
|
||||
import type { HostInfo } from '~/types';
|
||||
import * as hinfo from '~/utils/host-info';
|
||||
|
||||
export type Props = {
|
||||
reachable: boolean;
|
||||
hostInfo: HostInfo;
|
||||
};
|
||||
|
||||
export default function AgentManagement({ reachable, hostInfo }: Props) {
|
||||
console.log('hostInfo:', hostInfo);
|
||||
return (
|
||||
<div className="flex flex-col w-2/3">
|
||||
<h1 className="text-2xl font-medium mb-4">Local Agent Configuration</h1>
|
||||
<p className="mb-8">
|
||||
A local agent has already been configured for this Headplane instance.
|
||||
You can manage the agent settings here.
|
||||
</p>
|
||||
<Card>
|
||||
<div className="flex items-center gap-2">
|
||||
<StatusCircle isOnline={reachable} className="w-4 h-4 px-1" />
|
||||
<div>
|
||||
<p className="text-lg font-bold">
|
||||
{hostInfo.Hostname ?? 'Unknown'}
|
||||
</p>
|
||||
<p className="leading-snug">
|
||||
{hinfo.getTSVersion(hostInfo)}
|
||||
<span className="ml-2 text-sm text-headplane-600 dark:text-headplane-300">
|
||||
{hinfo.getOSInfo(hostInfo)}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{JSON.stringify(hostInfo)}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ArrowRightIcon } from '@primer/octicons-react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import {
|
||||
LoaderFunctionArgs,
|
||||
Link as RemixLink,
|
||||
@@ -34,8 +34,8 @@ export default function Page() {
|
||||
add devices to your Tailnet. To learn more about using
|
||||
pre-authentication keys, visit the{' '}
|
||||
<Link
|
||||
to="https://tailscale.com/kb/1085/auth-keys/"
|
||||
name="Tailscale Auth Keys documentation"
|
||||
to="https://tailscale.com/kb/1085/auth-keys/"
|
||||
>
|
||||
Tailscale documentation
|
||||
</Link>
|
||||
@@ -44,7 +44,7 @@ export default function Page() {
|
||||
<RemixLink to="/settings/auth-keys">
|
||||
<div className="text-lg font-medium flex items-center">
|
||||
Manage Auth Keys
|
||||
<ArrowRightIcon className="w-5 h-5 ml-2" />
|
||||
<ArrowRight className="w-5 h-5 ml-2" />
|
||||
</div>
|
||||
</RemixLink>
|
||||
{config && oidc ? (
|
||||
@@ -60,8 +60,8 @@ export default function Page() {
|
||||
groups and Headplane will also respect these settings when
|
||||
authenticating.{' '}
|
||||
<Link
|
||||
to="https://headscale.net/stable/ref/oidc/#basic-configuration"
|
||||
name="Headscale OIDC documentation"
|
||||
to="https://headscale.net/stable/ref/oidc/#basic-configuration"
|
||||
>
|
||||
Learn More
|
||||
</Link>
|
||||
@@ -70,7 +70,7 @@ export default function Page() {
|
||||
<RemixLink to="/settings/restrictions">
|
||||
<div className="text-lg font-medium flex items-center">
|
||||
Manage Restrictions
|
||||
<ArrowRightIcon className="w-5 h-5 ml-2" />
|
||||
<ArrowRight className="w-5 h-5 ml-2" />
|
||||
</div>
|
||||
</RemixLink>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user