mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-09 16:37:29 +00:00
fix(frontend): add missing explicit types for button elems
This commit is contained in:
@@ -75,6 +75,7 @@ const SortableCardItem = ({ card, onToggle }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => onToggle(card.cardId)}
|
onClick={() => onToggle(card.cardId)}
|
||||||
className={`flex items-center gap-1 px-2 py-1 rounded text-xs font-medium transition-colors ${
|
className={`flex items-center gap-1 px-2 py-1 rounded text-xs font-medium transition-colors ${
|
||||||
card.enabled
|
card.enabled
|
||||||
@@ -271,6 +272,7 @@ const DashboardSettingsModal = ({ isOpen, onClose }) => {
|
|||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -314,6 +316,7 @@ const DashboardSettingsModal = ({ isOpen, onClose }) => {
|
|||||||
|
|
||||||
<div className="bg-secondary-50 dark:bg-secondary-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
<div className="bg-secondary-50 dark:bg-secondary-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
disabled={!hasChanges || updatePreferencesMutation.isPending}
|
disabled={!hasChanges || updatePreferencesMutation.isPending}
|
||||||
className={`w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium text-white sm:ml-3 sm:w-auto sm:text-sm ${
|
className={`w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium text-white sm:ml-3 sm:w-auto sm:text-sm ${
|
||||||
@@ -336,6 +339,7 @@ const DashboardSettingsModal = ({ isOpen, onClose }) => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
className="mt-3 w-full inline-flex justify-center rounded-md border border-secondary-300 dark:border-secondary-600 shadow-sm px-4 py-2 bg-white dark:bg-secondary-800 text-base font-medium text-secondary-700 dark:text-secondary-200 hover:bg-secondary-50 dark:hover:bg-secondary-700 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
className="mt-3 w-full inline-flex justify-center rounded-md border border-secondary-300 dark:border-secondary-600 shadow-sm px-4 py-2 bg-white dark:bg-secondary-800 text-base font-medium text-secondary-700 dark:text-secondary-200 hover:bg-secondary-50 dark:hover:bg-secondary-700 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
>
|
>
|
||||||
@@ -344,6 +348,7 @@ const DashboardSettingsModal = ({ isOpen, onClose }) => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="mt-3 w-full inline-flex justify-center rounded-md border border-secondary-300 dark:border-secondary-600 shadow-sm px-4 py-2 bg-white dark:bg-secondary-800 text-base font-medium text-secondary-700 dark:text-secondary-200 hover:bg-secondary-50 dark:hover:bg-secondary-700 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
className="mt-3 w-full inline-flex justify-center rounded-md border border-secondary-300 dark:border-secondary-600 shadow-sm px-4 py-2 bg-white dark:bg-secondary-800 text-base font-medium text-secondary-700 dark:text-secondary-200 hover:bg-secondary-50 dark:hover:bg-secondary-700 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ const InlineEdit = ({
|
|||||||
} ${isLoading ? "opacity-50" : ""}`}
|
} ${isLoading ? "opacity-50" : ""}`}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
disabled={isLoading || editValue.trim() === ""}
|
disabled={isLoading || editValue.trim() === ""}
|
||||||
className="p-1 text-green-600 hover:text-green-700 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
className="p-1 text-green-600 hover:text-green-700 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
@@ -110,6 +111,7 @@ const InlineEdit = ({
|
|||||||
<Check className="h-4 w-4" />
|
<Check className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
className="p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
@@ -145,6 +147,7 @@ const InlineEdit = ({
|
|||||||
{displayValue}
|
{displayValue}
|
||||||
{!disabled && (
|
{!disabled && (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleEdit}
|
onClick={handleEdit}
|
||||||
className="p-1 text-secondary-400 hover:text-secondary-600 dark:hover:text-secondary-300 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded transition-colors opacity-0 group-hover:opacity-100"
|
className="p-1 text-secondary-400 hover:text-secondary-600 dark:hover:text-secondary-300 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded transition-colors opacity-0 group-hover:opacity-100"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ const InlineGroupEdit = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="p-1 text-green-600 hover:text-green-700 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
className="p-1 text-green-600 hover:text-green-700 hover:bg-green-50 dark:hover:bg-green-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
@@ -229,6 +230,7 @@ const InlineGroupEdit = ({
|
|||||||
<Check className="h-4 w-4" />
|
<Check className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
className="p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
@@ -256,6 +258,7 @@ const InlineGroupEdit = ({
|
|||||||
</span>
|
</span>
|
||||||
{!disabled && (
|
{!disabled && (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleEdit}
|
onClick={handleEdit}
|
||||||
className="p-1 text-secondary-400 hover:text-secondary-600 dark:hover:text-secondary-300 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded transition-colors opacity-0 group-hover:opacity-100"
|
className="p-1 text-secondary-400 hover:text-secondary-600 dark:hover:text-secondary-300 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded transition-colors opacity-0 group-hover:opacity-100"
|
||||||
title="Edit group"
|
title="Edit group"
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ const Layout = ({ children }) => {
|
|||||||
{subItem.name}
|
{subItem.name}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setSidebarOpen(false);
|
setSidebarOpen(false);
|
||||||
@@ -453,6 +454,7 @@ const Layout = ({ children }) => {
|
|||||||
>
|
>
|
||||||
{sidebarCollapsed ? (
|
{sidebarCollapsed ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
|
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
|
||||||
className="flex items-center justify-center w-8 h-8 rounded-md hover:bg-secondary-100 transition-colors"
|
className="flex items-center justify-center w-8 h-8 rounded-md hover:bg-secondary-100 transition-colors"
|
||||||
title="Expand sidebar"
|
title="Expand sidebar"
|
||||||
@@ -468,6 +470,7 @@ const Layout = ({ children }) => {
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
|
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
|
||||||
className="flex items-center justify-center w-8 h-8 rounded-md hover:bg-secondary-100 transition-colors"
|
className="flex items-center justify-center w-8 h-8 rounded-md hover:bg-secondary-100 transition-colors"
|
||||||
title="Collapse sidebar"
|
title="Collapse sidebar"
|
||||||
@@ -549,6 +552,7 @@ const Layout = ({ children }) => {
|
|||||||
)}
|
)}
|
||||||
{!sidebarCollapsed && (
|
{!sidebarCollapsed && (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleAddHost();
|
handleAddHost();
|
||||||
@@ -659,6 +663,7 @@ const Layout = ({ children }) => {
|
|||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleLogout}
|
onClick={handleLogout}
|
||||||
className="ml-2 p-1.5 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded transition-colors"
|
className="ml-2 p-1.5 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded transition-colors"
|
||||||
title="Sign out"
|
title="Sign out"
|
||||||
@@ -675,6 +680,7 @@ const Layout = ({ children }) => {
|
|||||||
Updated: {formatRelativeTimeShort(stats.lastUpdated)}
|
Updated: {formatRelativeTimeShort(stats.lastUpdated)}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="p-1 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded flex-shrink-0 disabled:opacity-50"
|
className="p-1 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded flex-shrink-0 disabled:opacity-50"
|
||||||
@@ -707,6 +713,7 @@ const Layout = ({ children }) => {
|
|||||||
<UserCircle className="h-5 w-5" />
|
<UserCircle className="h-5 w-5" />
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleLogout}
|
onClick={handleLogout}
|
||||||
className="flex items-center justify-center w-full p-2 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded-md transition-colors"
|
className="flex items-center justify-center w-full p-2 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded-md transition-colors"
|
||||||
title="Sign out"
|
title="Sign out"
|
||||||
@@ -717,6 +724,7 @@ const Layout = ({ children }) => {
|
|||||||
{stats && (
|
{stats && (
|
||||||
<div className="flex flex-col items-center py-1 border-t border-secondary-200 dark:border-secondary-700">
|
<div className="flex flex-col items-center py-1 border-t border-secondary-200 dark:border-secondary-700">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="p-1 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded disabled:opacity-50"
|
className="p-1 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded disabled:opacity-50"
|
||||||
|
|||||||
@@ -831,6 +831,7 @@ const Dashboard = () => {
|
|||||||
{error.message || "Failed to load dashboard statistics"}
|
{error.message || "Failed to load dashboard statistics"}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
className="mt-2 btn-danger text-xs"
|
className="mt-2 btn-danger text-xs"
|
||||||
>
|
>
|
||||||
@@ -1010,6 +1011,7 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowSettingsModal(true)}
|
onClick={() => setShowSettingsModal(true)}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
title="Customize dashboard layout"
|
title="Customize dashboard layout"
|
||||||
@@ -1018,6 +1020,7 @@ const Dashboard = () => {
|
|||||||
Customize Dashboard
|
Customize Dashboard
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ const HostDetail = () => {
|
|||||||
{error.message || "Failed to load host details"}
|
{error.message || "Failed to load host details"}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
className="mt-2 btn-danger text-xs"
|
className="mt-2 btn-danger text-xs"
|
||||||
>
|
>
|
||||||
@@ -257,6 +258,7 @@ const HostDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="btn-outline flex items-center gap-2 text-sm"
|
className="btn-outline flex items-center gap-2 text-sm"
|
||||||
@@ -268,6 +270,7 @@ const HostDetail = () => {
|
|||||||
{isFetching ? "Refreshing..." : "Refresh"}
|
{isFetching ? "Refreshing..." : "Refresh"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowCredentialsModal(true)}
|
onClick={() => setShowCredentialsModal(true)}
|
||||||
className="btn-outline flex items-center gap-2 text-sm"
|
className="btn-outline flex items-center gap-2 text-sm"
|
||||||
>
|
>
|
||||||
@@ -275,6 +278,7 @@ const HostDetail = () => {
|
|||||||
Deploy Agent
|
Deploy Agent
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowDeleteModal(true)}
|
onClick={() => setShowDeleteModal(true)}
|
||||||
className="btn-danger flex items-center gap-2 text-sm"
|
className="btn-danger flex items-center gap-2 text-sm"
|
||||||
>
|
>
|
||||||
@@ -292,6 +296,7 @@ const HostDetail = () => {
|
|||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="flex border-b border-secondary-200 dark:border-secondary-600">
|
<div className="flex border-b border-secondary-200 dark:border-secondary-600">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleTabChange("host")}
|
onClick={() => handleTabChange("host")}
|
||||||
className={`px-4 py-2 text-sm font-medium ${
|
className={`px-4 py-2 text-sm font-medium ${
|
||||||
activeTab === "host"
|
activeTab === "host"
|
||||||
@@ -302,6 +307,7 @@ const HostDetail = () => {
|
|||||||
Host Info
|
Host Info
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleTabChange("network")}
|
onClick={() => handleTabChange("network")}
|
||||||
className={`px-4 py-2 text-sm font-medium ${
|
className={`px-4 py-2 text-sm font-medium ${
|
||||||
activeTab === "network"
|
activeTab === "network"
|
||||||
@@ -312,6 +318,7 @@ const HostDetail = () => {
|
|||||||
Network
|
Network
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleTabChange("system")}
|
onClick={() => handleTabChange("system")}
|
||||||
className={`px-4 py-2 text-sm font-medium ${
|
className={`px-4 py-2 text-sm font-medium ${
|
||||||
activeTab === "system"
|
activeTab === "system"
|
||||||
@@ -322,6 +329,7 @@ const HostDetail = () => {
|
|||||||
System
|
System
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleTabChange("monitoring")}
|
onClick={() => handleTabChange("monitoring")}
|
||||||
className={`px-4 py-2 text-sm font-medium ${
|
className={`px-4 py-2 text-sm font-medium ${
|
||||||
activeTab === "monitoring"
|
activeTab === "monitoring"
|
||||||
@@ -332,6 +340,7 @@ const HostDetail = () => {
|
|||||||
Resource
|
Resource
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleTabChange("history")}
|
onClick={() => handleTabChange("history")}
|
||||||
className={`px-4 py-2 text-sm font-medium ${
|
className={`px-4 py-2 text-sm font-medium ${
|
||||||
activeTab === "history"
|
activeTab === "history"
|
||||||
@@ -427,6 +436,7 @@ const HostDetail = () => {
|
|||||||
Auto-update
|
Auto-update
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
toggleAutoUpdateMutation.mutate(!host.auto_update)
|
toggleAutoUpdateMutation.mutate(!host.auto_update)
|
||||||
}
|
}
|
||||||
@@ -862,6 +872,7 @@ const HostDetail = () => {
|
|||||||
{host.update_history.length > 5 && (
|
{host.update_history.length > 5 && (
|
||||||
<div className="px-4 py-2 border-t border-secondary-200 dark:border-secondary-600 bg-secondary-50 dark:bg-secondary-700">
|
<div className="px-4 py-2 border-t border-secondary-200 dark:border-secondary-600 bg-secondary-50 dark:bg-secondary-700">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAllUpdates(!showAllUpdates)}
|
onClick={() => setShowAllUpdates(!showAllUpdates)}
|
||||||
className="flex items-center gap-1.5 text-xs text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300 font-medium"
|
className="flex items-center gap-1.5 text-xs text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300 font-medium"
|
||||||
>
|
>
|
||||||
@@ -906,6 +917,7 @@ const HostDetail = () => {
|
|||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => navigate(`/packages?host=${hostId}`)}
|
onClick={() => navigate(`/packages?host=${hostId}`)}
|
||||||
className="text-center p-4 bg-primary-50 dark:bg-primary-900/20 rounded-lg hover:bg-primary-100 dark:hover:bg-primary-900/30 transition-colors group"
|
className="text-center p-4 bg-primary-50 dark:bg-primary-900/20 rounded-lg hover:bg-primary-100 dark:hover:bg-primary-900/30 transition-colors group"
|
||||||
title="View all packages for this host"
|
title="View all packages for this host"
|
||||||
@@ -922,6 +934,7 @@ const HostDetail = () => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => navigate(`/packages?host=${hostId}`)}
|
onClick={() => navigate(`/packages?host=${hostId}`)}
|
||||||
className="text-center p-4 bg-warning-50 dark:bg-warning-900/20 rounded-lg hover:bg-warning-100 dark:hover:bg-warning-900/30 transition-colors group"
|
className="text-center p-4 bg-warning-50 dark:bg-warning-900/20 rounded-lg hover:bg-warning-100 dark:hover:bg-warning-900/30 transition-colors group"
|
||||||
title="View outdated packages for this host"
|
title="View outdated packages for this host"
|
||||||
@@ -938,6 +951,7 @@ const HostDetail = () => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(`/packages?host=${hostId}&filter=security`)
|
navigate(`/packages?host=${hostId}&filter=security`)
|
||||||
}
|
}
|
||||||
@@ -1083,6 +1097,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
Host Setup - {host.friendly_name}
|
Host Setup - {host.friendly_name}
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -1094,6 +1109,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
<div className="border-b border-secondary-200 dark:border-secondary-600 mb-6">
|
<div className="border-b border-secondary-200 dark:border-secondary-600 mb-6">
|
||||||
<nav className="-mb-px flex space-x-8">
|
<nav className="-mb-px flex space-x-8">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("quick-install")}
|
onClick={() => setActiveTab("quick-install")}
|
||||||
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
||||||
activeTab === "quick-install"
|
activeTab === "quick-install"
|
||||||
@@ -1104,6 +1120,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
Quick Install
|
Quick Install
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("credentials")}
|
onClick={() => setActiveTab("credentials")}
|
||||||
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
||||||
activeTab === "credentials"
|
activeTab === "credentials"
|
||||||
@@ -1135,6 +1152,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-primary-300 dark:border-primary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-primary-300 dark:border-primary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
`curl -s ${serverUrl}/api/v1/hosts/install | bash -s -- ${serverUrl} "${host.api_id}" "${host.api_key}"`,
|
`curl -s ${serverUrl}/api/v1/hosts/install | bash -s -- ${serverUrl} "${host.api_id}" "${host.api_key}"`,
|
||||||
@@ -1168,6 +1186,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
`curl -o /tmp/patchmon-agent.sh ${serverUrl}/api/v1/hosts/agent/download`,
|
`curl -o /tmp/patchmon-agent.sh ${serverUrl}/api/v1/hosts/agent/download`,
|
||||||
@@ -1193,6 +1212,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
"sudo mkdir -p /etc/patchmon && sudo mv /tmp/patchmon-agent.sh /usr/local/bin/patchmon-agent.sh && sudo chmod +x /usr/local/bin/patchmon-agent.sh",
|
"sudo mkdir -p /etc/patchmon && sudo mv /tmp/patchmon-agent.sh /usr/local/bin/patchmon-agent.sh && sudo chmod +x /usr/local/bin/patchmon-agent.sh",
|
||||||
@@ -1218,6 +1238,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
`sudo /usr/local/bin/patchmon-agent.sh configure "${host.api_id}" "${host.api_key}"`,
|
`sudo /usr/local/bin/patchmon-agent.sh configure "${host.api_id}" "${host.api_key}"`,
|
||||||
@@ -1243,6 +1264,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
"sudo /usr/local/bin/patchmon-agent.sh test",
|
"sudo /usr/local/bin/patchmon-agent.sh test",
|
||||||
@@ -1268,6 +1290,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
"sudo /usr/local/bin/patchmon-agent.sh update",
|
"sudo /usr/local/bin/patchmon-agent.sh update",
|
||||||
@@ -1293,6 +1316,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-white dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
`echo "${new Date().getMinutes()} * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1" | sudo crontab -`,
|
`echo "${new Date().getMinutes()} * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1" | sudo crontab -`,
|
||||||
@@ -1329,6 +1353,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-secondary-50 dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-secondary-50 dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => copyToClipboard(host.api_id)}
|
onClick={() => copyToClipboard(host.api_id)}
|
||||||
className="btn-outline flex items-center gap-1"
|
className="btn-outline flex items-center gap-1"
|
||||||
>
|
>
|
||||||
@@ -1350,6 +1375,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-secondary-50 dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-md bg-secondary-50 dark:bg-secondary-800 text-sm font-mono text-secondary-900 dark:text-white"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowApiKey(!showApiKey)}
|
onClick={() => setShowApiKey(!showApiKey)}
|
||||||
className="btn-outline flex items-center gap-1"
|
className="btn-outline flex items-center gap-1"
|
||||||
>
|
>
|
||||||
@@ -1360,6 +1386,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => copyToClipboard(host.api_key)}
|
onClick={() => copyToClipboard(host.api_key)}
|
||||||
className="btn-outline flex items-center gap-1"
|
className="btn-outline flex items-center gap-1"
|
||||||
>
|
>
|
||||||
@@ -1389,7 +1416,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`;
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-end pt-6">
|
<div className="flex justify-end pt-6">
|
||||||
<button onClick={onClose} className="btn-primary">
|
<button type="button" onClick={onClose} className="btn-primary">
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1441,6 +1468,7 @@ const DeleteConfirmationModal = ({
|
|||||||
|
|
||||||
<div className="flex justify-end gap-3">
|
<div className="flex justify-end gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="btn-outline"
|
className="btn-outline"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -1448,6 +1476,7 @@ const DeleteConfirmationModal = ({
|
|||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ const HostGroups = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowCreateModal(true)}
|
onClick={() => setShowCreateModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -161,6 +162,7 @@ const HostGroups = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleEdit(group)}
|
onClick={() => handleEdit(group)}
|
||||||
className="p-1 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded"
|
className="p-1 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded"
|
||||||
title="Edit group"
|
title="Edit group"
|
||||||
@@ -168,6 +170,7 @@ const HostGroups = () => {
|
|||||||
<Edit className="h-4 w-4" />
|
<Edit className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleDeleteClick(group)}
|
onClick={() => handleDeleteClick(group)}
|
||||||
className="p-1 text-secondary-400 hover:text-danger-600 hover:bg-danger-50 rounded"
|
className="p-1 text-secondary-400 hover:text-danger-600 hover:bg-danger-50 rounded"
|
||||||
title="Delete group"
|
title="Delete group"
|
||||||
@@ -199,6 +202,7 @@ const HostGroups = () => {
|
|||||||
Create your first host group to organize your hosts
|
Create your first host group to organize your hosts
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowCreateModal(true)}
|
onClick={() => setShowCreateModal(true)}
|
||||||
className="btn-primary flex items-center gap-2 mx-auto"
|
className="btn-primary flex items-center gap-2 mx-auto"
|
||||||
>
|
>
|
||||||
@@ -479,6 +483,7 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
|
|||||||
|
|
||||||
<div className="flex justify-end gap-3">
|
<div className="flex justify-end gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="btn-outline"
|
className="btn-outline"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -486,6 +491,7 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
|
|||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
disabled={isLoading || group._count.hosts > 0}
|
disabled={isLoading || group._count.hosts > 0}
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ const AddHostModal = ({ isOpen, onClose, onSuccess }) => {
|
|||||||
Add New Host
|
Add New Host
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -369,6 +370,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
Host Setup - {host.friendly_name}
|
Host Setup - {host.friendly_name}
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600"
|
className="text-secondary-400 hover:text-secondary-600"
|
||||||
>
|
>
|
||||||
@@ -379,6 +381,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex space-x-1 mb-6 bg-secondary-100 p-1 rounded-lg">
|
<div className="flex space-x-1 mb-6 bg-secondary-100 p-1 rounded-lg">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("quick")}
|
onClick={() => setActiveTab("quick")}
|
||||||
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||||
activeTab === "quick"
|
activeTab === "quick"
|
||||||
@@ -389,6 +392,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
Quick Install
|
Quick Install
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("credentials")}
|
onClick={() => setActiveTab("credentials")}
|
||||||
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||||
activeTab === "credentials"
|
activeTab === "credentials"
|
||||||
@@ -399,6 +403,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
API Credentials
|
API Credentials
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("setup")}
|
onClick={() => setActiveTab("setup")}
|
||||||
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||||
activeTab === "setup"
|
activeTab === "setup"
|
||||||
@@ -409,6 +414,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
Setup Instructions
|
Setup Instructions
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTab("script")}
|
onClick={() => setActiveTab("script")}
|
||||||
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||||
activeTab === "script"
|
activeTab === "script"
|
||||||
@@ -444,6 +450,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
{commands.oneLine}
|
{commands.oneLine}
|
||||||
</code>
|
</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.oneLine, "Installation command")
|
copyToClipboard(commands.oneLine, "Installation command")
|
||||||
}
|
}
|
||||||
@@ -512,6 +519,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
className="flex-1 block w-full border-secondary-300 rounded-l-md shadow-sm bg-secondary-50"
|
className="flex-1 block w-full border-secondary-300 rounded-l-md shadow-sm bg-secondary-50"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => copyToClipboard(host.apiId, "API ID")}
|
onClick={() => copyToClipboard(host.apiId, "API ID")}
|
||||||
className="px-3 py-2 border border-l-0 border-secondary-300 rounded-r-md bg-secondary-50 hover:bg-secondary-100"
|
className="px-3 py-2 border border-l-0 border-secondary-300 rounded-r-md bg-secondary-50 hover:bg-secondary-100"
|
||||||
>
|
>
|
||||||
@@ -532,6 +540,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
className="flex-1 block w-full border-secondary-300 rounded-l-md shadow-sm bg-secondary-50"
|
className="flex-1 block w-full border-secondary-300 rounded-l-md shadow-sm bg-secondary-50"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowApiKey(!showApiKey)}
|
onClick={() => setShowApiKey(!showApiKey)}
|
||||||
className="px-3 py-2 border border-l-0 border-r-0 border-secondary-300 bg-secondary-50 hover:bg-secondary-100"
|
className="px-3 py-2 border border-l-0 border-r-0 border-secondary-300 bg-secondary-50 hover:bg-secondary-100"
|
||||||
>
|
>
|
||||||
@@ -542,6 +551,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => copyToClipboard(host.apiKey, "API Key")}
|
onClick={() => copyToClipboard(host.apiKey, "API Key")}
|
||||||
className="px-3 py-2 border border-l-0 border-secondary-300 rounded-r-md bg-secondary-50 hover:bg-secondary-100"
|
className="px-3 py-2 border border-l-0 border-secondary-300 rounded-r-md bg-secondary-50 hover:bg-secondary-100"
|
||||||
>
|
>
|
||||||
@@ -586,6 +596,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
{commands.download}
|
{commands.download}
|
||||||
</code>
|
</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.download, "Download commands")
|
copyToClipboard(commands.download, "Download commands")
|
||||||
}
|
}
|
||||||
@@ -606,6 +617,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<code className="flex-1">{commands.configure}</code>
|
<code className="flex-1">{commands.configure}</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.configure, "Configure command")
|
copyToClipboard(commands.configure, "Configure command")
|
||||||
}
|
}
|
||||||
@@ -626,6 +638,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<code className="flex-1">{commands.test}</code>
|
<code className="flex-1">{commands.test}</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.test, "Test command")
|
copyToClipboard(commands.test, "Test command")
|
||||||
}
|
}
|
||||||
@@ -650,6 +663,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<code className="flex-1">{commands.initialUpdate}</code>
|
<code className="flex-1">{commands.initialUpdate}</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(
|
copyToClipboard(
|
||||||
commands.initialUpdate,
|
commands.initialUpdate,
|
||||||
@@ -673,6 +687,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<code className="flex-1">{commands.crontab}</code>
|
<code className="flex-1">{commands.crontab}</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.crontab, "Crontab command")
|
copyToClipboard(commands.crontab, "Crontab command")
|
||||||
}
|
}
|
||||||
@@ -709,6 +724,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
Complete Setup Script
|
Complete Setup Script
|
||||||
</h5>
|
</h5>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(commands.fullSetup, "Complete setup script")
|
copyToClipboard(commands.fullSetup, "Complete setup script")
|
||||||
}
|
}
|
||||||
@@ -750,6 +766,7 @@ echo " - View logs: tail -f /var/log/patchmon-agent.log"`,
|
|||||||
Download Agent Script
|
Download Agent Script
|
||||||
</a>
|
</a>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="px-4 py-2 text-sm font-medium text-secondary-700 bg-white border border-secondary-300 rounded-md hover:bg-secondary-50"
|
className="px-4 py-2 text-sm font-medium text-secondary-700 bg-white border border-secondary-300 rounded-md hover:bg-secondary-50"
|
||||||
>
|
>
|
||||||
@@ -1270,6 +1287,7 @@ const Hosts = () => {
|
|||||||
case "select":
|
case "select":
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSelectHost(host.id)}
|
onClick={() => handleSelectHost(host.id)}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1373,6 +1391,7 @@ const Hosts = () => {
|
|||||||
case "updates":
|
case "updates":
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => navigate(`/packages?host=${host.id}`)}
|
onClick={() => navigate(`/packages?host=${host.id}`)}
|
||||||
className="text-sm text-primary-600 hover:text-primary-900 dark:text-primary-400 dark:hover:text-primary-300 font-medium hover:underline"
|
className="text-sm text-primary-600 hover:text-primary-900 dark:text-primary-400 dark:hover:text-primary-300 font-medium hover:underline"
|
||||||
title="View packages for this host"
|
title="View packages for this host"
|
||||||
@@ -1472,6 +1491,7 @@ const Hosts = () => {
|
|||||||
{error.message || "Failed to load hosts"}
|
{error.message || "Failed to load hosts"}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
className="mt-2 btn-danger text-xs"
|
className="mt-2 btn-danger text-xs"
|
||||||
>
|
>
|
||||||
@@ -1515,6 +1535,7 @@ const Hosts = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
@@ -1526,6 +1547,7 @@ const Hosts = () => {
|
|||||||
{isFetching ? "Refreshing..." : "Refresh"}
|
{isFetching ? "Refreshing..." : "Refresh"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAddModal(true)}
|
onClick={() => setShowAddModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -1615,6 +1637,7 @@ const Hosts = () => {
|
|||||||
{selectedHosts.length !== 1 ? "s" : ""} selected
|
{selectedHosts.length !== 1 ? "s" : ""} selected
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowBulkAssignModal(true)}
|
onClick={() => setShowBulkAssignModal(true)}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -1622,6 +1645,7 @@ const Hosts = () => {
|
|||||||
Assign to Group
|
Assign to Group
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowBulkDeleteModal(true)}
|
onClick={() => setShowBulkDeleteModal(true)}
|
||||||
className="btn-danger flex items-center gap-2"
|
className="btn-danger flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -1629,6 +1653,7 @@ const Hosts = () => {
|
|||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setSelectedHosts([])}
|
onClick={() => setSelectedHosts([])}
|
||||||
className="text-sm text-secondary-500 hover:text-secondary-700"
|
className="text-sm text-secondary-500 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1656,6 +1681,7 @@ const Hosts = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowFilters(!showFilters)}
|
onClick={() => setShowFilters(!showFilters)}
|
||||||
className={`btn-outline flex items-center gap-2 ${showFilters ? "bg-primary-50 border-primary-300" : ""}`}
|
className={`btn-outline flex items-center gap-2 ${showFilters ? "bg-primary-50 border-primary-300" : ""}`}
|
||||||
>
|
>
|
||||||
@@ -1663,6 +1689,7 @@ const Hosts = () => {
|
|||||||
Filters
|
Filters
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowColumnSettings(true)}
|
onClick={() => setShowColumnSettings(true)}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -1683,6 +1710,7 @@ const Hosts = () => {
|
|||||||
<ChevronDown className="absolute right-1 top-1/2 transform -translate-y-1/2 h-4 w-4 text-secondary-400 dark:text-secondary-500 pointer-events-none" />
|
<ChevronDown className="absolute right-1 top-1/2 transform -translate-y-1/2 h-4 w-4 text-secondary-400 dark:text-secondary-500 pointer-events-none" />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setHideStale(!hideStale)}
|
onClick={() => setHideStale(!hideStale)}
|
||||||
className={`btn-outline flex items-center gap-2 ${hideStale ? "bg-primary-50 border-primary-300" : ""}`}
|
className={`btn-outline flex items-center gap-2 ${hideStale ? "bg-primary-50 border-primary-300" : ""}`}
|
||||||
>
|
>
|
||||||
@@ -1690,6 +1718,7 @@ const Hosts = () => {
|
|||||||
Hide Stale
|
Hide Stale
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAddModal(true)}
|
onClick={() => setShowAddModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -1754,6 +1783,7 @@ const Hosts = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-end">
|
<div className="flex items-end">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSearchTerm("");
|
setSearchTerm("");
|
||||||
setGroupFilter("all");
|
setGroupFilter("all");
|
||||||
@@ -1819,6 +1849,7 @@ const Hosts = () => {
|
|||||||
>
|
>
|
||||||
{column.id === "select" ? (
|
{column.id === "select" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSelectAll}
|
onClick={handleSelectAll}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1831,6 +1862,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "host" ? (
|
) : column.id === "host" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleSort("friendlyName")
|
handleSort("friendlyName")
|
||||||
}
|
}
|
||||||
@@ -1841,6 +1873,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "hostname" ? (
|
) : column.id === "hostname" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("hostname")}
|
onClick={() => handleSort("hostname")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1849,6 +1882,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "ip" ? (
|
) : column.id === "ip" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("ip")}
|
onClick={() => handleSort("ip")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1857,6 +1891,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "group" ? (
|
) : column.id === "group" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("group")}
|
onClick={() => handleSort("group")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1865,6 +1900,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "os" ? (
|
) : column.id === "os" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("os")}
|
onClick={() => handleSort("os")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1873,6 +1909,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "os_version" ? (
|
) : column.id === "os_version" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("os_version")}
|
onClick={() => handleSort("os_version")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1881,6 +1918,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "agent_version" ? (
|
) : column.id === "agent_version" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleSort("agent_version")
|
handleSort("agent_version")
|
||||||
}
|
}
|
||||||
@@ -1895,6 +1933,7 @@ const Hosts = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : column.id === "status" ? (
|
) : column.id === "status" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("status")}
|
onClick={() => handleSort("status")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1903,6 +1942,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "updates" ? (
|
) : column.id === "updates" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort("updates")}
|
onClick={() => handleSort("updates")}
|
||||||
className="flex items-center gap-2 hover:text-secondary-700"
|
className="flex items-center gap-2 hover:text-secondary-700"
|
||||||
>
|
>
|
||||||
@@ -1911,6 +1951,7 @@ const Hosts = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : column.id === "last_update" ? (
|
) : column.id === "last_update" ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleSort("last_update")
|
handleSort("last_update")
|
||||||
}
|
}
|
||||||
@@ -2047,6 +2088,7 @@ const BulkAssignModal = ({
|
|||||||
Assign to Host Group
|
Assign to Host Group
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600"
|
className="text-secondary-400 hover:text-secondary-600"
|
||||||
>
|
>
|
||||||
@@ -2135,6 +2177,7 @@ const BulkDeleteModal = ({
|
|||||||
Delete Hosts
|
Delete Hosts
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -2236,6 +2279,7 @@ const ColumnSettingsModal = ({
|
|||||||
Column Settings
|
Column Settings
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -2270,6 +2314,7 @@ const ColumnSettingsModal = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => onToggleVisibility(column.id)}
|
onClick={() => onToggleVisibility(column.id)}
|
||||||
className={`p-1 rounded ${
|
className={`p-1 rounded ${
|
||||||
column.visible
|
column.visible
|
||||||
@@ -2288,10 +2333,10 @@ const ColumnSettingsModal = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between mt-6">
|
<div className="flex justify-between mt-6">
|
||||||
<button onClick={onReset} className="btn-outline">
|
<button type="button" onClick={onReset} className="btn-outline">
|
||||||
Reset to Default
|
Reset to Default
|
||||||
</button>
|
</button>
|
||||||
<button onClick={onClose} className="btn-primary">
|
<button type="button" onClick={onClose} className="btn-primary">
|
||||||
Done
|
Done
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ const Options = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowCreateModal(true)}
|
onClick={() => setShowCreateModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -178,6 +179,7 @@ const Options = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleEdit(group)}
|
onClick={() => handleEdit(group)}
|
||||||
className="p-1 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded"
|
className="p-1 text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 rounded"
|
||||||
title="Edit group"
|
title="Edit group"
|
||||||
@@ -185,6 +187,7 @@ const Options = () => {
|
|||||||
<Edit className="h-4 w-4" />
|
<Edit className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleDeleteClick(group)}
|
onClick={() => handleDeleteClick(group)}
|
||||||
className="p-1 text-secondary-400 hover:text-danger-600 hover:bg-danger-50 rounded"
|
className="p-1 text-secondary-400 hover:text-danger-600 hover:bg-danger-50 rounded"
|
||||||
title="Delete group"
|
title="Delete group"
|
||||||
@@ -216,6 +219,7 @@ const Options = () => {
|
|||||||
Create your first host group to organize your hosts
|
Create your first host group to organize your hosts
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowCreateModal(true)}
|
onClick={() => setShowCreateModal(true)}
|
||||||
className="btn-primary flex items-center gap-2 mx-auto"
|
className="btn-primary flex items-center gap-2 mx-auto"
|
||||||
>
|
>
|
||||||
@@ -260,6 +264,7 @@ const Options = () => {
|
|||||||
const Icon = tab.icon;
|
const Icon = tab.icon;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={`py-2 px-1 border-b-2 font-medium text-sm flex items-center gap-2 ${
|
className={`py-2 px-1 border-b-2 font-medium text-sm flex items-center gap-2 ${
|
||||||
@@ -558,6 +563,7 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
|
|||||||
|
|
||||||
<div className="flex justify-end gap-3">
|
<div className="flex justify-end gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="btn-outline"
|
className="btn-outline"
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -565,6 +571,7 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
|
|||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
disabled={isLoading || group._count.hosts > 0}
|
disabled={isLoading || group._count.hosts > 0}
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ const Packages = () => {
|
|||||||
pkg.affectedHostsCount || pkg.affectedHosts?.length || 0;
|
pkg.affectedHostsCount || pkg.affectedHosts?.length || 0;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleAffectedHostsClick(pkg)}
|
onClick={() => handleAffectedHostsClick(pkg)}
|
||||||
className="text-left hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded p-1 -m-1 transition-colors group"
|
className="text-left hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded p-1 -m-1 transition-colors group"
|
||||||
title={`Click to view all ${affectedHostsCount} affected hosts`}
|
title={`Click to view all ${affectedHostsCount} affected hosts`}
|
||||||
@@ -354,6 +355,7 @@ const Packages = () => {
|
|||||||
{error.message || "Failed to load packages"}
|
{error.message || "Failed to load packages"}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
className="mt-2 btn-danger text-xs"
|
className="mt-2 btn-danger text-xs"
|
||||||
>
|
>
|
||||||
@@ -380,6 +382,7 @@ const Packages = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
@@ -524,6 +527,7 @@ const Packages = () => {
|
|||||||
{/* Columns Button */}
|
{/* Columns Button */}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowColumnSettings(true)}
|
onClick={() => setShowColumnSettings(true)}
|
||||||
className="flex items-center gap-2 px-3 py-2 text-sm text-secondary-700 dark:text-secondary-300 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600 transition-colors"
|
className="flex items-center gap-2 px-3 py-2 text-sm text-secondary-700 dark:text-secondary-300 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600 transition-colors"
|
||||||
>
|
>
|
||||||
@@ -560,6 +564,7 @@ const Packages = () => {
|
|||||||
className="px-4 py-2 text-center text-xs font-medium text-secondary-500 dark:text-secondary-300 uppercase tracking-wider"
|
className="px-4 py-2 text-center text-xs font-medium text-secondary-500 dark:text-secondary-300 uppercase tracking-wider"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort(column.id)}
|
onClick={() => handleSort(column.id)}
|
||||||
className="flex items-center gap-1 hover:text-secondary-700 dark:hover:text-secondary-200 transition-colors"
|
className="flex items-center gap-1 hover:text-secondary-700 dark:hover:text-secondary-200 transition-colors"
|
||||||
>
|
>
|
||||||
@@ -644,6 +649,7 @@ const ColumnSettingsModal = ({
|
|||||||
Customize Columns
|
Customize Columns
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -672,6 +678,7 @@ const ColumnSettingsModal = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => onToggleVisibility(column.id)}
|
onClick={() => onToggleVisibility(column.id)}
|
||||||
className={`p-1 rounded ${
|
className={`p-1 rounded ${
|
||||||
column.visible
|
column.visible
|
||||||
@@ -691,12 +698,14 @@ const ColumnSettingsModal = ({
|
|||||||
|
|
||||||
<div className="flex justify-between mt-6">
|
<div className="flex justify-between mt-6">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onReset}
|
onClick={onReset}
|
||||||
className="px-4 py-2 text-sm font-medium text-secondary-700 dark:text-secondary-200 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600"
|
className="px-4 py-2 text-sm font-medium text-secondary-700 dark:text-secondary-200 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600"
|
||||||
>
|
>
|
||||||
Reset to Default
|
Reset to Default
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-md hover:bg-primary-700"
|
className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-md hover:bg-primary-700"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ const Permissions = () => {
|
|||||||
<div className="flex justify-end items-center">
|
<div className="flex justify-end items-center">
|
||||||
<div className="flex space-x-3">
|
<div className="flex space-x-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refreshPermissions()}
|
onClick={() => refreshPermissions()}
|
||||||
className="inline-flex items-center px-4 py-2 border border-secondary-300 text-sm font-medium rounded-md text-secondary-700 bg-white hover:bg-secondary-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
className="inline-flex items-center px-4 py-2 border border-secondary-300 text-sm font-medium rounded-md text-secondary-700 bg-white hover:bg-secondary-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
||||||
>
|
>
|
||||||
@@ -115,6 +116,7 @@ const Permissions = () => {
|
|||||||
Refresh Permissions
|
Refresh Permissions
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAddModal(true)}
|
onClick={() => setShowAddModal(true)}
|
||||||
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
||||||
>
|
>
|
||||||
@@ -265,6 +267,7 @@ const RolePermissionsCard = ({
|
|||||||
{isEditing ? (
|
{isEditing ? (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700"
|
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700"
|
||||||
>
|
>
|
||||||
@@ -272,6 +275,7 @@ const RolePermissionsCard = ({
|
|||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
className="inline-flex items-center px-3 py-1 border border-secondary-300 dark:border-secondary-600 text-sm font-medium rounded-md text-secondary-700 dark:text-secondary-200 bg-white dark:bg-secondary-700 hover:bg-secondary-50 dark:hover:bg-secondary-600"
|
className="inline-flex items-center px-3 py-1 border border-secondary-300 dark:border-secondary-600 text-sm font-medium rounded-md text-secondary-700 dark:text-secondary-200 bg-white dark:bg-secondary-700 hover:bg-secondary-50 dark:hover:bg-secondary-600"
|
||||||
>
|
>
|
||||||
@@ -282,6 +286,7 @@ const RolePermissionsCard = ({
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onEdit}
|
onClick={onEdit}
|
||||||
disabled={isBuiltInRole}
|
disabled={isBuiltInRole}
|
||||||
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
@@ -291,6 +296,7 @@ const RolePermissionsCard = ({
|
|||||||
</button>
|
</button>
|
||||||
{!isBuiltInRole && (
|
{!isBuiltInRole && (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => onDelete(role.role)}
|
onClick={() => onDelete(role.role)}
|
||||||
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700"
|
className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ const Profile = () => {
|
|||||||
const Icon = tab.icon;
|
const Icon = tab.icon;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={`py-4 px-1 border-b-2 font-medium text-sm flex items-center ${
|
className={`py-4 px-1 border-b-2 font-medium text-sm flex items-center ${
|
||||||
@@ -505,6 +506,7 @@ const Profile = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={toggleTheme}
|
onClick={toggleTheme}
|
||||||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 ${
|
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 ${
|
||||||
isDark ? "bg-primary-600" : "bg-secondary-300"
|
isDark ? "bg-primary-600" : "bg-secondary-300"
|
||||||
@@ -797,6 +799,7 @@ const TfaTab = () => {
|
|||||||
<div>
|
<div>
|
||||||
{tfaStatus?.enabled ? (
|
{tfaStatus?.enabled ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setSetupStep("disable")}
|
onClick={() => setSetupStep("disable")}
|
||||||
className="btn-outline text-danger-600 border-danger-300 hover:bg-danger-50"
|
className="btn-outline text-danger-600 border-danger-300 hover:bg-danger-50"
|
||||||
>
|
>
|
||||||
@@ -805,6 +808,7 @@ const TfaTab = () => {
|
|||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSetup}
|
onClick={handleSetup}
|
||||||
disabled={setupMutation.isPending}
|
disabled={setupMutation.isPending}
|
||||||
className="btn-primary"
|
className="btn-primary"
|
||||||
@@ -827,6 +831,7 @@ const TfaTab = () => {
|
|||||||
authenticator device.
|
authenticator device.
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleRegenerateBackupCodes}
|
onClick={handleRegenerateBackupCodes}
|
||||||
disabled={regenerateBackupCodesMutation.isPending}
|
disabled={regenerateBackupCodesMutation.isPending}
|
||||||
className="btn-outline"
|
className="btn-outline"
|
||||||
@@ -871,6 +876,7 @@ const TfaTab = () => {
|
|||||||
{setupMutation.data.manualEntryKey}
|
{setupMutation.data.manualEntryKey}
|
||||||
</code>
|
</code>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copyToClipboard(setupMutation.data.manualEntryKey)
|
copyToClipboard(setupMutation.data.manualEntryKey)
|
||||||
}
|
}
|
||||||
@@ -884,6 +890,7 @@ const TfaTab = () => {
|
|||||||
|
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setSetupStep("verify")}
|
onClick={() => setSetupStep("verify")}
|
||||||
className="btn-primary"
|
className="btn-primary"
|
||||||
>
|
>
|
||||||
@@ -979,11 +986,12 @@ const TfaTab = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-3">
|
<div className="flex space-x-3">
|
||||||
<button onClick={downloadBackupCodes} className="btn-outline">
|
<button type="button" onClick={downloadBackupCodes} className="btn-outline">
|
||||||
<Download className="h-4 w-4 mr-2" />
|
<Download className="h-4 w-4 mr-2" />
|
||||||
Download Codes
|
Download Codes
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSetupStep("status");
|
setSetupStep("status");
|
||||||
queryClient.invalidateQueries(["tfaStatus"]);
|
queryClient.invalidateQueries(["tfaStatus"]);
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ const Repositories = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => refetch()}
|
onClick={() => refetch()}
|
||||||
disabled={isFetching}
|
disabled={isFetching}
|
||||||
className="btn-outline flex items-center gap-2"
|
className="btn-outline flex items-center gap-2"
|
||||||
@@ -363,6 +364,7 @@ const Repositories = () => {
|
|||||||
{/* Columns Button */}
|
{/* Columns Button */}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowColumnSettings(true)}
|
onClick={() => setShowColumnSettings(true)}
|
||||||
className="flex items-center gap-2 px-3 py-2 text-sm text-secondary-700 dark:text-secondary-300 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600 transition-colors"
|
className="flex items-center gap-2 px-3 py-2 text-sm text-secondary-700 dark:text-secondary-300 bg-white dark:bg-secondary-700 border border-secondary-300 dark:border-secondary-600 rounded-md hover:bg-secondary-50 dark:hover:bg-secondary-600 transition-colors"
|
||||||
>
|
>
|
||||||
@@ -399,6 +401,7 @@ const Repositories = () => {
|
|||||||
className="px-4 py-2 text-center text-xs font-medium text-secondary-500 dark:text-secondary-300 uppercase tracking-wider"
|
className="px-4 py-2 text-center text-xs font-medium text-secondary-500 dark:text-secondary-300 uppercase tracking-wider"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleSort(column.id)}
|
onClick={() => handleSort(column.id)}
|
||||||
className="flex items-center gap-1 hover:text-secondary-700 dark:hover:text-secondary-200 transition-colors"
|
className="flex items-center gap-1 hover:text-secondary-700 dark:hover:text-secondary-200 transition-colors"
|
||||||
>
|
>
|
||||||
@@ -567,6 +570,7 @@ const ColumnSettingsModal = ({
|
|||||||
Column Settings
|
Column Settings
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
@@ -591,6 +595,7 @@ const ColumnSettingsModal = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => onToggleVisibility(column.id)}
|
onClick={() => onToggleVisibility(column.id)}
|
||||||
className={`w-4 h-4 rounded border-2 flex items-center justify-center ${
|
className={`w-4 h-4 rounded border-2 flex items-center justify-center ${
|
||||||
column.visible
|
column.visible
|
||||||
@@ -606,12 +611,14 @@ const ColumnSettingsModal = ({
|
|||||||
|
|
||||||
<div className="flex justify-between mt-6">
|
<div className="flex justify-between mt-6">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onReset}
|
onClick={onReset}
|
||||||
className="px-4 py-2 text-sm text-secondary-600 dark:text-secondary-400 hover:text-secondary-800 dark:hover:text-secondary-200"
|
className="px-4 py-2 text-sm text-secondary-600 dark:text-secondary-400 hover:text-secondary-800 dark:hover:text-secondary-200"
|
||||||
>
|
>
|
||||||
Reset to Default
|
Reset to Default
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="px-4 py-2 bg-primary-600 text-white text-sm rounded-md hover:bg-primary-700 transition-colors"
|
className="px-4 py-2 bg-primary-600 text-white text-sm rounded-md hover:bg-primary-700 transition-colors"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ const RepositoryDetail = () => {
|
|||||||
{editMode ? (
|
{editMode ? (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
className="btn-outline"
|
className="btn-outline"
|
||||||
disabled={updateRepositoryMutation.isPending}
|
disabled={updateRepositoryMutation.isPending}
|
||||||
@@ -168,6 +169,7 @@ const RepositoryDetail = () => {
|
|||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
className="btn-primary"
|
className="btn-primary"
|
||||||
disabled={updateRepositoryMutation.isPending}
|
disabled={updateRepositoryMutation.isPending}
|
||||||
@@ -178,7 +180,7 @@ const RepositoryDetail = () => {
|
|||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<button onClick={handleEdit} className="btn-primary">
|
<button type="button" onClick={handleEdit} className="btn-primary">
|
||||||
Edit Repository
|
Edit Repository
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -431,6 +431,7 @@ const Settings = () => {
|
|||||||
const Icon = tab.icon;
|
const Icon = tab.icon;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={`py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2 ${
|
className={`py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2 ${
|
||||||
@@ -792,6 +793,7 @@ const Settings = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAgentVersionModal(true)}
|
onClick={() => setShowAgentVersionModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
@@ -888,6 +890,7 @@ const Settings = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const downloadUrl = `/api/v1/hosts/agent/download?version=${version.version}`;
|
const downloadUrl = `/api/v1/hosts/agent/download?version=${version.version}`;
|
||||||
window.open(downloadUrl, "_blank");
|
window.open(downloadUrl, "_blank");
|
||||||
@@ -898,6 +901,7 @@ const Settings = () => {
|
|||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setCurrentAgentVersionMutation.mutate(version.id)
|
setCurrentAgentVersionMutation.mutate(version.id)
|
||||||
}
|
}
|
||||||
@@ -911,6 +915,7 @@ const Settings = () => {
|
|||||||
Set Current
|
Set Current
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setDefaultAgentVersionMutation.mutate(version.id)
|
setDefaultAgentVersionMutation.mutate(version.id)
|
||||||
}
|
}
|
||||||
@@ -924,6 +929,7 @@ const Settings = () => {
|
|||||||
Set Default
|
Set Default
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
deleteAgentVersionMutation.mutate(version.id)
|
deleteAgentVersionMutation.mutate(version.id)
|
||||||
}
|
}
|
||||||
@@ -1208,6 +1214,7 @@ const Settings = () => {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={checkForUpdates}
|
onClick={checkForUpdates}
|
||||||
disabled={versionInfo.checking}
|
disabled={versionInfo.checking}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
@@ -1360,6 +1367,7 @@ const AgentVersionModal = ({ isOpen, onClose, onSubmit, isLoading }) => {
|
|||||||
Add Agent Version
|
Add Agent Version
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ const Users = () => {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex justify-end items-center">
|
<div className="flex justify-end items-center">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setShowAddModal(true)}
|
onClick={() => setShowAddModal(true)}
|
||||||
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
|
||||||
>
|
>
|
||||||
@@ -193,6 +194,7 @@ const Users = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleEditUser(user)}
|
onClick={() => handleEditUser(user)}
|
||||||
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
className="text-secondary-400 hover:text-secondary-600 dark:text-secondary-500 dark:hover:text-secondary-300"
|
||||||
title="Edit user"
|
title="Edit user"
|
||||||
@@ -200,6 +202,7 @@ const Users = () => {
|
|||||||
<Edit className="h-4 w-4" />
|
<Edit className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleResetPassword(user)}
|
onClick={() => handleResetPassword(user)}
|
||||||
className="text-blue-400 hover:text-blue-600 dark:text-blue-500 dark:hover:text-blue-300 disabled:text-gray-300 disabled:cursor-not-allowed"
|
className="text-blue-400 hover:text-blue-600 dark:text-blue-500 dark:hover:text-blue-300 disabled:text-gray-300 disabled:cursor-not-allowed"
|
||||||
title={
|
title={
|
||||||
@@ -212,6 +215,7 @@ const Users = () => {
|
|||||||
<Key className="h-4 w-4" />
|
<Key className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => handleDeleteUser(user.id, user.username)}
|
onClick={() => handleDeleteUser(user.id, user.username)}
|
||||||
className="text-danger-400 hover:text-danger-600 dark:text-danger-500 dark:hover:text-danger-400 disabled:text-gray-300 disabled:cursor-not-allowed"
|
className="text-danger-400 hover:text-danger-600 dark:text-danger-500 dark:hover:text-danger-400 disabled:text-gray-300 disabled:cursor-not-allowed"
|
||||||
title={
|
title={
|
||||||
|
|||||||
Reference in New Issue
Block a user