solid_litequeen 0.18.1 → 0.19.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0805853d45f36526968d3c6480aee412b6c08b5bd4f6335eae6a63ddef1cd29
4
- data.tar.gz: ce7190ca5c2b3b755d1fbfb7cfba20c78cae7517cfc160c84df2a6d67706f759
3
+ metadata.gz: 5b075b9f956c23d7f80e7778872d9a1b1f04eb7b7917bc2e1824bb62311eb018
4
+ data.tar.gz: b6156fa03a6d00b5624171c540e9841c2cfd381c8049a0ca2915f8b1557ab4cf
5
5
  SHA512:
6
- metadata.gz: de2d962279c957507f44c3e3faa4dc50078bf380f099c64ef8300abda2a1568c94924f15484b0fe5b133bfda33b58c3b9662d5182e1abd1e64eb4d295cf2adfd
7
- data.tar.gz: 357f85988045dded8a119dfb7192a5a60d9fd364fb76852b9848e9d668702911444f5739bd04d7a06d9075f4c4925567f5e7d4c3c428090a80ad1c280263f0d7
6
+ metadata.gz: 97c1b9e99524020847a7a68be86cfe4d13dae4eb79002cd21cf4eaee2d4ff58bd9a67020b0ec9eb000aa68aa48f7353eaaa122677ce26f2ec6fd5a60130e6ba6
7
+ data.tar.gz: fe803864a6775505c2dbd331d43107386d27ce0adfaecfadd5b5579559a26b2f8314b316c0f483b16143d5c4945174f20ebb4f5129c99cb3c4077f160cf74764
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-table"><path d="M12 3v18"></path><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M3 9h18"></path><path d="M3 15h18"></path></svg>
@@ -154,6 +154,7 @@ module SolidLitequeen
154
154
  stored_order = session["#{@database_id}_#{@table_name}_column_order"] || []
155
155
  ordered_columns = stored_order & valid_columns
156
156
  ordered_columns += valid_columns - ordered_columns
157
+ # Persist merged column order so future requests use the updated schema
157
158
  session["#{@database_id}_#{@table_name}_column_order"] = ordered_columns
158
159
 
159
160
  order_clause = if @sort_column.present? && valid_columns.include?(@sort_column)
@@ -203,7 +204,6 @@ module SolidLitequeen
203
204
  end
204
205
 
205
206
 
206
-
207
207
  def set_column_order
208
208
  table_name = params[:table]
209
209
  database_id = params[:database_id]
@@ -248,9 +248,59 @@ module SolidLitequeen
248
248
  render partial: "foreign-key-data"
249
249
  end
250
250
 
251
+ def get_command_palette_data
252
+ palette_data = []
253
+ id_counter = 1
254
+
255
+ @available_databases ||= ActiveRecord::Base.configurations.configurations.select do |config|
256
+ config.adapter == "sqlite3" && config.env_name == Rails.env && config.database.present?
257
+ end
258
+
259
+ @available_databases.each do |db|
260
+ db_id = Base64.urlsafe_encode64(db.database)
261
+ db_file_name = db.database
262
+
263
+ # Add database entry
264
+ palette_data << {
265
+ id: id_counter,
266
+ type: "database",
267
+ name: db.name,
268
+ database_file_name: db_file_name,
269
+ rowCount: nil,
270
+ path: database_path(db_id)
271
+ }
272
+ id_counter += 1
273
+
274
+ # Establish a connection to fetch tables for this database
275
+ DynamicDatabase.establish_connection(
276
+ adapter: "sqlite3",
277
+ database: db.database
278
+ )
279
+
280
+ DynamicDatabase.connection.tables.each do |table_name|
281
+ row_count = DynamicDatabase.connection.select_value("SELECT COUNT(*) FROM #{table_name}").to_i
282
+
283
+ # Add table entry
284
+ palette_data << {
285
+ id: id_counter,
286
+ type: "table",
287
+ name: table_name,
288
+ database_name: db.name,
289
+ database_file_name: db_file_name,
290
+ rowCount: row_count,
291
+ path: database_table_rows_path(db_id, table_name)
292
+ }
293
+ id_counter += 1
294
+ end
295
+ end
296
+
297
+ render json: palette_data
298
+ end
299
+
251
300
  private
252
301
 
253
302
  def enum_mappings
303
+ # get all the enums defined in models in the app
254
304
  Rails.application.eager_load! unless Rails.application.config.eager_load
255
305
  ActiveRecord::Base.descendants.each_with_object({}) do |model, map|
