FEAT: Multi query support!
Queries will be split by the ';' and ran at the same time! They will each have their own table display and info.
This commit is contained in:
parent
da3ad813be
commit
3382a1537b
BIN
bin/web_server
BIN
bin/web_server
Binary file not shown.
@ -4,6 +4,7 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Azpect3120/Web-Database-Viewer/internal/templates"
|
||||
"github.com/gin-contrib/sessions"
|
||||
@ -16,13 +17,19 @@ func QueryCurrent(c *gin.Context) {
|
||||
query := c.PostForm("sql")
|
||||
conn := getConnection(c)
|
||||
|
||||
cols, data, err := queryConnection(query, conn)
|
||||
if err != nil {
|
||||
c.String(200, templates.ErrorQueryResults(err))
|
||||
return
|
||||
queries := strings.Split(query, ";")
|
||||
var results []string
|
||||
for _, query := range queries {
|
||||
cols, data, err := queryConnection(query, conn)
|
||||
if err != nil {
|
||||
c.String(200, templates.ErrorQueryResults(err))
|
||||
return
|
||||
}
|
||||
|
||||
results = append(results, templates.QueryResult(cols, data))
|
||||
}
|
||||
|
||||
c.String(200, templates.QueryResults(cols, data))
|
||||
c.String(200, templates.ConcatResults(results))
|
||||
}
|
||||
|
||||
func queryConnection(query, url string) ([]string, []map[string]interface{}, error) {
|
||||
|
||||
@ -13,7 +13,7 @@ const MANUAL_QUERY string = `
|
||||
<label for="auto-toggle" class="text-sm font-medium text-gray-700">Auto-Run</label>
|
||||
<input type="checkbox" name="toggle" class="toggle-checkbox">
|
||||
</form>
|
||||
<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>
|
||||
<button hx-post="/v1/api/query" hx-trigger="click" hx-swap="outerHTML" hx-target="#query-results" 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>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
@ -34,7 +34,7 @@ const AUTO_QUERY string = `
|
||||
<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>
|
||||
<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>
|
||||
<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-results" 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>
|
||||
|
||||
@ -4,8 +4,19 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Result list definition
|
||||
const result_list_open string = `<ul id="query-results">`
|
||||
const result_list_close string = `</ul>`
|
||||
|
||||
// Result item definition
|
||||
const result_item string = `
|
||||
<li class="overflow-x-auto overflow-y-hidden bg-white rounded-lg shadow-md mb-8">
|
||||
%s
|
||||
</li>
|
||||
`
|
||||
|
||||
// Table wrapper definitions
|
||||
const table_open string = `<table id="query-result" class="min-w-full divide-y divide-gray-200">`
|
||||
const table_open string = `<table class="min-w-full divide-y divide-gray-200">`
|
||||
const table_close string = `</table>`
|
||||
|
||||
// Header definitions
|
||||
@ -23,10 +34,20 @@ const query_error_message string = `<p id="query-error" hx-swap-oob="outerHTML"
|
||||
const query_error_message_blank string = `<p id="query-error" hx-swap-oob="outerHTML" class="text-red-500 py-2 text-sm hidden"></p>`
|
||||
|
||||
func ErrorQueryResults(e error) string {
|
||||
return table_open + table_close + fmt.Sprintf(query_error_message, e.Error())
|
||||
return result_list_open + result_list_close + fmt.Sprintf(query_error_message, e.Error())
|
||||
}
|
||||
|
||||
func QueryResults(cols []string, rows []map[string]interface{}) string {
|
||||
func ConcatResults(items []string) string {
|
||||
var html string = result_list_open
|
||||
|
||||
for _, h := range items {
|
||||
html += h
|
||||
}
|
||||
|
||||
return html + result_list_close
|
||||
}
|
||||
|
||||
func QueryResult(cols []string, rows []map[string]interface{}) string {
|
||||
head := generateHead(cols)
|
||||
|
||||
body := table_body_open
|
||||
@ -36,7 +57,7 @@ func QueryResults(cols []string, rows []map[string]interface{}) string {
|
||||
|
||||
body += table_body_close
|
||||
|
||||
return table_open + head + body + table_close + query_error_message_blank
|
||||
return fmt.Sprintf(result_item, table_open+head+body+table_close+query_error_message_blank)
|
||||
}
|
||||
|
||||
// Generate the tables head row
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,45 +1,45 @@
|
||||
<!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">
|
||||
</head>
|
||||
<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">
|
||||
</head>
|
||||
|
||||
<body class="bg-gray-100">
|
||||
<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 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 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="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">
|
||||
@ -72,172 +72,203 @@
|
||||
</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>
|
||||
<!-- 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>
|
||||
<!-- Manual Query Button -->
|
||||
<button hx-post="/v1/api/query" hx-trigger="click" hx-swap="outerHTML" hx-target="#query-results" 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> -->
|
||||
<!-- 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-results" 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>
|
||||
|
||||
<!-- 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>
|
||||
<!-- Query Results -->
|
||||
<ul id="query-results">
|
||||
<!-- <li class="overflow-x-auto overflow-y-hidden bg-white rounded-lg shadow-md"> -->
|
||||
<!-- <table class="min-w-full divide-y divide-gray-200"> -->
|
||||
<!-- <thead class="bg-gray-50"> -->
|
||||
<!-- <tr> -->
|
||||
<!-- <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">id</th> -->
|
||||
<!-- <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">username</th> -->
|
||||
<!-- <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">password</th> -->
|
||||
<!-- <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">secret</th> -->
|
||||
<!-- <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">permission</th> -->
|
||||
<!-- </tr> -->
|
||||
<!-- </thead> -->
|
||||
<!-- <tbody class="bg-white divide-y divide-gray-200"> -->
|
||||
<!-- <tr> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">513fbe25-ff69-4386-87c2-90ff6b691169</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">ConnieH</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">d1d15c321c523cbcfe2c18f92168cb5b:</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap"><nil></td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">Admin</td> -->
|
||||
<!-- </tr> -->
|
||||
<!-- <tr> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">5e02c767-f035-40da-867a-1c067c1678e2</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">AustinH</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">588b2205579a4ee48f9014f2742fd1b0:</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap"><nil></td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">User</td> -->
|
||||
<!-- </tr> -->
|
||||
<!-- <tr> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">1d007e19-d84b-4cc6-9e6b-1c51122aa3e5</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">Azpect</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">a8778398e9afed7f00a88b13ffc14a95:</td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap"><nil></td> -->
|
||||
<!-- <td class="px-6 py-4 whitespace-nowrap">Dev</td> -->
|
||||
<!-- </tr> -->
|
||||
<!-- </tbody> -->
|
||||
<!-- </table> -->
|
||||
<!-- <p id="query-error" hx-swap-oob="outerHTML" class="text-red-500 py-2 text-sm hidden"></p> -->
|
||||
<!-- </li> -->
|
||||
</ul>
|
||||
|
||||
<!-- 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>
|
||||
</main>
|
||||
</div>
|
||||
</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>
|
||||
<!-- 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>
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user