sqlite_dashboard 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,13 +21,12 @@
21
21
  </div>
22
22
 
23
23
  <!-- Main content area -->
24
- <div class="col-md-10 main-content">
24
+ <div class="col-md-10 main-content" data-controller="query-executor" data-database-name="<%= @database[:name] %>">
25
25
  <!-- Query Console -->
26
26
  <div class="query-console">
27
27
  <%= form_with url: execute_query_database_path(@database[:id]),
28
28
  method: :post,
29
29
  data: {
30
- controller: "query-executor",
31
30
  action: "submit->query-executor#execute"
32
31
  } do |form| %>
33
32
  <div class="mb-3">
@@ -45,6 +44,12 @@
45
44
  <button type="button" class="btn btn-outline-secondary" data-action="click->query-executor#clear">
46
45
  <i class="fas fa-eraser"></i> Clear
47
46
  </button>
47
+ <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#saveQueryModal">
48
+ <i class="fas fa-save"></i> Save Query
49
+ </button>
50
+ <%= link_to worksheet_path, class: "btn btn-outline-info" do %>
51
+ <i class="fas fa-file-code"></i> SQL Worksheet
52
+ <% end %>
48
53
  </div>
49
54
  <% end %>
50
55
  </div>
@@ -56,5 +61,34 @@
56
61
  <p>Execute a query to see results</p>
57
62
  </div>
58
63
  </div>
64
+
65
+ <!-- Save Query Modal -->
66
+ <div class="modal fade" id="saveQueryModal" tabindex="-1" aria-labelledby="saveQueryModalLabel" aria-hidden="true">
67
+ <div class="modal-dialog">
68
+ <div class="modal-content">
69
+ <div class="modal-header">
70
+ <h5 class="modal-title" id="saveQueryModalLabel">Save Query</h5>
71
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
72
+ </div>
73
+ <div class="modal-body">
74
+ <div class="mb-3">
75
+ <label for="query-name" class="form-label">Query Name *</label>
76
+ <input type="text" class="form-control" id="query-name" data-query-executor-target="queryName" required>
77
+ </div>
78
+ <div class="mb-3">
79
+ <label for="query-description" class="form-label">Description *</label>
80
+ <textarea class="form-control" id="query-description" rows="2" data-query-executor-target="queryDescription" required></textarea>
81
+ </div>
82
+ <div id="save-error" class="alert alert-danger d-none" data-query-executor-target="saveError"></div>
83
+ </div>
84
+ <div class="modal-footer">
85
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
86
+ <button type="button" class="btn btn-primary" data-action="click->query-executor#saveQuery">
87
+ <i class="fas fa-save"></i> Save
88
+ </button>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
59
93
  </div>
60
94
  </div>
