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
@@ -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">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "0.0.196",
3
+ "version": "0.0.198",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {