ultimate-jekyll-manager 0.0.196 → 0.0.198
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.
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
// Libraries
|
|
6
6
|
import { FormManager } from '__main_assets__/js/libs/form-manager.js';
|
|
7
|
+
import fetch from 'wonderful-fetch';
|
|
7
8
|
|
|
8
9
|
let webManager = null;
|
|
9
10
|
|
|
@@ -21,6 +22,7 @@ export default (Manager) => {
|
|
|
21
22
|
initializeSubscribeForm();
|
|
22
23
|
initializeTooltips();
|
|
23
24
|
initializeRefreshTimer();
|
|
25
|
+
initializeBuildInfo();
|
|
24
26
|
|
|
25
27
|
// Fetch status data (if configured)
|
|
26
28
|
fetchStatusData();
|
|
@@ -41,6 +43,14 @@ const config = {
|
|
|
41
43
|
incidentsList: '#incidents-list',
|
|
42
44
|
incidentsEmpty: '#incidents-empty',
|
|
43
45
|
subscribeForm: '#status-subscribe-form',
|
|
46
|
+
buildInfoLoading: '#build-info-loading',
|
|
47
|
+
buildInfoContent: '#build-info-content',
|
|
48
|
+
buildInfoError: '#build-info-error',
|
|
49
|
+
buildTime: '#build-time',
|
|
50
|
+
buildTimeAgo: '#build-time-ago',
|
|
51
|
+
buildEnvironment: '#build-environment',
|
|
52
|
+
buildPackages: '#build-packages',
|
|
53
|
+
buildRepo: '#build-repo',
|
|
44
54
|
},
|
|
45
55
|
// Maps status levels to Bootstrap bg-* classes
|
|
46
56
|
statusClasses: {
|
|
@@ -234,6 +244,148 @@ function initializeRefreshTimer() {
|
|
|
234
244
|
}, 1000);
|
|
235
245
|
}
|
|
236
246
|
|
|
247
|
+
// Initialize build info section
|
|
248
|
+
async function initializeBuildInfo() {
|
|
249
|
+
const $loading = document.querySelector(config.selectors.buildInfoLoading);
|
|
250
|
+
const $content = document.querySelector(config.selectors.buildInfoContent);
|
|
251
|
+
const $error = document.querySelector(config.selectors.buildInfoError);
|
|
252
|
+
|
|
253
|
+
if (!$loading || !$content) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
// Fetch build.json
|
|
259
|
+
const data = await fetch(`${window.location.origin}/build.json`, {
|
|
260
|
+
response: 'json',
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
console.log('Build info data:', data);
|
|
264
|
+
|
|
265
|
+
// Normalize the data structure
|
|
266
|
+
const buildData = {
|
|
267
|
+
timestamp: data.timestamp || null,
|
|
268
|
+
environment: data.environment || (data.serving ? 'development' : 'production'),
|
|
269
|
+
packages: data.packages || null,
|
|
270
|
+
repo: data.repo || null,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// Test older dates
|
|
274
|
+
// buildData.timestamp = Date.now() - 1000 * 60 * 60 * 24 * 7;
|
|
275
|
+
|
|
276
|
+
displayBuildInfo(buildData);
|
|
277
|
+
$loading.classList.add('d-none');
|
|
278
|
+
$content.classList.remove('d-none');
|
|
279
|
+
} catch (error) {
|
|
280
|
+
console.error('Failed to load build info:', error);
|
|
281
|
+
$loading.classList.add('d-none');
|
|
282
|
+
if ($error) {
|
|
283
|
+
$error.classList.remove('d-none');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Display build information
|
|
289
|
+
function displayBuildInfo(data) {
|
|
290
|
+
const $time = document.querySelector(config.selectors.buildTime);
|
|
291
|
+
const $timeAgo = document.querySelector(config.selectors.buildTimeAgo);
|
|
292
|
+
const $environment = document.querySelector(config.selectors.buildEnvironment);
|
|
293
|
+
const $packages = document.querySelector(config.selectors.buildPackages);
|
|
294
|
+
const $repo = document.querySelector(config.selectors.buildRepo);
|
|
295
|
+
|
|
296
|
+
// Build time
|
|
297
|
+
if ($time && data.timestamp) {
|
|
298
|
+
const buildDate = new Date(data.timestamp);
|
|
299
|
+
$time.textContent = buildDate.toLocaleString('en-US', {
|
|
300
|
+
weekday: 'short',
|
|
301
|
+
year: 'numeric',
|
|
302
|
+
month: 'short',
|
|
303
|
+
day: 'numeric',
|
|
304
|
+
hour: 'numeric',
|
|
305
|
+
minute: '2-digit',
|
|
306
|
+
hour12: true,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Time ago (and keep it updated every second)
|
|
311
|
+
if ($timeAgo && data.timestamp) {
|
|
312
|
+
updateTimeAgo($timeAgo, data.timestamp);
|
|
313
|
+
setInterval(() => updateTimeAgo($timeAgo, data.timestamp), 1000);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Environment
|
|
317
|
+
if ($environment && data.environment) {
|
|
318
|
+
const envText = data.environment.charAt(0).toUpperCase() + data.environment.slice(1);
|
|
319
|
+
const envClass = data.environment === 'production' ? 'text-success' : 'text-warning';
|
|
320
|
+
$environment.innerHTML = `<span class="${envClass}">${escapeHtml(envText)}</span>`;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Packages
|
|
324
|
+
if ($packages && data.packages) {
|
|
325
|
+
const packageBadges = Object.entries(data.packages)
|
|
326
|
+
.map(([name, version]) => {
|
|
327
|
+
return `<span class="badge bg-body-secondary text-body fw-normal">${escapeHtml(name)}: <span class="fw-semibold">${escapeHtml(version)}</span></span>`;
|
|
328
|
+
})
|
|
329
|
+
.join('');
|
|
330
|
+
$packages.innerHTML = packageBadges;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Repository
|
|
334
|
+
if ($repo && data.repo) {
|
|
335
|
+
const repoUrl = `https://github.com/${data.repo.user}/${data.repo.name}`;
|
|
336
|
+
$repo.innerHTML = `<a href="${repoUrl}" target="_blank" rel="noopener noreferrer" class="text-decoration-none">${escapeHtml(data.repo.user)}/${escapeHtml(data.repo.name)}</a>`;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Update relative time display
|
|
341
|
+
function updateTimeAgo($element, timestamp) {
|
|
342
|
+
const buildDate = new Date(timestamp);
|
|
343
|
+
const now = new Date();
|
|
344
|
+
const diffMs = now - buildDate;
|
|
345
|
+
const totalSeconds = Math.floor(diffMs / 1000);
|
|
346
|
+
|
|
347
|
+
if (totalSeconds <= 0) {
|
|
348
|
+
$element.textContent = 'Just now';
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Calculate each unit
|
|
353
|
+
const years = Math.floor(totalSeconds / (365 * 24 * 60 * 60));
|
|
354
|
+
const months = Math.floor((totalSeconds % (365 * 24 * 60 * 60)) / (30 * 24 * 60 * 60));
|
|
355
|
+
const days = Math.floor((totalSeconds % (30 * 24 * 60 * 60)) / (24 * 60 * 60));
|
|
356
|
+
const hours = Math.floor((totalSeconds % (24 * 60 * 60)) / (60 * 60));
|
|
357
|
+
const minutes = Math.floor((totalSeconds % (60 * 60)) / 60);
|
|
358
|
+
const seconds = totalSeconds % 60;
|
|
359
|
+
|
|
360
|
+
// Build parts - once we start, include all remaining units
|
|
361
|
+
const parts = [];
|
|
362
|
+
let started = false;
|
|
363
|
+
|
|
364
|
+
if (years > 0) {
|
|
365
|
+
parts.push(`${years}y`);
|
|
366
|
+
started = true;
|
|
367
|
+
}
|
|
368
|
+
if (started || months > 0) {
|
|
369
|
+
parts.push(`${months}mo`);
|
|
370
|
+
started = true;
|
|
371
|
+
}
|
|
372
|
+
if (started || days > 0) {
|
|
373
|
+
parts.push(`${days}d`);
|
|
374
|
+
started = true;
|
|
375
|
+
}
|
|
376
|
+
if (started || hours > 0) {
|
|
377
|
+
parts.push(`${hours}h`);
|
|
378
|
+
started = true;
|
|
379
|
+
}
|
|
380
|
+
if (started || minutes > 0) {
|
|
381
|
+
parts.push(`${minutes}m`);
|
|
382
|
+
started = true;
|
|
383
|
+
}
|
|
384
|
+
parts.push(`${seconds}s`);
|
|
385
|
+
|
|
386
|
+
$element.textContent = parts.join(' ') + ' ago';
|
|
387
|
+
}
|
|
388
|
+
|
|
237
389
|
// Fetch status data from API (if configured)
|
|
238
390
|
function fetchStatusData() {
|
|
239
391
|
// Check if there's a status API endpoint configured
|
package/dist/defaults/Gemfile
CHANGED
|
@@ -34,7 +34,7 @@ gem "wdm", "~> 0.1.0" if Gem.win_platform?
|
|
|
34
34
|
gem "logger"
|
|
35
35
|
|
|
36
36
|
# Parallel processing for faster builds
|
|
37
|
-
gem 'parallel'
|
|
37
|
+
# gem 'parallel'
|
|
38
38
|
|
|
39
39
|
# Fix x86_64 / arm64e error
|
|
40
40
|
# /Users/ian/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/redcarpet-3.6.0/lib/redcarpet.rb:1:in `require': dlopen(/Users/ian/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/redcarpet-3.6.0/lib/redcarpet.bundle, 0x0009): tried: '/Users/ian/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/redcarpet-3.6.0/lib/redcarpet.bundle' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))) - /Users/ian/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/redcarpet-3.6.0/lib/redcarpet.bundle (LoadError)
|
|
@@ -58,6 +58,10 @@ incidents:
|
|
|
58
58
|
empty_message: "No incidents reported"
|
|
59
59
|
show_history_link: "Show incident history"
|
|
60
60
|
history_url: null # Optional: Link to full incident history
|
|
61
|
+
|
|
62
|
+
# Build Info Section
|
|
63
|
+
build_info:
|
|
64
|
+
headline: "Build information"
|
|
61
65
|
---
|
|
62
66
|
|
|
63
67
|
<!-- Hero Section with Status Banner -->
|
|
@@ -275,6 +279,95 @@ incidents:
|
|
|
275
279
|
</div>
|
|
276
280
|
</section>
|
|
277
281
|
|
|
282
|
+
<!-- Build Info Section -->
|
|
283
|
+
<section class="py-5">
|
|
284
|
+
<div class="container">
|
|
285
|
+
<div class="row justify-content-center">
|
|
286
|
+
<div class="col-lg-10">
|
|
287
|
+
<h2 class="h4 mb-4" data-lazy="@class animation-slide-up">{{ page.resolved.build_info.headline }}</h2>
|
|
288
|
+
|
|
289
|
+
<div id="build-info" class="card border-0 bg-body-tertiary" data-lazy="@class animation-slide-up">
|
|
290
|
+
<div class="card-body p-4">
|
|
291
|
+
<!-- Loading state -->
|
|
292
|
+
<div id="build-info-loading" class="text-center text-muted py-3">
|
|
293
|
+
<div class="spinner-border spinner-border-sm me-2" role="status">
|
|
294
|
+
<span class="visually-hidden">Loading...</span>
|
|
295
|
+
</div>
|
|
296
|
+
Loading build information...
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<!-- Content (hidden until loaded) -->
|
|
300
|
+
<div id="build-info-content" class="d-none">
|
|
301
|
+
<div class="row g-4">
|
|
302
|
+
<!-- Build Time -->
|
|
303
|
+
<div class="col-md-6">
|
|
304
|
+
<div class="d-flex align-items-start gap-3">
|
|
305
|
+
<div class="avatar avatar-sm bg-primary bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center flex-shrink-0">
|
|
306
|
+
{% uj_icon "clock", "text-primary" %}
|
|
307
|
+
</div>
|
|
308
|
+
<div>
|
|
309
|
+
<div class="text-muted small mb-1">Last Build</div>
|
|
310
|
+
<div id="build-time" class="fw-semibold">—</div>
|
|
311
|
+
<div id="build-time-ago" class="text-muted small">—</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<!-- Environment -->
|
|
317
|
+
<div class="col-md-6">
|
|
318
|
+
<div class="d-flex align-items-start gap-3">
|
|
319
|
+
<div class="avatar avatar-sm bg-info bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center flex-shrink-0">
|
|
320
|
+
{% uj_icon "server", "text-info" %}
|
|
321
|
+
</div>
|
|
322
|
+
<div>
|
|
323
|
+
<div class="text-muted small mb-1">Environment</div>
|
|
324
|
+
<div id="build-environment" class="fw-semibold">—</div>
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
|
|
329
|
+
<!-- Packages -->
|
|
330
|
+
<div class="col-12">
|
|
331
|
+
<div class="d-flex align-items-start gap-3">
|
|
332
|
+
<div class="avatar avatar-sm bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center flex-shrink-0">
|
|
333
|
+
{% uj_icon "box", "text-success" %}
|
|
334
|
+
</div>
|
|
335
|
+
<div class="flex-grow-1">
|
|
336
|
+
<div class="text-muted small mb-2">Package Versions</div>
|
|
337
|
+
<div id="build-packages" class="d-flex flex-wrap gap-2">
|
|
338
|
+
<!-- Package badges will be inserted here -->
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<!-- Repository -->
|
|
345
|
+
<div class="col-12">
|
|
346
|
+
<div class="d-flex align-items-start gap-3">
|
|
347
|
+
<div class="avatar avatar-sm bg-secondary bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center flex-shrink-0">
|
|
348
|
+
{% uj_icon "code-branch", "text-secondary" %}
|
|
349
|
+
</div>
|
|
350
|
+
<div>
|
|
351
|
+
<div class="text-muted small mb-1">Repository</div>
|
|
352
|
+
<div id="build-repo" class="fw-semibold">—</div>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
359
|
+
<!-- Error state -->
|
|
360
|
+
<div id="build-info-error" class="d-none text-center text-muted py-3">
|
|
361
|
+
{% uj_icon "circle-exclamation", "fs-3 mb-2 text-warning opacity-75" %}
|
|
362
|
+
<p class="mb-0">Unable to load build information</p>
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</section>
|
|
370
|
+
|
|
278
371
|
<!-- Footer Links -->
|
|
279
372
|
<section class="py-5 pt-1">
|
|
280
373
|
<div class="container">
|