sqlui 0.1.70 → 0.1.72
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.release-version +1 -1
- data/app/github/cache.rb +2 -3
- data/app/github/caching_client.rb +5 -1
- data/app/github/client.rb +28 -1
- data/app/github/file.rb +16 -5
- data/app/github/paths.rb +16 -10
- data/app/github/tree.rb +32 -6
- data/app/github/tree_client.rb +79 -21
- data/app/pigs.rb +124 -0
- data/app/saved_config.rb +4 -1
- data/app/server.rb +86 -33
- data/app/sqlui.rb +36 -1
- data/app/views/databases.erb +50 -29
- data/app/views/error.erb +10 -2
- data/app/views/redirect.erb +20 -0
- data/app/views/sqlui.erb +34 -13
- data/client/resources/favicon.svg +50 -1
- data/client/resources/github.svg +3 -0
- data/client/resources/help.css +1 -1
- data/client/resources/saved.css +96 -0
- data/client/resources/sqlui.css +60 -53
- data/client/resources/sqlui.js +186 -100
- metadata +20 -2
data/client/resources/sqlui.js
CHANGED
@@ -24443,7 +24443,6 @@
|
|
24443
24443
|
const moveListener = (event) => {
|
24444
24444
|
const y = event.clientY - startY;
|
24445
24445
|
const height = Math.min(max, Math.max(min, startHeight + y));
|
24446
|
-
console.log(`y: ${y}, height: ${height}`);
|
24447
24446
|
resizableElement.style.height = `${height}px`;
|
24448
24447
|
};
|
24449
24448
|
|
@@ -24465,12 +24464,10 @@
|
|
24465
24464
|
|
24466
24465
|
const PAGE_SIZE = 100;
|
24467
24466
|
|
24467
|
+
const TABS = ['query', 'graph', 'saved', 'structure', 'help'];
|
24468
|
+
|
24468
24469
|
function getSqlFromUrl (url) {
|
24469
24470
|
const params = url.searchParams;
|
24470
|
-
if (params.has('file') && params.has('sql')) {
|
24471
|
-
// TODO: show an error.
|
24472
|
-
throw new Error('You can only specify a file or sql param, not both.')
|
24473
|
-
}
|
24474
24471
|
if (params.has('sql')) {
|
24475
24472
|
return params.get('sql')
|
24476
24473
|
} else if (params.has('file')) {
|
@@ -24501,6 +24498,12 @@
|
|
24501
24498
|
const runCurrentLabel = `run selection (${isMac ? '⌘' : 'Ctrl'}-Enter)`;
|
24502
24499
|
const runAllLabel = `run all (${isMac ? '⌘' : 'Ctrl'}-Shift-Enter)`;
|
24503
24500
|
|
24501
|
+
const dismissFileButton = document.getElementById('dismiss-file-button');
|
24502
|
+
addEventListener(dismissFileButton, 'click', (event) => dismissFile());
|
24503
|
+
|
24504
|
+
const saveFileButton = document.getElementById('save-file-button');
|
24505
|
+
addEventListener(saveFileButton, 'click', (event) => saveFile());
|
24506
|
+
|
24504
24507
|
const submitButtonCurrent = document.getElementById('submit-button-current');
|
24505
24508
|
submitButtonCurrent.value = runCurrentLabel;
|
24506
24509
|
addEventListener(submitButtonCurrent, 'click', (event) => submitCurrent(event.target, event));
|
@@ -24695,10 +24698,10 @@
|
|
24695
24698
|
function selectTab (event, tab) {
|
24696
24699
|
const url = new URL(window.location);
|
24697
24700
|
setActionInUrl(url, tab);
|
24698
|
-
route(event.target, event, url
|
24701
|
+
route(event.target, event, url);
|
24699
24702
|
}
|
24700
24703
|
|
24701
|
-
function route (target = null, event = null, url = null,
|
24704
|
+
function route (target = null, event = null, url = null, run = false) {
|
24702
24705
|
closePopup();
|
24703
24706
|
|
24704
24707
|
if (url) {
|
@@ -24716,7 +24719,7 @@
|
|
24716
24719
|
}
|
24717
24720
|
}
|
24718
24721
|
if (url.href !== window.location.href) {
|
24719
|
-
|
24722
|
+
pushState(url);
|
24720
24723
|
}
|
24721
24724
|
} else {
|
24722
24725
|
url = new URL(window.location);
|
@@ -24740,10 +24743,10 @@
|
|
24740
24743
|
|
24741
24744
|
switch (window.tab) {
|
24742
24745
|
case 'query':
|
24743
|
-
selectQueryTab(
|
24746
|
+
selectQueryTab(run);
|
24744
24747
|
break
|
24745
24748
|
case 'graph':
|
24746
|
-
selectGraphTab(
|
24749
|
+
selectGraphTab(run);
|
24747
24750
|
break
|
24748
24751
|
case 'saved':
|
24749
24752
|
selectSavedTab();
|
@@ -24932,7 +24935,7 @@
|
|
24932
24935
|
setTimeout(() => { helpBoxElement.focus(); }, 0);
|
24933
24936
|
}
|
24934
24937
|
|
24935
|
-
function selectGraphTab (
|
24938
|
+
function selectGraphTab (run) {
|
24936
24939
|
document.getElementById('query-box').style.display = 'flex';
|
24937
24940
|
document.getElementById('submit-box').style.display = 'flex';
|
24938
24941
|
document.getElementById('graph-box').style.display = 'flex';
|
@@ -24940,17 +24943,19 @@
|
|
24940
24943
|
document.getElementById('cancel-button').style.visibility = 'hidden';
|
24941
24944
|
updateDownloadButtons(window?.sqlFetch);
|
24942
24945
|
focus(getSelection());
|
24943
|
-
maybeFetchResult(
|
24946
|
+
maybeFetchResult(run);
|
24947
|
+
updateFileBox();
|
24944
24948
|
}
|
24945
24949
|
|
24946
|
-
function selectQueryTab (
|
24950
|
+
function selectQueryTab (run) {
|
24947
24951
|
document.getElementById('query-box').style.display = 'flex';
|
24948
24952
|
document.getElementById('submit-box').style.display = 'flex';
|
24949
24953
|
document.getElementById('result-box').style.display = 'flex';
|
24950
24954
|
document.getElementById('fetch-sql-box').style.display = 'none';
|
24951
24955
|
document.getElementById('cancel-button').style.visibility = 'hidden';
|
24952
24956
|
focus(getSelection());
|
24953
|
-
maybeFetchResult(
|
24957
|
+
maybeFetchResult(run);
|
24958
|
+
updateFileBox();
|
24954
24959
|
}
|
24955
24960
|
|
24956
24961
|
function selectSavedTab () {
|
@@ -24959,7 +24964,12 @@
|
|
24959
24964
|
});
|
24960
24965
|
|
24961
24966
|
const savedElement = document.getElementById('saved-box');
|
24962
|
-
setTimeout(() => {
|
24967
|
+
setTimeout(() => {
|
24968
|
+
// Little hack so that hitting tab after loading the saved tab will cause focus to go to the first file.
|
24969
|
+
savedElement.tabIndex = 0;
|
24970
|
+
savedElement.focus();
|
24971
|
+
savedElement.tabIndex = -1;
|
24972
|
+
}, 0);
|
24963
24973
|
|
24964
24974
|
const saved = window.metadata.saved;
|
24965
24975
|
const numFiles = Object.keys(saved).length;
|
@@ -24970,60 +24980,75 @@
|
|
24970
24980
|
}
|
24971
24981
|
|
24972
24982
|
Object.values(saved).forEach(file => {
|
24983
|
+
const gitHubElement = document.createElement('a');
|
24984
|
+
gitHubElement.classList.add('saved-github-link');
|
24985
|
+
gitHubElement.href = file.github_url;
|
24986
|
+
gitHubElement.target = '_blank';
|
24987
|
+
addEventListener(gitHubElement, 'click', (event) => {
|
24988
|
+
event.stopPropagation();
|
24989
|
+
});
|
24990
|
+
addEventListener(gitHubElement, 'keydown', (event) => {
|
24991
|
+
if (event.keyCode === 13) {
|
24992
|
+
event.stopPropagation();
|
24993
|
+
}
|
24994
|
+
});
|
24995
|
+
|
24996
|
+
const gitHubImageElement = document.createElement('img');
|
24997
|
+
gitHubImageElement.alt = 'GitHub';
|
24998
|
+
gitHubImageElement.src = window.resourcePathMap['github.svg'];
|
24999
|
+
gitHubElement.appendChild(gitHubImageElement);
|
25000
|
+
|
24973
25001
|
const viewUrl = new URL(window.location.origin + window.location.pathname);
|
24974
25002
|
setActionInUrl(viewUrl, 'query');
|
24975
25003
|
viewUrl.searchParams.set('file', file.filename);
|
24976
25004
|
|
24977
|
-
const
|
24978
|
-
|
24979
|
-
|
24980
|
-
|
24981
|
-
addEventListener(viewLinkElement, 'click', (event) => {
|
24982
|
-
clearResult();
|
24983
|
-
route(event.target, event, viewUrl, true);
|
24984
|
-
});
|
25005
|
+
const nameElement = document.createElement('a');
|
25006
|
+
nameElement.classList.add('saved-name');
|
25007
|
+
nameElement.innerText = file.filename;
|
25008
|
+
nameElement.href = viewUrl.pathname + viewUrl.search;
|
24985
25009
|
|
24986
|
-
const
|
24987
|
-
|
24988
|
-
|
24989
|
-
|
25010
|
+
const headerElement = document.createElement('div');
|
25011
|
+
headerElement.classList.add('saved-file-header');
|
25012
|
+
headerElement.appendChild(nameElement);
|
25013
|
+
headerElement.appendChild(gitHubElement);
|
24990
25014
|
|
24991
|
-
const
|
24992
|
-
|
24993
|
-
|
24994
|
-
|
24995
|
-
|
24996
|
-
|
24997
|
-
|
24998
|
-
});
|
25015
|
+
const contentLines = file.contents.endsWith('\n') ? file.contents.slice(0, -1).split('\n') : file.contents.split('\n');
|
25016
|
+
let preview;
|
25017
|
+
if (contentLines.length > 5) {
|
25018
|
+
preview = contentLines.slice(0, 4).join('\n');
|
25019
|
+
} else {
|
25020
|
+
preview = contentLines.join('\n');
|
25021
|
+
}
|
24999
25022
|
|
25000
|
-
const
|
25001
|
-
|
25002
|
-
|
25003
|
-
|
25004
|
-
|
25023
|
+
const previewElement = document.createElement('a');
|
25024
|
+
previewElement.classList.add('saved-preview');
|
25025
|
+
previewElement.tabIndex = -1;
|
25026
|
+
previewElement.innerText = preview;
|
25027
|
+
previewElement.href = viewUrl.pathname + viewUrl.search;
|
25005
25028
|
|
25006
|
-
|
25007
|
-
|
25008
|
-
|
25029
|
+
if (contentLines.length > 5) {
|
25030
|
+
const truncatedElement = document.createElement('div');
|
25031
|
+
truncatedElement.classList.add('saved-truncated');
|
25032
|
+
truncatedElement.innerText = `... ${contentLines.length - 4} more lines`;
|
25033
|
+
previewElement.appendChild(truncatedElement);
|
25034
|
+
}
|
25009
25035
|
|
25010
|
-
const
|
25011
|
-
|
25012
|
-
|
25013
|
-
|
25014
|
-
|
25015
|
-
|
25016
|
-
|
25017
|
-
|
25018
|
-
|
25019
|
-
|
25020
|
-
|
25021
|
-
|
25022
|
-
|
25023
|
-
|
25024
|
-
|
25025
|
-
|
25026
|
-
savedElement.appendChild(divElement);
|
25036
|
+
const itemElement = document.createElement('div');
|
25037
|
+
itemElement.classList.add('saved-list-item');
|
25038
|
+
itemElement.appendChild(headerElement);
|
25039
|
+
itemElement.appendChild(previewElement);
|
25040
|
+
addEventListener(itemElement, 'click', (event) => {
|
25041
|
+
clearResult();
|
25042
|
+
route(event.target, event, viewUrl);
|
25043
|
+
});
|
25044
|
+
addEventListener(itemElement, 'keydown', (event) => {
|
25045
|
+
if (event.keyCode === 13) {
|
25046
|
+
clearResult();
|
25047
|
+
route(event.target, event, viewUrl);
|
25048
|
+
}
|
25049
|
+
});
|
25050
|
+
|
25051
|
+
savedElement.appendChild(itemElement);
|
25027
25052
|
});
|
25028
25053
|
}
|
25029
25054
|
|
@@ -25048,19 +25073,15 @@
|
|
25048
25073
|
window.lastEditorValueSet = null;
|
25049
25074
|
|
25050
25075
|
const url = new URL(window.location);
|
25051
|
-
let sql = getEditorValue()
|
25052
|
-
sql = sql === '' ? null : sql;
|
25053
|
-
|
25054
|
-
url.searchParams.set('run', 'true');
|
25076
|
+
let sql = getEditorValue();
|
25077
|
+
sql = sql.trim() === '' ? null : sql;
|
25055
25078
|
|
25056
25079
|
if (url.searchParams.has('file')) {
|
25057
25080
|
if (window.metadata.saved[url.searchParams.get('file')].contents !== getEditorValue()) {
|
25058
|
-
url.searchParams.delete('file');
|
25059
25081
|
url.searchParams.set('sql', sql);
|
25060
25082
|
}
|
25061
25083
|
} else {
|
25062
|
-
|
25063
|
-
sqlParam = sqlParam === '' ? null : sqlParam;
|
25084
|
+
const sqlParam = url.searchParams.has('sql') ? url.searchParams.get('sql') : null;
|
25064
25085
|
|
25065
25086
|
if (sqlParam !== sql && sql === null) {
|
25066
25087
|
url.searchParams.delete('sql');
|
@@ -25079,7 +25100,6 @@
|
|
25079
25100
|
url.searchParams.delete('selection');
|
25080
25101
|
url.searchParams.delete('sql');
|
25081
25102
|
url.searchParams.delete('file');
|
25082
|
-
url.searchParams.delete('run');
|
25083
25103
|
}
|
25084
25104
|
|
25085
25105
|
route(target, event, url, true);
|
@@ -25225,31 +25245,18 @@
|
|
25225
25245
|
)
|
25226
25246
|
}
|
25227
25247
|
|
25228
|
-
function maybeFetchResult (
|
25248
|
+
function maybeFetchResult (run) {
|
25229
25249
|
const url = new URL(window.location);
|
25230
25250
|
const params = url.searchParams;
|
25231
25251
|
const sql = params.get('sql');
|
25232
25252
|
const file = params.get('file');
|
25233
25253
|
const selection = params.get('selection');
|
25234
|
-
const hasSqluiReferrer = document.referrer && new URL(document.referrer).origin === url.origin;
|
25235
25254
|
const variables = parseSqlVariables(params);
|
25236
25255
|
|
25237
|
-
if (
|
25238
|
-
|
25239
|
-
throw new Error('You can only specify a file or sql, not both.')
|
25240
|
-
}
|
25241
|
-
|
25242
|
-
// Only allow auto-run if coming from another SQLUI page. The idea here is to let the app link to URLs with run=true
|
25243
|
-
// but not other apps. This allows meta/shift-clicking to run a query.
|
25244
|
-
if (params.has('run')) {
|
25245
|
-
url.searchParams.delete('run');
|
25246
|
-
window.history.replaceState({}, '', url);
|
25256
|
+
if (run) {
|
25257
|
+
replaceState(url);
|
25247
25258
|
clearResult();
|
25248
25259
|
|
25249
|
-
if (!internal && !hasSqluiReferrer) {
|
25250
|
-
throw new Error('run only allowed for internal usage')
|
25251
|
-
}
|
25252
|
-
|
25253
25260
|
if (params.has('sql') || params.has('file')) {
|
25254
25261
|
const sqlFetch = buildSqlFetch(sql, file, variables, selection);
|
25255
25262
|
setEditorValue(sqlFetch.sql);
|
@@ -25269,10 +25276,13 @@
|
|
25269
25276
|
const existingRequest = window.sqlFetch;
|
25270
25277
|
if (existingRequest) {
|
25271
25278
|
const selectionMatches = selection === existingRequest.selection;
|
25272
|
-
|
25273
|
-
|
25279
|
+
let queryMatches = false;
|
25280
|
+
if (params.has('sql')) {
|
25281
|
+
queryMatches = sql === existingRequest.sql;
|
25282
|
+
} else if (params.has('file')) {
|
25283
|
+
queryMatches = file === existingRequest.file;
|
25284
|
+
}
|
25274
25285
|
const variablesMatch = JSON.stringify(variables) === JSON.stringify(existingRequest.variables);
|
25275
|
-
const queryMatches = sqlMatches || fileMatches;
|
25276
25286
|
if (selectionMatches && queryMatches && variablesMatch) {
|
25277
25287
|
displaySqlFetch(existingRequest);
|
25278
25288
|
if (params.has('selection') && window.lastSetSelectionValueFromUrlParam !== selection) {
|
@@ -25326,15 +25336,15 @@
|
|
25326
25336
|
function buildSqlFetch (sql, file, variables, selection) {
|
25327
25337
|
const sqlFetch = new SqlFetch(sql, file, variables, selection);
|
25328
25338
|
|
25329
|
-
if (
|
25339
|
+
if (sql) {
|
25340
|
+
sqlFetch.sql = sql;
|
25341
|
+
} else if (file) {
|
25330
25342
|
const fileDetails = window.metadata.saved[file];
|
25331
25343
|
if (!fileDetails) {
|
25332
25344
|
throw new Error(`no such file: ${file}`)
|
25333
25345
|
}
|
25334
25346
|
sqlFetch.file = file;
|
25335
25347
|
sqlFetch.sql = fileDetails.contents;
|
25336
|
-
} else if (sql) {
|
25337
|
-
sqlFetch.sql = sql;
|
25338
25348
|
}
|
25339
25349
|
|
25340
25350
|
return sqlFetch
|
@@ -25502,15 +25512,27 @@
|
|
25502
25512
|
addEventListener(tableElement, 'mousedown', listener);
|
25503
25513
|
}
|
25504
25514
|
function disableDownloadButtons () {
|
25505
|
-
document.getElementById('submit-dropdown-button-download-csv')
|
25506
|
-
|
25507
|
-
|
25515
|
+
const downloadCsvElement = document.getElementById('submit-dropdown-button-download-csv');
|
25516
|
+
downloadCsvElement.classList.add('disabled');
|
25517
|
+
downloadCsvElement.tabIndex = -1;
|
25518
|
+
const copyCsvElement = document.getElementById('submit-dropdown-button-copy-csv');
|
25519
|
+
copyCsvElement.classList.add('disabled');
|
25520
|
+
copyCsvElement.tabIndex = -1;
|
25521
|
+
const copyTsvElement = document.getElementById('submit-dropdown-button-copy-tsv');
|
25522
|
+
copyTsvElement.classList.add('disabled');
|
25523
|
+
copyTsvElement.tabIndex = -1;
|
25508
25524
|
}
|
25509
25525
|
|
25510
25526
|
function enableDownloadButtons () {
|
25511
|
-
document.getElementById('submit-dropdown-button-download-csv')
|
25512
|
-
|
25513
|
-
|
25527
|
+
const downloadCsvElement = document.getElementById('submit-dropdown-button-download-csv');
|
25528
|
+
downloadCsvElement.classList.remove('disabled');
|
25529
|
+
downloadCsvElement.tabIndex = 0;
|
25530
|
+
const copyCsvElement = document.getElementById('submit-dropdown-button-copy-csv');
|
25531
|
+
copyCsvElement.classList.remove('disabled');
|
25532
|
+
copyCsvElement.tabIndex = 0;
|
25533
|
+
const copyTsvElement = document.getElementById('submit-dropdown-button-copy-tsv');
|
25534
|
+
copyTsvElement.classList.remove('disabled');
|
25535
|
+
copyTsvElement.tabIndex = 0;
|
25514
25536
|
}
|
25515
25537
|
|
25516
25538
|
function updateDownloadButtons (fetch) {
|
@@ -25521,6 +25543,54 @@
|
|
25521
25543
|
}
|
25522
25544
|
}
|
25523
25545
|
|
25546
|
+
function updateFileBox () {
|
25547
|
+
const url = new URL(window.location);
|
25548
|
+
if (url.searchParams.has('file')) {
|
25549
|
+
document.getElementById('filename').innerText = url.searchParams.get('file');
|
25550
|
+
document.getElementById('filename-box').style.display = 'flex';
|
25551
|
+
} else {
|
25552
|
+
document.getElementById('filename-box').style.display = 'none';
|
25553
|
+
}
|
25554
|
+
}
|
25555
|
+
|
25556
|
+
function dismissFile () {
|
25557
|
+
const url = new URL(window.location);
|
25558
|
+
url.searchParams.set('sql', getSqlFromUrl(url));
|
25559
|
+
url.searchParams.delete('file');
|
25560
|
+
if (url.searchParams.has('selection')) {
|
25561
|
+
const selection = url.searchParams.get('selection');
|
25562
|
+
// Let's put selection after sql.
|
25563
|
+
url.searchParams.delete('selection');
|
25564
|
+
url.searchParams.set('selection', selection);
|
25565
|
+
}
|
25566
|
+
document.getElementById('filename-box').style.display = 'none';
|
25567
|
+
replaceState(url);
|
25568
|
+
}
|
25569
|
+
|
25570
|
+
function replaceState (url) {
|
25571
|
+
// Paths look so much better with slashes than with %2F. It seems to work even though it isn't technically valid.
|
25572
|
+
window.history.replaceState({}, '', url.href.replaceAll('%2F', '/'));
|
25573
|
+
}
|
25574
|
+
|
25575
|
+
function pushState (url) {
|
25576
|
+
// Paths look so much better with slashes than with %2F. It seems to work even though it isn't technically valid.
|
25577
|
+
window.history.pushState({}, '', url.href.replaceAll('%2F', '/'));
|
25578
|
+
}
|
25579
|
+
|
25580
|
+
function saveFile () {
|
25581
|
+
const url = new URL(window.location);
|
25582
|
+
if (!url.searchParams.has('file')) throw new Error('missing file param')
|
25583
|
+
|
25584
|
+
const file = url.searchParams.get('file');
|
25585
|
+
const fileDetails = window.metadata.saved[file];
|
25586
|
+
if (!fileDetails) throw new Error(`no such file: ${file}`)
|
25587
|
+
|
25588
|
+
document.getElementById('save-form-base-sha').value = fileDetails.tree_sha;
|
25589
|
+
document.getElementById('save-form-path').value = fileDetails.path;
|
25590
|
+
document.getElementById('save-form-content').value = getEditorValue();
|
25591
|
+
document.getElementById('save-form').submit();
|
25592
|
+
}
|
25593
|
+
|
25524
25594
|
function displaySqlFetch (fetch) {
|
25525
25595
|
updateDownloadButtons(fetch);
|
25526
25596
|
if (window.tab === 'query') {
|
@@ -25721,6 +25791,14 @@
|
|
25721
25791
|
selectTab(event, 'structure');
|
25722
25792
|
} else if (isMac && event.code === 'Digit5' && event.ctrlKey) {
|
25723
25793
|
selectTab(event, 'help');
|
25794
|
+
} else if (isMac && event.code === 'BracketLeft' && event.ctrlKey) {
|
25795
|
+
const currentTabIndex = TABS.indexOf(window.tab);
|
25796
|
+
const previousTabIndex = currentTabIndex === 0 ? TABS.length - 1 : currentTabIndex - 1;
|
25797
|
+
selectTab(event, TABS[previousTabIndex]);
|
25798
|
+
} else if (isMac && event.code === 'BracketRight' && event.ctrlKey) {
|
25799
|
+
const currentTabIndex = TABS.indexOf(window.tab);
|
25800
|
+
const nextTabIndex = (currentTabIndex + 1) % TABS.length;
|
25801
|
+
selectTab(event, TABS[nextTabIndex]);
|
25724
25802
|
}
|
25725
25803
|
});
|
25726
25804
|
|
@@ -25733,9 +25811,14 @@
|
|
25733
25811
|
});
|
25734
25812
|
|
25735
25813
|
window.onload = function () {
|
25814
|
+
const url = new URL(window.location);
|
25815
|
+
let requestUrl = 'metadata';
|
25816
|
+
if (url.searchParams.has('file')) {
|
25817
|
+
requestUrl += `?file=${url.searchParams.get('file')}`;
|
25818
|
+
}
|
25736
25819
|
Promise.all([
|
25737
25820
|
google.charts.load('current', { packages: ['corechart', 'line'] }),
|
25738
|
-
fetch(
|
25821
|
+
fetch(requestUrl, {
|
25739
25822
|
headers: {
|
25740
25823
|
Accept: 'application/json'
|
25741
25824
|
},
|
@@ -25748,12 +25831,15 @@
|
|
25748
25831
|
if (contentType && contentType.indexOf('application/json') !== -1) {
|
25749
25832
|
return response.json().then((result) => {
|
25750
25833
|
if (result.error) {
|
25751
|
-
let error = '<
|
25752
|
-
error +=
|
25834
|
+
let error = '<span style="font-family: monospace; color: #333; font-size: 16px;">\n';
|
25835
|
+
error += '<h2>Internal Error</h2>\n';
|
25836
|
+
error += '<h3>Message</h3>\n';
|
25837
|
+
error += `<p>${result.error}</p>\n`;
|
25753
25838
|
if (result.stacktrace) {
|
25839
|
+
error += '<h3>Stacktrace</h3>\n';
|
25754
25840
|
error += '<pre>\n' + result.stacktrace + '\n</pre>\n';
|
25755
25841
|
}
|
25756
|
-
error += '</
|
25842
|
+
error += '</span>\n';
|
25757
25843
|
document.getElementById('loading-box').innerHTML = error;
|
25758
25844
|
} else if (!result.server) {
|
25759
25845
|
document.getElementById('loading-box').innerHTML = `
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.72
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Dower
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -206,6 +206,20 @@ dependencies:
|
|
206
206
|
- - "~>"
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '4.0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: timecop
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0.0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0.0'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: webmock
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,6 +256,7 @@ files:
|
|
242
256
|
- app/github/tree.rb
|
243
257
|
- app/github/tree_client.rb
|
244
258
|
- app/mysql_types.rb
|
259
|
+
- app/pigs.rb
|
245
260
|
- app/saved_config.rb
|
246
261
|
- app/server.rb
|
247
262
|
- app/sql_parser.rb
|
@@ -250,10 +265,13 @@ files:
|
|
250
265
|
- app/version.rb
|
251
266
|
- app/views/databases.erb
|
252
267
|
- app/views/error.erb
|
268
|
+
- app/views/redirect.erb
|
253
269
|
- app/views/sqlui.erb
|
254
270
|
- bin/sqlui
|
255
271
|
- client/resources/favicon.svg
|
272
|
+
- client/resources/github.svg
|
256
273
|
- client/resources/help.css
|
274
|
+
- client/resources/saved.css
|
257
275
|
- client/resources/sqlui.css
|
258
276
|
- client/resources/sqlui.js
|
259
277
|
- client/resources/vertical-resizer.svg
|