Created
April 1, 2025 11:01
-
-
Save dexit/d4c1e021eaf5ab1d6b96b4b214caadbf to your computer and use it in GitHub Desktop.
datamapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>ETL Data Mapper Pro - Advanced Endpoint Registry & Data Mapping</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.2/jsoneditor.min.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.2/jsoneditor.min.js"></script> | |
<style> | |
/* Sidebar & Layout */ | |
.sidebar { | |
transition: all 0.3s ease; | |
min-width: 280px; | |
} | |
.sidebar.collapsed { | |
width: 80px; | |
min-width: 80px; | |
} | |
.sidebar.collapsed .sidebar-text { | |
display: none; | |
} | |
.sidebar.collapsed .logo-text { | |
display: none; | |
} | |
.sidebar.collapsed .nav-item { | |
justify-content: center; | |
} | |
.main-content { | |
transition: all 0.3s ease; | |
margin-left: 280px; | |
} | |
.sidebar.collapsed + .main-content { | |
margin-left: 80px; | |
} | |
/* Table & Data Display */ | |
.table-container { | |
max-height: calc(100vh - 250px); | |
overflow-y: auto; | |
} | |
.json-viewer { | |
font-family: monospace; | |
white-space: pre; | |
background-color: #f8f9fa; | |
padding: 10px; | |
border-radius: 4px; | |
max-height: 300px; | |
overflow-y: auto; | |
} | |
.schema-viewer { | |
max-height: 350px; | |
overflow-y: auto; | |
} | |
/* Drag & Drop */ | |
.mapping-line { | |
transition: all 0.2s ease; | |
} | |
.mapping-line:hover { | |
background-color: #f0f4ff; | |
} | |
.draggable { | |
cursor: move; | |
user-select: none; | |
} | |
.dropzone { | |
min-height: 50px; | |
border: 2px dashed #ccc; | |
border-radius: 4px; | |
padding: 10px; | |
background-color: #f9f9f9; | |
} | |
.dropzone.active { | |
border-color: #3b82f6; | |
background-color: #ebf4ff; | |
} | |
.connection-line { | |
position: absolute; | |
height: 2px; | |
background-color: #3b82f6; | |
transform-origin: left center; | |
z-index: 10; | |
} | |
.connection-dot { | |
width: 10px; | |
height: 10px; | |
border-radius: 50%; | |
background-color: #3b82f6; | |
position: absolute; | |
z-index: 11; | |
} | |
/* Tabs & Navigation */ | |
.tab-content { | |
display: none; | |
} | |
.tab-content.active { | |
display: block; | |
animation: fadeIn 0.3s ease-in-out; | |
} | |
@keyframes fadeIn { | |
from { opacity: 0; } | |
to { opacity: 1; } | |
} | |
/* Transformations */ | |
.transformation-card { | |
cursor: pointer; | |
transition: all 0.2s ease; | |
} | |
.transformation-card:hover { | |
transform: translateY(-2px); | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
} | |
.transformation-card.active { | |
border-color: #3b82f6; | |
background-color: #eff6ff; | |
} | |
/* Progress & Status */ | |
.progress-bar { | |
height: 6px; | |
border-radius: 3px; | |
transition: width 0.3s ease; | |
} | |
.status-badge { | |
font-size: 10px; | |
padding: 3px 8px; | |
border-radius: 10px; | |
} | |
/* Dark mode compatibility */ | |
.dark .json-viewer { | |
background-color: #1e293b; | |
color: #f8fafc; | |
} | |
.dark .dropzone { | |
background-color: #1e293b; | |
border-color: #334155; | |
} | |
.dark .dropzone.active { | |
background-color: #1e3a8a; | |
border-color: #3b82f6; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 dark:bg-gray-900"> | |
<div class="flex h-screen overflow-hidden"> | |
<!-- Sidebar --> | |
<div class="sidebar bg-indigo-800 text-white flex flex-col"> | |
<div class="p-4 flex items-center border-b border-indigo-700"> | |
<div class="w-8 h-8 bg-white rounded-md flex items-center justify-center mr-2"> | |
<i class="fas fa-database text-indigo-800"></i> | |
</div> | |
<h1 class="logo-text text-xl font-bold">ETL Mapper Pro</h1> | |
</div> | |
<div class="flex-1 overflow-y-auto"> | |
<nav class="p-4"> | |
<div class="mb-6"> | |
<h2 class="sidebar-text text-xs uppercase font-semibold text-indigo-400 mb-2">Integration</h2> | |
<ul> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="dashboard"> | |
<i class="fas fa-tachometer-alt mr-3"></i> | |
<span class="sidebar-text">Dashboard</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded bg-indigo-900" data-tab="endpoints"> | |
<i class="fas fa-plug mr-3"></i> | |
<span class="sidebar-text">Endpoint Registry</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="mappings"> | |
<i class="fas fa-exchange-alt mr-3"></i> | |
<span class="sidebar-text">Data Mappings</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="jobs"> | |
<i class="fas fa-tasks mr-3"></i> | |
<span class="sidebar-text">ETL Jobs</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="scheduler"> | |
<i class="fas fa-clock mr-3"></i> | |
<span class="sidebar-text">Job Scheduler</span> | |
</li> | |
</ul> | |
</div> | |
<div class="mb-6"> | |
<h2 class="sidebar-text text-xs uppercase font-semibold text-indigo-400 mb-2">Development</h2> | |
<ul> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="tester"> | |
<i class="fas fa-bolt mr-3"></i> | |
<span class="sidebar-text">API Tester</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="scripts"> | |
<i class="fas fa-code mr-3"></i> | |
<span class="sidebar-text">Script Editor</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="templates"> | |
<i class="fas fa-layer-group mr-3"></i> | |
<span class="sidebar-text">Mapping Templates</span> | |
</li> | |
</ul> | |
</div> | |
<div> | |
<h2 class="sidebar-text text-xs uppercase font-semibold text-indigo-400 mb-2">Administration</h2> | |
<ul> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="users"> | |
<i class="fas fa-users mr-3"></i> | |
<span class="sidebar-text">User Management</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="settings"> | |
<i class="fas fa-cog mr-3"></i> | |
<span class="sidebar-text">System Settings</span> | |
</li> | |
<li class="nav-item mb-2 flex items-center px-2 py-2 rounded hover:bg-indigo-700" data-tab="logs"> | |
<i class="fas fa-clipboard-list mr-3"></i> | |
<span class="sidebar-text">Audit Logs</span> | |
</li> | |
</ul> | |
</div> | |
</nav> | |
</div> | |
<div class="p-4 border-t border-indigo-700"> | |
<div class="flex items-center"> | |
<img src="https://ui-avatars.com/api/?name=Admin+User&background=random" class="w-8 h-8 rounded-full mr-2" alt="User"> | |
<div class="sidebar-text"> | |
<p class="text-sm">Admin User</p> | |
<p class="text-xs text-indigo-300">[email protected]</p> | |
</div> | |
<button id="dark-mode-toggle" class="ml-auto text-indigo-200 hover:text-white"> | |
<i class="fas fa-moon"></i> | |
</button> | |
</div> | |
<button id="sidebar-collapse" class="mt-3 w-full py-1 bg-indigo-700 hover:bg-indigo-600 rounded text-xs flex items-center justify-center"> | |
<i class="fas fa-chevron-left sidebar-text mr-2"></i> | |
<span class="sidebar-text">Collapse</span> | |
</button> | |
</div> | |
</div> | |
<!-- Main Content --> | |
<div class="main-content flex-1 flex flex-col overflow-hidden"> | |
<!-- Top Navigation --> | |
<header class="bg-white dark:bg-gray-800 shadow-sm"> | |
<div class="flex items-center justify-between px-6 py-3"> | |
<div class="flex items-center"> | |
<button id="sidebar-toggle" class="mr-4 text-gray-500 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-100"> | |
<i class="fas fa-bars"></i> | |
</button> | |
<h1 id="page-title" class="text-xl font-semibold text-gray-800 dark:text-gray-100">Endpoint Registry</h1> | |
<nav class="flex ml-6 space-x-4" id="breadcrumb"> | |
<!-- Breadcrumb will be populated dynamically --> | |
</nav> | |
</div> | |
<div class="flex items-center space-x-4"> | |
<div class="relative"> | |
<button id="notification-btn" class="p-2 text-gray-500 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-100 relative"> | |
<i class="fas fa-bell"></i> | |
<span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full"></span> | |
</button> | |
<div id="notification-dropdown" class="absolute hidden right-0 mt-2 w-72 bg-white dark:bg-gray-800 rounded-md shadow-lg py-1 z-50 border border-gray-200 dark:border-gray-700"> | |
<div class="px-4 py-2 border-b border-gray-100 dark:border-gray-700"> | |
<p class="text-sm font-medium text-gray-800 dark:text-gray-200">Notifications</p> | |
</div> | |
<div class="max-h-60 overflow-y-auto"> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<i class="fas fa-check-circle text-green-500"></i> | |
</div> | |
<div class="ml-2"> | |
<p>Job 'Customer Sync' completed successfully</p> | |
<p class="text-xs text-gray-500">2 minutes ago</p> | |
</div> | |
</div> | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<i class="fas fa-exclamation-triangle text-yellow-500"></i> | |
</div> | |
<div class="ml-2"> | |
<p>API endpoint 'Orders API' is down</p> | |
<p class="text-xs text-gray-500">15 minutes ago</p> | |
</div> | |
</div> | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<i class="fas fa-info-circle text-blue-500"></i> | |
</div> | |
<div class="ml-2"> | |
<p>New version available (v2.4.1)</p> | |
<p class="text-xs text-gray-500">1 hour ago</p> | |
</div> | |
</div> | |
</a> | |
</div> | |
<div class="px-4 py-2 border-t border-gray-100 dark:border-gray-700"> | |
<a href="#" class="text-sm font-medium text-indigo-600 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300">View all notifications</a> | |
</div> | |
</div> | |
</div> | |
<div class="relative"> | |
<button id="help-btn" class="p-2 text-gray-500 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-100"> | |
<i class="fas fa-question-circle"></i> | |
</button> | |
<div id="help-dropdown" class="absolute hidden right-0 mt-2 w-64 bg-white dark:bg-gray-800 rounded-md shadow-lg py-1 z-50 border border-gray-200 dark:border-gray-700"> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-book mr-2"></i> Documentation | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-video mr-2"></i> Tutorial Videos | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-comments mr-2"></i> Support Forum | |
</a> | |
<div class="border-t border-gray-100 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-info-circle mr-2"></i> About ETL Mapper | |
</a> | |
</div> | |
</div> | |
<button id="quick-actions" class="flex items-center space-x-1 bg-indigo-100 dark:bg-indigo-900 hover:bg-indigo-200 dark:hover:bg-indigo-800 text-indigo-800 dark:text-indigo-200 px-3 py-1 rounded-md text-sm"> | |
<i class="fas fa-bolt"></i> | |
<span>Quick Actions</span> | |
</button> | |
</div> | |
</div> | |
</header> | |
<!-- Main Content Area --> | |
<main class="flex-1 overflow-y-auto p-6 bg-gray-50 dark:bg-gray-900"> | |
<!-- Dashboard Content (Hidden by default) --> | |
<div id="dashboard-content" class="tab-content"> | |
<div class="mb-6"> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">ETL Dashboard</h2> | |
<p class="text-gray-600 dark:text-gray-400">Overview of your integration workflows and system status</p> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6"> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-blue-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-blue-800 dark:text-blue-200">Active Endpoints</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">24</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">HTTP endpoints configured</div> | |
</div> | |
<div class="w-16 h-16 bg-blue-100 dark:bg-blue-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-plug text-blue-500 dark:text-blue-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-green-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-green-800 dark:text-green-200">Data Mappings</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">48</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Field mappings defined</div> | |
</div> | |
<div class="w-16 h-16 bg-green-100 dark:bg-green-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-exchange-alt text-green-500 dark:text-green-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-purple-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-purple-800 dark:text-purple-200">Running Jobs</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">3</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Active processes</div> | |
</div> | |
<div class="w-16 h-16 bg-purple-100 dark:bg-purple-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-tasks text-purple-500 dark:text-purple-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-red-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-red-800 dark:text-red-200">Errors Today</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">2</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Failed executions</div> | |
</div> | |
<div class="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-exclamation-triangle text-red-500 dark:text-red-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6"> | |
<div class="lg:col-span-2 bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Recent Job Activity</h3> | |
</div> | |
<div class="p-4"> | |
<div class="table-container"> | |
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> | |
<thead class="bg-gray-50 dark:bg-gray-700"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Job Name</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Duration</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Records</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Time</th> | |
</tr> | |
</thead> | |
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"> | |
<tr> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-green-100 dark:bg-green-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-green-600 dark:text-green-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Customer Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">CRM Database</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Completed</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">1.2s</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">125</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">2 min ago</td> | |
</tr> | |
<tr> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-yellow-100 dark:bg-yellow-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-spinner text-yellow-600 dark:text-yellow-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Order Processing</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">ERP System</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">Running</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">15.7s</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">32/87</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">5 min ago</td> | |
</tr> | |
<tr> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-blue-100 dark:bg-blue-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-blue-600 dark:text-blue-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Inventory Update</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Warehouse DB</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">Pending</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">-</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">0</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">10 min ago</td> | |
</tr> | |
<tr> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-red-100 dark:bg-red-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-exclamation-triangle text-red-600 dark:text-red-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Payment Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Accounting System</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200">Failed</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">4.8s</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">0/42</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">25 min ago</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">System Health</h3> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">CPU Usage</span> | |
<span class="text-sm text-gray-500 dark:text-gray-400">58%</span> | |
</div> | |
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | |
<div class="bg-yellow-500 h-2 rounded-full" style="width: 58%"></div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Memory Usage</span> | |
<span class="text-sm text-gray-500 dark:text-gray-400">4.2/8 GB</span> | |
</div> | |
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | |
<div class="bg-blue-500 h-2 rounded-full" style="width: 52.5%"></div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<div class="flex justify-between mb-1"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Disk Space</span> | |
<span class="text-sm text-gray-500 dark:text-gray-400">120/200 GB</span> | |
</div> | |
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | |
<div class="bg-green-500 h-2 rounded-full" style="width: 60%"></div> | |
</div> | |
</div> | |
<div class="space-y-2 mt-6"> | |
<div class="flex items-center justify-between"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Database Connections</span> | |
<span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full">12/25</span> | |
</div> | |
<div class="flex items-center justify-between"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">API Connections</span> | |
<span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full">8/20</span> | |
</div> | |
<div class="flex items-center justify-between"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Worker Processes</span> | |
<span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full">4/6</span> | |
</div> | |
<div class="flex items-center justify-between"> | |
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Queue Size</span> | |
<span class="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 rounded-full">3 items</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">ETL Job Activity (Last 7 Days)</h3> | |
<div class="flex space-x-2"> | |
<select class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>Last 7 Days</option> | |
<option>Last 30 Days</option> | |
<option>Last 90 Days</option> | |
<option>This Year</option> | |
</select> | |
<button class="text-xs bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 px-2 py-1 rounded-md"> | |
<i class="fas fa-download mr-1"></i> Export | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="h-64"> | |
<!-- Chart would be rendered here --> | |
<div class="flex items-center justify-center h-full bg-gray-100 dark:bg-gray-700 rounded-lg"> | |
<p class="text-gray-500 dark:text-gray-400">Job activity chart visualization</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Endpoints Content --> | |
<div id="endpoints-content" class="tab-content active"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">Endpoint Registry</h2> | |
<p class="text-gray-600 dark:text-gray-400">Manage all your API endpoints for data extraction and loading</p> | |
</div> | |
<div class="flex space-x-3"> | |
<button class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-sync-alt mr-2"></i> Refresh | |
</button> | |
<button id="add-endpoint-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-plus mr-2"></i> Add Endpoint | |
</button> | |
<div class="relative"> | |
<button id="endpoint-actions" class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-3 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-ellipsis-h"></i> | |
</button> | |
<div id="endpoint-actions-dropdown" class="absolute hidden right-0 mt-1 w-48 bg-white dark:bg-gray-800 rounded-md shadow-lg py-1 z-50 border border-gray-200 dark:border-gray-700"> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-file-export mr-2"></i> Export Endpoints | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-file-import mr-2"></i> Import Endpoints | |
</a> | |
<div class="border-t border-gray-200 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-shield-alt mr-2"></i> Test All Endpoints | |
</a> | |
<div class="border-t border-gray-200 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-trash-alt mr-2"></i> Delete Inactive | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-6 bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Filters</h3> | |
<button class="text-xs text-indigo-600 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300">Reset</button> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="grid grid-cols-1 md:grid-cols-4 gap-4"> | |
<div> | |
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">Status</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md text-sm focus:border-indigo-500 focus:ring-indigo-500"> | |
<option>All Statuses</option> | |
<option>Active</option> | |
<option>Inactive</option> | |
<option>Error</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">Method</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md text-sm focus:border-indigo-500 focus:ring-indigo-500"> | |
<option>All Methods</option> | |
<option>GET</option> | |
<option>POST</option> | |
<option>PUT</option> | |
<option>DELETE</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">Authentication</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md text-sm focus:border-indigo-500 focus:ring-indigo-500"> | |
<option>All Types</option> | |
<option>None</option> | |
<option>API Key</option> | |
<option>Basic Auth</option> | |
<option>OAuth 2.0</option> | |
<option>Bearer Token</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">Search</label> | |
<div class="relative"> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md text-sm focus:border-indigo-500 focus:ring-indigo-500 pl-8" placeholder="Search endpoints..."> | |
<div class="absolute left-2 top-2 text-gray-400"> | |
<i class="fas fa-search"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="table-container"> | |
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> | |
<thead class="bg-gray-50 dark:bg-gray-700"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Name</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">URL</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Method</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Auth</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Mappings</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Actions</th> | |
</tr> | |
</thead> | |
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-indigo-100 dark:bg-indigo-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-users text-indigo-600 dark:text-indigo-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Customer API</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Customers data</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">https://api.example.com/v1/customers</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">JSON</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">GET</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"> | |
<span class="flex items-center"> | |
<i class="fas fa-key mr-1 text-yellow-500"></i> API Key | |
</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="text-sm text-gray-900 dark:text-gray-100">3</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Test"> | |
<i class="fas fa-vial"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Mappings"> | |
<i class="fas fa-project-diagram"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-blue-100 dark:bg-blue-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-shopping-cart text-blue-600 dark:text-blue-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Orders API</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Order processing</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">https://api.example.com/v1/orders</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">XML</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">POST</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"> | |
<span class="flex items-center"> | |
<i class="fas fa-lock mr-1 text-purple-500"></i> OAuth 2.0 | |
</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="text-sm text-gray-900 dark:text-gray-100">2</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Test"> | |
<i class="fas fa-vial"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Mappings"> | |
<i class="fas fa-project-diagram"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-purple-100 dark:bg-purple-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-boxes text-purple-600 dark:text-purple-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Inventory API</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Product inventory</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">https://api.example.com/v1/inventory</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">JSON</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">GET</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"> | |
<span class="flex items-center"> | |
<i class="fas fa-user-shield mr-1 text-blue-500"></i> Basic Auth | |
</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">Warning</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="text-sm text-gray-900 dark:text-gray-100">1</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Test"> | |
<i class="fas fa-vial"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Mappings"> | |
<i class="fas fa-project-diagram"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-red-100 dark:bg-red-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-file-invoice-dollar text-red-600 dark:text-red-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Billing API</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Payment processing</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">https://api.example.com/v1/billing</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">JSON</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">POST</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"> | |
<span class="flex items-center"> | |
<i class="fas fa-token mr-1 text-green-500"></i> Bearer Token | |
</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200">Error</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="text-sm text-gray-900 dark:text-gray-100">0</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Test"> | |
<i class="fas fa-vial"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Mappings"> | |
<i class="fas fa-project-diagram"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-green-100 dark:bg-green-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-shipping-fast text-green-600 dark:text-green-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Shipping API</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Shipment tracking</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">https://api.example.com/v1/shipping</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">SOAP</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200">GET</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"> | |
<span class="flex items-center"> | |
<i class="fas fa-key mr-1 text-yellow-500"></i> API Key | |
</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="text-sm text-gray-900 dark:text-gray-100">2</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Test"> | |
<i class="fas fa-vial"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Mappings"> | |
<i class="fas fa-project-diagram"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<!-- Endpoint Detail Modal (Hidden by default) --> | |
<div id="endpoint-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-4xl max-h-[90vh] overflow-y-auto"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Endpoint Configuration</h3> | |
<button id="close-endpoint-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
<div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Endpoint Name *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Customer API"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Endpoint URL *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="https://api.example.com/v1/customers"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">HTTP Method *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>GET</option> | |
<option>POST</option> | |
<option>PUT</option> | |
<option>PATCH</option> | |
<option>DELETE</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label> | |
<textarea rows="2" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="API endpoint for customer data"></textarea> | |
</div> | |
</div> | |
<div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Authentication Type *</label> | |
<select id="auth-type" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option value="none">None</option> | |
<option value="api_key">API Key</option> | |
<option value="basic">Basic Auth</option> | |
<option value="bearer">Bearer Token</option> | |
<option value="oauth2">OAuth 2.0</option> | |
</select> | |
</div> | |
<!-- Dynamic auth fields based on selection --> | |
<div id="auth-fields"> | |
<!-- None - no fields --> | |
<div id="api-key-fields" class="auth-field hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">API Key *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter API key"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Key Location *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Header</option> | |
<option>Query Parameter</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Key Name *</label> | |
<input type="text" class="w-full border-gray-30 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="X-API-Key"> | |
</div> | |
</div> | |
<div id="basic-auth-fields" class="auth-field hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Username *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter username"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Password *</label> | |
<input type="password" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter password"> | |
</div> | |
</div> | |
<div id="bearer-token-fields" class="auth-field hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Bearer Token *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter token"> | |
</div> | |
</div> | |
<div id="oauth2-fields" class="auth-field hidden"> | |
<div class="grid grid-cols-2 gap-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Client ID *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter client ID"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Client Secret *</label> | |
<input type="password" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter client secret"> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Token URL *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="https://api.example.com/oauth/token"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Scope</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="read write"> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Advanced options --> | |
<div class="mt-6 border-t border-gray-200 dark:border-gray-700 pt-6"> | |
<button id="toggle-advanced" class="flex items-center text-sm text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 mb-4"> | |
<span>Advanced Options</span> | |
<i class="fas fa-chevron-down ml-1 text-xs"></i> | |
</button> | |
<div id="advanced-options" class="hidden space-y-4"> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Request Headers</label> | |
<div class="space-y-2"> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Header name"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Header value"> | |
<button class="bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-200 px-2 rounded-md"> | |
<i class="fas fa-plus"></i> | |
</button> | |
</div> | |
<div id="headers-list"> | |
<!-- Headers will be added here --> | |
</div> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Query Parameters</label> | |
<div class="space-y-2"> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Param name"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Param value"> | |
<button class="bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-200 px-2 rounded-md"> | |
<i class="fas fa-plus"></i> | |
</button> | |
</div> | |
<div id="query-params-list"> | |
<!-- Query params will be added here --> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Request Body (for POST/PUT)</label> | |
<div id="request-body-editor" class="border-gray-300 dark:border-gray-600 rounded-md" style="height: 150px;"></div> | |
<div class="mt-1 flex items-center space-x-2"> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Content Type:</span> | |
<select class="text-xs border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md"> | |
<option>application/json</option> | |
<option>application/xml</option> | |
<option>text/plain</option> | |
<option>application/x-www-form-urlencoded</option> | |
</select> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Timeout (seconds)</label> | |
<input type="number" value="30" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Retry Attempts</label> | |
<input type="number" value="3" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">SSL Verification</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Enabled</option> | |
<option>Disabled</option> | |
</select> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-end space-x-3"> | |
<button type="button" class="px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Cancel | |
</button> | |
<button type="button" class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Save Endpoint | |
</button> | |
<button type="button" id="test-endpoint-btn" class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> | |
Test Connection | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Mappings Content (Hidden by default) --> | |
<div id="mappings-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">Data Mappings</h2> | |
<p class="text-gray-600 dark:text-gray-400">Define how data transforms between source and target systems</p> | |
</div> | |
<div class="flex space-x-3"> | |
<button class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-sync-alt mr-2"></i> Refresh | |
</button> | |
<button id="add-mapping-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-plus mr-2"></i> New Mapping | |
</button> | |
<div class="relative"> | |
<button id="mapping-actions" class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-3 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-ellipsis-h"></i> | |
</button> | |
<div id="mapping-actions-dropdown" class="absolute hidden right-0 mt-1 w-48 bg-white dark:bg-gray-800 rounded-md shadow-lg py-1 z-50 border border-gray-200 dark:border-gray-700"> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-file-export mr-2"></i> Export Mappings | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-file-import mr-2"></i> Import Mappings | |
</a> | |
<div class="border-t border-gray-200 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-copy mr-2"></i> Clone Selected | |
</a> | |
<div class="border-t border-gray-200 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-trash-alt mr-2"></i> Delete Selected | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-6 bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Mapping Workspace</h3> | |
<div class="flex items-center space-x-2"> | |
<span class="text-xs text-gray-600 dark:text-gray-300">Mapping:</span> | |
<select id="current-mapping" class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>Customer API to CRM Database</option> | |
<option>Orders API to ERP System</option> | |
<option>Inventory to Warehouse DB</option> | |
</select> | |
<button id="save-mapping" class="text-xs bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 px-2 py-1 rounded-md"> | |
<i class="fas fa-save mr-1"></i> Save | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
<!-- Source Panel --> | |
<div class="bg-white dark:bg-gray-700 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-200">Source</h3> | |
<select id="source-system" class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>Customer API</option> | |
<option>Orders API</option> | |
<option>Inventory API</option> | |
</select> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Endpoint</label> | |
<select class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200"> | |
<option>GET /v1/customers</option> | |
<option>GET /v1/customers/{id}</option> | |
<option>POST /v1/customers</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Sample Payload</label> | |
<div class="json-viewer bg-gray-100 dark:bg-gray-800 dark:text-gray-200 rounded-md"> | |
{ | |
"customers": [ | |
{ | |
"id": 123, | |
"name": "John Doe", | |
"email": "[email protected]", | |
"address": { | |
"street": "123 Main St", | |
"city": "New York", | |
"zip": "10001" | |
}, | |
"status": "active", | |
"created_at": "2023-01-15T10:30:00Z" | |
} | |
] | |
} | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Available Fields</label> | |
<div class="dropzone dark:bg-gray-800 dark:border-gray-600" id="source-fields"> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].id">customers[].id</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].name">customers[].name</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].email">customers[].email</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].address.street">customers[].address.street</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].address.city">customers[].address.city</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].address.zip">customers[].address.zip</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].status">customers[].status</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customers[].created_at">customers[].created_at</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Mapping Panel --> | |
<div class="bg-white dark:bg-gray-700 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-200">Field Mappings</h3> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Mapping Name *</label> | |
<input type="text" class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200" placeholder="Customer to CRM Mapping"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label> | |
<textarea class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200" rows="2" placeholder="Mapping customer data from API to CRM database"></textarea> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Mapping Rules</label> | |
<div class="dropzone dark:bg-gray-800 dark:border-gray-600 min-h-40" id="mapping-rules"> | |
<!-- Mapped pairs will appear here --> | |
<div class="border border-gray-200 dark:border-gray-600 rounded-md p-3 mb-2 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between"> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Source</div> | |
<div class="text-sm font-medium">customers[].id</div> | |
</div> | |
<div class="text-gray-400 dark:text-gray-300 mx-2"> | |
<i class="fas fa-arrow-right"></i> | |
</div> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Target</div> | |
<div class="text-sm font-medium">customer_id</div> | |
</div> | |
<button class="text-red-500 hover:text-red-700"> | |
<i class="fas fa-times-circle"></i> | |
</button> | |
</div> | |
<div class="mt-2 border-t border-gray-200 dark:border-gray-600 pt-2"> | |
<div class="text-xs text-gray-500 dark:text-gray-400">No Transformation</div> | |
</div> | |
</div> | |
<div class="border border-gray-200 dark:border-gray-600 rounded-md p-3 mb-2 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between"> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Source</div> | |
<div class="text-sm font-medium">customers[].name</div> | |
</div> | |
<div class="text-gray-400 dark:text-gray-300 mx-2"> | |
<i class="fas fa-arrow-right"></i> | |
</div> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Target</div> | |
<div class="text-sm font-medium">full_name</div> | |
</div> | |
<button class="text-red-500 hover:text-red-700"> | |
<i class="fas fa-times-circle"></i> | |
</button> | |
</div> | |
<div class="mt-2 border-t border-gray-200 dark:border-gray-600 pt-2"> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Trim Whitespace</div> | |
</div> | |
</div> | |
<div class="border border-gray-200 dark:border-gray-600 rounded-md p-3 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between"> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Source</div> | |
<div class="text-sm font-medium">customers[].created_at</div> | |
</div> | |
<div class="text-gray-400 dark:text-gray-300 mx-2"> | |
<i class="fas fa-arrow-right"></i> | |
</div> | |
<div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Target</div> | |
<div class="text-sm font-medium">registration_date</div> | |
</div> | |
<button class="text-red-500 hover:text-red-700"> | |
<i class="fas fa-times-circle"></i> | |
</button> | |
</div> | |
<div class="mt-2 border-t border-gray-200 dark:border-gray-600 pt-2"> | |
<div class="text-xs text-gray-500 dark:text-gray-400">ISO8601 to SQL Datetime</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-4 py-3 border-t border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-200">Transformations</h3> | |
<button id="add-transformation" class="text-xs bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 px-2 py-1 rounded-md"> | |
<i class="fas fa-plus mr-1"></i> Add | |
</button> | |
</div> | |
<div class="p-4"> | |
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-blue-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Trim Whitespace</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">String</div> | |
</div> | |
</div> | |
</div> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-purple-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Convert Case</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">String</div> | |
</div> | |
</div> | |
</div> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-green-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Date Format</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Date/Time</div> | |
</div> | |
</div> | |
</div> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-yellow-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Math Operation</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Number</div> | |
</div> | |
</div> | |
</div> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-red-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Conditional</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Logic</div> | |
</div> | |
</div> | |
</div> | |
<div class="transformation-card p-3 border border-gray-200 dark:border-gray-600 rounded-md"> | |
<div class="flex items-center"> | |
<div class="mr-3 text-indigo-500"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium">Custom Script</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Advanced</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Target Panel --> | |
<div class="bg-white dark:bg-gray-700 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-200">Target</h3> | |
<select id="target-system" class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>CRM Database</option> | |
<option>ERP System</option> | |
<option>Data Warehouse</option> | |
</select> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Table *</label> | |
<select class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200"> | |
<option>customers</option> | |
<option>orders</option> | |
<option>products</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Table Schema</label> | |
<div class="json-viewer bg-gray-100 dark:bg-gray-800 dark:text-gray-200 rounded-md"> | |
{ | |
"table": "customers", | |
"columns": [ | |
{"name": "customer_id", "type": "INT", "primary": true}, | |
{"name": "full_name", "type": "VARCHAR(255)"}, | |
{"name": "email_address", "type": "VARCHAR(255)"}, | |
{"name": "street_address", "type": "VARCHAR(255)"}, | |
{"name": "city", "type": "VARCHAR(100)"}, | |
{"name": "postal_code", "type": "VARCHAR(20)"}, | |
{"name": "account_status", "type": "VARCHAR(50)"}, | |
{"name": "registration_date", "type": "DATETIME"} | |
] | |
} | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Target Fields</label> | |
<div class="dropzone dark:bg-gray-800 dark:border-gray-600" id="target-fields"> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="customer_id">customer_id</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="full_name">full_name</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="email_address">email_address</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="street_address">street_address</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="city">city</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="postal_code">postal_code</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="account_status">account_status</div> | |
<div class="draggable bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2 cursor-move" draggable="true" data-field="registration_date">registration_date</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-end space-x-3"> | |
<button class="px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Cancel | |
</button> | |
<button class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Save Mapping | |
</button> | |
<button class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> | |
Test Mapping | |
</button> | |
</div> | |
</div> | |
<!-- Transformation Modal (Hidden by default) --> | |
<div id="transformation-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Add Transformation</h3> | |
<button id="close-transformation-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Transformation Type *</label> | |
<select id="transformation-type" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option value="">Select a transformation...</option> | |
<option value="trim">Trim Whitespace</option> | |
<option value="case">Convert Case</option> | |
<option value="date">Date Format</option> | |
<option value="math">Math Operation</option> | |
<option value="conditional">Conditional Logic</option> | |
<option value="script">Custom Script</option> | |
</select> | |
</div> | |
<div id="transformation-params"> | |
<!-- Dynamic fields based on transformation type --> | |
<div id="trim-params" class="transformation-param hidden"> | |
<p class="text-sm text-gray-500 dark:text-gray-400 mb-3">Trim leading and trailing whitespace from the value.</p> | |
</div> | |
<div id="case-params" class="transformation-param hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Convert To</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>UPPERCASE</option> | |
<option>lowercase</option> | |
<option>Title Case</option> | |
</select> | |
</div> | |
</div> | |
<div id="date-params" class="transformation-param hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Source Format</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="ISO8601"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Target Format</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="YYYY-MM-DD"> | |
</div> | |
</div> | |
<div id="math-params" class="transformation-param hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Operation</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Add</option> | |
<option>Subtract</option> | |
<option>Multiply</option> | |
<option>Divide</option> | |
<option>Modulo</option> | |
<option>Round</option> | |
<option>Ceiling</option> | |
<option>Floor</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block textsm font-medium text-gray-700 dark:text-gray-300 mb-1">Value</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Enter number or field reference"> | |
</div> | |
</div> | |
<div id="conditional-params" class="transformation-param hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Condition Type</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>If-Then</option> | |
<option>Switch Case</option> | |
</select> | |
</div> | |
<div class="mb-4 space-y-2"> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Condition"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Then value"> | |
<button class="bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-200 px-2 rounded-md"> | |
<i class="fas fa-plus"></i> | |
</button> | |
</div> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Else value"> | |
</div> | |
</div> | |
</div> | |
<div id="script-params" class="transformation-param hidden"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Language</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>JavaScript</option> | |
<option>Python</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Script</label> | |
<textarea rows="4" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="// Write your transformation script here"></textarea> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-end space-x-3"> | |
<button type="button" id="cancel-transformation" class="px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Cancel | |
</button> | |
<button type="button" id="save-transformation" class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Add Transformation | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Jobs Content (Hidden by default) --> | |
<div id="jobs-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">ETL Jobs</h2> | |
<p class="text-gray-600 dark:text-gray-400">Configure and monitor your automated data integration jobs</p> | |
</div> | |
<div class="flex space-x-3"> | |
<button class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-sync-alt mr-2"></i> Refresh | |
</button> | |
<button id="add-job-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-plus mr-2"></i> Create Job | |
</button> | |
<div class="relative"> | |
<button id="job-actions" class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-3 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-ellipsis-h"></i> | |
</button> | |
<div id="job-actions-dropdown" class="absolute hidden right-0 mt-1 w-48 bg-white dark:bg-gray-800 rounded-md shadow-lg py-1 z-50 border border-gray-200 dark:border-gray-700"> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-play mr-2"></i> Run Selected | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-pause mr-2"></i> Pause Selected | |
</a> | |
<a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-file-export mr-2"></i> Export Jobs | |
</a> | |
<div class="border-t border-gray-200 dark:border-gray-700"></div> | |
<a href="#" class="block px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<i class="fas fa-trash-alt mr-2"></i> Delete Selected | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6"> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-green-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-green-800 dark:text-green-200">Running Jobs</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">3</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Active processes</div> | |
</div> | |
<div class="w-16 h-16 bg-green-100 dark:bg-green-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-green-500 dark:text-green-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-blue-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-blue-800 dark:text-blue-200">Scheduled</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">7</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Waiting to run</div> | |
</div> | |
<div class="w-16 h-16 bg-blue-100 dark:bg-blue-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-clock text-blue-500 dark:text-blue-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-purple-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-purple-800 dark:text-purple-200">Completed</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">12</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Today</div> | |
</div> | |
<div class="w-16 h-16 bg-purple-100 dark:bg-purple-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-check-circle text-purple-500 dark:text-purple-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-red-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-red-800 dark:text-red-200">Failed</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-center justify-between"> | |
<div> | |
<div class="text-3xl font-bold text-gray-800 dark:text-gray-100 mb-2">2</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Today</div> | |
</div> | |
<div class="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center"> | |
<i class="fas fa-exclamation-triangle text-red-500 dark:text-red-300 text-xl"></i> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden mb-6"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Job Status Timeline</h3> | |
<select class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>Last 24 Hours</option> | |
<option>Last 7 Days</option> | |
<option>Last 30 Days</option> | |
<option>Custom Range</option> | |
</select> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="h-64"> | |
<!-- Timeline chart would be rendered here --> | |
<div class="flex items-center justify-center h-full bg-gray-100 dark:bg-gray-700 rounded-lg"> | |
<p class="text-gray-500 dark:text-gray-400">Job execution timeline visualization</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="table-container"> | |
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> | |
<thead class="bg-gray-50 dark:bg-gray-700"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Job Name</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Mapping</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Schedule</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Last Run</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Next Run</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Actions</th> | |
</tr> | |
</thead> | |
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-green-100 dark:bg-green-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-green-600 dark:text-green-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Customer Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Hourly update</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Customer to CRM</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">API → Database</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Every 1 hour</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 14:30:12</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Success</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-15 15:30:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Running</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-yellow-600 hover:text-yellow-900 dark:hover:text-yellow-300" title="Pause"> | |
<i class="fas fa-pause"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Logs"> | |
<i class="fas fa-clipboard-list"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-yellow-100 dark:bg-yellow-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-spinner text-yellow-600 dark:text-yellow-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Order Processing</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Order to ERP</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Orders to ERP</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">API → System</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Every 30 minutes</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 14:00:37</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Partial (32/87)</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-15 14:30:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">Queued</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-purple-600 hover:text-purple-900 dark:hover:text-purple-300" title="Run Now"> | |
<i class="fas fa-play"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Logs"> | |
<i class="fas fa-clipboard-list"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-blue-100 dark:bg-blue-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-blue-600 dark:text-blue-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Inventory Update</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Warehouse stock</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Inventory to WH</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">API → Database</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Daily at 2:00 AM</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 02:00:15</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Success</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-16 02:00:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-purple-600 hover:text-purple-900 dark:hover:text-purple-300" title="Run Now"> | |
<i class="fas fa-play"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Logs"> | |
<i class="fas fa-clipboard-list"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<input type="checkbox" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-red-100 dark:bg-red-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-exclamation-triangle text-red-600 dark:text-red-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Payment Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">Accounting data</div> | |
</div> | |
</div> | |
</td> | |
<td class="px-6 py-4"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Payments to Acct</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">API → System</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Every 15 minutes</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 14:15:08</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Failed</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-15 14:30:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200">Error</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x=2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-purple-600 hover:text-purple-900 dark:hover:text-purple-300" title="Run Now"> | |
<i class="fas fa-play"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="View Logs"> | |
<i class="fas fa-clipboard-list"></i> | |
</button> | |
<button class="text-red-600 hover:text-red-900 dark:hover:text-red-300" title="Delete"> | |
<i class="fas fa-trash-alt"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex items-center justify-between"> | |
<div class="flex-1 flex justify-between sm:hidden"> | |
<a href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"> Previous </a> | |
<a href="#" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"> Next </a> | |
</div> | |
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between"> | |
<div> | |
<p class="text-sm text-gray-700 dark:text-gray-300"> | |
Showing | |
<span class="font-medium">1</span> | |
to | |
<span class="font-medium">4</span> | |
of | |
<span class="font-medium">12</span> | |
results | |
</p> | |
</div> | |
<div> | |
<nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination"> | |
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"> <span class="sr-only">Previous</span> <i class="fas fa-chevron-left"></i> </a> | |
<a href="#" aria-current="page" class="z-10 bg-indigo-50 border-indigo-500 text-indigo-600 relative inline-flex items-center px-4 py-2 border text-sm font-medium"> 1 </a> | |
<a href="#" class="bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium"> 2 </a> | |
<a href="#" class="bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium"> 3 </a> | |
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"> <span class="sr-only">Next</span> <i class="fas fa-chevron-right"></i> </a> | |
</nav> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Job Detail Modal (Hidden by default) --> | |
<div id="job-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-2xl"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Create ETL Job</h3> | |
<button id="close-job-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Job Name *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Customer Data Sync"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Data Mapping *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Select a mapping...</option> | |
<option>Customer to CRM</option> | |
<option>Orders to ERP</option> | |
<option>Inventory to Warehouse</option> | |
</select> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Execution Mode *</label> | |
<select id="execution-mode" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option value="manual">Manual</option> | |
<option value="scheduled">Scheduled</option> | |
<option value="trigger">Event Trigger</option> | |
</select> | |
</div> | |
<div id="schedule-frequency-container" class="hidden"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Frequency *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Once</option> | |
<option>Minutely</option> | |
<option>Hourly</option> | |
<option>Daily</option> | |
<option>Weekly</option> | |
<option>Monthly</option> | |
<option>Custom CRON</option> | |
</select> | |
</div> | |
<div id="start-time-container" class="hidden"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Start Time *</label> | |
<input type="datetime-local" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
<div id="end-time-container" class="hidden"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">End Time</label> | |
<input type="datetime-local" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
</div> | |
<div id="cron-expression-container" class="hidden"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">CRON Expression</label> | |
<div class="flex"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-l-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="* * * * *"> | |
<button class="inline-flex items-center px-3 py-2 border border-l-0 border-gray-300 dark:border-gray-600 rounded-r-md bg-gray-50 dark:bg-gray-700 text-gray-500 dark:text-gray-300"> | |
<i class="fas fa-question-circle"></i> | |
</button> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label> | |
<textarea rows="2" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Job description..."></textarea> | |
</div> | |
<div class="pt-4 border-t border-gray-200 dark:border-gray-700"> | |
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Advanced Options</h4> | |
<div class="space-y-3"> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml-3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Enable error notifications</label> | |
<p class="text-gray-500 dark:text-gray-400">Send email alerts when this job fails</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml-3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Stop on error</label> | |
<p class="text-gray-500 dark:text-gray-400">Abort job if any record fails to process</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml-3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Enable logging</label> | |
<p class="text-gray-500 dark:text-gray-400">Save detailed execution logs for auditing</p> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Retry Policy</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>No retry</option> | |
<option>Retry 3 times (default)</option> | |
<option>Retry until success</option> | |
<option>Custom retry policy</option> | |
</select> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-end space-x-3"> | |
<button type="button" class="px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Cancel | |
</button> | |
<button type="button" class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Create Job | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Job Logs Modal (Hidden by default) --> | |
<div id="job-logs-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-4xl max-h-[80vh] overflow-y-auto"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Job Execution Details</h3> | |
<button id="close-job-logs-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="flex items-center justify-between mb-6"> | |
<div> | |
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100">Customer Sync Job</h4> | |
<p class="text-sm text-gray-500 dark:text-gray-400">Execution ID: JOB-20230615-1423-4892</p> | |
</div> | |
<div> | |
<span class="px-3 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Completed</span> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> | |
<div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-md"> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">General Info</h5> | |
<div class="space-y-2"> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Start Time</span> | |
<p class="text-sm">2023-06-15 14:23:15 UTC</p> | |
</div> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">End Time</span> | |
<p class="text-sm">2023-06-15 14:23:37 UTC</p> | |
</div> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Duration</span> | |
<p class="text-sm">22 seconds</p> | |
</div> | |
</div> | |
</div> | |
<div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-md"> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Statistics</h5> | |
<div class="space-y-2"> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Records Processed</span> | |
<p class="text-sm">125 records</p> | |
</div> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Records Skipped</span> | |
<p class="text-sm">0 records</p> | |
</div> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Throughput</span> | |
<p class="text-sm">~5.7 records/sec</p> | |
</div> | |
</div> | |
</div> | |
<div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-md"> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Resources</h5> | |
<div class="space-y-2"> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">Memory Usage</span> | |
<div class="w-full bg-gray-200 dark:bg-gray-600 rounded-full h-1.5"> | |
<div class="bg-blue-600 h-1.5 rounded-full" style="width: 45%"></div> | |
</div> | |
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">95MB / 512MB allocated</p> | |
</div> | |
<div> | |
<span class="text-xs text-gray-500 dark:text-gray-400">CPU Usage</span> | |
<div class="w-full bg-gray-200 dark:bg-gray-600 rounded-full h-1.5"> | |
<div class="bg-green-600 h-1.5 rounded-full" style="width: 32%"></div> | |
</div> | |
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Average: 32%</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-6"> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Execution Log</h5> | |
<div class="bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md p-4 max-h-60 overflow-y-auto"> | |
<div class="font-mono text-xs"> | |
<div class="text-green-600 dark:text-green-400">[14:23:15] INFO: Job JOB-20230615-1423-4892 started</div> | |
<div class="text-blue-600 dark:text-blue-400">[14:23:15] INFO: Connecting to source system (Customer API)</div> | |
<div class="text-blue-600 dark:text-blue-400">[14:23:15] INFO: Source connection established</div> | |
<div class="text-blue-600 dark:text-blue-400">[14:23:16] INFO: Connecting to target system (CRM Database)</div> | |
<div class="text-blue-600 dark:text-blue-400">[14:23:16] INFO: Target connection established</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:16] INFO: Processing batch 1/3 (50 records)</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:21] INFO: Processed batch 1/3 (50 records) in 5.2s</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:21] INFO: Processing batch 2/3 (50 records)</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:26] INFO: Processed batch 2/3 (50 records) in 5.1s</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:26] INFO: Processing batch 3/3 (25 records)</div> | |
<div class="text-gray-600 dark:text-gray-400">[14:23:30] INFO: Processed batch 3/3 (25 records) in 4.8s</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:30] INFO: Job completed successfully</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:30] INFO: Disconnecting from source system</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:30] INFO: Disconnecting from target system</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:31] INFO: All connections closed</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:31] INFO: Job execution summary: 125 records processed (0 failed)</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:31] INFO: Memory usage: 95MB, Duration: 22.3s</div> | |
<div class="text-green-600 dark:text-green-400">[14:23:31] INFO: Job JOB-20230615-1423-4892 completed</div> | |
</div> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
<div> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Source Summary</h5> | |
<div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-md"> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">API Endpoint:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">GET /v1/customers</span> | |
</div> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Data Format:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">JSON</span> | |
</div> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Request Time:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">1.3s</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Data Size:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">92KB</span> | |
</div> | |
</div> | |
</div> | |
<div> | |
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Target Summary</h5> | |
<div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-md"> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Destination:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">CRM Database</span> | |
</div> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Table:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">customers</span> | |
</div> | |
<div class="flex justify-between mb-2"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Operation:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">Insert/Update</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Commit Time:</span> | |
<span class="text-xs text-gray-700 dark:text-gray-200">18.4s</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-between"> | |
<button class="text-xs bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 px-3 py-1 rounded-md"> | |
<i class="fas fa-download mr-1"></i> Export Log | |
</button> | |
<button class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-md"> | |
Close | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Scheduler Content (Hidden by default) --> | |
<div id="scheduler-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100">Job Scheduler</h2> | |
<button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-plus mr-2"></i> New Schedule | |
</button> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden mb-6"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Upcoming Jobs</h3> | |
</div> | |
<div class="p-4"> | |
<div class="space-y-4"> | |
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded-md"> | |
<div class="flex items-center"> | |
<div class="p-2 bg-blue-100 dark:bg-blue-900 rounded-full mr-3"> | |
<i class="fas fa-sync-alt text-blue-500 dark:text-blue-300"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Customer Sync</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Every hour</div> | |
</div> | |
</div> | |
<div class="text-right"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">15:30:00</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">In 42 minutes</div> | |
</div> | |
</div> | |
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded-md"> | |
<div class="flex items-center"> | |
<div class="p-2 bg-purple-100 dark:bg-purple-900 rounded-full mr-3"> | |
<i class="fas fa-shopping-cart text-purple-500 dark:text-purple-300"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Order Processing</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Every 15 minutes</div> | |
</div> | |
</div> | |
<div class="text-right"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">14:45:00</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">In 3 minutes</div> | |
</div> | |
</div> | |
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded-md"> | |
<div class="flex items-center"> | |
<div class="p-2 bg-green-100 dark:bg-green-900 rounded-full mr-3"> | |
<i class="fas fa-boxes text-green-500 dark:text-green-300"></i> | |
</div> | |
<div> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Inventory Update</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Daily at 2:00 AM</div> | |
</div> | |
</div> | |
<div class="text-right"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">02:00:00</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Tomorrow</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Scheduled Jobs</h3> | |
<select class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
<option>All Statuses</option> | |
<option>Active</option> | |
<option>Paused</option> | |
<option>Completed</option> | |
</select> | |
</div> | |
</div> | |
<div class="table-container"> | |
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> | |
<thead class="bg-gray-50 dark:bg-gray-700"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Job</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Schedule</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Last Run</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Next Run</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Actions</th> | |
</tr> | |
</thead> | |
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-green-100 dark:bg-green-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-sync-alt text-green-600 dark:text-green-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Customer Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">ETL Job</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Every 1 hour</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">CRON: 0 * * * *</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 14:23:37</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Success</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-15 15:23:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-yellow-600 hover:text-yellow-900 dark:hover:text-yellow-300" title="Pause"> | |
<i class="fas fa-pause"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="History"> | |
<i class="fas fa-history"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-purple-100 dark:bg-purple-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-shopping-cart text-purple-600 dark:text-purple-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Order Processing</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">ETL Job</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Every 15 minutes</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">CRON: */15 * * * *</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 14:30:08</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Success</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-15 14:45:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-yellow-600 hover:text-yellow-900 dark:hover:text-yellow-300" title="Pause"> | |
<i class="fas fa-pause"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="History"> | |
<i class="fas fa-history"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w-10 bg-blue-100 dark:bg-blue-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-boxes text-blue-600 dark:text-blue-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Inventory Update</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">ETL Job</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">Daily at 2:00 AM</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">CRON: 0 2 * * *</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-15 02:00:17</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Success</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-06-16 02:00:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">Active</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-yellow-600 hover:text-yellow-900 dark:hover:text-yellow-300" title="Pause"> | |
<i class="fas fa-pause"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="History"> | |
<i class="fas fa-history"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700"> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-10 w=10 bg-red-100 dark:bg-red-900 rounded-md flex items-center justify-center"> | |
<i class="fas fa-file-invoice-dollar text-red-600 dark:text-red-300"></i> | |
</div> | |
<div class="ml-4"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">Billing Sync</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">ETL Job</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray=900 dark:text-gray-100">Monthly (1st at 3:00 AM)</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">CRON: 0 3 1 * *</div> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<div class="text-sm text-gray-900 dark:text-gray-100">2023-06-01 03:00:23</div> | |
<div class="text-xs text-gray-500 dark:text-gray-400">Failed</div> | |
</td> | |
<td class="px=6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"> | |
2023-07-01 03:00:00 | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap"> | |
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">Paused</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
<div class="flex space-x-2"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300" title="Edit"> | |
<i class="fas fa-pencil-alt"></i> | |
</button> | |
<button class="text-green-600 hover:text-green-900 dark:hover:text-green-300" title="Resume"> | |
<i class="fas fa-play"></i> | |
</button> | |
<button class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-300" title="History"> | |
<i class="fas fa-history"></i> | |
</button> | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<!-- Schedule Modal (Hidden by default) --> | |
<div id="schedule-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-xl"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Schedule Settings</h3> | |
<button id="close-schedule-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="space-y-6"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Job *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Select a job...</option> | |
<option>Customer Sync</option> | |
<option>Order Processing</option> | |
<option>Inventory Update</option> | |
<option>Billing Sync</option> | |
</select> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Schedule Type *</label> | |
<select id="schedule-type" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option value="simple">Simple</option> | |
<option value="advanced">Advanced (CRON)</option> | |
</select> | |
</div> | |
<div id="simple-freq"> | |
<label class="block text-sm font-medium text-gray=700 dark:text-gray-300 mb-1">Frequency *</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Once</option> | |
<option>Minutely</option> | |
<option>Hourly</option> | |
<option>Daily</option> | |
<option>Weekly</option> | |
<option>Monthly</option> | |
<option>Yearly</option> | |
</select> | |
</div> | |
<div id="cron-expression" class="hidden"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">CRON Expression *</label> | |
<input type="text" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="* * * * *"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Start Date/Time *</label> | |
<input type="datetime-local" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">End Date/Time</label> | |
<input type="datetime-local" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Timezone</label> | |
<select class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>UTC</option> | |
<option>Local Time (America/New_York)</option> | |
</select> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label> | |
<textarea rows="2" class="w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Describe this schedule..."></textarea> | |
</div> | |
<div class="pt-3 border-t border-gray-200 dark:border-gray-700"> | |
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Advanced Options</h4> | |
<div class="space-y-2"> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml-3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Active</label> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml-3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Catch up missed executions</label> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex items-center h-5"> | |
<input type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 dark:bg-gray-700 rounded"> | |
</div> | |
<div class="ml=3 text-sm"> | |
<label class="font-medium text-gray-700 dark:text-gray-300">Overlap prevention</label> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 flex justify-end space-x-3"> | |
<button type="button" class="px-4 py=2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray=200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Cancel | |
</button> | |
<button type="button" class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
Save Schedule | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- API Tester Content (Hidden by default) --> | |
<div id="tester-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">API Tester</h2> | |
<p class="text-gray-600 dark:text-gray-400">Test and debug your API endpoints in real-time</p> | |
</div> | |
<button id="run-test-btn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-play mr-2"></i> Run Test | |
</button> | |
</div> | |
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6"> | |
<!-- Request Panel --> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-200">Request</h3> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Endpoint</label> | |
<select class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200"> | |
<option>Select an endpoint...</option> | |
<option>Customer API - GET /v1/customers</option> | |
<option>Orders API - POST /v1/orders</option> | |
<option>Inventory API - GET /v1/inventory</option> | |
</select> | |
</div> | |
<div class="grid grid-cols-2 gap-4 mb-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">HTTP Method</label> | |
<select class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:text-gray-200"> | |
<option>GET</option> | |
<option>POST</option> | |
<option>PUT</option> | |
<option>PATCH</option> | |
<option>DELETE</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Timeout (ms)</label> | |
<input type="number" value="30000" class="block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray=700 dark:text-gray-200"> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Request Headers</label> | |
<div class="space-y-2"> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Header name"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Header value"> | |
<button class="bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-200 px-2 rounded-md"> | |
<i class="fas fa-plus"></i> | |
</button> | |
</div> | |
<div id="test-headers-list"> | |
<!-- Headers will be added here --> | |
<div class="flex items-center justify-between px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded"> | |
<div class="text-xs">Content-Type: application/json</div> | |
<button class="text-red-500 hover:text-red-700 text-xs"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Query Parameters</label> | |
<div class="space-y-2"> | |
<div class="flex space-x-2"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray=600 dark:bg-gray=700 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Param name"> | |
<input type="text" class="flex-1 border-gray-300 dark:border-gray=600 dark:bg-gray=700 dark:text-gray=200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Param value"> | |
<button class="bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray=600 text-gray=700 dark:text-gray=200 px-2 rounded-md"> | |
<i class="fas fa-plus"></i> | |
</button> | |
</div> | |
<div id="test-query-params-list"> | |
<!-- Query params will be added here --> | |
</div> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray=700 dark:text-gray=300 mb-1">Request Body</label> | |
<div id="test-request-body-editor" class="border-gray-300 dark:border-gray-600 rounded-md" style="height: 150px;"></div> | |
</div> | |
</div> | |
</div> | |
<!-- Response Panel --> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray=700 bg-blue-50 dark:bg-gray=700"> | |
<div class="flex justify-between items-center"> | |
<h3 class="text-sm font-medium text-blue-800 dark:text-blue-200">Response</h3> | |
<div class="flex items-center space-x-2"> | |
<span class="text-xs bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-gray-200 px-2 py-1 rounded">Status: --</span> | |
<span class="text-xs bg-gray=200 dark:bg-gray=600 text-gray-800 dark:text-gray=200 px-2 py-1 rounded">Time: --ms</span> | |
<span class="text-xs bg-gray=200 dark:bg-gray=600 text-gray-800 dark:text-gray=200 px=2 py=1 rounded">Size: --KB</span> | |
</div> | |
</div> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<div class="flex border-b border-gray-200 dark:border-gray-600"> | |
<button class="px-4 py-2 text-sm font-medium border-b-2 border-blue-500 text-blue-600">Body</button> | |
<button class="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray 400 hover:text-gray-700 dark:hover:text-gray-300">Headers</button> | |
<button class="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray=300">Cookies</button> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<div class="flex items-center justify-between mb-2"> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Response Data</label> | |
<div class="flex space-x-2"> | |
<button class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 px-2 py-1 rounded"> | |
<i class="fas fa-copy mr-1"></i> Copy | |
</button> | |
<button class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 px-2 py-1 rounded"> | |
<i class="fas fa-search-plus mr-1"></i> Expand | |
</button> | |
</div> | |
</div> | |
<div class="json-viewer bg-gray-100 dark:bg-gray-800 dark:text-gray-200 rounded-md min-h-64 flex items-center justify-center"> | |
<p class="text-gray-500 dark:text-gray-400">Run a request to see response data</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Script Editor Content (Hidden by default) --> | |
<div id="scripts-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">Script Editor</h2> | |
<p class="text-gray-600 dark:text-gray-400">Create and manage custom transformation scripts</p> | |
</div> | |
<div class="flex space-x-3"> | |
<button class="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-save mr-2"></i> Save | |
</button> | |
<button class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-play mr-2"></i> Run | |
</button> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<div class="flex justify-between items-center"> | |
<div class="flex items-center space-x-4"> | |
<select class="border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"> | |
<option>Select a script...</option> | |
<option>Customer Name Formatter</option> | |
<option>Date Converter</option> | |
<option>Currency Normalizer</option> | |
</select> | |
<span class="text-xs bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 px-2 py-1 rounded">JavaScript</span> | |
</div> | |
<div> | |
<button class="text-xs bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 px-2 py-1 rounded"> | |
<i class="fas fa-plus mr-1"></i> New Script | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="h-96" id="script-editor"> | |
<!-- Code editor would be rendered here --> | |
<div class="flex items-center justify-center h-full bg-gray-100 dark:bg-gray-800"> | |
<div class="text-center"> | |
<div class="text-gray-500 dark:text-gray-400 mb-2"> | |
<i class="fas fa-code text-4xl"></i> | |
</div> | |
<p class="text-gray-500 dark:text-gray-400">Select or create a script to edit</p> | |
</div> | |
</div> | |
</div> | |
<div class="p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700"> | |
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Test Script</h4> | |
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Input Data</label> | |
<div id="script-input-editor" class="border-gray-300 dark:border-gray-600 rounded-md" style="height: 120px;"></div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Output Result</label> | |
<div id="script-output-editor" class="border-gray-300 dark:border-gray-600 rounded-md bg-gray-100 dark:bg-gray-800" style="height: 120px;"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Mapping Templates Content (Hidden by default) --> | |
<div id="templates-content" class="tab-content"> | |
<div class="flex justify-between items-center mb-6"> | |
<div> | |
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 mb-2">Mapping Templates</h2> | |
<p class="text-gray-600 dark:text-gray-400">Predefined templates for common data integration patterns</p> | |
</div> | |
<button id="add-template-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> | |
<i class="fas fa-plus mr-2"></i> New Template | |
</button> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-indigo-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-indigo-800 dark:text-indigo-200">API to Database</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 h-10 w-10 bg-indigo-100 dark:bg-indigo-900 rounded-md flex items-center justify-center mr-3"> | |
<i class="fas fa-database text-indigo-600 dark:text-indigo-300"></i> | |
</div> | |
<div> | |
<h4 class="text-sm font-medium text-gray-900 dark:text-gray-100">Basic API to SQL Mapping</h4> | |
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Maps JSON API response to a relational database table with field transformations.</p> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<span class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 px-2 py-1 rounded">JSON to SQL</span> | |
<button class="text-xs bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-2 py-1 rounded"> | |
Use Template | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px=4 py=3 border-b border-gray-200 dark:border-gray-700 bg-purple-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-purple-800 dark:text-purple-200">Flat File to Database</h3> | |
</div> | |
<div class="p=4"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 h-10 w-10 bg-purple-100 dark:bg-purple-900 rounded-md flex items-center justify-center mr-3"> | |
<i class="fas fa-file-excel text-purple-600 dark:text-purple-300"></i> | |
</div> | |
<div> | |
<h4 class="text-sm font-medium text-gray-900 dark:text-gray-100">CSV/Excel to SQL</h4> | |
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Maps spreadsheet data to a database table with type conversion and validation.</p> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<span class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 px-2 py-1 rounded">CSV to SQL</span> | |
<button class="text-xs bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-2 py-1 rounded"> | |
Use Template | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-green-50 dark:bg-gray-700"> | |
<h3 class="text-sm font-medium text-green-800 dark:text-green-200">Database to API</h3> | |
</div> | |
<div class="p-4"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 h-10 w-10 bg-green-100 dark:bg-green-900 rounded-md flex items-center justify-center mr-3"> | |
<i class="fas fa-server text-green-600 dark:text-green-300"></i> | |
</div> | |
<div> | |
<h4 class="text-sm font-medium text-gray-900 dark:text-gray-100">SQL to REST API</h4> | |
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Transforms database query results to a REST API compatible JSON structure.</p> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<span class="text-xs bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 px-2 py-1 rounded">SQL to JSON</span> | |
<button class="text-xs bg-gray-100 dark:bg-gray=700 hover:bg-gray-200 dark:hover:bg-gray=600 text-gray-800 dark:text-gray-200 px=2 py-1 rounded"> | |
Use Template | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mt-8"> | |
<h3 class="text-lg font-semibold text-gray-800 dark:text-gray-100 mb-4">Recent Templates</h3> | |
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden"> | |
<div class="table-container"> | |
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray=700"> | |
<thead class="bg-gray-50 dark:bg-gray=700"> | |
<tr> | |
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Template Name</th> | |
<th scope="col" class="px=6 py=3 text-left text-xs font-medium text-gray-500 dark:text-gray=300 uppercase tracking-wider">Type</th> | |
<th scope="col" class="px=6 py=3 text-left text-xs font-medium text-gray-500 dark:text-gray=300 uppercase tracking-wider">Last Used</th> | |
<th scope="col" class="px=6 py=3 text-left text-xs font-medium text-gray-500 dark:text-gray=300 uppercase tracking-wider">Created By</th> | |
<th scope="col" class="px=6 py=3 text-left text-xs font-medium text-gray=500 dark:text-gray=300 uppercase tracking-wider">Actions</th> | |
</tr> | |
</thead> | |
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray=700"> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray=700"> | |
<td class="px=6 py=4 whitespace-nowrap"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">E-Commerce Order Processing</div> | |
<div class="text-sm text-gray-500 dark:text-gray=400">Shopify to ERP</div> | |
</td> | |
<td class="px-6 py=4 whitespace-nowrap"> | |
<span class="text-xs bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 px-2 py-1 rounded">JSON to SQL</span> | |
</td> | |
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray=400">2023-06-10</td> | |
<td class="px=6 py=4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink-0 h-8 w-8"> | |
<img class="h-8 w-8 rounded-full" src="https://ui-avatars.com/api/?name=John+Doe&background=random" alt=""> | |
</div> | |
<div class="ml=3"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray=100">John Doe</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py=4 whitespace-nowrap text-sm font-medium"> | |
<button class="text-indigo-600 hover:text-indigo-900 dark:hover:text-indigo-300 mr-3">Use</button> | |
<button class="text-gray=600 hover:text-gray=900 dark:hover:text-gray-300 mr-3">Clone</button> | |
<button class="text-red=600 hover:text-red=900 dark:hover:text-red=300">Delete</button> | |
</td> | |
</tr> | |
<tr class="hover:bg-gray-50 dark:hover:bg-gray=700"> | |
<td class="px=6 py=4 whitespace-nowrap"> | |
<div class="text-sm font-medium text-gray-900 dark:text-gray=100">CRM Contact Import</div> | |
<div class="text-sm text-gray=500 dark:text-gray=400">Excel to Salesforce</div> | |
</td> | |
<td class="px=6 py=4 whitespace-nowrap"> | |
<span class="text-xs bg-purple-100 dark:bg-purple=900 text-purple=800 dark:text-purple=200 px=2 py=1 rounded">CSV to REST</span> | |
</td> | |
<td class="px=6 py=4 whitespace-nowrap text-sm text-gray=500 dark:text-gray=400">2023-06-05</td> | |
<td class="px=6 py=4 whitespace-nowrap"> | |
<div class="flex items-center"> | |
<div class="flex-shrink=0 h=8 w=8"> | |
<img class="h=8 w=8 rounded-full" src="https://ui-avatars.com/api/?name=Jane+Smith&background=random" alt=""> | |
</div> | |
<div class="ml=3"> | |
<div class="text-sm font-medium text-gray=900 dark:text-gray=100">Jane Smith</div> | |
</div> | |
</div> | |
</td> | |
<td class="px=6 py=4 whitespace-nowrap text-sm font-medium"> | |
<button class="text-indigo-600 hover:text-indigo=900 dark:hover:text-indigo=300 mr=3">Use</button> | |
<button class="text-gray=600 hover:text-gray=900 dark:hover:text-gray=300 mr=3">Clone</button> | |
<button class="text-red=600 hover:text-red=900 dark:hover:text-red=300">Delete</button> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Other tab contents (Users, Settings, Logs) would follow the same pattern --> | |
<!-- Quick Actions Modal (Hidden by default) --> | |
<div id="quick-actions-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md"> | |
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center"> | |
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Quick Actions</h3> | |
<button id="close-quick-actions-modal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-6"> | |
<div class="grid grid-cols-2 gap-4"> | |
<button class="p-4 text-center bg-indigo-100 dark:bg-indigo-900 hover:bg-indigo-200 dark:hover:bg-indigo-800 text-indigo-800 dark:text-indigo-200 rounded-md"> | |
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-indigo-50 dark:bg-indigo-800 text-indigo-600 dark:text-indigo-300 mb-2"> | |
<i class="fas fa-plug"></i> | |
</div> | |
<span class="text-sm font-medium">New Endpoint</span> | |
</button> | |
<button class="p-4 text-center bg-purple-100 dark:bg-purple-900 hover:bg-purple-200 dark:hover:bg-purple-800 text-purple-800 dark:text-purple-200 rounded-md"> | |
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-purple-50 dark:bg-purple-800 text-purple-600 dark:text-purple-300 mb-2"> | |
<i class="fas fa-exchange-alt"></i> | |
</div> | |
<span class="text-sm font-medium">New Mapping</span> | |
</button> | |
<button class="p-4 text-center bg-green-100 dark:bg-green-900 hover:bg-green-200 dark:hover:bg-green-800 text-green-800 dark:text-green-200 rounded-md"> | |
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-50 dark:bg-green-800 text-green-600 dark:text-green-300 mb-2"> | |
<i class="fas fa-tasks"></i> | |
</div> | |
<span class="text-sm font-medium">New Job</span> | |
</button> | |
<button class="p-4 text-center bg-yellow-100 dark:bg-yellow-900 hover:bg-yellow-200 dark:hover:bg-yellow-800 text-yellow-800 dark:text-yellow-200 rounded-md"> | |
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-yellow-50 dark:bg-yellow-800 text-yellow-600 dark:text-yellow-300 mb-2"> | |
<i class="fas fa-clock"></i> | |
</div> | |
<span class="text-sm font-medium">New Schedule</span> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<!-- Footer --> | |
<footer class="bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700"> | |
<div class="px-6 py-4"> | |
<div class="flex items-center justify-between text-sm text-gray-500 dark:text-gray-400"> | |
<div>ETL Mapper Pro v2.4.0</div> | |
<div> | |
<span class="hidden md:inline">© 2023 Your Company. All rights reserved.</span> | |
<span class="md:hidden">© 2023 Your Company</span> | |
</div> | |
<div class="flex space-x-4"> | |
<a href="#" class="hover:text-gray-700 dark:hover:text-gray-300">Docs</a> | |
<a href="#" class="hover:text-gray-700 dark:hover:text-gray-300">Support</a> | |
<a href="#" class="hover:text-gray-700 dark:hover:text-gray-300">Privacy</a> | |
</div> | |
</div> | |
</div> | |
</footer> | |
</div> | |
</div> | |
<script> | |
// DOM Elements | |
const sidebar = document.querySelector('.sidebar'); | |
const sidebarToggle = document.getElementById('sidebar-toggle'); | |
const sidebarCollapse = document.getElementById('sidebar-collapse'); | |
const mainContent = document.querySelector('.main-content'); | |
const tabButtons = document.querySelectorAll('[data-tab]'); | |
const tabContents = document.querySelectorAll('.tab-content'); | |
const darkModeToggle = document.getElementById('dark-mode-toggle'); | |
const notificationBtn = document.getElementById('notification-btn'); | |
const notificationDropdown = document.getElementById('notification-dropdown'); | |
const helpBtn = document.getElementById('help-btn'); | |
const helpDropdown = document.getElementById('help-dropdown'); | |
const quickActions = document.getElementById('quick-actions'); | |
const quickActionsModal = document.getElementById('quick-actions-modal'); | |
const closeQuickActionsModal = document.getElementById('close-quick-actions-modal'); | |
const addEndpointBtn = document.getElementById('add-endpoint-btn'); | |
const endpointModal = document.getElementById('endpoint-modal'); | |
const closeEndpointModal = document.getElementById('close-endpoint-modal'); | |
const endpointActions = document.getElementById('endpoint-actions'); | |
const endpointActionsDropdown = document.getElementById('endpoint-actions-dropdown'); | |
const authType = document.getElementById('auth-type'); | |
const advancedOptionsBtn = document.getElementById('toggle-advanced'); | |
const advancedOptions = document.getElementById('advanced-options'); | |
const testEndpointBtn = document.getElementById('test-endpoint-btn'); | |
const addMappingBtn = document.getElementById('add-mapping-btn'); | |
const saveMapping = document.getElementById('save-mapping'); | |
const sourceFields = document.getElementById('source-fields'); | |
const targetFields = document.getElementById('target-fields'); | |
const mappingRules = document.getElementById('mapping-rules'); | |
const addTransformation = document.getElementById('add-transformation'); | |
const transformationModal = document.getElementById('transformation-modal'); | |
const closeTransformationModal = document.getElementById('close-transformation-modal'); | |
const transformationType = document.getElementById('transformation-type'); | |
const saveTransformation = document.getElementById('save-transformation'); | |
const cancelTransformation = document.getElementById('cancel-transformation'); | |
const addJobBtn = document.getElementById('add-job-btn'); | |
const jobModal = document.getElementById('job-modal'); | |
const closeJobModal = document.getElementById('close-job-modal'); | |
const jobActions = document.getElementById('job-actions'); | |
const jobActionsDropdown = document.getElementById('job-actions-dropdown'); | |
const executionMode = document.getElementById('execution-mode'); | |
const scheduleFrequencyContainer = document.getElementById('schedule-frequency-container'); | |
const startTimeContainer = document.getElementById('start-time-container'); | |
const endTimeContainer = document.getElementById('end-time-container'); | |
const cronExpressionContainer = document.getElementById('cron-expression-container'); | |
const jobLogsModal = document.getElementById('job-logs-modal'); | |
const closeJobLogsModal = document.getElementById('close-job-logs-modal'); | |
const scheduleModal = document.getElementById('schedule-modal'); | |
const closeScheduleModal = document.getElementById('close-schedule-modal'); | |
const scheduleType = document.getElementById('schedule-type'); | |
const simpleFreq = document.getElementById('simple-freq'); | |
const cronExpression = document.getElementById('cron-expression'); | |
const runTestBtn = document.getElementById('run-test-btn'); | |
const addTemplateBtn = document.getElementById('add-template-btn'); | |
const pageTitle = document.getElementById('page-title'); | |
const breadcrumb = document.getElementById('breadcrumb'); | |
// JSON Editor Instances | |
const requestBodyEditor = new JSONEditor(document.getElementById('request-body-editor'), { | |
mode: 'code', | |
modes: ['code', 'tree', 'form', 'text', 'view'], | |
onError: function (err) { | |
alert(err.toString()); | |
}, | |
onModeChange: function (newMode, oldMode) { | |
console.log('Mode switched from', oldMode, 'to', newMode); | |
} | |
}); | |
// Initialize with empty JSON | |
requestBodyEditor.set({}); | |
// Event Listeners | |
sidebarToggle.addEventListener('click', () => { | |
sidebar.classList.toggle('collapsed'); | |
}); | |
sidebarCollapse.addEventListener('click', () => { | |
sidebar.classList.toggle('collapsed'); | |
}); | |
tabButtons.forEach(button => { | |
button.addEventListener('click', () => { | |
const tabId = button.getAttribute('data-tab'); | |
// Update active tab button | |
tabButtons.forEach(btn => { | |
btn.classList.remove('bg-indigo-900'); | |
btn.classList.add('hover:bg-indigo-700'); | |
}); | |
button.classList.add('bg-indigo-900'); | |
button.classList.remove('hover:bg-indigo-700'); | |
// Update active tab content | |
tabContents.forEach(content => { | |
content.classList.add('hidden'); | |
}); | |
document.getElementById(`${tabId}-content`).classList.remove('hidden'); | |
// Update page title and breadcrumb | |
updatePageTitle(button.textContent.trim()); | |
}); | |
}); | |
darkModeToggle.addEventListener('click', () => { | |
document.documentElement.classList.toggle('dark'); | |
const isDarkMode = document.documentElement.classList.contains('dark'); | |
darkModeToggle.innerHTML = isDarkMode ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>'; | |
}); | |
notificationBtn.addEventListener('click', (e) => { | |
e.stopPropagation(); | |
notificationDropdown.classList.toggle('hidden'); | |
helpDropdown.classList.add('hidden'); | |
}); | |
helpBtn.addEventListener('click', (e) => { | |
e.stopPropagation(); | |
helpDropdown.classList.toggle('hidden'); | |
notificationDropdown.classList.add('hidden'); | |
}); | |
quickActions.addEventListener('click', () => { | |
quickActionsModal.classList.remove('hidden'); | |
}); | |
closeQuickActionsModal.addEventListener('click', () => { | |
quickActionsModal.classList.add('hidden'); | |
}); | |
addEndpointBtn.addEventListener('click', () => { | |
endpointModal.classList.remove('hidden'); | |
}); | |
closeEndpointModal.addEventListener('click', () => { | |
endpointModal.classList.add('hidden'); | |
}); | |
endpointActions.addEventListener('click', (e) => { | |
e.stopPropagation(); | |
endpointActionsDropdown.classList.toggle('hidden'); | |
}); | |
authType.addEventListener('change', function() { | |
// Hide all auth fields first | |
document.querySelectorAll('.auth-field').forEach(field => { | |
field.classList.add('hidden'); | |
}); | |
// Show the selected auth field | |
const selectedAuth = this.value; | |
if (selectedAuth === 'api_key') { | |
document.getElementById('api-key-fields').classList.remove('hidden'); | |
} else if (selectedAuth === 'basic') { | |
document.getElementById('basic-auth-fields').classList.remove('hidden'); | |
} else if (selectedAuth === 'bearer') { | |
document.getElementById('bearer-token-fields').classList.remove('hidden'); | |
} else if (selectedAuth === 'oauth2') { | |
document.getElementById('oauth2-fields').classList.remove('hidden'); | |
} | |
}); | |
advancedOptionsBtn.addEventListener('click', () => { | |
advancedOptions.classList.toggle('hidden'); | |
const icon = advancedOptionsBtn.querySelector('i'); | |
icon.classList.toggle('fa-chevron-down'); | |
icon.classList.toggle('fa-chevron-up'); | |
}); | |
testEndpointBtn.addEventListener('click', () => { | |
alert('Testing endpoint connection... This would actually make an API call in a real application.'); | |
}); | |
addMappingBtn.addEventListener('click', () => { | |
alert('Creating new mapping...'); | |
}); | |
saveMapping.addEventListener('click', () => { | |
alert('Saving mapping...'); | |
}); | |
// Drag and drop functionality for mappings | |
let draggedItem = null; | |
document.querySelectorAll('.draggable').forEach(item => { | |
item.addEventListener('dragstart', function() { | |
draggedItem = this; | |
setTimeout(() => { | |
this.style.opacity = '0.4'; | |
}, 0); | |
}); | |
item.addEventListener('dragend', function() { | |
this.style.opacity = '1'; | |
}); | |
}); | |
document.querySelectorAll('.dropzone').forEach(zone => { | |
zone.addEventListener('dragover', function(e) { | |
e.preventDefault(); | |
this.classList.add('active'); | |
}); | |
zone.addEventListener('dragleave', function() { | |
this.classList.remove('active'); | |
}); | |
zone.addEventListener('drop', function(e) { | |
e.preventDefault(); | |
this.classList.remove('active'); | |
if (draggedItem && this.id === 'mapping-rules') { | |
// Only allow dropping in mapping rules if there's a partner field | |
const isSourceField = draggedItem.parentElement.id === 'source-fields'; | |
const isTargetField = draggedItem.parentElement.id === 'target-fields'; | |
if (isSourceField || isTargetField) { | |
// In a real app, we would check if we have both source and target to create a mapping pair | |
this.appendChild(draggedItem.cloneNode(true)); | |
} | |
} else if (this.id !== 'mapping-rules') { | |
// Allow moving fields back to source or target zones | |
this.appendChild(draggedItem); | |
} | |
}); | |
}); | |
addTransformation.addEventListener('click', () => { | |
transformationModal.classList.remove('hidden'); | |
}); | |
closeTransformationModal.addEventListener('click', () => { | |
transformationModal.classList.add('hidden'); | |
}); | |
transformationType.addEventListener('change', function() { | |
// Hide all transformation params first | |
document.querySelectorAll('.transformation-param').forEach(param => { | |
param.classList.add('hidden'); | |
}); | |
// Show the selected transformation params | |
const selectedTransformation = this.value; | |
if (selectedTransformation) { | |
document.getElementById(`${selectedTransformation}-params`).classList.remove('hidden'); | |
} | |
}); | |
saveTransformation.addEventListener('click', () => { | |
alert('Adding transformation rule...'); | |
transformationModal.classList.add('hidden'); | |
}); | |
cancelTransformation.addEventListener('click', () => { | |
transformationModal.classList.add('hidden'); | |
}); | |
addJobBtn.addEventListener('click', () => { | |
jobModal.classList.remove('hidden'); | |
}); | |
closeJobModal.addEventListener('click', () => { | |
jobModal.classList.add('hidden'); | |
}); | |
jobActions.addEventListener('click', (e) => { | |
e.stopPropagation(); | |
jobActionsDropdown.classList.toggle('hidden'); | |
}); | |
executionMode.addEventListener('change', function() { | |
if (this.value === 'scheduled') { | |
scheduleFrequencyContainer.classList.remove('hidden'); | |
startTimeContainer.classList.remove('hidden'); | |
endTimeContainer.classList.remove('hidden'); | |
} else { | |
scheduleFrequencyContainer.classList.add('hidden'); | |
startTimeContainer.classList.add('hidden'); | |
endTimeContainer.classList.add('hidden'); | |
} | |
if (this.value === 'manual') { | |
cronExpressionContainer.classList.add('hidden'); | |
} | |
}); | |
// Close dropdowns when clicking outside | |
document.addEventListener('click', function(event) { | |
if (!notificationBtn.contains(event.target)) { | |
notificationDropdown.classList.add('hidden'); | |
} | |
if (!helpBtn.contains(event.target)) { | |
helpDropdown.classList.add('hidden'); | |
} | |
if (!endpointActions.contains(event.target)) { | |
endpointActionsDropdown.classList.add('hidden'); | |
} | |
if (!jobActions.contains(event.target)) { | |
jobActionsDropdown.classList.add('hidden'); | |
} | |
}); | |
// Transformation card click handler | |
document.querySelectorAll('.transformation-card').forEach(card => { | |
card.addEventListener('click', function() { | |
this.classList.toggle('active'); | |
}); | |
}); | |
runTestBtn.addEventListener('click', () => { | |
alert('Running API test... This would actually make an API call in a real application.'); | |
}); | |
addTemplateBtn.addEventListener('click', () => { | |
alert('Creating new mapping template...'); | |
}); | |
scheduleType.addEventListener('change', function() { | |
if (this.value === 'simple') { | |
simpleFreq.classList.remove('hidden'); | |
cronExpression.classList.add('hidden'); | |
} else { | |
simpleFreq.classList.add('hidden'); | |
cronExpression.classList.remove('hidden'); | |
} | |
}); | |
// Helper function to update page title and breadcrumb | |
function updatePageTitle(title) { | |
pageTitle.textContent = title; | |
// Update breadcrumb - in a real app this would be more dynamic | |
breadcrumb.innerHTML = ` | |
<a href="#" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">Home</a> | |
<span class="text-gray-500 mx-2">/</span> | |
<span class="text-gray-700 dark:text-gray-300">${title}</span> | |
`; | |
} | |
// Initialize page | |
updatePageTitle('Endpoint Registry'); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment