Merge pull request #268 from sosedoff/fetch-unique-rows
Table headers context menu
This commit is contained in:
commit
003a661c08
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>
|
||||||
|
@ -4,16 +4,6 @@ var bookmarks = {};
|
|||||||
var default_rows_limit = 100;
|
var default_rows_limit = 100;
|
||||||
var currentObject = null;
|
var currentObject = null;
|
||||||
|
|
||||||
if (!Array.prototype.forEach) {
|
|
||||||
// Simplified iterator for browsers without forEach support
|
|
||||||
Array.prototype.forEach = function(cb) {
|
|
||||||
if (typeof this.length != 'number') return;
|
|
||||||
if (typeof callback != 'function') return;
|
|
||||||
|
|
||||||
for (var i = 0; i < this.length; i++) cb(this[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var filterOptions = {
|
var filterOptions = {
|
||||||
"equal": "= 'DATA'",
|
"equal": "= 'DATA'",
|
||||||
"not_equal": "!= 'DATA'",
|
"not_equal": "!= 'DATA'",
|
||||||
@ -27,11 +17,6 @@ var filterOptions = {
|
|||||||
"not_null": "IS NOT NULL"
|
"not_null": "IS NOT NULL"
|
||||||
};
|
};
|
||||||
|
|
||||||
function guid() {
|
|
||||||
function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); }
|
|
||||||
return [s4(), s4(), "-", s4(), "-", s4(), "-", s4(), "-", s4(), s4(), s4()].join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSessionId() {
|
function getSessionId() {
|
||||||
var id = sessionStorage.getItem("session_id");
|
var id = sessionStorage.getItem("session_id");
|
||||||
|
|
||||||
@ -200,7 +185,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 +452,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 +566,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 +618,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 +776,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",
|
||||||
|
28
static/js/utils.js
Normal file
28
static/js/utils.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
if (!Array.prototype.forEach) {
|
||||||
|
// Simplified iterator for browsers without forEach support
|
||||||
|
Array.prototype.forEach = function(cb) {
|
||||||
|
if (typeof this.length != 'number') return;
|
||||||
|
if (typeof callback != 'function') return;
|
||||||
|
|
||||||
|
for (var i = 0; i < this.length; i++) cb(this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
function guid() {
|
||||||
|
function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); }
|
||||||
|
return [s4(), s4(), "-", s4(), "-", s4(), "-", s4(), "-", s4(), s4(), s4()].join("");
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user