drixio 1.2.0 → 1.2.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.
@@ -0,0 +1,135 @@
1
+ import{t as e}from"./index-CmbAXgDl.js";async function t(){let t=document.getElementById(`schema-health-modal`);t&&t.remove(),t=document.createElement(`div`),t.id=`schema-health-modal`,t.className=`modal-overlay`,t.setAttribute(`role`,`dialog`),t.setAttribute(`aria-modal`,`true`),t.setAttribute(`aria-labelledby`,`health-modal-title`),document.body.appendChild(t);let r=e=>{e.key===`Escape`&&i()};window.addEventListener(`keydown`,r);function i(){window.removeEventListener(`keydown`,r),t.remove()}t.onclick=e=>{e.target===t&&i()},t.innerHTML=`
2
+ <div class="modal-dialog schema-health-dialog" style="max-width: 780px; width: 90vw;">
3
+ <div class="modal-header">
4
+ <div class="modal-header-info">
5
+ <div class="modal-icon-badge" style="background: rgba(16, 185, 129, 0.1); color: #10b981;">
6
+ <span class="material-symbols-outlined">health_and_safety</span>
7
+ </div>
8
+ <div>
9
+ <h3 id="health-modal-title" class="modal-title">Schema Health Doctor</h3>
10
+ <p class="modal-subtitle">Automated architectural linter, foreign key index auditor, and 1-click remediation.</p>
11
+ </div>
12
+ </div>
13
+ <button class="modal-close-btn" id="health-modal-close-btn" aria-label="Close modal">
14
+ <span class="material-symbols-outlined">close</span>
15
+ </button>
16
+ </div>
17
+
18
+ <div class="modal-body" id="health-modal-body" style="min-height: 280px; display: flex; align-items: center; justify-content: center;">
19
+ <div style="display: flex; align-items: center; gap: 8px; color: var(--color-text-dim);">
20
+ <span class="material-symbols-outlined animate-spin icon-20">progress_activity</span>
21
+ <span>Running database health check...</span>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ `,document.getElementById(`health-modal-close-btn`).onclick=i;let a=await e();if(!a.success){let e=document.getElementById(`health-modal-body`);e&&(e.innerHTML=`
26
+ <div style="text-align: center; color: #ef4444; padding: 20px;">
27
+ <span class="material-symbols-outlined" style="font-size: 32px;">error</span>
28
+ <p style="margin-top: 8px;">Health Check Failed: ${a.error}</p>
29
+ </div>
30
+ `);return}n(a.data,i)}function n(e,t){let n=document.getElementById(`health-modal-body`);if(!n)return;let{score:a,grade:o,statusText:s,analyzedTablesCount:c,issuesCount:l,issues:u}=e,d=`#10b981`,f=`rgba(16, 185, 129, 0.1)`;a<50?(d=`#ef4444`,f=`rgba(239, 68, 68, 0.1)`):a<75?(d=`#f59e0b`,f=`rgba(245, 158, 11, 0.1)`):a<90&&(d=`#3b82f6`,f=`rgba(59, 130, 246, 0.1)`),n.style.display=`block`,n.innerHTML=`
31
+ <!-- Hero Score Card -->
32
+ <div style="display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-radius: 10px; background: ${f}; border: 1px solid ${d}33; margin-bottom: 20px;">
33
+ <div style="display: flex; align-items: center; gap: 16px;">
34
+ <div style="width: 64px; height: 64px; border-radius: 50%; background: var(--color-bg); border: 3px solid ${d}; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
35
+ <span style="font-size: 20px; font-weight: 800; color: ${d}; line-height: 1;">${a}</span>
36
+ <span style="font-size: 9px; font-weight: 700; color: var(--color-text-dim); text-transform: uppercase;">Grade ${o}</span>
37
+ </div>
38
+ <div>
39
+ <h4 style="margin: 0 0 4px 0; font-size: 16px; font-weight: 700; color: var(--color-text);">${s}</h4>
40
+ <div style="display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--color-text-dim);">
41
+ <span>Analyzed ${c} tables</span>
42
+ <span>•</span>
43
+ <span>${l.total} total observations</span>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <div style="display: flex; gap: 8px;">
49
+ <div style="text-align: center; padding: 6px 12px; border-radius: 6px; background: rgba(0,0,0,0.15);">
50
+ <div style="font-size: 14px; font-weight: 700; color: #ef4444;">${l.critical}</div>
51
+ <div style="font-size: 10px; color: var(--color-text-dim);">Critical</div>
52
+ </div>
53
+ <div style="text-align: center; padding: 6px 12px; border-radius: 6px; background: rgba(0,0,0,0.15);">
54
+ <div style="font-size: 14px; font-weight: 700; color: #f59e0b;">${l.warning}</div>
55
+ <div style="font-size: 10px; color: var(--color-text-dim);">Warning</div>
56
+ </div>
57
+ <div style="text-align: center; padding: 6px 12px; border-radius: 6px; background: rgba(0,0,0,0.15);">
58
+ <div style="font-size: 14px; font-weight: 700; color: #3b82f6;">${l.suggestion}</div>
59
+ <div style="font-size: 10px; color: var(--color-text-dim);">Suggestions</div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <!-- Filter Tabs -->
65
+ <div style="display: flex; gap: 8px; border-bottom: 1px solid var(--color-border); padding-bottom: 10px; margin-bottom: 16px;">
66
+ <button class="health-tab-btn active" data-filter="all" style="font-size: 12.5px; padding: 4px 12px; border-radius: 6px; background: var(--color-primary); color: #fff; border: none; cursor: pointer; font-weight: 600;">
67
+ All (${l.total})
68
+ </button>
69
+ <button class="health-tab-btn" data-filter="critical" style="font-size: 12.5px; padding: 4px 12px; border-radius: 6px; background: transparent; color: var(--color-text-dim); border: 1px solid var(--color-border); cursor: pointer; font-weight: 500;">
70
+ 🔴 Critical (${l.critical})
71
+ </button>
72
+ <button class="health-tab-btn" data-filter="warning" style="font-size: 12.5px; padding: 4px 12px; border-radius: 6px; background: transparent; color: var(--color-text-dim); border: 1px solid var(--color-border); cursor: pointer; font-weight: 500;">
73
+ 🟡 Warning (${l.warning})
74
+ </button>
75
+ <button class="health-tab-btn" data-filter="suggestion" style="font-size: 12.5px; padding: 4px 12px; border-radius: 6px; background: transparent; color: var(--color-text-dim); border: 1px solid var(--color-border); cursor: pointer; font-weight: 500;">
76
+ 🔵 Suggestions (${l.suggestion})
77
+ </button>
78
+ </div>
79
+
80
+ <!-- Issues List Container -->
81
+ <div id="health-issues-container" style="display: flex; flex-direction: column; gap: 12px; max-height: 420px; overflow-y: auto;">
82
+ ${r(u)}
83
+ </div>
84
+ `;let p=n.querySelectorAll(`.health-tab-btn`);p.forEach(e=>{e.onclick=()=>{p.forEach(e=>{e.classList.remove(`active`),e.style.background=`transparent`,e.style.color=`var(--color-text-dim)`}),e.classList.add(`active`),e.style.background=`var(--color-primary)`,e.style.color=`#fff`;let n=e.dataset.filter,a=n===`all`?u:u.filter(e=>e.severity===n),o=document.getElementById(`health-issues-container`);o&&(o.innerHTML=r(a),i(o,t))}}),i(n,t)}function r(e){return e.length===0?`
85
+ <div style="text-align: center; padding: 30px; color: var(--color-text-dim);">
86
+ <span class="material-symbols-outlined" style="font-size: 32px; color: #10b981; margin-bottom: 8px;">verified</span>
87
+ <h4 style="margin: 0 0 4px 0; color: var(--color-text);">No Issues Found</h4>
88
+ <p style="margin: 0; font-size: 13px;">No schema warnings or performance antipatterns in this category.</p>
89
+ </div>
90
+ `:e.map(e=>{let t=e.severity===`critical`?`#ef4444`:e.severity===`warning`?`#f59e0b`:`#3b82f6`;return`
91
+ <div class="health-issue-card" style="border: 1px solid var(--color-border); border-radius: 8px; padding: 14px 16px; background: var(--color-bg-subtle, rgba(255,255,255,0.02));">
92
+ <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
93
+ <div style="display: flex; align-items: center; gap: 8px;">
94
+ <span style="font-size: 10px; font-weight: 700; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; background: ${e.severity===`critical`?`rgba(239, 68, 68, 0.1)`:e.severity===`warning`?`rgba(245, 158, 11, 0.1)`:`rgba(59, 130, 246, 0.1)`}; color: ${t}; border: 1px solid ${t}33;">
95
+ ${e.severity} (-${e.deduction} pts)
96
+ </span>
97
+ <span style="font-size: 13.5px; font-weight: 600; color: var(--color-text);">${e.title}</span>
98
+ </div>
99
+ <div style="display: flex; gap: 6px; font-size: 11px; font-family: monospace;">
100
+ <span class="badge" style="padding: 2px 6px; border-radius: 4px; background: var(--color-bg); border: 1px solid var(--color-border); color: var(--color-text-dim);">
101
+ table: ${e.tableName}
102
+ </span>
103
+ ${e.columnName?`<span class="badge" style="padding: 2px 6px; border-radius: 4px; background: var(--color-bg); border: 1px solid var(--color-border); color: var(--color-text-dim);">col: ${e.columnName}</span>`:``}
104
+ </div>
105
+ </div>
106
+
107
+ <p style="margin: 0 0 6px 0; font-size: 12.5px; color: var(--color-text-dim); line-height: 1.4;">
108
+ ${e.description}
109
+ </p>
110
+
111
+ <div style="display: flex; align-items: flex-start; gap: 6px; padding: 6px 10px; border-radius: 6px; background: rgba(0,0,0,0.15); margin-bottom: 10px; font-size: 11.5px; color: var(--color-text-secondary);">
112
+ <span class="material-symbols-outlined" style="font-size: 15px; color: #f59e0b; margin-top: 1px;">warning</span>
113
+ <span><strong>Performance Impact:</strong> ${e.impact}</span>
114
+ </div>
115
+
116
+ ${e.remediationSql?`
117
+ <div style="margin-top: 8px;">
118
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
119
+ <span style="font-size: 11px; font-weight: 600; color: var(--color-text-dim); text-transform: uppercase;">Remediation SQL</span>
120
+ <div style="display: flex; gap: 6px;">
121
+ <button class="btn btn-ghost copy-fix-sql-btn" data-sql="${encodeURIComponent(e.remediationSql)}" style="font-size: 11.5px; padding: 2px 8px; display: inline-flex; align-items: center; gap: 4px;">
122
+ <span class="material-symbols-outlined icon-14">content_copy</span>
123
+ <span>Copy SQL</span>
124
+ </button>
125
+ <button class="btn btn-primary run-fix-console-btn" data-sql="${encodeURIComponent(e.remediationSql)}" style="font-size: 11.5px; padding: 2px 10px; display: inline-flex; align-items: center; gap: 4px;">
126
+ <span class="material-symbols-outlined icon-14">terminal</span>
127
+ <span>Run in Console</span>
128
+ </button>
129
+ </div>
130
+ </div>
131
+ <pre style="margin: 0; padding: 8px 12px; border-radius: 6px; background: #0f172a; color: #38bdf8; font-family: monospace; font-size: 11.5px; overflow-x: auto; white-space: pre-wrap;"><code>${e.remediationSql}</code></pre>
132
+ </div>
133
+ `:``}
134
+ </div>
135
+ `}).join(``)}function i(e,t){e.querySelectorAll(`.copy-fix-sql-btn`).forEach(e=>{e.onclick=async()=>{let t=decodeURIComponent(e.dataset.sql);try{await navigator.clipboard.writeText(t),window.showToast&&window.showToast(`SQL copied to clipboard`,`success`)}catch{alert(`Failed to copy SQL`)}}}),e.querySelectorAll(`.run-fix-console-btn`).forEach(e=>{e.onclick=()=>{let n=decodeURIComponent(e.dataset.sql);t(),window.handleSwitchTab&&window.handleSwitchTab(`sql-btn`),setTimeout(()=>{if(window.editorInstance)window.editorInstance.setValue(n),window.editorInstance.focus();else{let e=document.getElementById(`sql-editor`);e&&(e.value=n,e.focus())}window.showToast&&window.showToast(`Remediation SQL loaded into editor. Press Ctrl+Enter to execute.`,`info`)},150)}})}export{t as openHealthModal};