-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
312 lines (284 loc) · 20.3 KB
/
index.html
File metadata and controls
312 lines (284 loc) · 20.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SuiteQL</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: { sans: ['Inter', 'sans-serif'] },
colors: {
google: {
blue: '#1a73e8',
blueHover: '#1557b0',
red: '#ea4335',
green: '#34a853',
yellow: '#fbbc04',
gray: '#f1f3f4'
}
}
}
}
}
</script>
<style>
body { font-family: 'Inter', sans-serif; -webkit-font-smoothing: antialiased; }
.view-container { position: relative; min-height: 400px; }
.view {
display: none;
opacity: 0;
transform: translateY(10px);
transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
}
.view.active {
display: block;
opacity: 1;
transform: translateY(0);
}
.nav-item.active {
color: #1a73e8;
background-color: #e8f0fe;
}
code { font-family: 'Menlo', 'Monaco', 'Courier New', monospace; }
</style>
</head>
<body class="bg-white text-zinc-900 flex flex-col items-center min-h-screen pt-12">
<div class="w-full max-w-3xl px-4">
<header class="flex items-center justify-between mb-8">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-google-blue rounded-lg flex items-center justify-center text-white shadow-sm">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4" />
</svg>
</div>
<h1 class="text-2xl font-semibold tracking-tight text-gray-800">SuiteQL Query Tool</h1>
</div>
<div class="text-xs font-medium text-zinc-500 bg-zinc-100 px-2 py-1 rounded">v2025.6</div>
</header>
<nav class="flex space-x-1 border-b border-zinc-200 mb-6 overflow-x-auto">
<button onclick="switchTab('overview')" id="nav-overview" class="nav-item active px-4 py-3 text-sm font-medium rounded-t-lg text-zinc-600 hover:bg-zinc-50 transition-colors whitespace-nowrap">Overview</button>
<button onclick="switchTab('features')" id="nav-features" class="nav-item px-4 py-3 text-sm font-medium rounded-t-lg text-zinc-600 hover:bg-zinc-50 transition-colors whitespace-nowrap">Features & Shortcuts</button>
<button onclick="switchTab('deploy')" id="nav-deploy" class="nav-item px-4 py-3 text-sm font-medium rounded-t-lg text-zinc-600 hover:bg-zinc-50 transition-colors whitespace-nowrap">How to Deploy</button>
<button onclick="switchTab('versions')" id="nav-versions" class="nav-item px-4 py-3 text-sm font-medium rounded-t-lg text-zinc-600 hover:bg-zinc-50 transition-colors whitespace-nowrap">Versions</button>
<button onclick="switchTab('about')" id="nav-about" class="nav-item px-4 py-3 text-sm font-medium rounded-t-lg text-zinc-600 hover:bg-zinc-50 transition-colors whitespace-nowrap">About</button>
</nav>
<main class="view-container">
<!-- OVERVIEW TAB -->
<div id="view-overview" class="view active">
<div class="bg-white border border-zinc-200 rounded-xl p-8 shadow-sm">
<h2 class="text-xl font-semibold mb-2">Get Started</h2>
<p class="text-zinc-600 mb-6">A lightweight, modern Suitelet for testing SQL directly in NetSuite. Write queries, visualize results, and perform DML operations safely.</p>
<a id="downloadLink" href="#" class="group flex items-center justify-between w-full bg-google-blue hover:bg-google-blueHover text-white p-4 rounded-lg transition-all shadow-sm hover:shadow-md cursor-pointer">
<div class="flex items-center">
<svg class="w-6 h-6 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
<div class="text-left">
<div class="font-semibold">Download SuiteQL Tool</div>
<div class="text-xs text-blue-100 opacity-90">v2025.6 • suiteql-tool-sl.js • Single File</div>
</div>
</div>
<svg class="w-5 h-5 opacity-0 group-hover:opacity-100 transition-opacity transform -translate-x-2 group-hover:translate-x-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</a>
<div class="mt-8 pt-6 border-t border-zinc-100 grid grid-cols-2 gap-4">
<div class="p-3 bg-zinc-50 rounded-lg">
<div class="text-zinc-500 text-xs font-semibold uppercase tracking-wider mb-1">Type</div>
<div class="font-medium text-zinc-800">NetSuite Suitelet (2.1)</div>
</div>
<div class="p-3 bg-zinc-50 rounded-lg">
<div class="text-zinc-500 text-xs font-semibold uppercase tracking-wider mb-1">License</div>
<div class="font-medium text-zinc-800">MIT / Open Source</div>
</div>
</div>
</div>
</div>
<!-- FEATURES & SHORTCUTS TAB -->
<div id="view-features" class="view">
<div class="bg-white border border-zinc-200 rounded-xl p-8 shadow-sm space-y-8">
<!-- Shortcuts Section -->
<div>
<div class="flex items-center gap-2 mb-4">
<span class="p-1 bg-zinc-100 text-zinc-600 rounded"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"></path></svg></span>
<h3 class="text-lg font-semibold text-zinc-900">Keyboard Shortcuts</h3>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="flex items-center justify-between bg-zinc-50 p-3 rounded-lg border border-zinc-100">
<span class="text-sm text-zinc-600">Execute Query</span>
<span class="text-xs font-mono font-semibold bg-white border border-zinc-200 px-2 py-1 rounded shadow-sm text-zinc-700">Ctrl + Enter</span>
</div>
<div class="flex items-center justify-between bg-zinc-50 p-3 rounded-lg border border-zinc-100">
<span class="text-sm text-zinc-600">Autocomplete</span>
<span class="text-xs font-mono font-semibold bg-white border border-zinc-200 px-2 py-1 rounded shadow-sm text-zinc-700">Ctrl + Space</span>
</div>
</div>
</div>
<hr class="border-zinc-100">
<!-- Actions Section -->
<div>
<div class="flex items-center gap-2 mb-4">
<span class="p-1 bg-blue-100 text-blue-600 rounded"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg></span>
<h3 class="text-lg font-semibold text-zinc-900">Supported Actions</h3>
</div>
<div class="space-y-3">
<div class="flex items-start">
<div class="flex-shrink-0 mt-1">
<div class="w-2 h-2 rounded-full bg-green-500"></div>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-zinc-900">Run Standard Queries</p>
<p class="text-xs text-zinc-500">Execute any standard SuiteQL (SQL-92) query. Supports JOINs, Aggregates, and built-in Oracle functions.</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 mt-1">
<div class="w-2 h-2 rounded-full bg-amber-500"></div>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-zinc-900">DML Operations (Safe Mode)</p>
<p class="text-xs text-zinc-500">
Perform <code>INSERT</code>, <code>UPDATE</code>, and <code>DELETE</code> directly.
<br><span class="italic text-zinc-400">Note: DROP and TRUNCATE are blocked for safety.</span>
</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 mt-1">
<div class="w-2 h-2 rounded-full bg-blue-500"></div>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-zinc-900">Recent Queries History</p>
<p class="text-xs text-zinc-500">The tool automatically saves your last 20 queries to your browser's local storage.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- DEPLOY TAB -->
<div id="view-deploy" class="view">
<div class="bg-white border border-zinc-200 rounded-xl p-8 shadow-sm">
<h2 class="text-xl font-semibold mb-6">Simple Deployment</h2>
<p class="text-sm text-zinc-500 mb-6">Single-file solution. No external assets needed.</p>
<div class="space-y-8">
<div class="flex gap-4">
<div class="flex-shrink-0 w-8 h-8 bg-zinc-100 rounded-full flex items-center justify-center font-bold text-zinc-600">1</div>
<div>
<h3 class="font-medium text-zinc-900">Download the Script</h3>
<p class="text-sm text-zinc-500">Download <code class="bg-zinc-100 px-1 rounded text-zinc-800 font-mono">suiteql-tool-sl.js</code> from the Overview tab.</p>
</div>
</div>
<div class="flex gap-4">
<div class="flex-shrink-0 w-8 h-8 bg-zinc-100 rounded-full flex items-center justify-center font-bold text-zinc-600">2</div>
<div>
<h3 class="font-medium text-zinc-900">Upload to NetSuite</h3>
<p class="text-sm text-zinc-500">Navigate to <strong>Documents > Files > SuiteScripts</strong> and upload the file.</p>
</div>
</div>
<div class="flex gap-4">
<div class="flex-shrink-0 w-8 h-8 bg-zinc-100 rounded-full flex items-center justify-center font-bold text-zinc-600">3</div>
<div>
<h3 class="font-medium text-zinc-900">Create Script Record</h3>
<p class="text-sm text-zinc-500">Go to <strong>Customization > Scripting > Scripts > New</strong>. Select the file you just uploaded.</p>
</div>
</div>
<div class="flex gap-4">
<div class="flex-shrink-0 w-8 h-8 bg-google-green text-white rounded-full flex items-center justify-center font-bold">4</div>
<div>
<h3 class="font-medium text-zinc-900">Deploy</h3>
<p class="text-sm text-zinc-500">Click <strong>Deploy Script</strong>. Set Status to <strong>Released</strong> and Audience to <strong>All Roles</strong> (or specific admins).</p>
<p class="text-xs text-zinc-400 mt-1">Copy the generated URL link to your bookmarks!</p>
</div>
</div>
</div>
</div>
</div>
<!-- VERSIONS TAB -->
<div id="view-versions" class="view">
<div class="bg-white border border-zinc-200 rounded-xl overflow-hidden shadow-sm">
<div class="px-6 py-4 border-b border-zinc-100 bg-zinc-50 flex justify-between items-center">
<span class="font-medium text-zinc-700">v2025.6</span>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full font-medium">Latest</span>
</div>
<div class="p-6">
<a href="https://raw.githubusercontent.com/MossesRoss/SuiteQL-Tool/main/suiteql-tool-sl.js" target="_blank" class="text-google-blue hover:underline text-sm font-medium">Download v2025.6 Source</a>
</div>
<div class="px-6 py-4 border-b border-zinc-100 bg-zinc-50 flex justify-between items-center border-t">
<span class="font-medium text-zinc-500">v2021.2</span>
<span class="text-xs bg-zinc-100 text-zinc-600 px-2 py-1 rounded-full">Legacy</span>
</div>
<div class="p-6">
<a href="https://suiteql.s3.amazonaws.com/query-tool/suiteql-query-tool.v20211027.suitelet.js.zip" class="text-zinc-500 hover:text-zinc-700 hover:underline text-sm">Download Archive</a>
</div>
</div>
</div>
<!-- ABOUT TAB -->
<div id="view-about" class="view">
<div class="bg-white border border-zinc-200 rounded-xl p-8 shadow-sm">
<div class="flex items-start justify-between">
<div>
<h2 class="text-lg font-semibold text-zinc-900">Mosses Ross</h2>
<p class="text-zinc-500 text-sm">Technical Consultant @ Metafygx</p>
</div>
<div class="flex space-x-2">
<a href="https://github.com/MossesRoss" target="_blank" class="p-2 text-zinc-400 hover:text-zinc-900 transition-colors">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
</a>
</div>
</div>
<p class="text-zinc-600 mt-4 text-sm leading-relaxed">
Originally created by <span class="font-medium text-zinc-800">Tim Dietrich</span>. Reconstructed with help from <span class="font-medium text-zinc-800">Yogan Sriram</span>.
</p>
<div class="mt-6 flex gap-3">
<a href="https://github.com/MossesRoss/SuiteQL-Query-Tool" target="_blank" class="text-sm font-medium text-zinc-600 hover:text-zinc-900 border border-zinc-200 px-4 py-2 rounded-lg hover:bg-zinc-50 transition-colors">
Contribute Code
</a>
</div>
</div>
</div>
</main>
</div>
<script>
function switchTab(tabId) {
document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active'));
document.getElementById(`nav-${tabId}`).classList.add('active');
document.querySelectorAll('.view').forEach(el => el.classList.remove('active'));
document.getElementById(`view-${tabId}`).classList.add('active');
}
document.addEventListener('DOMContentLoaded', () => {
const downloadLink = document.getElementById('downloadLink');
if (downloadLink) {
downloadLink.download = 'suiteql-tool-sl.js';
downloadLink.href = 'https://raw.githubusercontent.com/MossesRoss/SuiteQL-Tool/main/suiteql-tool-sl.js';
downloadLink.addEventListener('click', async (e) => {
e.preventDefault();
const originalContent = downloadLink.innerHTML;
downloadLink.innerHTML = `<div class="flex items-center"><svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Downloading...</div>`;
try {
const response = await fetch(downloadLink.href);
if (!response.ok) throw new Error('Network error');
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.href = url;
tempLink.setAttribute('download', 'suiteql-tool-sl.js');
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
window.URL.revokeObjectURL(url);
downloadLink.innerHTML = `<div class="flex items-center">Download Complete</div>`;
setTimeout(() => { downloadLink.innerHTML = originalContent; }, 2000);
} catch (error) {
console.error('Download failed:', error);
window.open(downloadLink.href, '_blank');
downloadLink.innerHTML = originalContent;
}
});
}
});
</script>
</body>
</html>