sqlui 0.1.66 → 0.1.67
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/database_metadata.rb +78 -1
- data/app/sql_parser.rb +3 -3
- data/app/views/databases.erb +22 -30
- data/app/views/sqlui.erb +10 -4
- data/client/resources/sqlui.css +64 -39
- data/client/resources/sqlui.js +49 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b91f535db1da5166bfebd7b9d9097db156b429aa283c6084e1f79bb348f56c4
|
4
|
+
data.tar.gz: bec7b344b15ee7730f88e77ad88910a8e316ac135aa9f66a4ea96aafecf763ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e470fbc8f9ea18c9de08eb05ce67a491f6a0b42a9e0895033566f97953da3e630963f431192411af6471dc678979e45e67aa845fbde3b07093abc4c95c119e3d
|
7
|
+
data.tar.gz: bd4030d8b1e3095873b887c36dad1303b63aa1e020851ce5fa3336b8b5f055b6b33b20b21db28a203350c3cc7746cd1dc422a221a08412903a39b8d0f6a79afa
|
data/.release-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.67
|
data/app/database_metadata.rb
CHANGED
@@ -10,6 +10,7 @@ class DatabaseMetadata
|
|
10
10
|
def lookup(client, database_config)
|
11
11
|
result = load_columns(client, database_config)
|
12
12
|
load_stats(result, client, database_config)
|
13
|
+
load_tables(result, client, database_config)
|
13
14
|
|
14
15
|
result
|
15
16
|
end
|
@@ -91,7 +92,7 @@ class DatabaseMetadata
|
|
91
92
|
from information_schema.statistics
|
92
93
|
#{where_clause}
|
93
94
|
order by table_schema, table_name, if(index_name = "PRIMARY", 0, index_name), seq_in_index;
|
94
|
-
|
95
|
+
SQL
|
95
96
|
)
|
96
97
|
stats_result.each do |row|
|
97
98
|
table_schema = row.shift
|
@@ -110,5 +111,81 @@ class DatabaseMetadata
|
|
110
111
|
column[:column_name] = column_name
|
111
112
|
end
|
112
113
|
end
|
114
|
+
|
115
|
+
def load_tables(result, client, _database_config)
|
116
|
+
tables_result = client.query(
|
117
|
+
<<~SQL
|
118
|
+
SELECT
|
119
|
+
TABLE_SCHEMA,
|
120
|
+
TABLE_NAME,
|
121
|
+
CREATE_TIME,
|
122
|
+
UPDATE_TIME,
|
123
|
+
ENGINE,
|
124
|
+
TABLE_ROWS,
|
125
|
+
AVG_ROW_LENGTH,
|
126
|
+
DATA_LENGTH,
|
127
|
+
INDEX_LENGTH,
|
128
|
+
TABLE_COLLATION,
|
129
|
+
AUTO_INCREMENT
|
130
|
+
FROM information_schema.TABLES;
|
131
|
+
SQL
|
132
|
+
)
|
133
|
+
tables_hash = {}
|
134
|
+
tables_result.each do |row|
|
135
|
+
table_schema = row.shift
|
136
|
+
table_name = row.shift
|
137
|
+
tables_hash[table_schema] ||= {}
|
138
|
+
tables_hash[table_schema][table_name] = {
|
139
|
+
created_at: row.shift,
|
140
|
+
updated_at: row.shift,
|
141
|
+
engine: row.shift,
|
142
|
+
rows: add_thousands_separator(row.shift),
|
143
|
+
average_row_size: pretty_data_size(row.shift),
|
144
|
+
data_size: pretty_data_size(row.shift),
|
145
|
+
index_size: pretty_data_size(row.shift),
|
146
|
+
encoding: row.shift,
|
147
|
+
auto_increment: add_thousands_separator(row.shift)
|
148
|
+
}
|
149
|
+
end
|
150
|
+
result.each do |table_schema, schema_hash|
|
151
|
+
schema_hash[:tables].each do |table_name, table|
|
152
|
+
table[:info] = tables_hash[table_schema][table_name]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def pretty_data_size(size)
|
158
|
+
if size.nil?
|
159
|
+
return nil
|
160
|
+
elsif size < 1024
|
161
|
+
unit = "byte#{size == 1 ? '' : 's'}"
|
162
|
+
converted = size
|
163
|
+
elsif size < 1024 * 1024
|
164
|
+
unit = 'KiB'
|
165
|
+
converted = (size.to_f / 1024).round(2)
|
166
|
+
elsif size < 1024 * 1024 * 1024
|
167
|
+
unit = 'MiB'
|
168
|
+
converted = (size.to_f / (1024 * 1024)).round(2)
|
169
|
+
elsif size < 1024 * 1024 * 1024 * 1024
|
170
|
+
unit = 'GiB'
|
171
|
+
converted = (size.to_f / (1024 * 1024 * 1024)).round(2)
|
172
|
+
end
|
173
|
+
|
174
|
+
"#{add_thousands_separator(converted)} #{unit}"
|
175
|
+
end
|
176
|
+
|
177
|
+
def add_thousands_separator(value)
|
178
|
+
return nil if value.nil?
|
179
|
+
|
180
|
+
integer = value.round(1).floor
|
181
|
+
fractional = ((value.round(1) - integer) * 10).floor
|
182
|
+
|
183
|
+
with_commas = integer.to_s.reverse.scan(/.{1,3}/).join(',').reverse
|
184
|
+
if fractional.zero?
|
185
|
+
with_commas
|
186
|
+
else
|
187
|
+
"#{with_commas}.#{fractional}"
|
188
|
+
end
|
189
|
+
end
|
113
190
|
end
|
114
191
|
end
|
data/app/sql_parser.rb
CHANGED
@@ -40,10 +40,10 @@ class SqlParser
|
|
40
40
|
multi_commented = true
|
41
41
|
elsif multi_commented && char == '*' && scanner.peek(1) == '/'
|
42
42
|
multi_commented = false
|
43
|
-
elsif multi_commented
|
43
|
+
elsif multi_commented || (single_commented && char != "\n")
|
44
44
|
next
|
45
45
|
elsif !single_quoted && !double_quoted && !escaped && !multi_commented &&
|
46
|
-
char == '-' && scanner.peek(
|
46
|
+
char == '-' && scanner.peek(2).match?(/-[ \n\t]/)
|
47
47
|
current += scanner.getch
|
48
48
|
single_commented = true
|
49
49
|
elsif !single_quoted && !double_quoted && !escaped && !multi_commented && char == '#'
|
@@ -51,7 +51,7 @@ class SqlParser
|
|
51
51
|
elsif single_commented && char == "\n"
|
52
52
|
single_commented = false
|
53
53
|
elsif single_commented
|
54
|
-
|
54
|
+
single_commented = false if char == "\n"
|
55
55
|
elsif char == '\\'
|
56
56
|
escaped = true
|
57
57
|
elsif char == "'"
|
data/app/views/databases.erb
CHANGED
@@ -11,18 +11,6 @@
|
|
11
11
|
margin: 0;
|
12
12
|
}
|
13
13
|
|
14
|
-
h1 {
|
15
|
-
font-size: 22px;
|
16
|
-
}
|
17
|
-
|
18
|
-
h2 {
|
19
|
-
font-size: 20px;
|
20
|
-
}
|
21
|
-
|
22
|
-
p {
|
23
|
-
font-size: 18px;
|
24
|
-
}
|
25
|
-
|
26
14
|
.header-box {
|
27
15
|
display: flex;
|
28
16
|
flex-direction: row;
|
@@ -37,6 +25,12 @@
|
|
37
25
|
align-items: center;
|
38
26
|
justify-content: start;
|
39
27
|
color: #333;
|
28
|
+
font-size: 22px;
|
29
|
+
}
|
30
|
+
|
31
|
+
.header {
|
32
|
+
font-weight: bold;
|
33
|
+
padding-left: 5px;
|
40
34
|
}
|
41
35
|
|
42
36
|
.server-name {
|
@@ -45,30 +39,28 @@
|
|
45
39
|
font-weight: normal;
|
46
40
|
}
|
47
41
|
|
48
|
-
.
|
42
|
+
.links {
|
49
43
|
display: flex;
|
50
44
|
flex-direction: row;
|
51
45
|
align-items: center;
|
46
|
+
margin-top: 5px;
|
52
47
|
}
|
53
48
|
|
54
|
-
.
|
55
|
-
|
56
|
-
padding-left: 5px;
|
57
|
-
}
|
58
|
-
|
59
|
-
.database a {
|
60
|
-
margin-right: 5px;
|
49
|
+
.link {
|
50
|
+
margin-right: 10px;
|
61
51
|
color: darkblue;
|
62
|
-
font-size:
|
52
|
+
font-size: 17px;
|
63
53
|
text-decoration: none;
|
64
54
|
}
|
65
55
|
|
66
|
-
.
|
67
|
-
margin: 0
|
56
|
+
.name {
|
57
|
+
margin: 0 200px 0 0;
|
58
|
+
font-size: 20px;
|
68
59
|
}
|
69
60
|
|
70
|
-
.
|
71
|
-
margin:
|
61
|
+
.description {
|
62
|
+
margin: 20px 0 0;
|
63
|
+
font-size: 18px;
|
72
64
|
}
|
73
65
|
|
74
66
|
.database {
|
@@ -90,11 +82,11 @@
|
|
90
82
|
</div>
|
91
83
|
<% config.database_configs.each do |database_config| %>
|
92
84
|
<div class="database">
|
93
|
-
<
|
94
|
-
|
95
|
-
<a class='query-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/query" %>">query</a>
|
96
|
-
<a class='saved-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/saved" %>">saved</a>
|
97
|
-
<a class='structure-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/structure" %>">structure</a>
|
85
|
+
<h2 class='name'><%= database_config.display_name %></h2>
|
86
|
+
<div class="links">
|
87
|
+
<a class='link query-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/query" %>">query</a>
|
88
|
+
<a class='link saved-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/saved" %>">saved</a>
|
89
|
+
<a class='link structure-link' href="<%= "#{config.base_url_path}/#{database_config.url_path}/structure" %>">structure</a>
|
98
90
|
</div>
|
99
91
|
<p class='description'>
|
100
92
|
<%= database_config.description %>
|
data/app/views/sqlui.erb
CHANGED
@@ -84,10 +84,16 @@
|
|
84
84
|
|
85
85
|
<div id="structure-box" class="tab-content-element structure-element" style="display: none;">
|
86
86
|
<div class="structure-wrapper">
|
87
|
-
<
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
<div id="schemas-tables-and-stats">
|
88
|
+
<div id="schemas-and-tables">
|
89
|
+
<select id="schemas" size="4">
|
90
|
+
</select>
|
91
|
+
<select id="tables" size="4">
|
92
|
+
</select>
|
93
|
+
</div>
|
94
|
+
<div id="stats">
|
95
|
+
</div>
|
96
|
+
</div>
|
91
97
|
<div id="table-info">
|
92
98
|
<div id="columns">
|
93
99
|
</div>
|
data/client/resources/sqlui.css
CHANGED
@@ -8,18 +8,6 @@ body {
|
|
8
8
|
overflow: hidden;
|
9
9
|
}
|
10
10
|
|
11
|
-
h1 {
|
12
|
-
font-size: 22px;
|
13
|
-
}
|
14
|
-
|
15
|
-
h2 {
|
16
|
-
font-size: 20px;
|
17
|
-
}
|
18
|
-
|
19
|
-
p {
|
20
|
-
font-size: 18px;
|
21
|
-
}
|
22
|
-
|
23
11
|
#loading-box {
|
24
12
|
font-family: monospace;
|
25
13
|
display: flex;
|
@@ -48,6 +36,7 @@ p {
|
|
48
36
|
align-items: center;
|
49
37
|
justify-content: start;
|
50
38
|
color: #333;
|
39
|
+
font-size: 22px;
|
51
40
|
}
|
52
41
|
|
53
42
|
#header {
|
@@ -126,6 +115,7 @@ p {
|
|
126
115
|
cursor: row-resize;
|
127
116
|
flex-direction: column;
|
128
117
|
align-items: center;
|
118
|
+
padding-left: 220px; /* To center the resizer icon. Ok, it's a hack. Get over it. */
|
129
119
|
}
|
130
120
|
|
131
121
|
#cancel-button {
|
@@ -135,7 +125,7 @@ p {
|
|
135
125
|
border: 1px solid #888;
|
136
126
|
height: 32px;
|
137
127
|
font-size: 18px;
|
138
|
-
margin: 0
|
128
|
+
margin: 0;
|
139
129
|
}
|
140
130
|
|
141
131
|
#cancel-button-spacer {
|
@@ -258,6 +248,7 @@ p {
|
|
258
248
|
display: flex;
|
259
249
|
flex-direction: column;
|
260
250
|
}
|
251
|
+
|
261
252
|
table tbody tr td {
|
262
253
|
height: 21px;
|
263
254
|
}
|
@@ -384,16 +375,28 @@ thead {
|
|
384
375
|
font-family: Helvetica, sans-serif;
|
385
376
|
}
|
386
377
|
|
387
|
-
|
388
|
-
|
378
|
+
.links {
|
379
|
+
display: flex;
|
380
|
+
flex-direction: row;
|
381
|
+
align-items: center;
|
382
|
+
margin-top: 5px;
|
389
383
|
}
|
390
384
|
|
391
|
-
.
|
392
|
-
|
385
|
+
.link {
|
386
|
+
margin-right: 10px;
|
387
|
+
color: darkblue;
|
388
|
+
font-size: 17px;
|
389
|
+
text-decoration: none;
|
393
390
|
}
|
394
391
|
|
395
|
-
|
396
|
-
margin: 0;
|
392
|
+
.name {
|
393
|
+
margin: 0 200px 0 0;
|
394
|
+
font-size: 20px;
|
395
|
+
}
|
396
|
+
|
397
|
+
.description {
|
398
|
+
margin: 20px 0 0;
|
399
|
+
font-size: 18px;
|
397
400
|
}
|
398
401
|
|
399
402
|
.saved-list-item {
|
@@ -402,25 +405,8 @@ thead {
|
|
402
405
|
padding: 10px;
|
403
406
|
}
|
404
407
|
|
405
|
-
.saved-list-item
|
406
|
-
|
407
|
-
}
|
408
|
-
|
409
|
-
.saved-list-item p {
|
410
|
-
margin: 10px 0 0;
|
411
|
-
}
|
412
|
-
|
413
|
-
.name-and-links {
|
414
|
-
display: flex;
|
415
|
-
flex-direction: row;
|
416
|
-
align-items: center;
|
417
|
-
}
|
418
|
-
|
419
|
-
.name-and-links a {
|
420
|
-
margin-right: 5px;
|
421
|
-
color: darkblue;
|
422
|
-
font-size: 16px;
|
423
|
-
text-decoration: none;
|
408
|
+
.saved-list-item:last-child {
|
409
|
+
border-bottom: none;
|
424
410
|
}
|
425
411
|
|
426
412
|
.cm-editor.cm-focused {
|
@@ -435,10 +421,49 @@ thead {
|
|
435
421
|
height: 100%;
|
436
422
|
}
|
437
423
|
|
424
|
+
#schemas-and-tables {
|
425
|
+
display: flex;
|
426
|
+
flex-direction: row;
|
427
|
+
flex: 1;
|
428
|
+
}
|
429
|
+
|
430
|
+
#schemas-tables-and-stats {
|
431
|
+
display: flex;
|
432
|
+
flex-direction: column;
|
433
|
+
border-right: 1px solid #ddd;
|
434
|
+
min-width: 400px;
|
435
|
+
}
|
436
|
+
|
437
|
+
#stats {
|
438
|
+
border-top: 1px solid #ddd;
|
439
|
+
padding: 5px 0;
|
440
|
+
}
|
441
|
+
|
442
|
+
#stats table {
|
443
|
+
width: 100%;
|
444
|
+
}
|
445
|
+
|
446
|
+
#stats table td {
|
447
|
+
padding: 2px 5px;
|
448
|
+
font-size: 18px;
|
449
|
+
color: #333;
|
450
|
+
}
|
451
|
+
|
452
|
+
table td:nth-child(1) {
|
453
|
+
text-align: left;
|
454
|
+
font-family: Helvetica, sans-serif;
|
455
|
+
}
|
456
|
+
|
457
|
+
table td:nth-child(2) {
|
458
|
+
text-align: right;
|
459
|
+
font-family: monospace;
|
460
|
+
}
|
461
|
+
|
438
462
|
#schemas, #tables {
|
439
463
|
border: none;
|
440
464
|
display: flex;
|
441
|
-
|
465
|
+
flex: 1;
|
466
|
+
padding: 5px
|
442
467
|
}
|
443
468
|
|
444
469
|
#table-info {
|
data/client/resources/sqlui.js
CHANGED
@@ -25127,6 +25127,23 @@
|
|
25127
25127
|
}
|
25128
25128
|
}
|
25129
25129
|
|
25130
|
+
function statsHtml (info) {
|
25131
|
+
const hidden = info == null;
|
25132
|
+
info ||= {};
|
25133
|
+
return `
|
25134
|
+
<table ${hidden ? 'style="visibility: hidden;"' : ''}>
|
25135
|
+
<tr><td>created:</td><td>${valueOrNullHtml(info.created_at)}</td></tr>
|
25136
|
+
<tr><td>updated:</td><td>${valueOrNullHtml(info.updated_at)}</td></tr>
|
25137
|
+
<tr><td>data size:</td><td>${valueOrNullHtml(info.data_size)}</td></tr>
|
25138
|
+
<tr><td>index size:</td><td>${valueOrNullHtml(info.index_size)}</td></tr>
|
25139
|
+
<tr><td>rows:</td><td>${valueOrNullHtml(info.rows)}</td></tr>
|
25140
|
+
<tr><td>row size:</td><td>${valueOrNullHtml(info.average_row_size)}</td></tr>
|
25141
|
+
<tr><td>encoding:</td><td>${valueOrNullHtml(info.encoding)}</td></tr>
|
25142
|
+
<tr><td>auto increment:</td><td>${valueOrNullHtml(info.auto_increment)}</td></tr>
|
25143
|
+
</table>
|
25144
|
+
`
|
25145
|
+
}
|
25146
|
+
|
25130
25147
|
function selectStructureTab () {
|
25131
25148
|
Array.prototype.forEach.call(document.getElementsByClassName('structure-element'), function (selected) {
|
25132
25149
|
selected.style.display = 'flex';
|
@@ -25138,6 +25155,9 @@
|
|
25138
25155
|
|
25139
25156
|
const schemasElement = document.getElementById('schemas');
|
25140
25157
|
const tablesElement = document.getElementById('tables');
|
25158
|
+
const statsElement = document.getElementById('stats');
|
25159
|
+
statsElement.innerHTML = statsHtml(null);
|
25160
|
+
|
25141
25161
|
const columnsElement = document.getElementById('columns');
|
25142
25162
|
const indexesElement = document.getElementById('indexes');
|
25143
25163
|
|
@@ -25166,6 +25186,10 @@
|
|
25166
25186
|
schemasElement.appendChild(optionElement);
|
25167
25187
|
});
|
25168
25188
|
schemasElement.addEventListener('change', function () {
|
25189
|
+
while (statsElement.firstChild) {
|
25190
|
+
statsElement.removeChild(statsElement.firstChild);
|
25191
|
+
}
|
25192
|
+
statsElement.innerHTML = statsHtml(null);
|
25169
25193
|
while (tablesElement.firstChild) {
|
25170
25194
|
tablesElement.removeChild(tablesElement.firstChild);
|
25171
25195
|
}
|
@@ -25187,6 +25211,9 @@
|
|
25187
25211
|
});
|
25188
25212
|
}
|
25189
25213
|
tablesElement.addEventListener('change', function () {
|
25214
|
+
while (statsElement.firstChild) {
|
25215
|
+
statsElement.removeChild(statsElement.firstChild);
|
25216
|
+
}
|
25190
25217
|
while (columnsElement.firstChild) {
|
25191
25218
|
columnsElement.removeChild(columnsElement.firstChild);
|
25192
25219
|
}
|
@@ -25196,7 +25223,9 @@
|
|
25196
25223
|
const schemaName = schemaNames.length === 1 ? schemaNames[0] : schemasElement.value;
|
25197
25224
|
const tableName = tablesElement.value;
|
25198
25225
|
const table = window.metadata.schemas[schemaName].tables[tableName];
|
25226
|
+
const info = table.info;
|
25199
25227
|
|
25228
|
+
statsElement.innerHTML = statsHtml(info);
|
25200
25229
|
const columnEntries = Object.entries(table.columns);
|
25201
25230
|
if (columnEntries.length > 0) {
|
25202
25231
|
const columns = Object.keys(columnEntries[0][1]);
|
@@ -25284,7 +25313,7 @@
|
|
25284
25313
|
viewUrl.searchParams.set('file', file.filename);
|
25285
25314
|
|
25286
25315
|
const viewLinkElement = document.createElement('a');
|
25287
|
-
viewLinkElement.classList.add('view-link');
|
25316
|
+
viewLinkElement.classList.add('link', 'view-link');
|
25288
25317
|
viewLinkElement.innerText = 'view';
|
25289
25318
|
viewLinkElement.href = viewUrl.pathname + viewUrl.search;
|
25290
25319
|
addEventListener(viewLinkElement, 'click', (event) => {
|
@@ -25298,7 +25327,7 @@
|
|
25298
25327
|
runUrl.searchParams.set('run', 'true');
|
25299
25328
|
|
25300
25329
|
const runLinkElement = document.createElement('a');
|
25301
|
-
runLinkElement.classList.add('run-link');
|
25330
|
+
runLinkElement.classList.add('link', 'run-link');
|
25302
25331
|
runLinkElement.innerText = 'run';
|
25303
25332
|
runLinkElement.href = runUrl.pathname + runUrl.search;
|
25304
25333
|
addEventListener(runLinkElement, 'click', (event) => {
|
@@ -25309,25 +25338,31 @@
|
|
25309
25338
|
|
25310
25339
|
const nameElement = document.createElement('h2');
|
25311
25340
|
nameElement.innerText = file.filename;
|
25341
|
+
nameElement.classList.add('name');
|
25312
25342
|
|
25313
|
-
const
|
25314
|
-
|
25315
|
-
|
25316
|
-
|
25317
|
-
nameAndLinksElement.appendChild(runLinkElement);
|
25343
|
+
const linksElement = document.createElement('div');
|
25344
|
+
linksElement.classList.add('links');
|
25345
|
+
linksElement.appendChild(viewLinkElement);
|
25346
|
+
linksElement.appendChild(runLinkElement);
|
25318
25347
|
|
25319
25348
|
const descriptionElement = document.createElement('p');
|
25320
25349
|
descriptionElement.innerText = file.description;
|
25350
|
+
descriptionElement.classList.add('description');
|
25321
25351
|
|
25322
25352
|
const divElement = document.createElement('div');
|
25323
25353
|
divElement.classList.add('saved-list-item');
|
25324
|
-
divElement.appendChild(
|
25354
|
+
divElement.appendChild(nameElement);
|
25355
|
+
divElement.appendChild(linksElement);
|
25325
25356
|
divElement.appendChild(descriptionElement);
|
25326
25357
|
|
25327
25358
|
savedElement.appendChild(divElement);
|
25328
25359
|
});
|
25329
25360
|
}
|
25330
25361
|
|
25362
|
+
function valueOrNullHtml (value) {
|
25363
|
+
return value == null ? '<span style="color: #888">null</span>' : value
|
25364
|
+
}
|
25365
|
+
|
25331
25366
|
function submitAll (target, event) {
|
25332
25367
|
submit(target, event);
|
25333
25368
|
}
|
@@ -25973,6 +26008,12 @@
|
|
25973
26008
|
}
|
25974
26009
|
});
|
25975
26010
|
|
26011
|
+
document.addEventListener('keydown', (event) => {
|
26012
|
+
if (event.code === 'Escape') {
|
26013
|
+
focus();
|
26014
|
+
}
|
26015
|
+
});
|
26016
|
+
|
25976
26017
|
window.onload = function () {
|
25977
26018
|
Promise.all([
|
25978
26019
|
google.charts.load('current', { packages: ['corechart', 'line'] }),
|
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.67
|
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-02-
|
11
|
+
date: 2023-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: airbrake
|