sqlui 0.1.70 → 0.1.72

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, true);
24701
+ route(event.target, event, url);
24699
24702
  }
24700
24703
 
24701
- function route (target = null, event = null, url = null, internal = false) {
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
- window.history.pushState({}, '', url);
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(internal);
24746
+ selectQueryTab(run);
24744
24747
  break
24745
24748
  case 'graph':
24746
- selectGraphTab(internal);
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 (internal) {
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(internal);
24946
+ maybeFetchResult(run);
24947
+ updateFileBox();
24944
24948
  }
24945
24949
 
24946
- function selectQueryTab (internal) {
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(internal);
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(() => { savedElement.focus(); }, 0);
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 viewLinkElement = document.createElement('a');
24978
- viewLinkElement.classList.add('link', 'view-link');
24979
- viewLinkElement.innerText = 'view';
24980
- viewLinkElement.href = viewUrl.pathname + viewUrl.search;
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 runUrl = new URL(window.location.origin + window.location.pathname);
24987
- setActionInUrl(runUrl, 'query');
24988
- runUrl.searchParams.set('file', file.filename);
24989
- runUrl.searchParams.set('run', 'true');
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 runLinkElement = document.createElement('a');
24992
- runLinkElement.classList.add('link', 'run-link');
24993
- runLinkElement.innerText = 'run';
24994
- runLinkElement.href = runUrl.pathname + runUrl.search;
24995
- addEventListener(runLinkElement, 'click', (event) => {
24996
- clearResult();
24997
- route(event.target, event, runUrl, true);
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 viewOnGithubLinkElement = document.createElement('a');
25001
- viewOnGithubLinkElement.classList.add('link', 'view-github-link');
25002
- viewOnGithubLinkElement.innerText = 'github';
25003
- viewOnGithubLinkElement.href = file.github_url;
25004
- viewOnGithubLinkElement.target = '_blank';
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
- const nameElement = document.createElement('h2');
25007
- nameElement.innerText = file.filename;
25008
- nameElement.classList.add('name');
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 linksElement = document.createElement('div');
25011
- linksElement.classList.add('links');
25012
- linksElement.appendChild(viewLinkElement);
25013
- linksElement.appendChild(runLinkElement);
25014
- linksElement.appendChild(viewOnGithubLinkElement);
25015
-
25016
- const descriptionElement = document.createElement('p');
25017
- descriptionElement.innerText = file.description;
25018
- descriptionElement.classList.add('description');
25019
-
25020
- const divElement = document.createElement('div');
25021
- divElement.classList.add('saved-list-item');
25022
- divElement.appendChild(nameElement);
25023
- divElement.appendChild(linksElement);
25024
- divElement.appendChild(descriptionElement);
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().trim();
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
- let sqlParam = url.searchParams.get('sql')?.trim();
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 (internal) {
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 (params.has('file') && params.has('sql')) {
25238
- // TODO: show an error.
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
- const sqlMatches = params.has('sql') && sql === existingRequest.sql;
25273
- const fileMatches = params.has('file') && file === existingRequest.file;
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 (file) {
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').classList.add('disabled');
25506
- document.getElementById('submit-dropdown-button-copy-csv').classList.add('disabled');
25507
- document.getElementById('submit-dropdown-button-copy-tsv').classList.add('disabled');
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').classList.remove('disabled');
25512
- document.getElementById('submit-dropdown-button-copy-csv').classList.remove('disabled');
25513
- document.getElementById('submit-dropdown-button-copy-tsv').classList.remove('disabled');
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('metadata', {
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 = '<div style="font-family: monospace; font-size: 16px;">\n';
25752
- error += `<div>${result.error}</div>\n`;
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 += '</div>\n';
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.70
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-03 00:00:00.000000000 Z
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