Skip to content

Commit 51b3b31

Browse files
committed
Improve demo application
1 parent cdfc67a commit 51b3b31

File tree

2 files changed

+105
-32
lines changed

2 files changed

+105
-32
lines changed

docs/client-demo.html

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
brand: {
1818
DEFAULT: '#E14817',
1919
hover: '#C23E14'
20+
},
21+
terminal: {
22+
text: '#F2951C' /* Custom console font color */
2023
}
2124
}
2225
}
@@ -62,62 +65,84 @@
6265
display: flex;
6366
flex-direction: column;
6467
padding-bottom: 2rem;
65-
min-height: 0; /* Crucial for flex child to allow inner scrolling */
68+
min-height: 0;
6669
}
6770

6871
.terminal-container {
6972
flex: 1;
7073
display: flex;
7174
flex-direction: column;
72-
min-height: 0; /* Crucial for flex child to allow inner scrolling */
75+
min-height: 0;
7376
}
7477

7578
#console-log-text {
7679
flex: 1;
77-
overflow-y: auto; /* Enables vertical scrolling */
80+
overflow-y: auto;
7881
word-wrap: break-word;
7982
}
8083

8184
/* Prevent layout shift during auto-scroll */
8285
.log-entry {
8386
margin-bottom: 0.5rem;
84-
white-space: pre-wrap;
85-
word-break: break-all;
87+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
88+
}
89+
90+
/* Hide the default triangle marker for summary */
91+
summary::-webkit-details-marker {
92+
display: none;
93+
}
94+
summary {
95+
list-style: none;
8696
}
8797
</style>
8898
</head>
8999
<body class="bg-gray-50 font-sans text-gray-800">
90100

91-
<div class="main-container w-[1024px] max-w-[1024px] mx-auto pt-8 px-4">
101+
<div class="main-container w-[1024px] max-w-[1024px] mx-auto pt-6 px-4">
92102

93103
<!-- Header Section -->
94-
<div class="text-center mb-6 shrink-0">
104+
<div class="text-center mb-4 shrink-0">
95105
<h1 class="text-4xl font-extrabold text-gray-900 tracking-tight mb-2">
96-
<span class="block text-brand">Labs64</span>
97-
<a href="https://netlicensing.io/" target="_blank" class="hover:text-brand-hover transition-colors">
98-
NetLicensing JavaScript Client
106+
<a class="block text-brand" href="https://netlicensing.io/" target="_blank" class="hover:text-brand-hover transition-colors">
107+
Labs64 NetLicensing
99108
</a>
109+
<span class="block">JavaScript Client</span>
100110
</h1>
101-
<p class="mt-2 text-lg text-gray-500 max-w-2xl mx-auto">
111+
<p class="mt-1 text-base text-gray-500 max-w-2xl mx-auto">
102112
Interactive demo showcasing <a href="https://netlicensing.io/wiki/restful-api" target="_blank" class="text-brand hover:underline">RESTful API</a> access.
103113
</p>
104114
</div>
105115

106116
<!-- Controls Section -->
107-
<div class="flex justify-center gap-4 mb-6 shrink-0">
117+
<div class="flex justify-center gap-3 mb-4 shrink-0 flex-wrap">
108118
<button
109119
onclick="NetLicensingDemo()"
110-
class="inline-flex items-center px-6 py-2 border border-transparent text-base font-medium rounded-md shadow-sm text-white bg-brand hover:bg-brand-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand transition-colors duration-200">
111-
<svg class="w-5 h-5 mr-2 -ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
120+
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-brand hover:bg-brand-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand transition-colors duration-200">
121+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
112122
Execute Demo
113123
</button>
114124

115125
<button
116126
onclick="clearBox('console-log-text')"
117-
class="inline-flex items-center px-6 py-2 border border-gray-300 text-base font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand transition-colors duration-200 shadow-sm">
118-
<svg class="w-5 h-5 mr-2 -ml-1 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
127+
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none transition-colors duration-200 shadow-sm">
128+
<svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
119129
Clear Console
120130
</button>
131+
132+
<!-- New Navigability Buttons -->
133+
<button
134+
onclick="toggleAllLogs(true)"
135+
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none transition-colors duration-200 shadow-sm">
136+
<svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
137+
Expand All
138+
</button>
139+
140+
<button
141+
onclick="toggleAllLogs(false)"
142+
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none transition-colors duration-200 shadow-sm">
143+
<svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path></svg>
144+
Collapse All
145+
</button>
121146
</div>
122147

123148
<!-- Terminal Output Section -->
@@ -132,15 +157,27 @@ <h1 class="text-4xl font-extrabold text-gray-900 tracking-tight mb-2">
132157
<div class="mx-auto text-gray-400 text-xs font-mono">demo-output.log</div>
133158
</div>
134159