256
306
  next if model.abstract_class?
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Command palette
3
+ *
4
+ * eg:
5
+ *
6
+
7
+ *
8
+ *
9
+ * */
10
+
11
+
12
+ import { Controller } from "@hotwired/stimulus";
13
+
14
+
15
+ // Connects to data-controller="command_palette"
16
+ export default class extends Controller {
17
+
18
+
19
+ connect() {
20
+ this.isOpen = false;
21
+ this.selectedIndex = 0;
22
+ this.searchItems = [];
23
+ this.filteredItems = [];
24
+
25
+ this.modal = document.getElementById('commandPaletteModal');
26
+ this.dialog = document.getElementById('commandPaletteDialog');
27
+ this.input = document.getElementById('commandPaletteInput');
28
+ this.input_timeout = null;
29
+ this.resultsList = document.getElementById('resultsList');
30
+ this.noResults = document.getElementById('noResults');
31
+ this.resultsCount = document.getElementById('resultsCount');
32
+ this.trigger = document.getElementById('commandPaletteTrigger');
33
+
34
+ this.initializeSearchItems();
35
+ this.bindEvents();
36
+ this.updateResults();
37
+ }
38
+
39
+ async initializeSearchItems() {
40
+ this.searchItems = [];
41
+ const request = await fetch(this.element.dataset.command_palette_data_path);
42
+ const data = await request.json();
43
+ this.searchItems = [...data];
44
+ }
45
+
46
+ bindEvents() {
47
+ // Trigger button click
48
+ this.trigger.addEventListener('click', () => this.open());
49
+
50
+ // Keyboard shortcuts
51
+ document.addEventListener('keydown', (e) => this.handleKeyDown(e));
52
+
53
+ // Input change
54
+ this.input.addEventListener('input', (e) => this.handleSearch(e.target.value));
55
+
56
+ // Click outside to close
57
+ this.modal.addEventListener('click', (e) => {
58
+ if (!this.dialog.contains(e.target)) {
59
+ this.close();
60
+ }
61
+ });
62
+ }
63
+
64
+ handleKeyDown(e) {
65
+ // Global shortcut
66
+ if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
67
+ e.preventDefault();
68
+ if(this.isOpen) return this.close();
69
+
70
+ this.open();
71
+ return;
72
+ }
73
+
74
+ if (!this.isOpen) return;
75
+
76
+ switch (e.key) {
77
+ case 'Escape':
78
+ this.close();
79
+ break;
80
+ case 'ArrowDown':
81
+ e.preventDefault();
82
+ this.selectedIndex = this.selectedIndex < this.filteredItems.length - 1
83
+ ? this.selectedIndex + 1
84
+ : 0;
85
+ this.updateSelection();
86
+ break;
87
+ case 'ArrowUp':
88
+ e.preventDefault();
89
+ this.selectedIndex = this.selectedIndex > 0
90
+ ? this.selectedIndex - 1
91
+ : this.filteredItems.length - 1;
92
+ this.updateSelection();
93
+ break;
94
+ case 'Enter':
95
+ if (this.filteredItems[this.selectedIndex]) {
96
+ this.selectItem(this.filteredItems[this.selectedIndex]);
97
+ }
98
+ break;
99
+ }
100
+ }
101
+
102
+ handleSearch(query) {
103
+ clearTimeout(this.input_timeout);
104
+
105
+ if (!query) {
106
+ this.filteredItems = [...this.searchItems];
107
+ this.selectedIndex = 0;
108
+ this.updateResults();
109
+
110
+ } else {
111
+
112
+ this.input_timeout = setTimeout(() => {
113
+ this.filteredItems = this.searchItems.filter(item =>
114
+ item.name.toLowerCase().includes(query.toLowerCase()) ||
115
+ (item.database_name && item.database_name.toLowerCase().includes(query.toLowerCase())) ||
116
+ (item.database_file_name && item.database_file_name.toLowerCase().includes(query.toLowerCase()))
117
+ );
118
+
119
+ this.selectedIndex = 0;
120
+ this.updateResults();
121
+ }, 200);
122
+ }
123
+
124
+
125
+ }
126
+
127
+ updateResults() {
128
+ this.resultsCount.textContent = `${this.filteredItems.length} results`;
129
+
130
+ if (this.filteredItems.length === 0) {
131
+ this.noResults.classList.remove('hidden');
132
+ this.resultsList.innerHTML = '';
133
+ return;
134
+ }
135
+
136
+ this.noResults.classList.add('hidden');
137
+
138
+ this.resultsList.innerHTML = this.filteredItems.slice(0, 25).map((item, index) => {
139
+ const isSelected = index === this.selectedIndex;
140
+
141
+ const icon = item.type === 'database'
142
+ ? `<img src="${this.element.dataset.database_svg_img_path}" class="size-4 filter-blue opacity-80" />`
143
+ : `<img src="${this.element.dataset.table_svg_img_path}" class="size-4 filter-lime opacity-80" />`;
144
+
145
+ const badge = item.type === 'table'
146
+ ? `<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-neutral-content text-neutral">${item.rowCount?.toLocaleString()} rows</span>`
147
+ : '';
148
+
149
+ const database = item.database_file_name
150
+ ? `<div class="text-xs text-base-content/60 truncate">in ${item.database_file_name}</div>`
151
+ : '';
152
+
153
+ return `
154
+ <div ${isSelected ? 'data-selected': ''} data-index="${index}" class="data-selected:outline-2 outline-[var(--color-primary)] data-selected:bg-[var(--color-base-100)] flex items-center gap-3 rounded-md px-3 py-2 text-sm cursor-pointer transition-colors">
155
+ ${icon}
156
+ <div class="flex-1 min-w-0">
157
+ <div class="flex items-center gap-2">
158
+ <span class="font-medium truncate">${item.name}</span>
159
+ ${badge}
160
+ </div>
161
+ ${database}
162
+ </div>
163
+ <svg class="w-4 h-4 text-base-content/60" fill="none" stroke="currentColor" viewBox="0 0 24 24">
164
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
165
+ </svg>
166
+ </div>
167
+ `;
168
+ }).join('');
169
+
170
+ // Add click handlers to result items
171
+ this.resultsList.querySelectorAll('[data-index]').forEach((element, index) => {
172
+ element.addEventListener('click', () => this.selectItem(this.filteredItems[index]));
173
+ element.addEventListener('mouseenter', () => {
174
+ this.selectedIndex = index;
175
+ this.updateSelection();
176
+ });
177
+ });
178
+ }
179
+
180
+ updateSelection() {
181
+ this.resultsList.querySelectorAll('[data-index]').forEach((element, index) => {
182
+ if (index === this.selectedIndex) {
183
+ element.setAttribute('data-selected', true);
184
+ element.scrollIntoView({ block: 'nearest' });
185
+ } else {
186
+ element.removeAttribute('data-selected');
187
+ }
188
+ });
189
+ }
190
+
191
+ selectItem(item) {
192
+ this.close(true);
193
+ Turbo.visit(item.path);
194
+
195
+ }
196
+
197
+ open() {
198
+ this.isOpen = true;
199
+ this.modal.classList.remove('hidden');
200
+ // this.dialog.classList.add('dialog-enter');
201
+ this.input.focus();
202
+ this.input.value = '';
203
+ this.handleSearch('');
204
+ }
205
+
206
+ close(quiet=false) {
207
+ this.isOpen = false;
208
+ // this.dialog.classList.remove('dialog-enter');
209
+
210
+ if(quiet){
211
+ this.modal.classList.add('hidden');
212
+ this.selectedIndex = 0;
213
+ return
214
+ }
215
+
216
+ // this.dialog.classList.add('dialog-exit');
217
+
218
+ setTimeout(() => {
219
+ this.modal.classList.add('hidden');
220
+ // this.dialog.classList.remove('dialog-exit');
221
+ this.selectedIndex = 0;
222
+ }, 100);
223
+ }
224
+
225
+
226
+ }
227
+
@@ -0,0 +1,65 @@
1
+ /**
2
+ *
3
+ * Stimulus to put an object in the "orbit" or another object using floating-ui.
4
+ * We define a "planet" and its "moon" that'll orbit around it.
5
+ * eg:
6
+ *
7
+ <div data-controller="orbit">
8
+ <button data-orbit-target="planet" popovertarget="menu-popover" style="anchor-name:--anchor-menu">🌐</button>
9
+
10
+ <ul popover id="menu-popover" data-orbit-target="moon" style="position-anchor:--anchor-menu">
11
+ <li>one</li>
12
+ <li>two</li>
13
+ </ul>
14
+ </div>
15
+ *
16
+ **/
17
+
18
+ import { Controller } from "@hotwired/stimulus"
19
+
20
+ const { computePosition, flip, shift, offset, autoUpdate } = window.FloatingUIDOM;
21
+
22
+ // data-controller="orbit"
23
+ export default class extends Controller {
24
+ // data-orbit-target="planet"
25
+ // data-orbit-target="moon"
26
+ static targets = ["planet", "moon"]
27
+
28
+ connect() {
29
+ this.setupOrbit();
30
+
31
+ }
32
+
33
+ setupOrbit() {
34
+ this.cleanup = autoUpdate(
35
+ this.planetTarget,
36
+ this.moonTarget,
37
+ () => this.updatePosition()
38
+ );
39
+ }
40
+
41
+ updatePosition() {
42
+ computePosition(this.planetTarget, this.moonTarget, {
43
+ placement: 'bottom',
44
+ strategy: 'fixed', // wow this was what was missing!
45
+ middleware: [
46
+ offset(6),
47
+ flip(),
48
+ shift({ padding: 5 })
49
+ ],
50
+ }).then(({x, y}) => {
51
+ Object.assign(this.moonTarget.style, {
52
+ left: `${x}px`,
53
+ top: `${y}px`,
54
+ });
55
+ });
56
+ }
57
+
58
+
59
+ disconnect() {
60
+ if (this.cleanup) {
61
+ this.cleanup();
62
+ }
63
+
64
+ }
65
+ }
@@ -21,7 +21,7 @@ export default class extends Controller {
21
21
  gridSize: 10,
22
22
  drawGrid: true,
23
23
  background: {
24
- color: "var(--color-paper-background)",
24
+ // color: "var(--color-neutral)",
25
25
  },
26
26
  interactive: (cellView) => {
27
27
  // If this cell is embedded (a field node),
@@ -68,7 +68,7 @@ export default class extends Controller {
68
68
  target: { id: targetId },
69
69
  attrs: {
70
70
  line: {
71
- stroke: "var(--color-paper-links)",
71
+ stroke: "var(--color-info)",
72
72
  strokeWidth: 2,
73
73
  targetMarker: {
74
74
  type: "path",
@@ -98,19 +98,19 @@ export default class extends Controller {
98
98
  size: { width: width, height: height },
99
99
  attrs: {
100
100
  body: {
101
- fill: "#f5f5f5",
101
+ fill: "var(--color-base-100)",
102
102
  strokeWidth: 2,
103
- stroke: "#ccc",
103
+ stroke: "var(--color-base-100)",
104
104
  },
105
105
  header: {
106
- fill: "#e0e0e0",
106
+ fill: "var(--color-base-100)",
107
107
  strokeWidth: 1,
108
- stroke: "#ccc",
108
+ stroke: "var(--color-base-content)",
109
109
  height: headerHeight,
110
110
  },
111
111
  headerText: {
112
112
  text: tableName,
113
- fill: "#000",
113
+ fill: "var(--color-primary)",
114
114
  fontWeight: "bold",
115
115
  fontSize: 16,
116
116
  },
@@ -128,13 +128,13 @@ export default class extends Controller {
128
128
  size: { width: width, height: fieldHeight },
129
129
  attrs: {
130
130
  body: {
131
- fill: "var(--color-paper-background)",
131
+ fill: "var(--color-base-100)",
132
132
  strokeWidth: 1,
133
- stroke: "#ddd",
133
+ stroke: "var(--color-base-content)",
134
134
  },
135
135
  label: {
136
136
  text: field,
137
- fill: "var(--color-text)",
137
+ fill: "var(--color-base-content)",
138
138
  fontSize: 14,
139
139
  },
140
140
  },
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html class="text-base-content bg-base-100">
3
3
  <head>
4
4
  <title>Solid litequeen</title>
5
5
  <%= csrf_meta_tags %>
@@ -11,38 +11,19 @@
11
11
 
12
12
  <%= stylesheet_link_tag "solid_litequeen/application", media: "all", "data-turbo-track": "reload" %>
13
13
  <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
14
+ <link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
15
+ <link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
14
16
  <script src="https://cdn.jsdelivr.net/npm/@joint/core@4.0.1/dist/joint.js"></script>
15
17
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"></script>
18
+ <script src="https://cdn.jsdelivr.net/npm/@floating-ui/core@1.7.2"></script>
19
+ <script src="https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.2"></script>
16
20
  <style type="text/tailwindcss">
17
- @plugins "form";
18
-
19
- :root{
20
- color-scheme: light dark;
21
-
22
- --color-background: var(--color-slate-50);
23
- --color-background-light: var(--color-white);
24
- --color-border-muted: var(--color-slate-200);
25
- --color-text: var(--color-gray-900);
26
- --color-text-muted: var(--color-gray-500);
27
- --color-background-secondary: var(--color-slate-50);
28
- /* paper is the graph generated by joint.js. */
29
- --color-paper-background: var(--color-slate-50);
30
- --color-paper-links: var(--color-slate-600);
31
- }
21
+ /* @plugin "@tailwindcss/forms"; */
22
+
23
+ /* @utility text-muted{
24
+ @apply text-base-content/60;
25
+ } */
32
26
 
33
- @media (prefers-color-scheme: dark) {
34
- :root {
35
- --color-background: var(--color-slate-900);
36
- --color-background-light: var(--color-slate-800);
37
- --color-text: var(--color-slate-300);
38
- --color-text-muted: var(--color-gray-400);
39
- --color-background-secondary: var(--color-slate-300);
40
- /* paper is the graph generated by joint.js. */
41
- --color-paper-background: var(--color-slate-600);
42
- --color-paper-links: var(--color-slate-300);
43
- }
44
- }
45
-
46
27
 
47
28
  @utility filter-blue{
48
29
  filter: invert(32%) sepia(65%) saturate(6380%) hue-rotate(219deg) brightness(98%) contrast(102%);
@@ -57,21 +38,17 @@
57
38
  filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(100%) contrast(100%);
58
39
  }
59
40
 
41
+ @utility filter-lime{
42
+ filter: invert(50%) sepia(100%) saturate(3000%) hue-rotate(90deg) brightness(100%) contrast(100%);
43
+ }
60
44
 
61
- /* popover fix for safari */
62
- @media screen and (-webkit-min-device-pixel-ratio: 0) {
63
- /* Safari-only CSS here */
64
- _::-webkit-full-page-media, _:future, :root div[popover] {
65
- position: fixed !important;
66
- top: 50% !important;
67
- left: 50% !important;
68
- transform: translate(-50%, -50%) !important;
69
- margin: 0 !important;
70
- max-width: 90vw;
71
- z-index: 1000;
72
- }
45
+ @utility filter-orange{
46
+ filter: invert(53%) sepia(91%) saturate(7000%) hue-rotate(22deg) brightness(110%) contrast(110%);
73
47
  }
74
48
 
49
+
50
+
51
+
75
52
  </style>
76
53
 
77
54
 
@@ -79,13 +56,24 @@
79
56
 
80
57
  <%= yield :head %>
81
58
  </head>
82
- <body class="bg-[var(--color-background)] text-[var(--color-text)]">
83
- <header class="container mx-auto mt-4 mb-8">
59
+ <script>
60
+ const setTheme = () => {
61
+ const storedTheme = localStorage.getItem('theme');
62
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
63
+ document.documentElement.setAttribute('data-theme', storedTheme || (prefersDark ? 'sunset' : 'light'));
64
+ };
65
+ setTheme();
66
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setTheme);
67
+ </script>
68
+ <body class="">
69
+ <header class="container flex items-center justify-between mx-auto mt-4 mb-8">
84
70
  <%= render "solid_litequeen/database-selector" %>
71
+
72
+ <%= render "solid_litequeen/command-palette" %>
85
73
  </header>
86
74
  <%= yield %>
87
75
 
88
- <footer class="container mx-auto mt-8 mb-4 text-center text-[var(--color-text-muted)]/50 text-xs">
76
+ <footer class="container mx-auto mt-8 mb-4 text-center text-base-content/60 text-xs">
89
77
  <p>Solid litequeen v<%= SolidLitequeen::VERSION %></p>
90
78
  </footer>
91
79
  </body>
@@ -0,0 +1,91 @@
1
+ <style>
2
+
3
+ .dialog-enter {
4
+ animation: dialogEnter 0.2s ease-out;
5
+ }
6
+ .dialog-exit {
7
+ animation: dialogExit 0.2s ease-in;
8
+ }
9
+ @keyframes dialogEnter {
10
+ from {
11
+ opacity: 0;
12
+ transform: scale(0.95);
13
+ }
14
+ to {
15
+ opacity: 1;
16
+ transform: scale(1);
17
+ }
18
+ }
19
+ @keyframes dialogExit {
20
+ from {
21
+ opacity: 1;
22
+ transform: scale(1);
23
+ }
24
+ to {
25
+ opacity: 0;
26
+ transform: scale(0.95);
27
+ }
28
+ }
29
+
30
+ </style>
31
+
32
+ <section
33
+ data-controller="command-palette"
34
+ data-command_palette_data_path="<%= command_palette_data_path %>"
35
+ data-database_svg_img_path="<%= image_path("solid_litequeen/icons/database.svg") %>"
36
+ data-table_svg_img_path="<%= image_path("solid_litequeen/icons/table.svg") %>"
37
+
38
+ >
39
+ <!-- Command Palette Trigger -->
40
+ <button id="commandPaletteTrigger" class="flex items-center gap-2 px-3 py-2 text-sm bg-base-200 border border-base-content/20 hover:bg-base-100 rounded-md transition-colors">
41
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
42
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
43
+ </svg>
44
+ <span>Search databases and tables...</span>
45
+ <kbd class="ml-auto pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-base-300 px-1.5 font-mono text-[10px] font-medium opacity-100">
46
+ <span class="text-xs">⌘</span>K
47
+ </kbd>
48
+ </button>
49
+
50
+ <!-- Command Palette Modal -->
51
+ <div id="commandPaletteModal" class="fixed inset-0 z-50 hidden">
52
+ <!-- Backdrop -->
53
+ <div class="fixed inset-0 backdrop-blur "></div>
54
+
55
+ <!-- Dialog -->
56
+ <div class="fixed inset-0 flex items-start justify-center pt-[10vh]">
57
+ <div id="commandPaletteDialog" class="bg-base-200 border border-base-content/20 rounded-lg shadow-xl w-full max-w-2xl mx-4 dialog-enter">
58
+ <!-- Search Input -->
59
+ <div class="flex items-center border-b border-base-content/30 px-3">
60
+ <svg class="mr-2 h-4 w-4 shrink-0 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
61
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
62
+ </svg>
63
+ <input
64
+ id="commandPaletteInput"
65
+ type="text"
66
+ placeholder="Search databases and tables..."
67
+ class="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none border-0 focus:ring-0"
68
+ autocomplete="off"
69
+ />
70
+ </div>
71
+
72
+ <!-- Results -->
73
+ <div id="commandPaletteResults" class="max-h-[400px] overflow-y-auto">
74
+ <div id="noResults" class="py-6 text-center text-sm text-base-content/60 hidden">
75
+ No databases or tables found.
76
+ </div>
77
+ <div id="resultsList" class="p-2"></div>
78
+ </div>
79
+
80
+ <!-- Footer -->
81
+ <div class="border-t border-base-content/30 px-3 py-2 text-xs text-base-content/60">
82
+ <div class="flex items-center justify-between">
83
+ <span>Use ↑↓ to navigate, Enter to select, Esc to close</span>
84
+ <span id="resultsCount">0 results</span>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ </div>
90
+
91
+ </section>
@@ -2,7 +2,7 @@
2
2
  <% if controller.controller_name == "databases" && action_name.in?([ "show", "table_rows"]) %>
3
3
  <div class="w-86">
4
4
  <div class="database-selector p-4">
5
- <select id="database-select" class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
5
+ <select id="database-select" class="select block w-52 focus:outline-none outline-none ring-0">
6
6
  <option value="">Select a database...</option>
7
7
  <% available_databases.each do |db| %>
8
8
  <option value="<%= Base64.urlsafe_encode64(db.database) %>" <%= 'selected' if defined?(@database_id) && @database_id == Base64.urlsafe_encode64(db.database) %>>
@@ -9,23 +9,23 @@
9
9
  </h1>
10
10
 
11
11
  <div class="mx-auto my-4 p-4 max-w-[90%]">
12
- <table class="min-w-full divide-y divide-gray-200 dark:border-gray-200/50 border border-gray-200">
13
- <thead class="bg-gray-50 dark:bg-[var(--color-background)]/40">
12
+ <table class="min-w-full border border-base-content/20">
13
+ <thead class="bg-base-300 border-b border-base-content/20">
14
14
  <tr>
15
- <th class="px-6 py-3 text-left text-xs font-medium dark:font-bold text-gray-500 dark:text-[var(--color-text)] uppercase tracking-wider">
15
+ <th class="px-6 py-3 text-left text-xs font-medium dark:font-bold text-base-content/80 uppercase tracking-wider">
16
16
  Column Name
17
17
  </th>
18
- <th class="px-6 py-3 text-left text-xs font-medium dark:font-bold text-gray-500 dark:text-[var(--color-text)] uppercase tracking-wider">
18
+ <th class="px-6 py-3 text-left text-xs font-medium dark:font-bold text-base-content/80 uppercase tracking-wider">
19
19
  Value
20
20
  </th>
21
21
  </tr>
22
22
  </thead>
23
- <tbody class="bg-white dark:bg-transparent divide-y divide-gray-200 dark:divide-gray-200/50">
23
+ <tbody class="bg-base-200 ">
24
24
  <% @result.rows.each do |row| %>
25
25
  <% @result.columns.zip(row).each do |column, value| %>
26
- <tr>
27
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold"><%= column %></td>
28
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 in-aria-busy:blur"><%= value&.truncate(80) %></td>
26
+ <tr class="border-b border-base-content/10 last:border-none hover:bg-base-100">
27
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold"><%= column %></td>
28
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 in-aria-busy:blur"><%= value&.truncate(80) %></td>
29
29
  </tr>
30
30
  <% end %>
31
31
  <% end %>
@@ -14,16 +14,16 @@
14
14
  end
15
15
  %>
16
16
 
17
- <dialog id="<%= dialog_id %>" data-controller="dialog" class="bg-[var(--color-background-light)] dark:border dark:rounded dark:border-gray-50/20 w-[800px] m-auto overscroll-y-contain">
17
+ <dialog id="<%= dialog_id %>" data-controller="dialog" class="bg-base-200 rounded border border-base-content/20 w-[800px] m-auto overscroll-y-contain">
18
18
  <div class="flex flex-row-reverse">
19
19
  <button data-action="click->dialog#close" class="cursor-pointer mr-4 mt-2 outline-none">
20
- <%= image_tag "solid_litequeen/icons/x.svg", class: "size-5 dark:filter-white" %>
20
+ <%= image_tag "solid_litequeen/icons/x.svg", class: "size-5 opacity-60 dark:filter-white" %>
21
21
  </button>
22
22
  </div>
23
23
 
24
24
  <h1 class="text-lg font-semibold text-center"><%= column_name %></h1>
25
25
 
26
- <div data-controller="clipboard" class="relative flex items-center max-w-[90%] h-80 max-h-80 mx-auto my-4 p-2 dark:bg-transparent bg-gray-100 dark:border dark:border-gray-50/50 rounded ">
26
+ <div data-controller="clipboard" class="relative flex items-center max-w-[90%] h-80 max-h-80 mx-auto my-4 p-2 dark:bg-transparent bg-base-300 rounded ">
27
27
 
28
28
  <button title="Copy" data-action="clipboard#copy" class="absolute top-2 right-2 hover:cursor-pointer">
29
29
  <%= image_tag "solid_litequeen/icons/copy-clipboard.svg", class: "in-data-copied:hidden size-5 dark:filter-white opacity-50" %>
@@ -1,12 +1,12 @@
1
- <dialog id="table_relationships" data-controller="dialog table-relations" data-relations="<%= @table_relations.to_json %>" class="dark:bg-[var(--color-background-light)] dark:border dark:border-gray-50/20 rounded w-[1000px] h-full m-auto overscroll-y-contain">
1
+ <dialog id="table_relationships" data-controller="dialog table-relations" data-relations="<%= @table_relations.to_json %>" class="bg-base-200 border border-base-content/20 backdrop-blur rounded w-[1000px] h-full m-auto overscroll-y-contain">
2
2
  <div class="flex flex-row-reverse">
3
3
  <button data-action="click->dialog#close" class="cursor-pointer mr-4 mt-2 outline-none">
4
- <%= image_tag "solid_litequeen/icons/x.svg", class: "size-5 dark:filter-white" %>
4
+ <%= image_tag "solid_litequeen/icons/x.svg", class: "opacity-60 size-5 dark:filter-white" %>
5
5
  </button>
6
6
  </div>
7
7
  <h1 class=" text-center mt-4">Table Relationships</h1>
8
8
 
9
9
  <div class="w-full p-4 mx-auto overflow-x-auto">
10
- <div id="paper" class="m-auto my-10 w-full h-[600px] border border-gray-200 dark:border-gray-50/20 rounded"></div>
10
+ <div id="paper" class="m-auto my-10 w-full h-[600px] border border-base-content/20 shadow rounded"></div>
11
11
  </div>
12
12
  </dialog>
@@ -3,21 +3,21 @@
3
3
  <h1 class="text-3xl font-bold mb-6">Solid Lite Queen</h1>
4
4
 
5
5
  <div class="mb-6">
6
- <p class="text-[var(--color-text-muted)]"><%= pluralize(available_databases.count, "SQLite database") %> found</p>
6
+ <p class="text-base-content/60"><%= pluralize(available_databases.count, "SQLite database") %> found</p>
7
7
  </div>
8
8
 
9
9
  <% if available_databases.any? %>
10
10
  <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
11
11
  <% available_databases.each do |db| %>
12
- <a href="<%= database_path(Base64.urlsafe_encode64(db.database)) %>" class="block bg-white dark:bg-[var(--color-background-secondary)] rounded-lg shadow-sm border border-gray-200 hover:shadow-md transition duration-150 overflow-hidden">
12
+ <a href="<%= database_path(Base64.urlsafe_encode64(db.database)) %>" class="block bg-base-200 border border-base-content/20 rounded-lg shadow-sm hover:shadow-md transition duration-150 overflow-hidden">
13
13
  <div class="p-5">
14
14
  <div class="flex items-center justify-between mb-2">
15
- <h2 class="text-lg font-semibold text-gray-900 truncate"><%= db.name %></h2>
16
- <span class="px-2 py-1 text-xs font-medium rounded-full bg-blue-100 text-blue-800"><%= db.env_name %></span>
15
+ <h2 class="text-lg font-semibold truncate"><%= db.name %></h2>
16
+ <span class="badge badge-soft badge-xs badge-info px-2 py-1 text-xs font-medium rounded-full "><%= db.env_name %></span>
17
17
  </div>
18
- <p class="text-sm text-gray-500 truncate mb-4"><%= db.database %></p>
18
+ <p class="text-sm text-base-content/60 truncate mb-4"><%= db.database %></p>
19
19
  <div class="flex justify-end">
20
- <span class="inline-flex items-center text-sm font-medium text-blue-600 hover:text-blue-800">
20
+ <span class="inline-flex items-center text-sm font-medium">
21
21
  Open
22
22
  <svg class="w-4 h-4 ml-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
23
23
  <path fill-rule="evenodd" d="M10.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H5a1 1 0 110-2h7.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
@@ -1,6 +1,6 @@
1
1
  <div class="container mx-auto px-4 py-8">
2
2
  <h1 class="text-3xl font-bold mb-6 flex gap-1 items-center justify-center">
3
- <%= image_tag "solid_litequeen/icons/database.svg", class: "size-6 dark:filter-white" %>
3
+ <%= image_tag "solid_litequeen/icons/database.svg", class: "opacity-60 size-6 dark:filter-white" %>
4
4
  <span>
5
5
  <%= @database_location %>
6
6
  </span>
@@ -16,31 +16,31 @@
16
16
  <%= render "table-relationships-dialog" %>
17
17
 
18
18
  <button title="Relationships" onclick="table_relationships.showModal()" class="hover:cursor-pointer outline-none">
19
- <%= image_tag "solid_litequeen/icons/workflow.svg", class: "size-5 -mb-1 dark:filter-white" %>
19
+ <%= image_tag "solid_litequeen/icons/workflow.svg", class: "size-5 -mb-1 opacity-60 dark:filter-white" %>
20
20
  </button>
21
21
 
22
22
  <% end %>
23
23
  </h2>
24
- <p class="text-[var(--color-text-muted)]"><%= pluralize(@tables.count, "table") %> found</p>
24
+ <p class="text-base-content/60"><%= pluralize(@tables.count, "table") %> found</p>
25
25
  </div>
26
26
 
27
- <div class="bg-white dark:bg-transparent rounded-lg shadow overflow-hidden">
27
+ <div class="bg-base-200 border border-base-content/20 rounded-lg shadow overflow-hidden">
28
28
  <table class="w-full">
29
29
  <thead>
30
- <tr class="bg-gray-100 dark:bg-[var(--color-background-light)] border-b border-gray-200">
31
- <th class="px-6 py-3 text-left text-sm font-medium text-gray-700 dark:text-[var(--color-text)] ">Table Name</th>
32
- <th class="px-6 py-3 text-left text-sm font-medium text-gray-700 dark:text-[var(--color-text)]">Row Count</th>
30
+ <tr class="bg-base-300 border-b border-base-content/20">
31
+ <th class="px-6 py-3 text-left text-sm font-medium ">Table Name</th>
32
+ <th class="px-6 py-3 text-left text-sm font-medium">Row Count</th>
33
33
  </tr>
34
34
  </thead>
35
- <tbody class="divide-y divide-gray-200 dark:divide-gray-200/50">
35
+ <tbody class="">
36
36
  <% @tables.each do |table| %>
37
- <tr class="hover:bg-gray-50 dark:hover:bg-[var(--color-background-light)]/50">
37
+ <tr class="hover:bg-base-100 border-b last:border-none border-base-content/10">
38
38
  <td class="px-6 py-4">
39
- <%= link_to database_table_rows_path(@database_id, table[:name]), class: "text-blue-600 hover:text-blue-800 dark:text-cyan-500 dark:hover:text-cyan-600 font-medium" do %>
39
+ <%= link_to database_table_rows_path(@database_id, table[:name]), class: "link-primary font-medium" do %>
40
40
  <%= table.dig(:name) %>
41
41
  <% end %>
42
42
  </td>
43
- <td class="px-6 py-4 text-gray-600 dark:text-gray-300">
43
+ <td class="px-6 py-4 text-base-content/60">
44
44
  <%= pluralize(table.dig(:row_count), "Row") %>
45
45
  </td>
46
46
  </tr>
@@ -48,5 +48,5 @@
48
48
  </tbody>
49
49
  </table>
50
50
  </div>
51
- <%= link_to "Download Database", database_download_path(@database_id), class: "btn btn-primary text-xs mt-4" %>
51
+ <%= link_to "Download Database", database_download_path(@database_id), class: "link link-hover link-secondary text-xs mt-4" %>
52
52
  </div>
@@ -1,10 +1,10 @@
1
1
  <div class="container mx-auto px-4 py-8">
2
2
  <h1 class="text-3xl font-bold mb-6 flex gap-1 items-center justify-center">
3
3
  <%= link_to database_path(params[:database_id]) do %>
4
- <%= image_tag "solid_litequeen/icons/database.svg", class: "size-6 dark:filter-white" %>
4
+ <%= image_tag "solid_litequeen/icons/database.svg", class: "opacity-60 size-6 dark:filter-white" %>
5
5
  <% end %>
6
6
 
7
- <%= image_tag "solid_litequeen/icons/chevron-right.svg", class: "size-6 dark:filter-white" %>
7
+ <%= image_tag "solid_litequeen/icons/chevron-right.svg", class: "opacity-60 size-6 dark:filter-white" %>
8
8
 
9
9
  <span>
10
10
  <%= @table_name %>
@@ -12,10 +12,10 @@
12
12
  </h1>
13
13
 
14
14
  <div class="mb-6">
15
- <p class="text-[var(--color-text-muted)]"><%= pluralize(@row_count, "row") %> found</p>
15
+ <p class="text-base-content/60"><%= pluralize(@row_count, "row") %> found</p>
16
16
  </div>
17
17
 
18
- <div class="bg-white dark:bg-transparent rounded-lg shadow overflow-x-auto">
18
+ <div class="bg-base-200 border border-base-content/20 rounded-lg shadow overflow-x-auto">
19
19
  <div class="min-w-full inline-block align-middle">
20
20
  <table
21
21
  data-controller="table"
@@ -24,52 +24,57 @@
24
24
  class="min-w-full relative"
25
25
  >
26
26
  <thead class="">
27
- <tr class="bg-gray-100 dark:bg-[var(--color-background-light)] border-b border-gray-200 dark:border-gray-50/20">
27
+ <tr class="bg-base-300 border-b border-base-content/20">
28
28
  <% @data.columns.each_with_index do |column, index| %>
29
29
  <th
30
- draggable="true"
30
+ draggable="true"
31
+ data-controller="orbit"
31
32
  data-column-index="<%= index %>"
32
33
  data-column-name="<%= column %>"
33
- class="hover:cursor-move px-6 py-3 text-left text-sm font-medium text-gray-700 dark:text-[var(--color-text)] whitespace-nowrap data-[is-dragging]:bg-orange-300/30 data-[column-order-about-to-be-swapped]:bg-green-300/30"
34
+ class="hover:cursor-move px-6 py-3 text-left text-sm font-medium whitespace-nowrap data-[is-dragging]:bg-orange-300/30 data-[column-order-about-to-be-swapped]:bg-green-300/30"
34
35
  >
35
36
 
36
37
  <%# popover the the column info %>
37
- <% popover_id = "popover_#{column}_#{SecureRandom.hex(8)}" %>
38
+ <%
39
+ popover_id = "popover_#{column}_#{SecureRandom.hex(8)}"
40
+ anchor_name = "--anchor_#{popover_id}"
41
+ %>
42
+
38
43
 
39
- <button popovertarget="<%= popover_id %>" class="mr-1 p-1 hover:cursor-pointer" style="anchor-name: --anchor_<%= popover_id %>;">
40
- <%= image_tag "solid_litequeen/icons/info.svg", class: "size-3.5 dark:filter-white" %>
44
+ <button popovertarget="<%= popover_id %>" data-orbit-target="planet" class="mr-1 p-1 hover:cursor-pointer" style="anchor-name: <%= anchor_name %> ;">
45
+ <%= image_tag "solid_litequeen/icons/info.svg", class: "size-3.5 opacity-60 dark:filter-white" %>
41
46
  </button>
42
47
 
43
- <div popover id="<%= popover_id %>" class="max-w-lg min-h-10 bg-gray-100 dark:bg-[var(--color-background)] border-gray-400 dark:border-gray-200/50 border p-4 rounded-md" style="position-anchor: --anchor_<%= popover_id%>; top: anchor(--anchor_<%= popover_id%> bottom); left: anchor(--anchor_<%= popover_id%> right);">
44
- <table class="min-w-full divide-y divide-gray-200 black:divide-gray-50/20 border border-gray-200 dark:border-gray-50/20">
48
+ <div popover id="<%= popover_id %>" data-orbit-target="moon" class="max-w-lg min-h-10 bg-base-200 border border-base-content/20 p-4 rounded-md" style="position-anchor: <%= anchor_name %>;">
49
+ <table class="min-w-full divide-y border border-base-content/10">
45
50
 
46
- <tbody class="bg-white dark:dark:bg-[var(--color-background-light)] divide-y divide-gray-200 dark:divide-gray-200/50 ">
51
+ <tbody class="bg-base-100">
47
52
  <% column_info = @columns_info[column] %>
48
53
 
49
- <tr>
50
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Type</td>
51
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "><%= column_info&.dig(:sql_type) %></td>
54
+ <tr class="border-b last:border-none border-base-content/10">
55
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Type</td>
56
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "><%= column_info&.dig(:sql_type) %></td>
52
57
  </tr>
53
58
 
54
- <tr>
55
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Primary Key</td>
56
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "><%= column_info&.dig(:is_primary_key) %></td>
59
+ <tr class="border-b last:border-none border-base-content/10">
60
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Primary Key</td>
61
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "><%= column_info&.dig(:is_primary_key) %></td>
57
62
  </tr>
58
63
 
59
- <tr>
60
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Nullable</td>
61
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "><%= column_info&.dig(:null) %></td>
64
+ <tr class="border-b last:border-none border-base-content/10">
65
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Nullable</td>
66
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "><%= column_info&.dig(:null) %></td>
62
67
  </tr>
63
68
 
64
- <tr>
65
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Default</td>
66
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "><%= column_info&.dig(:default) %></td>
69
+ <tr class="border-b last:border-none border-base-content/10">
70
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Default</td>
71
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "><%= column_info&.dig(:default) %></td>
67
72
  </tr>
68
73
 
69
74
  <% if column_info[:enum_options] %>
70
- <tr>
71
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Enum values</td>
72
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80">
75
+ <tr class="border-b last:border-none border-base-content/10">
76
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Enum values</td>
77
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80">
73
78
  <%= column_info[:enum_options].map { |k, v| "#{k}: #{v}" }.join(', ') %>
74
79
  </td>
75
80
  </tr>
@@ -77,49 +82,49 @@
77
82
 
78
83
  <% if column_info&.dig(:foreign_key).present? %>
79
84
 
80
- <tr>
81
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold"></td>
82
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "> </td>
85
+ <tr class="border-b last:border-none border-base-content/10">
86
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold"></td>
87
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "> </td>
83
88
  </tr>
84
89
 
85
- <tr>
86
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Foreign Key</td>
87
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80">
90
+ <tr class="border-b last:border-none border-base-content/10">
91
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Foreign Key</td>
92
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80">
88
93
  <%= column_info&.dig(:foreign_key).dig(:to_table) %>
89
94
  &gt;
90
95
  <%= column_info&.dig(:foreign_key).dig(:primary_key) %>
91
96
  </td>
92
97
  </tr>
93
98
 
94
- <tr>
95
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">ON_UPDATE</td>
96
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80"><%= column_info&.dig(:foreign_key).dig(:on_update) %></td>
99
+ <tr class="border-b last:border-none border-base-content/10">
100
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">ON_UPDATE</td>
101
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80"><%= column_info&.dig(:foreign_key).dig(:on_update) %></td>
97
102
  </tr>
98
103
 
99
- <tr>
100
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">ON_DELETE</td>
101
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80"><%= column_info&.dig(:foreign_key).dig(:on_delete) %></td>
104
+ <tr class="border-b last:border-none border-base-content/10">
105
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">ON_DELETE</td>
106
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80"><%= column_info&.dig(:foreign_key).dig(:on_delete) %></td>
102
107
  </tr>
103
108
 
104
109
  <% end %>
105
110
 
106
111
  <% if column_info&.dig(:indexes).present? %>
107
112
 
108
- <tr>
109
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold"></td>
110
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80 "> </td>
113
+ <tr class="border-b last:border-none border-base-content/10">
114
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold"></td>
115
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80 "> </td>
111
116
  </tr>
112
117
 
113
118
  <% column_info&.dig(:indexes).each do |index| %>
114
- <tr>
115
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Index Name</td>
116
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80">
119
+ <tr class="border-b last:border-none border-base-content/10">
120
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Index Name</td>
121
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80">
117
122
  <%= index[:name] %>
118
123
  </td>
119
124
  </tr>
120
- <tr>
121
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)] font-semibold">Unique</td>
122
- <td class="px-6 py-4 whitespace-nowrap text-sm text-[var(--color-text)]/80">
125
+ <tr class="border-b last:border-none border-base-content/10">
126
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content font-semibold">Unique</td>
127
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-base-content/80">
123
128
  <%= index[:unique] %>
124
129
  </td>
125
130
  </tr>
@@ -149,9 +154,9 @@
149
154
  </tr>
150
155
  </thead>
151
156
 
152
- <tbody class="main divide-y divide-gray-200 dark:divide-gray-200/50">
157
+ <tbody class="main">
153
158
  <% @data.rows.each do |row| %>
154
- <tr class="hover:bg-gray-50 dark:hover:bg-[var(--color-background-light)]/50" >
159
+ <tr class="border-b border-base-content/10 last:border-none hover:bg-base-100" >
155
160
  <% row.each_with_index do |item, index| %>
156
161
  <% truncated_item = item&.truncate(80) %>
157
162
  <% column_name = @data.columns[index] %>
@@ -159,7 +164,7 @@
159
164
  <td
160
165
  data-column="<%= column_name %>"
161
166
  data-data_type="<%= @columns_info.dig(column_name).dig(:type) %>"
162
- class="px-6 py-4 text-sm text-gray-800 dark:text-gray-300 whitespace-nowrap"
167
+ class="px-6 py-4 text-sm whitespace-nowrap"
163
168
  >
164
169
 
165
170
  <div class="flex justify-between gap-1">
@@ -176,7 +181,7 @@
176
181
  data-fk_target_field_value="<%= truncated_item %>"
177
182
  class="size-4 mt-0.5 hover:cursor-pointer flex-grow outline-none"
178
183
  >
179
- <%= image_tag "solid_litequeen/icons/spline.svg", class: "size-4 filter-blue dark:filter-cyan" %>
184
+ <%= image_tag "solid_litequeen/icons/spline.svg", class: "size-4 filter-orange" %>
180
185
  </button>
181
186
 
182
187
  <% end %>
@@ -189,7 +194,7 @@
189
194
  <%= render "table-data-context-dialog", dialog_id: dialog_id, column_name: column_name, data: item %>
190
195
 
191
196
  <button onclick="document.getElementById('<%= dialog_id %>').showModal()" class="cursor-pointer size-4 outline-none">
192
- <%= image_tag "solid_litequeen/icons/circle-elipsis.svg", class: "size-4 dark:filter-white" %>
197
+ <%= image_tag "solid_litequeen/icons/circle-elipsis.svg", class: "opacity-60 size-4 dark:filter-white" %>
193
198
 
194
199
  </button>
195
200
 
@@ -204,10 +209,10 @@
204
209
  <% end %>
205
210
  </tbody>
206
211
 
207
- <dialog id="foreign-key-data" data-controller="dialog" class="bg-[var(--color-background-light)] dark:border dark:rounded dark:border-gray-50/20 w-[900px] m-auto overscroll-y-contain">
212
+ <dialog id="foreign-key-data" data-controller="dialog" class="bg-base-200 border rounded border-base-content/20 w-[900px] m-auto overscroll-y-contain">
208
213
  <div class="flex flex-row-reverse">
209
214
  <button data-action="click->dialog#close" class="cursor-pointer mr-4 mt-2 outline-none">
210
- <%= image_tag "solid_litequeen/icons/x.svg", class: "size-5 dark:filter-white" %>
215
+ <%= image_tag "solid_litequeen/icons/x.svg", class: "opacity-60 size-5 dark:filter-white" %>
211
216
  </button>
212
217
 
213
218
  </div>
data/config/routes.rb CHANGED
@@ -5,5 +5,6 @@ SolidLitequeen::Engine.routes.draw do
5
5
  get "/tables/:table/foreign-key-data/:target_table/:target_field/:target_field_value", to: "databases#get_foreign_key_data", as: :get_table_foreign_key_data
6
6
  get "download", to: "databases#download", as: "download"
7
7
  end
8
+ get "command-palette-data", to: "databases#get_command_palette_data"
8
9
  root to: "databases#index"
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module SolidLitequeen
2
- VERSION = "0.18.1"
2
+ VERSION = "0.19.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_litequeen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vik Borges
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-06-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -170,6 +169,7 @@ files:
170
169
  - app/assets/images/solid_litequeen/icons/database.svg
171
170
  - app/assets/images/solid_litequeen/icons/info.svg
172
171
  - app/assets/images/solid_litequeen/icons/spline.svg
172
+ - app/assets/images/solid_litequeen/icons/table.svg
173
173
  - app/assets/images/solid_litequeen/icons/workflow.svg
174
174
  - app/assets/images/solid_litequeen/icons/x.svg
175
175
  - app/assets/stylesheets/solid_litequeen/application.css
@@ -180,14 +180,17 @@ files:
180
180
  - app/javascript/solid_litequeen/application.js
181
181
  - app/javascript/solid_litequeen/controllers/application.js
182
182
  - app/javascript/solid_litequeen/controllers/clipboard_controller.js
183
+ - app/javascript/solid_litequeen/controllers/command_palette_controller.js
183
184
  - app/javascript/solid_litequeen/controllers/dialog_controller.js
184
185
  - app/javascript/solid_litequeen/controllers/index.js
186
+ - app/javascript/solid_litequeen/controllers/orbit_controller.js
185
187
  - app/javascript/solid_litequeen/controllers/table_controller.js
186
188
  - app/javascript/solid_litequeen/controllers/table_relations_controller.js
187
189
  - app/jobs/solid_litequeen/application_job.rb
188
190
  - app/mailers/solid_litequeen/application_mailer.rb
189
191
  - app/models/solid_litequeen/application_record.rb
190
192
  - app/views/layouts/solid_litequeen/application.html.erb
193
+ - app/views/solid_litequeen/_command-palette.html.erb
191
194
  - app/views/solid_litequeen/_database-selector.html.erb
192
195
  - app/views/solid_litequeen/_loading-animation.html.erb
193
196
  - app/views/solid_litequeen/databases/_foreign-key-data.html.erb
@@ -209,7 +212,6 @@ metadata:
209
212
  homepage_uri: https://solid.litequeen.com
210
213
  source_code_uri: https://github.com/kivS/solid_litequeen
211
214
  changelog_uri: https://solid.litequeen.com
212
- post_install_message:
213
215
  rdoc_options: []
214
216
  require_paths:
215
217
  - lib
@@ -224,8 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
226
  - !ruby/object:Gem::Version
225
227
  version: '0'
226
228
  requirements: []
227
- rubygems_version: 3.5.21
228
- signing_key:
229
+ rubygems_version: 3.6.7
229
230
  specification_version: 4
230
231
  summary: Manage SQLite databases on your server with ease
231
232
  test_files: []