@@ -0,0 +1,111 @@
1
+ <div class="row g-0" style="height: 100vh;" data-controller="saved-queries">
2
+ <!-- Sidebar with saved queries -->
3
+ <div class="col-md-2 sidebar">
4
+ <div class="p-3">
5
+ <h6 class="mb-3">
6
+ <i class="fas fa-file-code"></i> SQL Worksheet
7
+ </h6>
8
+ <%= link_to "← Back to Databases", databases_path, class: "btn btn-sm btn-outline-secondary mb-3" %>
9
+
10
+ <h6 class="mb-2">Saved Queries</h6>
11
+ <div id="saved-queries-list" data-saved-queries-target="list">
12
+ <div class="text-muted small text-center py-3">
13
+ <i class="fas fa-spinner fa-spin"></i> Loading...
14
+ </div>
15
+ </div>
16
+
17
+ <button type="button" class="btn btn-sm btn-primary w-100 mt-3" data-action="click->saved-queries#refresh">
18
+ <i class="fas fa-sync-alt"></i> Refresh
19
+ </button>
20
+ </div>
21
+ </div>
22
+
23
+ <!-- Main content area -->
24
+ <div class="col-md-10 main-content">
25
+ <!-- Database Selector -->
26
+ <div class="mb-3 px-4 pt-2">
27
+ <label for="database-selector" class="form-label fw-bold">Select Database</label>
28
+ <select id="database-selector" class="form-select" data-saved-queries-target="databaseSelector">
29
+ <option value="">-- Select a database --</option>
30
+ <% @databases.each do |db| %>
31
+ <option value="<%= db[:id] %>"><%= db[:name] %></option>
32
+ <% end %>
33
+ </select>
34
+ </div>
35
+
36
+ <!-- Query Console -->
37
+ <div class="query-console">
38
+ <div class="mb-3">
39
+ <label for="worksheet-query" class="form-label fw-bold">SQL Query</label>
40
+ <textarea id="worksheet-query"
41
+ class="form-control query-textarea"
42
+ data-saved-queries-target="queryInput"
43
+ placeholder="Enter your SQL query here..."></textarea>
44
+ </div>
45
+ <div class="d-flex gap-2 mb-2">
46
+ <button type="button" class="btn btn-primary" data-action="click->saved-queries#execute">
47
+ <i class="fas fa-play"></i> Execute Query
48
+ </button>
49
+ <button type="button" class="btn btn-outline-secondary" data-action="click->saved-queries#clear">
50
+ <i class="fas fa-eraser"></i> Clear
51
+ </button>
52
+ <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#saveQueryModal">
53
+ <i class="fas fa-save"></i> Save Query
54
+ </button>
55
+ <button type="button" class="btn btn-outline-info" data-action="click->saved-queries#exportCSV">
56
+ <i class="fas fa-file-csv"></i> Export CSV
57
+ </button>
58
+ <button type="button" class="btn btn-outline-info" data-action="click->saved-queries#exportJSON">
59
+ <i class="fas fa-file-code"></i> Export JSON
60
+ </button>
61
+ </div>
62
+ </div>
63
+
64
+ <!-- Results Container -->
65
+ <div class="results-container" id="worksheet-results">
66
+ <div class="text-muted text-center py-5">
67
+ <i class="fas fa-database fa-3x mb-3"></i>
68
+ <p>Select a database and execute a query to see results</p>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ <!-- Save Query Modal -->
75
+ <div class="modal fade" id="saveQueryModal" tabindex="-1" aria-labelledby="saveQueryModalLabel" aria-hidden="true">
76
+ <div class="modal-dialog">
77
+ <div class="modal-content">
78
+ <div class="modal-header">
79
+ <h5 class="modal-title" id="saveQueryModalLabel">Save Query</h5>
80
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
81
+ </div>
82
+ <div class="modal-body">
83
+ <div class="mb-3">
84
+ <label for="query-name" class="form-label">Query Name *</label>
85
+ <input type="text" class="form-control" id="query-name" data-saved-queries-target="queryName" required>
86
+ </div>
87
+ <div class="mb-3">
88
+ <label for="query-description" class="form-label">Description *</label>
89
+ <textarea class="form-control" id="query-description" rows="2" data-saved-queries-target="queryDescription" required></textarea>
90
+ </div>
91
+ <div id="save-error" class="alert alert-danger d-none" data-saved-queries-target="saveError"></div>
92
+ </div>
93
+ <div class="modal-footer">
94
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
95
+ <button type="button" class="btn btn-primary" data-action="click->saved-queries#saveQuery">
96
+ <i class="fas fa-save"></i> Save
97
+ </button>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </div>
102
+
103
+ <script>
104
+ // Initialize the saved queries controller when the page loads
105
+ document.addEventListener('turbo:load', () => {
106
+ const element = document.querySelector('[data-controller="saved-queries"]');
107
+ if (!element) {
108
+ document.body.setAttribute('data-controller', 'saved-queries');
109
+ }
110
+ });
111
+ </script>
data/config/routes.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  SqliteDashboard::Engine.routes.draw do
2
2
  root to: "databases#index"
