dbviewer 0.6.7 → 0.7.0

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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/dbviewer/entity_relationship_diagram.js +553 -0
  3. data/app/assets/javascripts/dbviewer/home.js +287 -0
  4. data/app/assets/javascripts/dbviewer/layout.js +194 -0
  5. data/app/assets/javascripts/dbviewer/query.js +277 -0
  6. data/app/assets/javascripts/dbviewer/table.js +1563 -0
  7. data/app/assets/stylesheets/dbviewer/application.css +1460 -21
  8. data/app/assets/stylesheets/dbviewer/entity_relationship_diagram.css +181 -0
  9. data/app/assets/stylesheets/dbviewer/home.css +229 -0
  10. data/app/assets/stylesheets/dbviewer/logs.css +64 -0
  11. data/app/assets/stylesheets/dbviewer/query.css +171 -0
  12. data/app/assets/stylesheets/dbviewer/table.css +1144 -0
  13. data/app/views/dbviewer/connections/index.html.erb +0 -30
  14. data/app/views/dbviewer/entity_relationship_diagrams/index.html.erb +14 -713
  15. data/app/views/dbviewer/home/index.html.erb +9 -499
  16. data/app/views/dbviewer/logs/index.html.erb +5 -220
  17. data/app/views/dbviewer/tables/index.html.erb +0 -65
  18. data/app/views/dbviewer/tables/query.html.erb +129 -565
  19. data/app/views/dbviewer/tables/show.html.erb +4 -2429
  20. data/app/views/layouts/dbviewer/application.html.erb +13 -1544
  21. data/lib/dbviewer/version.rb +1 -1
  22. metadata +12 -7
  23. data/app/assets/javascripts/dbviewer/connections.js +0 -70
  24. data/app/assets/stylesheets/dbviewer/dbviewer.css +0 -0
  25. data/app/assets/stylesheets/dbviewer/enhanced.css +0 -0
  26. data/app/views/dbviewer/connections/new.html.erb +0 -79
  27. data/app/views/dbviewer/tables/mini_erd.html.erb +0 -517
