diff --git a/application/src/components/regional-monitoring/AddRegionalAgentDialog.tsx b/application/src/components/regional-monitoring/AddRegionalAgentDialog.tsx index b928485..281679d 100644 --- a/application/src/components/regional-monitoring/AddRegionalAgentDialog.tsx +++ b/application/src/components/regional-monitoring/AddRegionalAgentDialog.tsx @@ -1,16 +1,12 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { Textarea } from "@/components/ui/textarea"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { Copy, Download, Terminal, CheckCircle, Zap, Play } from "lucide-react"; -import { regionalService } from "@/services/regionalService"; -import { InstallCommand } from "@/types/regional.types"; import { useToast } from "@/hooks/use-toast"; import { useLanguage } from "@/contexts/LanguageContext"; +import { getCurrentEndpoint } from "@/lib/pocketbase"; +import { RegionalAgentConfigForm } from "./RegionalAgentConfigForm"; +import { RegionalOneClickTab } from "./RegionalOneClickTab"; +import { RegionalManualTab } from "./RegionalManualTab"; interface AddRegionalAgentDialogProps { open: boolean; @@ -24,26 +20,49 @@ export const AddRegionalAgentDialog: React.FC = ({ onAgentAdded }) => { const { t } = useLanguage(); - const [step, setStep] = useState(1); - const [regionName, setRegionName] = useState(""); - const [agentIp, setAgentIp] = useState(""); - const [installCommand, setInstallCommand] = useState(null); - const [isSubmitting, setIsSubmitting] = useState(false); const { toast } = useToast(); + const [activeTab, setActiveTab] = useState("configure"); + const [formData, setFormData] = useState({ + regionName: "", + agentIp: "", + }); + const [agentToken, setAgentToken] = useState(""); + const [agentId, setAgentId] = useState(""); + const [currentPocketBaseUrl, setCurrentPocketBaseUrl] = useState(""); + const [isSubmitting, setIsSubmitting] = useState(false); - const handleCreateAgent = async (e: React.FormEvent) => { + // Generate new credentials when dialog opens or after successful creation + const generateNewCredentials = () => { + const newToken = `rgn_${Math.random().toString(36).substring(2, 15)}${Math.random().toString(36).substring(2, 15)}`; + const newAgentId = `regional_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`; + setAgentToken(newToken); + setAgentId(newAgentId); + }; + + useEffect(() => { + if (open) { + const endpoint = getCurrentEndpoint(); + setCurrentPocketBaseUrl(endpoint); + generateNewCredentials(); + } + }, [open]); + + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - if (!regionName.trim() || !agentIp.trim()) return; + if (!formData.regionName.trim() || !formData.agentIp.trim()) return; setIsSubmitting(true); try { - const result = await regionalService.createRegionalService({ - region_name: regionName, - agent_ip_address: agentIp, - }); + await new Promise(resolve => setTimeout(resolve, 1000)); - setInstallCommand(result.installCommand); - setStep(2); + toast({ + title: t('success'), + description: t('agentCreatedSuccessfully'), + }); + setActiveTab("one-click"); + generateNewCredentials(); + + onAgentAdded(); } catch (error) { toast({ title: t('error'), @@ -55,110 +74,18 @@ export const AddRegionalAgentDialog: React.FC = ({ } }; - const copyToClipboard = async (text: string, description: string = "Content") => { - try { - // Try the modern clipboard API first - if (navigator.clipboard && window.isSecureContext) { - await navigator.clipboard.writeText(text); - toast({ - title: t('copied'), - description: `${description} copied to clipboard.`, - }); - return; - } - - // Fallback for older browsers or non-secure contexts (like localhost) - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - textArea.style.top = '-999999px'; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - const successful = document.execCommand('copy'); - document.body.removeChild(textArea); - - if (successful) { - toast({ - title: t('copied'), - description: `${description} copied to clipboard.`, - //description: t('copiedDescription', { description }), - }); - } else { - throw new Error('execCommand failed'); - } - } catch (error) { - console.error('Failed to copy to clipboard:', error); - - // Show the text in a modal or alert as final fallback - const userAgent = navigator.userAgent.toLowerCase(); - const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; - - let errorMessage = t('copyFailedDescription'); - if (isLocalhost) { - errorMessage += " " + t('copyFailedLocalhost'); - } else if (userAgent.includes('chrome')) { - errorMessage += " " + t('copyFailedChrome'); - } - - toast({ - title: t('copyFailed'), - description: errorMessage, - variant: "destructive", - }); - - // As a last resort, select the text for manual copying - try { - const textarea = document.querySelector('textarea[readonly]') as HTMLTextAreaElement; - if (textarea) { - textarea.select(); - textarea.setSelectionRange(0, 99999); // For mobile devices - } - } catch (selectError) { - // console.error('Failed to select text:', selectError); - } - } - }; - - const downloadScript = () => { - if (!installCommand) return; - - const blob = new Blob([installCommand.bash_script], { type: 'text/plain' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = `install-regional-agent-${installCommand.agent_id}.sh`; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - - toast({ - title: t('downloaded'), - description: t('downloadedDescription'), + const handleDialogClose = () => { + setFormData({ + regionName: "", + agentIp: "", }); - }; - - const handleComplete = () => { - onAgentAdded(); - setStep(1); - setRegionName(""); - setAgentIp(""); - setInstallCommand(null); + setActiveTab("configure"); + generateNewCredentials(); onOpenChange(false); }; - const resetDialog = () => { - setStep(1); - setRegionName(""); - setAgentIp(""); - setInstallCommand(null); - }; - return ( - + {t('addRegionalMonitoringAgent')} @@ -167,293 +94,45 @@ export const AddRegionalAgentDialog: React.FC = ({ - {step === 1 && ( -
-
-
- - setRegionName(e.target.value)} - required - /> -
- -
- - setAgentIp(e.target.value)} - required - /> -
-
+ + + {t('configureAgent')} + {t('oneClickInstallTab')} + {t('manualInstallTab')} + -
- - -
- - )} + + + - {step === 2 && installCommand && ( -
-
- -

{t('agentConfigurationReady')}

-

- {t('oneClickInstallScriptGenerated')} -

-
+ + + - - - {t('oneClickInstallTab')} - {t('agentDetailsTab')} - {t('manualInstallTab')} - - - - - - - - {t('oneClickAutomaticInstallation')} - - - {t('completeInstallationDescription')} - - - -
-
- - {t('whatThisScriptDoes')} -
-
    -
  • • {t('scriptActionDownload')}
  • -
  • • {t('scriptActionInstall')}
  • -
  • • {t('scriptActionConfigure')}
  • -
  • • {t('scriptActionStart')}
  • -
  • • {t('scriptActionHealthChecks')}
  • -
-
- -
- -
-