diff --git a/app/(protected)/tunnels/[id]/page.tsx b/app/(protected)/tunnels/[id]/page.tsx
index 9354e5cc..4122b722 100644
--- a/app/(protected)/tunnels/[id]/page.tsx
+++ b/app/(protected)/tunnels/[id]/page.tsx
@@ -13,6 +13,7 @@ import {
import { InteractionContextType, useInteractionContext } from '@lib/contexts/interaction';
import { TunnelsContextType, useTunnelsContext } from '@lib/contexts/tunnels';
import { routePath } from '@lib/routes/route-paths';
+import { tunnelStatusTagVariantByStatus } from '@lib/tunnel-status';
import ActionButton from '@shared/ActionButton';
import { CompactCustomCard } from '@shared/cards/CompactCustomCard';
import { CopyableValue } from '@shared/CopyableValue';
@@ -266,24 +267,6 @@ export default function TunnelPage() {
}
};
- const getStatusTagVariant = () => {
- if (!tunnel) {
- return 'slate';
- }
-
- switch (tunnel.status) {
- case 'healthy':
- return 'green';
- case 'degraded':
- return 'yellow';
- case 'down':
- return 'red';
-
- default:
- return 'slate';
- }
- };
-
if (!tunnel) {
return (
@@ -313,7 +296,7 @@ export default function TunnelPage() {
{tunnel.alias}
-
+
{tunnel.status}
diff --git a/src/components/create-job/sections/AppParametersSection.tsx b/src/components/create-job/sections/AppParametersSection.tsx
index 53410229..b06aaefe 100644
--- a/src/components/create-job/sections/AppParametersSection.tsx
+++ b/src/components/create-job/sections/AppParametersSection.tsx
@@ -5,6 +5,7 @@ import { SelectItem } from '@heroui/select';
import { BOOLEAN_TYPES } from '@data/booleanTypes';
import { getTunnels } from '@lib/api/tunnels';
import { TunnelsContextType, useTunnelsContext } from '@lib/contexts/tunnels';
+import { compareTunnelStatusAndAlias, tunnelStatusDotColorClassByStatus, type TunnelStatus } from '@lib/tunnel-status';
import InputWithLabel from '@shared/InputWithLabel';
import Label from '@shared/Label';
import DeeployInfoTag from '@shared/jobs/DeeployInfoTag';
@@ -25,12 +26,20 @@ type ExistingTunnelOption = {
alias: string;
token: string;
url: string;
+ status: TunnelStatus;
+ isCustom?: false;
};
-type TunnelSelectOption = ExistingTunnelOption & {
- isCustom?: boolean;
+type CustomTunnelOption = {
+ id: string;
+ alias: string;
+ token: string;
+ url: string;
+ isCustom: true;
};
+type TunnelSelectOption = ExistingTunnelOption | CustomTunnelOption;
+
const CUSTOM_TUNNEL_OPTION = 'custom';
export default function AppParametersSection({
@@ -102,8 +111,9 @@ export default function AppParametersSection({
alias: (tunnel.metadata.alias || tunnel.metadata.dns_name) as string,
token: tunnel.metadata.tunnel_token as string,
url: tunnel.metadata.dns_name as string,
+ status: tunnel.status as TunnelStatus,
}))
- .sort((a, b) => a.alias.localeCompare(b.alias));
+ .sort(compareTunnelStatusAndAlias);
setExistingTunnels(tunnels);
return tunnels;
@@ -240,6 +250,17 @@ export default function AppParametersSection({
}}
placeholder={isFetchingTunnels ? 'Loading tunnels...' : 'Select an existing tunnel'}
isDisabled={isFetchingTunnels}
+ renderValue={(items) => {
+ return items.map((item) => {
+ const tunnel = item.data as TunnelSelectOption | undefined;
+
+ if (!tunnel) {
+ return
{item.textValue}
;
+ }
+
+ return
;
+ });
+ }}
>
{(option: object) => {
const tunnel = option as TunnelSelectOption;
@@ -249,10 +270,7 @@ export default function AppParametersSection({
key={tunnel.id}
textValue={tunnel.isCustom ? tunnel.alias : `${tunnel.alias} | ${tunnel.url}`}
>
-
-
{tunnel.alias}
-
{tunnel.url}
-
+
);
}}
@@ -313,3 +331,28 @@ export default function AppParametersSection({
);
}
+
+function TunnelSelectOptionContent({ tunnel }: { tunnel: TunnelSelectOption }) {
+ if (tunnel.isCustom) {
+ return (
+