@@ -0,0 +1,181 @@
1
+ #erd-container {
2
+ overflow: auto;
3
+ height: calc(100vh - 125px);
4
+ padding: 20px;
5
+ position: relative;
6
+ }
7
+
8
+ .mermaid {
9
+ display: flex;
10
+ justify-content: center;
11
+ min-width: 100%;
12
+ }
13
+
14
+ /* Loading state styling */
15
+ #erd-loading {
16
+ background-color: var(--bs-body-bg);
17
+ }
18
+
19
+ #erd-loading .text-center p {
20
+ margin-bottom: 0.5rem;
21
+ font-weight: 500;
22
+ }
23
+
24
+ #erd-loading .text-center small {
25
+ font-size: 0.875rem;
26
+ }
27
+
28
+ /* Error state styling */
29
+ #erd-error {
30
+ max-width: 600px;
31
+ margin: 2rem auto;
32
+ }
33
+
34
+ #erd-error h5 {
35
+ color: var(--bs-danger);
36
+ margin-bottom: 0.75rem;
37
+ }
38
+
39
+ #erd-error-details {
40
+ font-size: 0.8rem;
41
+ max-height: 150px;
42
+ overflow-y: auto;
43
+ }
44
+
45
+ /* SVG Pan Zoom styles */
46
+ .svg-pan-zoom_viewport {
47
+ transition: 0.2s;
48
+ }
49
+
50
+ /* Make sure SVG maintains its size */
51
+ #erd-container svg {
52
+ width: 100%;
53
+ height: auto;
54
+ display: block;
55
+ min-width: 800px;
56
+ min-height: 600px;
57
+ }
58
+
59
+ /* Override mermaid defaults for a better look */
60
+ .entityBox {
61
+ fill: #f8f9fa;
62
+ stroke: #6c757d;
63
+ }
64
+
65
+ .entityLabel,
66
+ .mermaid .label {
67
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
68
+ "Helvetica Neue", Arial, sans-serif;
69
+ font-size: 20px !important;
70
+ }
71
+
72
+ /* Dark mode overrides - comprehensive styling like mini ERD */
73
+ [data-bs-theme="dark"] .entityBox {
74
+ fill: #2d3748;
75
+ stroke: #6ea8fe;
76
+ }
77
+
78
+ [data-bs-theme="dark"] .entityLabel,
79
+ [data-bs-theme="dark"] .mermaid .label {
80
+ color: #f8f9fa;
81
+ }
82
+
83
+ [data-bs-theme="dark"] #erd-error-details {
84
+ background-color: var(--bs-dark) !important;
85
+ color: var(--bs-light);
86
+ border-color: var(--bs-border-color);
87
+ }
88
+
89
+ /* Dark mode: Update mermaid diagram elements */
90
+ [data-bs-theme="dark"] .mermaid .er .entityBox {
91
+ fill: #2d3748 !important;
92
+ stroke: #6ea8fe !important;
93
+ stroke-width: 1.5px !important;
94
+ }
95
+
96
+ [data-bs-theme="dark"] .mermaid .er .entityLabel {
97
+ fill: #f8f9fa !important;
98
+ color: #f8f9fa !important;
99
+ }
100
+
101
+ [data-bs-theme="dark"] .mermaid .er .relationshipLine {
102
+ stroke: #6ea8fe !important;
103
+ stroke-width: 2px !important;
104
+ }
105
+
106
+ [data-bs-theme="dark"] .mermaid .er .relationshipLabel {
107
+ fill: #f8f9fa !important;
108
+ color: #f8f9fa !important;
109
+ }
110
+
111
+ [data-bs-theme="dark"] .mermaid .er .attributeBoxEven,
112
+ [data-bs-theme="dark"] .mermaid .er .attributeBoxOdd {
113
+ fill: #374151 !important;
114
+ }
115
+
116
+ [data-bs-theme="dark"] .mermaid text {
117
+ fill: #f8f9fa !important;
118
+ }
119
+
120
+ /* Loading indicator dark mode */
121
+ [data-bs-theme="dark"] #erd-loading {
122
+ background-color: var(--bs-dark);
123
+ color: var(--bs-light);
124
+ }
125
+
126
+ [data-bs-theme="dark"] #erd-loading .spinner-border {
127
+ color: #6ea8fe;
128
+ }
129
+
130
+ /* Zoom percentage display styling */
131
+ #zoomPercentage {
132
+ font-size: 0.9rem;
133
+ font-weight: 500;
134
+ width: 45px;
135
+ display: inline-block;
136
+ text-align: center;
137
+ }
138
+
139
+ /* Data loading badge styling */
140
+ #data-loading-badge {
141
+ animation: pulse 2s infinite;
142
+ }
143
+
144
+ @keyframes pulse {
145
+ 0% {
146
+ opacity: 1;
147
+ }
148
+ 50% {
149
+ opacity: 0.7;
150
+ }
151
+ 100% {
152
+ opacity: 1;
153
+ }
154
+ }
155
+
156
+ #data-loading-badge .badge {
157
+ font-size: 0.75rem;
158
+ padding: 0.4rem 0.6rem;
159
+ }
160
+
161
+ /* Mermaid override for text size */
162
+ .mermaid .entityLabel div {
163
+ font-size: 20px !important;
164
+ }
165
+
166
+ .mermaid .er.relationshipLabel {
167
+ font-size: 20px !important;
168
+ }
169
+
170
+ /* Enhanced table highlighting for current table */
171
+ .current-table-highlight rect {
172
+ fill: var(--bs-primary-bg-subtle) !important;
173
+ stroke: var(--bs-primary) !important;
174
+ stroke-width: 2px !important;
175
+ }
176
+
177
+ [data-bs-theme="dark"] .current-table-highlight rect {
178
+ fill: #2c3034 !important;
179
+ stroke: #6ea8fe !important;
180
+ stroke-width: 2px !important;
181
+ }
@@ -0,0 +1,229 @@
1
+ /* ================================================
2
+ CSS Custom Properties (CSS Variables)
3
+ ================================================ */
4
+ :root {
5
+ /* Colors */
6
+ --dbviewer-code-bg: rgba(0, 0, 0, 0.05);
7
+ --dbviewer-code-border: rgba(0, 0, 0, 0.1);
8
+ --dbviewer-muted-color: #6c757d;
9
+ --dbviewer-success-color: #28a745;
10
+ --dbviewer-danger-color: #dc3545;
11
+ --dbviewer-warning-color: #ffc107;
12
+
13
+ /* Skeleton loader colors */
14
+ --skeleton-base-color: #f0f0f0;
15
+ --skeleton-highlight-color: #e0e0e0;
16
+
17
+ /* Typography */
18
+ --dbviewer-monospace-font: "Courier New", Courier, monospace;
19
+ --dbviewer-code-font-size: 0.85rem;
20
+
21
+ /* Spacing and sizing */
22
+ --dbviewer-border-radius: 4px;
23
+ --dbviewer-border-radius-sm: 3px;
24
+ --dbviewer-padding-sm: 2px 4px;
25
+ }
26
+
27
+ /* ================================================
28
+ Dark Mode Support
29
+ ================================================ */
30
+ @media (prefers-color-scheme: dark) {
31
+ :root {
32
+ --dbviewer-code-bg: rgba(255, 255, 255, 0.1);
33
+ --dbviewer-code-border: rgba(255, 255, 255, 0.15);
34
+ --dbviewer-muted-color: #adb5bd;
35
+ --skeleton-base-color: #2a2a2a;
36
+ --skeleton-highlight-color: #404040;
37
+ }
38
+ }
39
+
40
+ /* Bootstrap dark mode support */
41
+ [data-bs-theme="dark"] {
42
+ --dbviewer-code-bg: rgba(255, 255, 255, 0.1);
43
+ --dbviewer-code-border: rgba(255, 255, 255, 0.15);
44
+ --dbviewer-muted-color: #adb5bd;
45
+ --skeleton-base-color: #2a2a2a;
46
+ --skeleton-highlight-color: #404040;
47
+ }
48
+
49
+ /* ================================================
50
+ SQL Query Styling
51
+ ================================================ */
52
+ .sql-query-code {
53
+ font-family: var(--dbviewer-monospace-font);
54
+ font-size: var(--dbviewer-code-font-size);
55
+ background-color: var(--dbviewer-code-bg);
56
+ padding: var(--dbviewer-padding-sm);
57
+ border-radius: var(--dbviewer-border-radius-sm);
58
+ border: 1px solid var(--dbviewer-code-border);
59
+ transition: background-color 0.2s ease, border-color 0.2s ease;
60
+ }
61
+
62
+ .sql-query-code:hover {
63
+ background-color: var(--dbviewer-code-bg);
64
+ filter: brightness(0.95);
65
+ }
66
+
67
+ /* ================================================
68
+ Query Performance Indicators
69
+ ================================================ */
70
+ .query-duration {
71
+ color: var(--dbviewer-success-color);
72
+ font-weight: 500;
73
+ font-variant-numeric: tabular-nums;
74
+ transition: color 0.2s ease;
75
+ }
76
+
77
+ .query-duration-slow {
78
+ color: var(--dbviewer-danger-color);
79
+ font-weight: 600;
80
+ font-variant-numeric: tabular-nums;
81
+ transition: color 0.2s ease;
82
+ }
83
+
84
+ .query-timestamp {
85
+ color: var(--dbviewer-muted-color);
86
+ font-variant-numeric: tabular-nums;
87
+ transition: color 0.2s ease;
88
+ }
89
+
90
+ /* ================================================
91
+ Empty States and Messages
92
+ ================================================ */
93
+ .empty-data-message {
94
+ color: var(--dbviewer-muted-color);
95
+ transition: color 0.2s ease;
96
+ }
97
+
98
+ .empty-data-message p {
99
+ margin-bottom: 0.5rem;
100
+ font-weight: 500;
101
+ }
102
+
103
+ .empty-data-message small {
104
+ opacity: 0.8;
105
+ }
106
+
107
+ /* ================================================
108
+ Loading States
109
+ ================================================ */
110
+ .spinner-border-sm {
111
+ width: 1rem;
112
+ height: 1rem;
113
+ }
114
+
115
+ /* ================================================
116
+ Skeleton Loader System
117
+ ================================================ */
118
+ .skeleton-loader {
119
+ display: inline-block;
120
+ height: 1.2em;
121
+ width: 100%;
122
+ background: linear-gradient(
123
+ 90deg,
124
+ var(--skeleton-base-color) 25%,
125
+ var(--skeleton-highlight-color) 37%,
126
+ var(--skeleton-base-color) 63%
127
+ );
128
+ background-size: 400% 100%;
129
+ animation: skeleton-loading 1.2s ease-in-out infinite;
130
+ border-radius: var(--dbviewer-border-radius);
131
+ }
132
+
133
+ /* Skeleton loader variants */
134
+ .skeleton-loader.number-loader {
135
+ width: 2.5em;
136
+ height: 1.5em;
137
+ margin-bottom: 0.2em;
138
+ }
139
+
140
+ .skeleton-loader.table-cell-loader {
141
+ width: 6em;
142
+ height: 1.2em;
143
+ }
144
+
145
+ .skeleton-loader.records-loader {
146
+ width: 3em;
147
+ height: 1.2em;
148
+ }
149
+
150
+ .skeleton-loader.query-cell-loader {
151
+ width: 12em;
152
+ height: 1.2em;
153
+ }
154
+
155
+ .skeleton-loader.duration-cell-loader {
156
+ width: 4em;
157
+ height: 1.2em;
158
+ }
159
+
160
+ .skeleton-loader.time-cell-loader {
161
+ width: 7em;
162
+ height: 1.2em;
163
+ }
164
+
165
+ /* ================================================
166
+ Animations
167
+ ================================================ */
168
+ @keyframes skeleton-loading {
169
+ 0% {
170
+ background-position: 100% 50%;
171
+ }
172
+ 100% {
173
+ background-position: 0 50%;
174
+ }
175
+ }
176
+
177
+ /* ================================================
178
+ Table Enhancements
179
+ ================================================ */
180
+ .table-hover tbody tr:hover .sql-query-code {
181
+ background-color: var(--dbviewer-code-bg);
182
+ filter: brightness(0.9);
183
+ }
184
+
185
+ /* ================================================
186
+ Responsive Design
187
+ ================================================ */
188
+ @media (max-width: 768px) {
189
+ .sql-query-code {
190
+ font-size: 0.75rem;
191
+ padding: 1px 3px;
192
+ }
193
+
194
+ .query-cell-loader {
195
+ width: 8em;
196
+ }
197
+
198
+ .duration-cell-loader {
199
+ width: 3em;
200
+ }
201
+
202
+ .time-cell-loader {
203
+ width: 5em;
204
+ }
205
+ }
206
+
207
+ /* ================================================
208
+ Accessibility Improvements
209
+ ================================================ */
210
+ @media (prefers-reduced-motion: reduce) {
211
+ .skeleton-loader {
212
+ animation: none;
213
+ background: var(--skeleton-base-color);
214
+ }
215
+
216
+ .sql-query-code,
217
+ .query-duration,
218
+ .query-duration-slow,
219
+ .query-timestamp,
220
+ .empty-data-message {
221
+ transition: none;
222
+ }
223
+ }
224
+
225
+ /* Focus states for better keyboard navigation */
226
+ .sql-query-code:focus-visible {
227
+ outline: 2px solid var(--dbviewer-success-color);
228
+ outline-offset: 2px;
229
+ }
@@ -0,0 +1,64 @@
1
+ /* SQL query styling with dark mode support */
2
+ .sql-query {
3
+ white-space: pre-wrap;
4
+ word-wrap: break-word;
5
+ max-height: 100px;
6
+ overflow-y: auto;
7
+ font-size: 0.85rem;
8
+ border-radius: 3px;
9
+ padding: 0.5rem;
10
+ }
11
+
12
+ /* Dark mode compatible styling */
13
+ .sql-code-block {
14
+ background-color: var(--bs-secondary-bg);
15
+ }
16
+
17
+ [data-bs-theme="dark"] .sql-code-block {
18
+ background-color: var(--bs-tertiary-bg);
19
+ }
20
+
21
+ /* Request group header styling */
22
+ .request-group-header {
23
+ border-top: 2px solid var(--bs-border-color);
24
+ }
25
+
26
+ .request-header-bg {
27
+ background-color: var(--bs-secondary-bg);
28
+ }
29
+
30
+ .request-group-header:first-child {
31
+ border-top: none;
32
+ }
33
+
34
+ /* Collapsed section styling */
35
+ details summary {
36
+ cursor: pointer;
37
+ }
38
+
39
+ .cursor-pointer {
40
+ cursor: pointer;
41
+ }
42
+
43
+ /* Rotate icon when expanded */
44
+ .collapsed-section[aria-expanded="true"] .bi-chevron-down {
45
+ transform: rotate(180deg);
46
+ transition: transform 0.3s ease;
47
+ }
48
+
49
+ .collapsed-section[aria-expanded="false"] .bi-chevron-down {
50
+ transform: rotate(0deg);
51
+ transition: transform 0.3s ease;
52
+ }
53
+
54
+ /* Code styling */
55
+ .pattern-code,
56
+ .query-binds {
57
+ background-color: var(--bs-secondary-bg);
58
+ border: 1px solid var(--bs-border-color);
59
+ }
60
+
61
+ /* Empty data message */
62
+ .empty-data-message {
63
+ color: var(--bs-secondary-color);
64
+ }
@@ -0,0 +1,171 @@
1
+ /* Monaco Editor styling */
2
+ #monaco-editor {
3
+ margin-bottom: 1rem;
4
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
5
+ }
6
+
7
+ .monaco-editor-container {
8
+ border: 1px solid #ced4da;
9
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
10
+ }
11
+
12
+ [data-bs-theme="dark"] .monaco-editor-container {
13
+ border: 1px solid #495057;
14
+ }
15
+
16
+ [data-bs-theme="dark"] #monaco-editor {
17
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
18
+ }
19
+
20
+ .example-queries {
21
+ display: flex;
22
+ flex-wrap: wrap;
23
+ gap: 5px;
24
+ margin-top: 8px;
25
+ }
26
+
27
+ .example-query {
28
+ display: inline-block;
29
+ transition: all 0.2s ease;
30
+ cursor: pointer;
31
+ font-size: 0.85rem;
32
+ white-space: nowrap;
33
+ overflow: hidden;
34
+ text-overflow: ellipsis;
35
+ max-width: 100%;
36
+ }
37
+
38
+ [data-bs-theme="light"] .example-query {
39
+ border-color: #ced4da;
40
+ }
41
+
42
+ [data-bs-theme="dark"] .example-query {
43
+ border-color: #495057;
44
+ color: #f8f9fa;
45
+ }
46
+
47
+ /* Result table styling */
48
+ .results-table {
49
+ border-collapse: collapse;
50
+ }
51
+
52
+ [data-bs-theme="dark"] .results-table {
53
+ border-color: #495057;
54
+ }
55
+
56
+ .example-query:hover {
57
+ background-color: #0d6efd;
58
+ color: white;
59
+ border-color: #0d6efd;
60
+ }
61
+
62
+ /* Keyboard shortcut helper */
63
+ .keyboard-hint {
64
+ font-size: 0.8rem;
65
+ margin-left: 8px;
66
+ opacity: 0.7;
67
+ }
68
+
69
+ [data-bs-theme="light"] .shortcut-hints {
70
+ color: #6c757d;
71
+ }
72
+
73
+ [data-bs-theme="dark"] .shortcut-hints {
74
+ color: #adb5bd;
75
+ }
76
+
77
+ /* Monaco status bar */
78
+ .monaco-status-bar {
79
+ display: flex;
80
+ justify-content: space-between;
81
+ padding: 3px 8px;
82
+ font-size: 0.75rem;
83
+ border-top: none;
84
+ border-bottom-left-radius: 4px;
85
+ border-bottom-right-radius: 4px;
86
+ }
87
+
88
+ [data-bs-theme="light"] .monaco-status-bar {
89
+ background-color: #f8f9fa;
90
+ border: 1px solid #ced4da;
91
+ color: #6c757d;
92
+ }
93
+
94
+ [data-bs-theme="dark"] .monaco-status-bar {
95
+ background-color: #343a40;
96
+ border: 1px solid #495057;
97
+ color: #adb5bd;
98
+ }
99
+
100
+ .monaco-status-bar .column-info {
101
+ font-weight: 500;
102
+ }
103
+
104
+ /* Table structure styles */
105
+ #tableStructureHeader .btn-link {
106
+ font-weight: 500;
107
+ display: flex;
108
+ align-items: center;
109
+ width: 100%;
110
+ text-align: left;
111
+ }
112
+
113
+ [data-bs-theme="light"] #tableStructureHeader .btn-link {
114
+ color: #212529;
115
+ }
116
+
117
+ [data-bs-theme="dark"] #tableStructureHeader .btn-link {
118
+ color: #f8f9fa;
119
+ }
120
+
121
+ [data-bs-theme="light"] .table-columns-count {
122
+ color: #6c757d;
123
+ }
124
+
125
+ [data-bs-theme="dark"] .table-columns-count {
126
+ color: #adb5bd;
127
+ }
128
+
129
+ #tableStructureHeader .btn-link:hover,
130
+ #tableStructureHeader .btn-link:focus {
131
+ text-decoration: none;
132
+ color: #0d6efd;
133
+ }
134
+
135
+ #tableStructureHeader .btn-link i {
136
+ transition: transform 0.2s ease-in-out;
137
+ }
138
+
139
+ /* Table style overrides for query page */
140
+ [data-bs-theme="dark"] .table-sm th,
141
+ [data-bs-theme="dark"] .table-sm td {
142
+ border-color: #495057;
143
+ }
144
+
145
+ /* Results card styling */
146
+ [data-bs-theme="dark"] .card-header h5 {
147
+ color: #f8f9fa;
148
+ }
149
+
150
+ /* Alert styling for dark mode */
151
+ [data-bs-theme="dark"] .alert-warning {
152
+ background-color: rgba(255, 193, 7, 0.15);
153
+ border-color: rgba(255, 193, 7, 0.4);
154
+ color: #ffc107;
155
+ }
156
+
157
+ [data-bs-theme="dark"] .alert-danger {
158
+ background-color: rgba(220, 53, 69, 0.15);
159
+ border-color: rgba(220, 53, 69, 0.4);
160
+ color: #f8d7da;
161
+ }
162
+
163
+ /* Make headings stand out in dark mode */
164
+ [data-bs-theme="dark"] h1,
165
+ [data-bs-theme="dark"] h2,
166
+ [data-bs-theme="dark"] h3,
167
+ [data-bs-theme="dark"] h4,
168
+ [data-bs-theme="dark"] h5,
169
+ [data-bs-theme="dark"] h6 {
170
+ color: #f8f9fa;
171
+ }