3
3
 
4
+ # Saved queries
5
+ get 'saved_queries', to: 'databases#saved_queries'
6
+ post 'saved_queries', to: 'databases#create_saved_query'
7
+ get 'saved_queries/:id', to: 'databases#show_saved_query', as: :saved_query
8
+ delete 'saved_queries/:id', to: 'databases#destroy_saved_query'
9
+
10
+ # SQL Worksheet
11
+ get 'worksheet', to: 'databases#worksheet', as: :worksheet
12
+
4
13
  resources :databases, only: [:index, :show] do
5
14
  member do
6
15
  post :execute_query
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateSqliteDashboardSavedQueries < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :dashboard_saved_queries do |t|
6
+ t.string :name, null: false
7
+ t.text :query, null: false
8
+ t.string :database_name
9
+ t.text :description
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :dashboard_saved_queries, :name
15
+ add_index :dashboard_saved_queries, :created_at
16
+ end
17
+ end
@@ -21,6 +21,10 @@ module SqliteDashboard
21
21
  route route_content.strip
22
22
  end
23
23
 
24
+ def copy_migrations
25
+ rake "sqlite_dashboard:install:migrations"
26
+ end
27
+
24
28
  def display_readme
25
29
  readme "README" if behavior == :invoke
26
30
  end
@@ -1,3 +1,3 @@
1
1
  module SqliteDashboard
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
43
43
  # Runtime dependencies
44
44
  spec.add_dependency "rails", ">= 7.0.0"
45
45
  spec.add_dependency "sqlite3", ">= 1.4"
46
+ spec.add_dependency "csv", ">= 3.0"
46
47
 
47
48
  # Development dependencies
48
49
  spec.add_development_dependency "bundler", ">= 2.0"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqlite_dashboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - SQLite Dashboard Contributors
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-10-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -37,6 +37,20 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '1.4'
40
+ - !ruby/object:Gem::Dependency
41
+ name: csv
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
40
54
  - !ruby/object:Gem::Dependency
41
55
  name: bundler
42
56
  requirement: !ruby/object:Gem::Requirement
@@ -151,15 +165,20 @@ files:
151
165
  - app/controllers/sqlite_dashboard/application_controller.rb
152
166
  - app/controllers/sqlite_dashboard/databases_controller.rb
153
167
  - app/javascript/controllers/query_executor_controller.js
168
+ - app/javascript/controllers/saved_queries_controller.js
154
169
  - app/javascript/controllers/table_selector_controller.js
155
170
  - app/javascript/sqlite_dashboard/application.js
171
+ - app/models/sqlite_dashboard/application_record.rb
172
+ - app/models/sqlite_dashboard/saved_query.rb
156
173
  - app/views/layouts/sqlite_dashboard/application.html.erb
157
174
  - app/views/sqlite_dashboard/databases/_error.html.erb
158
175
  - app/views/sqlite_dashboard/databases/execute_query.turbo_stream.erb
159
176
  - app/views/sqlite_dashboard/databases/index.html.erb
160
177
  - app/views/sqlite_dashboard/databases/show.html.erb
178
+ - app/views/sqlite_dashboard/databases/worksheet.html.erb
161
179
  - config/importmap.rb
162
180
  - config/routes.rb
181
+ - db/migrate/20250101000001_create_sqlite_dashboard_saved_queries.rb
163
182
  - lib/generators/sqlite_dashboard/install_generator.rb
164
183
  - lib/generators/sqlite_dashboard/templates/README
165
184
  - lib/generators/sqlite_dashboard/templates/initializer.rb
@@ -194,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
213
  - !ruby/object:Gem::Version
195
214
  version: '0'
196
215
  requirements: []
197
- rubygems_version: 3.6.9
216
+ rubygems_version: 3.6.2
198
217
  specification_version: 4
199
218
  summary: Beautiful SQLite database browser and query interface for Rails
200
219
  test_files: []