135-
<!-- Output container now takes up remaining screen height AND allows scrolling -->
136-
<div class="p-4 font-mono text-sm w-full" id="console-log-text">
137-
<div class="text-gray-500 mb-2">Ready. Click 'Execute Demo' to start the NetLicensing API simulation...</div>
160+
<!-- Output container -->
161+
<div class="p-4 text-sm w-full" id="console-log-text">
162+
<div class="text-gray-500 mb-2 font-mono">Ready. Click 'Execute Demo' to start the NetLicensing API simulation...</div>
138163
</div>
139164
</div>
140165
</div>
141166

142167
<!-- Intercept Console Output -->
143168
<script>
169+
// Helper function for the Expand/Collapse buttons
170+
function toggleAllLogs(expand) {
171+
const details = document.querySelectorAll('#console-log-text details');
172+
details.forEach(detail => {
173+
if (expand) {
174+
detail.setAttribute('open', '');
175+
} else {
176+
detail.removeAttribute('open');
177+
}
178+
});
179+
}
180+
144181
(function() {
145182
const oldLog = console.log;
146183
const oldError = console.error;
@@ -165,28 +202,64 @@ <h1 class="text-4xl font-extrabold text-gray-900 tracking-tight mb-2">
165202

166203
function appendLog(args, colorClass, prefixChar = '>') {
167204
const msg = formatArgs(args);
168-
const div = document.createElement('div');
169-
div.className = `log-entry ${colorClass}`;
205+
const lines = msg.split('\n');
206+
207+
// If it's a multi-line output (like an API JSON response), make it foldable
208+
if (lines.length > 1) {
209+
const details = document.createElement('details');
210+
details.className = `log-entry ${colorClass} group`;
211+
212+
const summary = document.createElement('summary');
213+
summary.className = 'cursor-pointer hover:opacity-80 transition-opacity outline-none flex items-start select-none';
214+
215+
// Arrow indicator that rotates when expanded
216+
const arrow = document.createElement('span');
217+
arrow.className = 'text-[#E14817] mr-2 font-bold transform transition-transform group-open:rotate-90 inline-block w-3 flex-shrink-0 text-center';
218+
arrow.textContent = prefixChar;
170219

171-
const prefix = document.createElement('span');
172-
prefix.className = 'text-[#E14817] mr-2 select-none font-bold';
173-
prefix.textContent = prefixChar;
220+
const summaryText = document.createElement('span');
221+
// Show the first line with an ellipsis, so the user knows there is hidden data
222+
summaryText.textContent = lines[0] + ' ...';
223+
summaryText.className = 'truncate';
174224

175-
div.appendChild(prefix);
176-
div.appendChild(document.createTextNode(msg));
225+
summary.appendChild(arrow);
226+
summary.appendChild(summaryText);
177227

178-
logger.appendChild(div);
228+
const content = document.createElement('div');
229+
// Indent the expanded JSON, add a subtle border on the left
230+
content.className = 'pl-4 ml-[0.35rem] border-l-2 border-gray-700 mt-1 whitespace-pre-wrap break-all opacity-90';
231+
content.textContent = lines.slice(1).join('\n');
232+
233+
details.appendChild(summary);
234+
details.appendChild(content);
235+
logger.appendChild(details);
236+
}
237+
// Single line output (like a basic string log)
238+
else {
239+
const div = document.createElement('div');
240+
div.className = `log-entry ${colorClass} flex items-start`;
241+
242+
const prefix = document.createElement('span');
243+
prefix.className = 'text-[#E14817] mr-2 select-none font-bold inline-block w-3 flex-shrink-0 text-center';
244+
prefix.textContent = prefixChar;
245+
246+
const text = document.createElement('span');
247+
text.className = 'whitespace-pre-wrap break-all';
248+
text.textContent = msg;
249+
250+
div.appendChild(prefix);
251+
div.appendChild(text);
252+
logger.appendChild(div);
253+
}
179254

180-
// Ensure the scroll goes all the way to the newly added item
181-
// Use requestAnimationFrame to ensure the DOM has updated before calculating height
182255
requestAnimationFrame(() => {
183256
logger.scrollTop = logger.scrollHeight;
184257
});
185258
}
186259

187260
console.log = function() {
188261
oldLog.apply(console, arguments);
189-
appendLog(arguments, 'text-green-400');
262+
appendLog(arguments, 'text-terminal-text');
190263
};
191264

192265
console.error = function() {
@@ -211,7 +284,7 @@ <h1 class="text-4xl font-extrabold text-gray-900 tracking-tight mb-2">
211284
window.clearBox = function(elementID) {
212285
const el = document.getElementById(elementID);
213286
if (el) {
214-
el.innerHTML = '<div class="text-gray-500 mb-2">Console cleared. Ready.</div>';
287+
el.innerHTML = '<div class="text-gray-500 mb-2 font-mono">Console cleared. Ready.</div>';
215288
}
216289
};
217290
})();

docs/client-demo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ const NetLicensingDemo = async () => {
301301

302302
// region ********* CleanUp
303303

304-
console.log('All done.');
304+
console.log('All done');
305305
await ProductService.delete(context, productNumber, true);
306306
// endregion
307307

0 commit comments

Comments
 (0)