Add table results headers context menu
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -404,11 +404,21 @@
|
|||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#results th:hover {
|
||||||
|
background: #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#results th.active {
|
#results th.active {
|
||||||
background: #f3f3f3;
|
background: #f3faff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#results[data-mode="browse"] th:hover {
|
#results[data-mode="browse"] th:hover {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<script type="text/javascript" src="static/js/ace.js"></script>
|
<script type="text/javascript" src="static/js/ace.js"></script>
|
||||||
<script type="text/javascript" src="static/js/ace-pgsql.js"></script>
|
<script type="text/javascript" src="static/js/ace-pgsql.js"></script>
|
||||||
<script type="text/javascript" src="static/js/bootstrap-contextmenu.js"></script>
|
<script type="text/javascript" src="static/js/bootstrap-contextmenu.js"></script>
|
||||||
|
<script type="text/javascript" src="static/js/utils.js"></script>
|
||||||
<script type="text/javascript" src="static/js/app.js"></script>
|
<script type="text/javascript" src="static/js/app.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -238,12 +239,19 @@
|
|||||||
<li><a href="#" data-action="export" data-format="csv">Export to CSV</a></li>
|
<li><a href="#" data-action="export" data-format="csv">Export to CSV</a></li>
|
||||||
<li><a href="#" data-action="export" data-format="xml">Export to XML</a></li>
|
<li><a href="#" data-action="export" data-format="xml">Export to XML</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="#" data-action="truncate">Truncate table</a></li>
|
<li><a href="#" data-action="truncate">Truncate Table</a></li>
|
||||||
<li><a href="#" data-action="delete">Delete table</a></li>
|
<li><a href="#" data-action="delete">Delete Table</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="databases_context_menu">
|
<div id="databases_context_menu">
|
||||||
<ul class="dropdown-menu" role="menu"></ul>
|
<ul class="dropdown-menu" role="menu"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="results_header_menu">
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="#" data-action="unique_values" data-counts="false">Unique Values</a></li>
|
||||||
|
<li><a href="#" data-action="unique_values" data-counts="true">Unique Values + Counts</a></li>
|
||||||
|
<li><a href="#" data-action="copy_name">Copy Column Name</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ function getCurrentObject() {
|
|||||||
|
|
||||||
function resetTable() {
|
function resetTable() {
|
||||||
$("#results").
|
$("#results").
|
||||||
attr("data-mode", "").
|
data("mode", "").
|
||||||
text("").
|
text("").
|
||||||
removeClass("empty").
|
removeClass("empty").
|
||||||
removeClass("no-crop");
|
removeClass("no-crop");
|
||||||
@@ -467,13 +467,14 @@ function showTableContent(sortColumn, sortOrder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTableRows(name, opts, function(data) {
|
getTableRows(name, opts, function(data) {
|
||||||
$("#results").attr("data-mode", "browse");
|
|
||||||
$("#input").hide();
|
$("#input").hide();
|
||||||
$("#body").prop("class", "with-pagination");
|
$("#body").prop("class", "with-pagination");
|
||||||
|
|
||||||
buildTable(data, sortColumn, sortOrder);
|
buildTable(data, sortColumn, sortOrder);
|
||||||
setCurrentTab("table_content");
|
setCurrentTab("table_content");
|
||||||
updatePaginator(data.pagination);
|
updatePaginator(data.pagination);
|
||||||
|
|
||||||
|
$("#results").data("mode", "browse").data("table", name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,15 +581,14 @@ function runQuery() {
|
|||||||
$("#query_progress").hide();
|
$("#query_progress").hide();
|
||||||
$("#input").show();
|
$("#input").show();
|
||||||
$("#body").removeClass("full");
|
$("#body").removeClass("full");
|
||||||
|
$("#results").data("mode", "query");
|
||||||
|
|
||||||
if (query.toLowerCase().indexOf("explain") != -1) {
|
if (query.toLowerCase().indexOf("explain") != -1) {
|
||||||
$("#results").addClass("no-crop");
|
$("#results").addClass("no-crop");
|
||||||
}
|
}
|
||||||
|
|
||||||
var re = /(create|drop)\s/i;
|
|
||||||
|
|
||||||
// Reload objects list if anything was created/deleted
|
// Reload objects list if anything was created/deleted
|
||||||
if (query.match(re)) {
|
if (query.match(/(create|drop)\s/i)) {
|
||||||
loadSchemas();
|
loadSchemas();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -633,6 +633,24 @@ function exportTo(format) {
|
|||||||
win.focus();
|
win.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch all unique values for the selected column in the table
|
||||||
|
function showUniqueColumnsValues(table, column, showCounts) {
|
||||||
|
var query = 'SELECT DISTINCT "' + column + '" FROM ' + table;
|
||||||
|
|
||||||
|
// Display results ordered by counts.
|
||||||
|
// This could be slow on large sets without an index.
|
||||||
|
if (showCounts) {
|
||||||
|
query = 'SELECT DISTINCT "' + column + '", COUNT(1) AS total_count FROM ' + table + ' GROUP BY "' + column + '" ORDER BY total_count DESC';
|
||||||
|
}
|
||||||
|
|
||||||
|
executeQuery(query, function(data) {
|
||||||
|
$("#input").hide();
|
||||||
|
$("#body").prop("class", "full");
|
||||||
|
$("#results").data("mode", "query");
|
||||||
|
buildTable(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function buildTableFilters(name, type) {
|
function buildTableFilters(name, type) {
|
||||||
getTableStructure(name, { type: type }, function(data) {
|
getTableStructure(name, { type: type }, function(data) {
|
||||||
if (data.rows.length == 0) {
|
if (data.rows.length == 0) {
|
||||||
@@ -773,7 +791,42 @@ function getConnectionString() {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a context menu to the results table header columns
|
||||||
|
function bindTableHeaderMenu() {
|
||||||
|
$("#results").contextmenu({
|
||||||
|
scopes: "th",
|
||||||
|
target: "#results_header_menu",
|
||||||
|
before: function(e, element, target) {
|
||||||
|
// Enable menu for browsing table rows view only.
|
||||||
|
if ($("#results").data("mode") != "browse") {
|
||||||
|
e.preventDefault();
|
||||||
|
this.closemenu();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onItem: function(context, e) {
|
||||||
|
var menuItem = $(e.target);
|
||||||
|
|
||||||
|
switch(menuItem.data("action")) {
|
||||||
|
case "copy_name":
|
||||||
|
copyToClipboard($(context).data("name"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "unique_values":
|
||||||
|
showUniqueColumnsValues(
|
||||||
|
$("#results").data("table"), // table name
|
||||||
|
$(context).data("name"), // column name
|
||||||
|
menuItem.data("counts") // display counts
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function bindContextMenus() {
|
function bindContextMenus() {
|
||||||
|
bindTableHeaderMenu();
|
||||||
|
|
||||||
$(".schema-group ul").each(function(id, el) {
|
$(".schema-group ul").each(function(id, el) {
|
||||||
$(el).contextmenu({
|
$(el).contextmenu({
|
||||||
target: "#tables_context_menu",
|
target: "#tables_context_menu",
|
||||||
|
|||||||
12
static/js/utils.js
Normal file
12
static/js/utils.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function copyToClipboard(text) {
|
||||||
|
const element = document.createElement("textarea");
|
||||||
|
element.style.display = "none;"
|
||||||
|
element.value = text;
|
||||||
|
|
||||||
|
document.body.appendChild(element);
|
||||||
|
element.focus();
|
||||||
|
element.setSelectionRange(0, element.value.length);
|
||||||
|
|
||||||
|
document.execCommand("copy");
|
||||||
|
document.body.removeChild(element);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user