Azpect3120 8ab00b20d4 FIX: Bug with clearing modal before sending
The creation modal was sending data after being wiped, this was fixed
and the data does not get cleared from the modal until AFTER the request
is sent.
2024-08-15 09:22:39 -07:00

238 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Query Tool</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
<script src="https://unpkg.com/htmx.org@2.0.1"></script>
<link rel="icon" type="image/png" href="/v1/web/assets/favicon.ico">
<style>
.htmx-request {
display: block;
}
</style>
</head>
<body class="bg-gray-100">
<div class="flex flex-col h-screen">
<!-- Top Bar -->
<div class="bg-white shadow-md p-4 flex items-center justify-between border-b">
<div>
<h1 class="text-2xl font-bold">Database Query Tool</h1>
<p class="text-sm text-gray-600">Connect and query your databases effortlessly.</p>
</div>
<div class="flex items-center justify-end space-x-4 flex-wrap">
<form hx-post="/v1/api/connections/connect" hx-trigger="change" hx-swap="outerHTML"
hx-target="#connected-database" hx-indicator="#table-loading" hx-encoding="multipart/form-data"
class="flex items-center justify-end space-x-2 flex-wrap">
<label for="connected-database" class="block text-sm font-medium text-gray-700">Connected Database:</label>
<select hx-get="/v1/web/connections" hx-trigger="load, change" hx-swap="outerHTML" id="connected-database"
name="connected-database" hx-params="none"
class="mt-1 block p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm md:text-base"></select>
</form>
<button onclick="ShowModal();" class="bg-blue-500 text-white px-4 py-2 my-2 rounded-md text-sm md:text-base">
Add Connection
</button>
<button hx-get="/v1/web/manager/open" hx-trigger="click" hx-target="#manager-modal" hx-swap="outerHTML"
class="bg-blue-500 text-white px-4 py-2 my-2 rounded-md text-sm md:text-base">
Manage Connections
</button>
</div>
</div>
<div class="flex flex-col md:flex-row flex-grow">
<!-- Sidebar -->
<div class="w-full md:w-1/4 bg-white shadow-md">
<div class="p-4 border-b flex justify-between items-center">
<h2 class="text-lg font-bold">
<span id="database-name-tree">database</span>
<span id="table-loading" class="text-sm font-normal mx-1 htmx-indicator duration-300">loading
tables...</span>
</h2>
<button hx-get="/v1/web/connections/tree" hx-trigger="click" hx-target="#database-table-tree"
class="hover:bg-gray-100 p-2 rounded-md" hx-indicator="#table-loading">
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon h-4 w-4" viewBox="0 0 512 512">
<path
d="M400 148l-21.12-24.57A191.43 191.43 0 00240 64C134 64 48 150 48 256s86 192 192 192a192.09 192.09 0 00181.07-128"
fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" />
<path
d="M464 97.42V208a16 16 0 01-16 16H337.42c-14.26 0-21.4-17.23-11.32-27.31L436.69 86.1C446.77 76 464 83.16 464 97.42z" />
</svg>
</button>
</div>
<div class="p-4 max-h-full" hx-get="/v1/web/connections/tree" hx-trigger="load" hx-params="none"
hx-indicator="#table-loading" hx-target="#database-table-tree">
<ul hx-swap-oob="outerHTML" id="database-table-tree" class="space-y-2"></ul>
</div>
</div>
<!-- Main Content -->
<div class="w-full md:w-3/4 p-4">
<main>
<!-- Query Input -->
<div id="query-main" class="mb-4">
<div class="flex items-center justify-between">
<label for="sql" class="block text-sm font-medium text-gray-700">SQL Query</label>
<div class="flex items-center space-x-6">
<form class="flex items-center space-x-2" hx-get="/v1/web/query/auto" hx-swap="outerHTML"
hx-target="#query-main" hx-trigger="input">
<label for="auto-toggle" class="text-sm font-medium text-gray-700">Auto-Run</label>
<input type="checkbox" name="toggle" class="toggle-checkbox"
title="Toggle auto-query functionality. Note: This will send whatever query is in the input and clear the box.">
</form>
<!-- Manual Query Button -->
<button hx-post="/v1/api/query" hx-trigger="click" hx-swap="outerHTML" hx-target="#query-result"
hx-indicator="#spinner" hx-include="#sql"
class="bg-blue-500 text-white py-2 px-3 rounded-md text-xs md:text-sm">Run Query</button>
<!-- Auto Query Button -->
<!-- <button class="bg-blue-500 text-white py-2 px-3 rounded-md text-xs md:text-sm opacity-60 cursor-default" title="Disable Auto-Run to use manual queries." disabled>Run Query</button> -->
</div>
</div>
<!-- Manual Query Input -->
<textarea id="sql" name="sql" rows="4"
class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm"></textarea>
<!-- Auto Query Input -->
<!-- <textarea id="sql" name="sql" rows="4" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" hx-post="/v1/api/query" hx-trigger="input delay:500ms" hx-swap="outerHTML" hx-target="#query-result" hx-indicator="#spinner"></textarea> -->
<p id="spinner" class="text-gray-700 text-sm px-1 py-2 htmx-indicator hidden"> Query running... </p>
<p id="query-error" hx-swap-oob="outerHTML" class="text-red-500 py-2 text-sm hidden"></p>
</div>
<!-- Query Results -->
<div class="overflow-x-auto overflow-y-hidden bg-white shadow-md rounded-lg">
<table id="query-result" class="min-w-full divide-y divide-gray-200"></table>
</div>
</main>
</div>
</div>
</div>
<!-- Create Connection Modal -->
<div id="connection-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden opacity-0">
<div class="flex items-center justify-center min-h-screen">
<div class="bg-white p-6 rounded-lg shadow-lg w-2/3">
<div class="flex justify-between items-center border-b pb-2">
<h2 class="text-xl font-bold">Add New Connection</h2>
<button onclick="HideModal();" class="text-gray-500 hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<div class="mt-4">
<form id="connection-form" class="grid grid-cols-2 gap-4">
<div>
<label for="db-host" class="block text-sm font-medium text-gray-700">Host</label>
<input id="db-host" name="db-host" type="text" placeholder="127.0.0.1" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
</div>
<div>
<label for="db-port" class="block text-sm font-medium text-gray-700">Port</label>
<input id="db-port" name="db-port" type="text" placeholder="5432" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
</div>
<div>
<label for="db-username" class="block text-sm font-medium text-gray-700">Username</label>
<input id="db-username" name="db-username" type="text" placeholder="admin" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
</div>
<div>
<label for="db-password" class="block text-sm font-medium text-gray-700">Password</label>
<div class="relative mt-1">
<input id="db-password" name="db-password" type="password" placeholder="●●●●●●●●●" class="block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
<button type="button" id="togglePassword" class="absolute inset-y-0 right-0 px-3 py-2 text-gray-500 bg-gray-200 rounded-r-md border border-gray-300" title="Display secret details">
<svg id="eyeIcon" xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 12s3.5-7 11-7 11 7 11 7-3.5 7-11 7S1 12 1 12z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
</button>
</div>
</div>
<div>
<label for="db-driver" class="block text-sm font-medium text-gray-700">Driver/Type of Database</label>
<select id="db-driver" name="db-driver"
class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
<option value="postgresql">PostgreSQL</option>
<option value="mysql">MySQL</option>
<option value="sqlite">SQLite</option>
<option value="sqlserver">SQL Server</option>
<option value="oracle">Oracle</option>
<option value="mariadb">MariaDB</option>
<option value="db2">DB2</option>
</select>
</div>
<div>
<label for="db-database" class="block text-sm font-medium text-gray-700">Database Name</label>
<input id="db-database" name="db-database" type="text" placeholder="master_database" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
</div>
<div class="col-span-2">
<label for="db-url" class="block text-sm font-medium text-gray-700">
Connection Name
<br>
<span class="text-xs font-light">
This is the name of the connection that will be displayed in the list of connections. By default it
will match the database name.
</span>
</label>
<input name="db-conn-name" id="db-conn-name" placeholder="master_database" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
</div>
<div class="col-span-2">
<label for="db-url" class="block text-sm font-medium text-gray-700">
Connection URL
<br>
<span class="text-xs font-light">
The connection URL will be automatically generated based on the above fields. To view the URL
generated,
push the "display secret details" button in the password section.
</span>
</label>
<input id="db-url" name="db-url" type="password"
placeholder="postgresql://admin:password@127.0.0.1:5432/master_database"
value="postgresql://azpect:Panther4487!!!!@127.0.0.1:5432/azpect?sslmode=disable"
class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
<span id="db-url-invalid" class="text-xs text-red-500 hidden">Connection URL is incomplete or
invalid.</span>
</div>
</form>
<div class="flex items-center space-x-4 mt-4">
<button
hx-post="/v1/api/connections"
hx-trigger="click"
hx-target="#connected-database"
hx-swap="outerHTML"
hx-include="#connection-form"
hx-on::after-request="HideModal();"
class="bg-blue-500 text-white px-4 py-2 rounded-md"
>
Create Connection
</button>
<button hx-post="/v1/api/connections/test" hx-trigger="click" hx-swap="outerHTML"
hx-target="#connection-status" hx-include="#connection-form" hx-encoding="multipart/form-data"
class="bg-gray-200 text-gray-700 px-4 py-2 rounded-md flex items-center space-x-2">
<span>Test Connection</span>
<span id="connection-status" class="w-3 h-3 rounded-full bg-gray-400"></span>
</button>
<span id="connection-message"></span>
</div>
</div>
</div>
</div>
</div>
<!-- Manage Connections Modal -->
<div id="manager-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden opacity-0"></div>
<!-- Scripts -->
<script src="/v1/web/static/scripts/password.js"></script>
<script src="/v1/web/static/scripts/modal.js"></script>
<script src="/v1/web/static/scripts/tree.js"></script>
</body>
</html>