style: replace emojis with text indicators in UI components
- SecurityWarning: replace emoji icons with text-based indicators - NodeModal: minor formatting cleanup
This commit is contained in:
parent
7eb6d33dad
commit
7891027d55
2 changed files with 81 additions and 87 deletions
|
|
@ -92,11 +92,11 @@ export const SecurityWarning: Component = () => {
|
||||||
return 'text-red-600 dark:text-red-400';
|
return 'text-red-600 dark:text-red-400';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getScoreEmoji = (score: number, max: number) => {
|
const getScoreIcon = (score: number, max: number) => {
|
||||||
const percentage = (score / max) * 100;
|
const percentage = (score / max) * 100;
|
||||||
if (percentage >= 80) return '🛡️';
|
if (percentage >= 80) return 'shield';
|
||||||
if (percentage >= 60) return '⚠️';
|
if (percentage >= 60) return 'warning';
|
||||||
return '🚨';
|
return 'alert';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show more aggressively if public access detected
|
// Show more aggressively if public access detected
|
||||||
|
|
@ -120,16 +120,17 @@ export const SecurityWarning: Component = () => {
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<div
|
<div
|
||||||
class={`fixed top-0 left-0 right-0 z-50 border-b shadow-sm ${
|
class={`fixed top-0 left-0 right-0 z-50 border-b shadow-sm ${status()!.publicAccess && !status()!.hasAuthentication
|
||||||
status()!.publicAccess && !status()!.hasAuthentication
|
|
||||||
? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'
|
? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'
|
||||||
: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800'
|
: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div class="max-w-7xl mx-auto px-4 py-3">
|
<div class="max-w-7xl mx-auto px-4 py-3">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<span class="text-2xl">{getScoreEmoji(status()!.score, status()!.maxScore)}</span>
|
<span class={`text-2xl ${getScoreIcon(status()!.score, status()!.maxScore) === 'shield' ? 'text-green-600' : getScoreIcon(status()!.score, status()!.maxScore) === 'warning' ? 'text-yellow-600' : 'text-red-600'}`}>
|
||||||
|
{getScoreIcon(status()!.score, status()!.maxScore) === 'shield' ? '✓' : getScoreIcon(status()!.score, status()!.maxScore) === 'warning' ? '!' : '!!'}
|
||||||
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<SectionHeader
|
<SectionHeader
|
||||||
|
|
@ -157,7 +158,7 @@ export const SecurityWarning: Component = () => {
|
||||||
<p class="text-sm text-gray-700 dark:text-gray-300 mt-1">
|
<p class="text-sm text-gray-700 dark:text-gray-300 mt-1">
|
||||||
{status()!.publicAccess ? (
|
{status()!.publicAccess ? (
|
||||||
<span class="font-semibold text-red-700 dark:text-red-300">
|
<span class="font-semibold text-red-700 dark:text-red-300">
|
||||||
⚠️ PUBLIC NETWORK ACCESS DETECTED - Your Proxmox credentials are exposed to
|
WARNING: PUBLIC NETWORK ACCESS DETECTED - Your Proxmox credentials are exposed to
|
||||||
the internet!
|
the internet!
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -172,13 +173,13 @@ export const SecurityWarning: Component = () => {
|
||||||
<span
|
<span
|
||||||
class={status()!.credentialsEncrypted ? 'text-green-600' : 'text-red-600'}
|
class={status()!.credentialsEncrypted ? 'text-green-600' : 'text-red-600'}
|
||||||
>
|
>
|
||||||
{status()!.credentialsEncrypted ? '✅' : '❌'}
|
{status()!.credentialsEncrypted ? 'Yes' : 'No'}
|
||||||
</span>
|
</span>
|
||||||
<span>Credentials encrypted at rest</span>
|
<span>Credentials encrypted at rest</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class={status()!.exportProtected ? 'text-green-600' : 'text-red-600'}>
|
<span class={status()!.exportProtected ? 'text-green-600' : 'text-red-600'}>
|
||||||
{status()!.exportProtected ? '✅' : '❌'}
|
{status()!.exportProtected ? 'Yes' : 'No'}
|
||||||
</span>
|
</span>
|
||||||
<span>Export requires authentication</span>
|
<span>Export requires authentication</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -186,19 +187,19 @@ export const SecurityWarning: Component = () => {
|
||||||
<span
|
<span
|
||||||
class={status()!.hasAuthentication ? 'text-green-600' : 'text-red-600'}
|
class={status()!.hasAuthentication ? 'text-green-600' : 'text-red-600'}
|
||||||
>
|
>
|
||||||
{status()!.hasAuthentication ? '✅' : '❌'}
|
{status()!.hasAuthentication ? 'Yes' : 'No'}
|
||||||
</span>
|
</span>
|
||||||
<span>Authentication enabled</span>
|
<span>Authentication enabled</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class={status()!.hasHTTPS ? 'text-green-600' : 'text-red-600'}>
|
<span class={status()!.hasHTTPS ? 'text-green-600' : 'text-red-600'}>
|
||||||
{status()!.hasHTTPS ? '✅' : '❌'}
|
{status()!.hasHTTPS ? 'Yes' : 'No'}
|
||||||
</span>
|
</span>
|
||||||
<span>HTTPS connection</span>
|
<span>HTTPS connection</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class={status()!.hasAuditLogging ? 'text-green-600' : 'text-red-600'}>
|
<span class={status()!.hasAuditLogging ? 'text-green-600' : 'text-red-600'}>
|
||||||
{status()!.hasAuditLogging ? '✅' : '❌'}
|
{status()!.hasAuditLogging ? 'Yes' : 'No'}
|
||||||
</span>
|
</span>
|
||||||
<span>Audit logging enabled</span>
|
<span>Audit logging enabled</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,15 @@ interface NodeModalProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TemperatureTransportDetail = {
|
type TemperatureTransportDetail = {
|
||||||
tone: 'info' | 'success' | 'warning' | 'danger';
|
tone: 'info' | 'success' | 'warning' | 'danger';
|
||||||
message: string;
|
message: string;
|
||||||
disable?: boolean;
|
disable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ProxyInstallResponse {
|
interface ProxyInstallResponse {
|
||||||
command: string;
|
command: string;
|
||||||
pulseURL: string;
|
pulseURL: string;
|
||||||
node?: string;
|
node?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deriveNameFromHost = (host: string): string => {
|
const deriveNameFromHost = (host: string): string => {
|
||||||
|
|
@ -280,11 +280,11 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
const pmgConfig =
|
const pmgConfig =
|
||||||
node.type === 'pmg'
|
node.type === 'pmg'
|
||||||
? (node as NodeConfig & {
|
? (node as NodeConfig & {
|
||||||
monitorMailStats?: boolean;
|
monitorMailStats?: boolean;
|
||||||
monitorQueues?: boolean;
|
monitorQueues?: boolean;
|
||||||
monitorQuarantine?: boolean;
|
monitorQuarantine?: boolean;
|
||||||
monitorDomainStats?: boolean;
|
monitorDomainStats?: boolean;
|
||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const formSource: ReturnType<typeof getCleanFormData> = {
|
const formSource: ReturnType<typeof getCleanFormData> = {
|
||||||
|
|
@ -776,11 +776,10 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'agent')}
|
onClick={() => updateField('setupMode', 'agent')}
|
||||||
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'agent'
|
||||||
formData().setupMode === 'agent'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
Agent Install
|
Agent Install
|
||||||
<span class="ml-1.5 px-1.5 py-0.5 text-[10px] font-semibold bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 rounded">
|
<span class="ml-1.5 px-1.5 py-0.5 text-[10px] font-semibold bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 rounded">
|
||||||
|
|
@ -790,22 +789,20 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'auto')}
|
onClick={() => updateField('setupMode', 'auto')}
|
||||||
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'auto'
|
||||||
formData().setupMode === 'auto'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
API Only
|
API Only
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'manual')}
|
onClick={() => updateField('setupMode', 'manual')}
|
||||||
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'manual'
|
||||||
formData().setupMode === 'manual'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
Manual
|
Manual
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -1007,7 +1004,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
<code class="text-blue-400">
|
<code class="text-blue-400">
|
||||||
{formData().host
|
{formData().host
|
||||||
? 'Click the button above to copy the setup command'
|
? 'Click the button above to copy the setup command'
|
||||||
: '⚠️ Please enter the Host URL above first'}
|
: 'Please enter the Host URL above first'}
|
||||||
</code>
|
</code>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -1153,7 +1150,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="text-xs text-green-600 dark:text-green-400 mt-2 font-semibold">
|
<p class="text-xs text-green-600 dark:text-green-400 mt-2 font-semibold">
|
||||||
✨ Fully automatic - no manual token copying needed!
|
Fully automatic - no manual token copying needed!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
@ -1252,7 +1249,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-amber-600 dark:text-amber-400 text-xs mt-1">
|
<p class="text-amber-600 dark:text-amber-400 text-xs mt-1">
|
||||||
⚠️ Copy the token value immediately - it won't be shown again!
|
Important: Copy the token value immediately - it won't be shown again!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1337,7 +1334,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-gray-600 dark:text-gray-400 text-xs mt-1">
|
<p class="text-gray-600 dark:text-gray-400 text-xs mt-1">
|
||||||
ℹ️ PVEAuditor gives read-only API access. PulseMonitor adds
|
Note: PVEAuditor gives read-only API access. PulseMonitor adds
|
||||||
Sys.Audit plus either VM.Monitor (PVE 8) or VM.GuestAgent.Audit
|
Sys.Audit plus either VM.Monitor (PVE 8) or VM.GuestAgent.Audit
|
||||||
(PVE 9+) for disk and guest metrics. PVEDatastoreAdmin on
|
(PVE 9+) for disk and guest metrics. PVEDatastoreAdmin on
|
||||||
/storage adds backup visibility.
|
/storage adds backup visibility.
|
||||||
|
|
@ -1374,11 +1371,10 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'agent')}
|
onClick={() => updateField('setupMode', 'agent')}
|
||||||
class={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'agent'
|
||||||
formData().setupMode === 'agent'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
Agent Install
|
Agent Install
|
||||||
<span class="text-[10px] px-1.5 py-0.5 bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 rounded">Recommended</span>
|
<span class="text-[10px] px-1.5 py-0.5 bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 rounded">Recommended</span>
|
||||||
|
|
@ -1386,22 +1382,20 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'auto')}
|
onClick={() => updateField('setupMode', 'auto')}
|
||||||
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'auto'
|
||||||
formData().setupMode === 'auto'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
API Only
|
API Only
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => updateField('setupMode', 'manual')}
|
onClick={() => updateField('setupMode', 'manual')}
|
||||||
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${
|
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'manual'
|
||||||
formData().setupMode === 'manual'
|
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
||||||
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
|
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
Manual Setup
|
Manual Setup
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -1931,30 +1925,30 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<Show when={props.nodeType === 'pmg'}>
|
||||||
|
<div class="space-y-3 text-xs text-gray-700 dark:text-gray-200">
|
||||||
|
<p>
|
||||||
|
Generate a dedicated API token in <strong>Configuration → API Tokens</strong> on your
|
||||||
|
Mail Gateway. We recommend creating a service user such as <code class="font-mono">pulse-monitor@pmg</code>
|
||||||
|
with <em>Auditor</em> privileges.
|
||||||
|
</p>
|
||||||
|
<ol class="list-decimal ml-4 space-y-1">
|
||||||
|
<li>Click <em>Add</em> and choose the service user (or create one if needed).</li>
|
||||||
|
<li>Enable <em>Privilege Separation</em> and assign the <em>Auditor</em> role.</li>
|
||||||
|
<li>Copy the generated Token ID (e.g. <code class="font-mono">pulse-monitor@pmg!pulse-edge</code>) and the secret value into the fields below.</li>
|
||||||
|
</ol>
|
||||||
|
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
Pulse only requires read-only access. Avoid granting administrator permissions to the token.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
|
||||||
<Show when={props.nodeType === 'pmg'}>
|
|
||||||
<div class="space-y-3 text-xs text-gray-700 dark:text-gray-200">
|
|
||||||
<p>
|
|
||||||
Generate a dedicated API token in <strong>Configuration → API Tokens</strong> on your
|
|
||||||
Mail Gateway. We recommend creating a service user such as <code class="font-mono">pulse-monitor@pmg</code>
|
|
||||||
with <em>Auditor</em> privileges.
|
|
||||||
</p>
|
|
||||||
<ol class="list-decimal ml-4 space-y-1">
|
|
||||||
<li>Click <em>Add</em> and choose the service user (or create one if needed).</li>
|
|
||||||
<li>Enable <em>Privilege Separation</em> and assign the <em>Auditor</em> role.</li>
|
|
||||||
<li>Copy the generated Token ID (e.g. <code class="font-mono">pulse-monitor@pmg!pulse-edge</code>) and the secret value into the fields below.</li>
|
|
||||||
</ol>
|
|
||||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
|
||||||
Pulse only requires read-only access. Avoid granting administrator permissions to the token.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Token Input Fields */}
|
{/* Token Input Fields */}
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<div class={formField}>
|
<div class={formField}>
|
||||||
<label class={labelClass()}>
|
<label class={labelClass()}>
|
||||||
Token ID <span class="text-red-500">*</span>
|
Token ID <span class="text-red-500">*</span>
|
||||||
|
|
@ -2261,13 +2255,12 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
|
||||||
return null;
|
return null;
|
||||||
})()}
|
})()}
|
||||||
<div
|
<div
|
||||||
class={`mx-6 p-3 rounded-lg text-sm ${
|
class={`mx-6 p-3 rounded-lg text-sm ${testResult()?.status === 'success'
|
||||||
testResult()?.status === 'success'
|
? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
|
||||||
? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
|
: testResult()?.status === 'warning'
|
||||||
: testResult()?.status === 'warning'
|
? 'bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 text-amber-800 dark:text-amber-200'
|
||||||
? 'bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 text-amber-800 dark:text-amber-200'
|
: 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
|
||||||
: 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div class="flex items-start gap-2">
|
<div class="flex items-start gap-2">
|
||||||
<Show when={testResult()?.status === 'success'}>
|
<Show when={testResult()?.status === 'success'}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue