Compare commits

..

13 Commits

Author SHA1 Message Date
Raj Nandan Sharma 5f33c02064 Merge pull request #222 from rajnandan1/release/3.0.4
Release/3.0.4
2025-01-25 21:43:05 +05:30
Raj Nandan Sharma 46c1a392b8 refactor: remove docs from docker build 2025-01-25 21:41:11 +05:30
Raj Nandan Sharma c6880c5df6 feat: sitemap and bug fixes 2025-01-25 21:18:42 +05:30
Raj Nandan Sharma 646da94ef9 feat: sitemap and bug fixes 2025-01-25 21:16:17 +05:30
Raj Nandan Sharma 36ede93dce feat: sitemap and bug fixes 2025-01-25 21:12:41 +05:30
Raj Nandan Sharma 9ed35589f7 Merge pull request #220 from rajnandan1/release/3.0.3
fix: load time #219
2025-01-24 21:45:33 +05:30
Raj Nandan Sharma e946dd18e0 fix: load time #219 2025-01-24 21:44:36 +05:30
Raj Nandan Sharma 51cad598c1 fix: load time #219 2025-01-24 21:42:57 +05:30
Raj Nandan Sharma 0595f23c18 Merge pull request #218 from cosmic-jellyfish/feature/ENG-Locale-Fix
English Locale tweaks
2025-01-24 13:04:58 +05:30
Raj Nandan Sharma b88816706b fix: retry await decrease from 4000 to 500ms 2025-01-24 11:42:06 +05:30
Cake 80edaae023 fix: update localisation strings across the board 2025-01-24 17:08:09 +11:00
Cake 468d7f445d fix: update localisation strings further 2025-01-24 15:15:13 +11:00
Cake 4cc74deece fix: update localisation strings 2025-01-24 15:11:50 +11:00
27 changed files with 195 additions and 69 deletions
+3
View File
@@ -30,6 +30,9 @@ RUN npm install && npm cache clean --force
# Copy the rest of the application code
COPY . .
# remove dir src/routes/(docs)
RUN rm -rf src/routes/\(docs\)
# Ensure /app/uploads and /app/database have rw permissions
RUN mkdir -p /app/uploads /app/database && \
chmod -R 777 /app/uploads /app/database
+2 -2
View File
@@ -1,6 +1,6 @@
---
title: Kener - A Sveltekit NodeJS Status Page System
description: Kener is an open-source Node.js status page tool, designed to make service monitoring and incident handling a breeze. It offers a sleek and user-friendly interface that simplifies tracking service outages and improves how we communicate during incidents.
title: Kener Documentation
description: Kener is a feature-rich and modern status page system built with SvelteKit and NodeJS. It is open-source and free to use.
---
# Kener - A Feature Rich & Modern Status Page
+3 -3
View File
@@ -59,7 +59,7 @@ Copy and update the translation file in the `locales` folder. The translation fi
"MONITORING": "MONITORING",
"No Data": "No Data",
"No Incidents": "No Incidents",
"No Incident On %date": "No Incident On %date",
"No Incident in %date": "No Incident in %date",
"No Monitor Found": "No Monitor Found",
"No Updates Yet": "No Updates Yet",
"Ongoing Incidents": "Ongoing Incidents",
@@ -69,8 +69,8 @@ Copy and update the translation file in the `locales` folder. The translation fi
"Share": "Share",
"Share this monitor using a link with others": "Share this monitor using a link with others",
"Standard": "Standard",
"Started about %startedAt ago, lasted for about %lastedFor": "Started about %startedAt ago, lasted for about %lastedFor",
"Started about %startedAt ago, still ongoing": "Started about %startedAt ago, still ongoing",
"Started about %startedAt, lasted for about %lastedFor": "Started about %startedAt, lasted for about %lastedFor",
"Started about %startedAt, still ongoing": "Started about %startedAt, still ongoing",
"Starts in %startedAt": "Starts in %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Starts in %startedAt, will last for about %lastedFor",
"Status": "Status",
+1 -1
View File
@@ -26,7 +26,7 @@ description: Roadmap for Kener
~~Handle uploaded images for docker containers~~
Introduce sitemap.xml
~~Introduce sitemap.xml~~
~~Migrate from moment to date-fns for status page~~ (moment remains in dashboard. Will remove later)
+5
View File
@@ -4,6 +4,7 @@ import dotenv from "dotenv";
dotenv.config();
import express from "express";
import Startup from "./src/lib/server/startup.js";
import { GetSiteMap } from "./src/lib/server/controllers/controller.js";
import fs from "fs-extra";
import knex from "knex";
import knexOb from "./knexfile.js";
@@ -24,6 +25,10 @@ app.use((req, res, next) => {
app.get(base + "/healthcheck", (req, res) => {
res.end("ok");
});
app.get(base + "/sitemap.xml", async (req, res) => {
res.header("Content-Type", "application/xml");
res.send(await GetSiteMap());
});
//part /uploads server static files from static/uploads
//set env variable for upload path
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kener",
"version": "3.0.2",
"version": "3.0.4",
"private": false,
"license": "MIT",
"description": "Kener: An open-source Node.js status page application for real-time service monitoring, incident management, and customizable reporting. Simplify service outage tracking, enhance incident communication, and ensure a seamless user experience.",
+2 -2
View File
@@ -45,7 +45,7 @@
>
{#if !isFuture && incident.state != "RESOLVED"}
<span>
{l(lang, "Started about %startedAt ago, still ongoing", {
{l(lang, "Started about %startedAt, still ongoing", {
startedAt
})}
</span>
@@ -53,7 +53,7 @@
<span>
{l(
lang,
"Started about %startedAt ago, lasted for about %lastedFor",
"Started about %startedAt, lasted for about %lastedFor",
{ startedAt, lastedFor }
)}
</span>
+1 -4
View File
@@ -169,10 +169,7 @@
{l(lang, "Embed")}
</h2>
<p class="mb-1 text-xs text-muted-foreground">
{@html l(
lang,
"Embed this moni2tor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app."
)}
{l(lang, "Embed this monitor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app.")}
</p>
<div class="mb-4 grid grid-cols-2 gap-2">
<div class="col-span-1">
+1 -9
View File
@@ -27,15 +27,8 @@ const fdm = function (duration, locale) {
};
const l = function (sessionLangMap, key, args = {}) {
const keys = key.split(".");
let obj = sessionLangMap;
let obj = sessionLangMap[key];
for (const keyPart of keys) {
obj = obj?.[keyPart];
if (!obj) {
break;
}
}
// Replace placeholders in the string using the args object
if (obj && typeof obj === "string") {
obj = obj.replace(/%\w+/g, (placeholder) => {
@@ -43,7 +36,6 @@ const l = function (sessionLangMap, key, args = {}) {
return args[argKey] !== undefined ? args[argKey] : placeholder;
});
}
return obj || key;
};
const summaryTime = function (summaryStatus) {
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "ÜBERWACHUNG",
"No Data": "Keine Daten",
"No Incidents": "Keine Vorfälle",
"No Incident On %date": "Kein Vorfall am %date",
"No Incident in %date": "Kein Vorfall am %date",
"No Monitor Found": "Kein Monitor gefunden",
"No Updates Yet": "Noch keine Updates",
"Ongoing Incidents": "Laufende Vorfälle",
@@ -40,8 +40,8 @@
"Share": "Teilen",
"Share this monitor using a link with others": "Teilen Sie diesen Monitor mit einem Link mit anderen",
"Standard": "Standard",
"Started about %startedAt ago, lasted for about %lastedFor": "Begann vor etwa %startedAt und dauerte etwa %lastedFor",
"Started about %startedAt ago, still ongoing": "Begann vor etwa %startedAt und dauert noch an",
"Started about %startedAt, lasted for about %lastedFor": "Begann vor etwa %startedAt und dauerte etwa %lastedFor",
"Started about %startedAt, still ongoing": "Begann vor etwa %startedAt und dauert noch an",
"Starts in %startedAt": "Beginnt in %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Beginnt in %startedAt und wird etwa %lastedFor dauern",
"Status": "Status",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "OVERVÅGNING",
"No Data": "Ingen Data",
"No Incidents": "Ingen Hændelser",
"No Incident On %date": "Ingen Hændelse Den %date",
"No Incident in %date": "Ingen Hændelse Den %date",
"No Monitor Found": "Ingen Monitor Fundet",
"No Updates Yet": "Ingen Opdateringer Endnu",
"Ongoing Incidents": "Igangværende Hændelser",
@@ -40,8 +40,8 @@
"Share": "Del",
"Share this monitor using a link with others": "Del denne monitor ved hjælp af et link med andre",
"Standard": "Standard",
"Started about %startedAt ago, lasted for about %lastedFor": "Startede for cirka %startedAt siden, varede i cirka %lastedFor",
"Started about %startedAt ago, still ongoing": "Startede for cirka %startedAt siden, stadig igangværende",
"Started about %startedAt, lasted for about %lastedFor": "Startede for cirka %startedAt siden, varede i cirka %lastedFor",
"Started about %startedAt, still ongoing": "Startede for cirka %startedAt siden, stadig igangværende",
"Starts in %startedAt": "Starter om %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Starter om %startedAt, vil vare i cirka %lastedFor",
"Status": "Status",
+5 -5
View File
@@ -30,7 +30,7 @@
"MONITORING": "MONITORING",
"No Data": "No Data",
"No Incidents": "No Incidents",
"No Incident On %date": "No Incident On %date",
"No Incident in %date": "No Incident in %date",
"No Monitor Found": "No Monitor Found",
"No Updates Yet": "No Updates Yet",
"Ongoing Incidents": "Ongoing Incidents",
@@ -40,10 +40,10 @@
"Share": "Share",
"Share this monitor using a link with others": "Share this monitor using a link with others",
"Standard": "Standard",
"Started about %startedAt ago, lasted for about %lastedFor": "Started about %startedAt ago, lasted for about %lastedFor",
"Started about %startedAt ago, still ongoing": "Started about %startedAt ago, still ongoing",
"Started about %startedAt, lasted for about %lastedFor": "Started %startedAt, lasted for about %lastedFor",
"Started about %startedAt, still ongoing": "Started %startedAt, still ongoing",
"Starts in %startedAt": "Starts in %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Starts in %startedAt, will last for about %lastedFor",
"Starts in %startedAt, will last for about %lastedFor": "Starts in %startedAt, will last for %lastedFor",
"Status": "Status",
"Status OK": "Status OK",
"Theme": "Theme",
@@ -52,4 +52,4 @@
"Updates": "Updates",
"Uptime": "Uptime",
"%status for %duration": "%status for %duration"
}
}
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "En surveillance",
"No Data": "Pas de données",
"No Incidents": "Pas d'incidents",
"No Incident On %date": "Pas d'incident le %date",
"No Incident in %date": "Pas d'incident le %date",
"No Monitor Found": "Aucun moniteur trouvé",
"No Updates Yet": "Pas encore de mises à jour",
"Ongoing Incidents": "Incidents en cours",
@@ -40,8 +40,8 @@
"Share": "Partager",
"Share this monitor using a link with others": "Partagez ce moniteur avec un lien à d'autres personnes",
"Standard": "Standard",
"Started about %startedAt ago, lasted for about %lastedFor": "Commencé il y a environ %startedAt, a duré environ %lastedFor",
"Started about %startedAt ago, still ongoing": "Commencé il y a environ %startedAt, toujours en cours",
"Started about %startedAt, lasted for about %lastedFor": "Commencé il y a environ %startedAt, a duré environ %lastedFor",
"Started about %startedAt, still ongoing": "Commencé il y a environ %startedAt, toujours en cours",
"Starts in %startedAt": "Commence dans %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Commence dans %startedAt, durera environ %lastedFor",
"Status": "Statut",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "निगरानी",
"No Data": "कोई डेटा नहीं",
"No Incidents": "कोई घटना नहीं",
"No Incident On %date": "%date को कोई घटना नहीं",
"No Incident in %date": "%date को कोई घटना नहीं",
"No Monitor Found": "कोई मॉनिटर नहीं मिला",
"No Updates Yet": "अभी तक कोई अपडेट नहीं",
"Ongoing Incidents": "चल रही घटनाएँ",
@@ -40,8 +40,8 @@
"Share": "साझा करें",
"Share this monitor using a link with others": "इस मॉनिटर को दूसरों के साथ लिंक के माध्यम से साझा करें",
"Standard": "मानक",
"Started about %startedAt ago, lasted for about %lastedFor": "लगभग %startedAt पहले शुरू हुआ, लगभग %lastedFor तक चला",
"Started about %startedAt ago, still ongoing": "लगभग %startedAt पहले शुरू हुआ, अभी भी जारी है",
"Started about %startedAt, lasted for about %lastedFor": "लगभग %startedAt पहले शुरू हुआ, लगभग %lastedFor तक चला",
"Started about %startedAt, still ongoing": "लगभग %startedAt पहले शुरू हुआ, अभी भी जारी है",
"Starts in %startedAt": "%startedAt में शुरू होगा",
"Starts in %startedAt, will last for about %lastedFor": "%startedAt में शुरू होगा, लगभग %lastedFor तक चलेगा",
"Status": "स्थिति",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "モニタリング中",
"No Data": "データなし",
"No Incidents": "インシデントなし",
"No Incident On %date": "%date にインシデントなし",
"No Incident in %date": "%date にインシデントなし",
"No Monitor Found": "モニターが見つかりません",
"No Updates Yet": "まだ更新はありません",
"Ongoing Incidents": "進行中のインシデント",
@@ -40,8 +40,8 @@
"Share": "共有",
"Share this monitor using a link with others": "このモニターをリンクで他の人と共有",
"Standard": "標準",
"Started about %startedAt ago, lasted for about %lastedFor": "%startedAt 前に開始し、約 %lastedFor 続きました",
"Started about %startedAt ago, still ongoing": "%startedAt 前に開始し、まだ進行中です",
"Started about %startedAt, lasted for about %lastedFor": "%startedAt 前に開始し、約 %lastedFor 続きました",
"Started about %startedAt, still ongoing": "%startedAt 前に開始し、まだ進行中です",
"Starts in %startedAt": "%startedAt 後に開始",
"Starts in %startedAt, will last for about %lastedFor": "%startedAt 後に開始し、約 %lastedFor 続きます",
"Status": "ステータス",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "감시 중",
"No Data": "데이터 없음",
"No Incidents": "사건 없음",
"No Incident On %date": "%date 에는 아무 사건도 없었음",
"No Incident in %date": "%date 에는 아무 사건도 없었음",
"No Monitor Found": "모니터링 항목을 찾을 수 없음",
"No Updates Yet": "아직 아무 업데이트도 없음",
"Ongoing Incidents": "진행중 사건",
@@ -40,8 +40,8 @@
"Share": "공유",
"Share this monitor using a link with others": "링크를 사용하여 다른 사람들과 이 모니터링 데이터를 공유해보세요",
"Standard": "기본",
"Started about %startedAt ago, lasted for about %lastedFor": "%startedAt 전에 시작되었으며, %lastedFor 동안 지속되었습니다",
"Started about %startedAt ago, still ongoing": "%startedAt 전에 시작되었으며, 아직 진행중입니다",
"Started about %startedAt, lasted for about %lastedFor": "%startedAt 전에 시작되었으며, %lastedFor 동안 지속되었습니다",
"Started about %startedAt, still ongoing": "%startedAt 전에 시작되었으며, 아직 진행중입니다",
"Starts in %startedAt": "%startedAt 에 시작되었습니다",
"Starts in %startedAt, will last for about %lastedFor": "%startedAt 전에 시작되었으며, %lastedFor 까지 지속될 예정입니다",
"Status": "상태",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "MONITOREN",
"No Data": "Geen gegevens",
"No Incidents": "Geen incidenten",
"No Incident On %date": "Geen incident op %date",
"No Incident in %date": "Geen incident op %date",
"No Monitor Found": "Geen monitor gevonden",
"No Updates Yet": "Nog geen updates",
"Ongoing Incidents": "Lopende incidenten",
@@ -40,8 +40,8 @@
"Share": "Delen",
"Share this monitor using a link with others": "Deel deze monitor met anderen via een link",
"Standard": "Standaard",
"Started about %startedAt ago, lasted for about %lastedFor": "Begonnen ongeveer %startedAt geleden, duurde ongeveer %lastedFor",
"Started about %startedAt ago, still ongoing": "Begonnen ongeveer %startedAt geleden, nog steeds bezig",
"Started about %startedAt, lasted for about %lastedFor": "Begonnen ongeveer %startedAt geleden, duurde ongeveer %lastedFor",
"Started about %startedAt, still ongoing": "Begonnen ongeveer %startedAt geleden, nog steeds bezig",
"Starts in %startedAt": "Begint over %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Begint over %startedAt, zal ongeveer %lastedFor duren",
"Status": "Status",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "MONITORANDO",
"No Data": "Sem dados",
"No Incidents": "Sem Incidentes",
"No Incident On %date": "Nenhum incidente em %date",
"No Incident in %date": "Nenhum incidente em %date",
"No Monitor Found": "Nenhum monitor encontrado",
"No Updates Yet": "Nenhuma atualização ainda",
"Ongoing Incidents": "Incidentes em Andamento",
@@ -40,8 +40,8 @@
"Share": "Compartilhar",
"Share this monitor using a link with others": "Compartilhar este monitor através do link",
"Standard": "Padrão",
"Started about %startedAt ago, lasted for about %lastedFor": "Iniciado há cerca de %startedAt e durou aproximadamente %lastedFor",
"Started about %startedAt ago, still ongoing": "Iniciado há cerca de %startedAt, ainda em andamento",
"Started about %startedAt, lasted for about %lastedFor": "Iniciado há cerca de %startedAt e durou aproximadamente %lastedFor",
"Started about %startedAt, still ongoing": "Iniciado há cerca de %startedAt, ainda em andamento",
"Starts in %startedAt": "Inicia em %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Inícia em %startedAt, com duração de aproximadamente %lastedFor",
"Status": "Status",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "МОНИТОРИНГ",
"No Data": "Нет данных",
"No Incidents": "Нет инцидентов",
"No Incident On %date": "Нет инцидентов на %date",
"No Incident in %date": "Нет инцидентов на %date",
"No Monitor Found": "Монитор не найден",
"No Updates Yet": "Пока нет обновлений",
"Ongoing Incidents": "Текущие инциденты",
@@ -40,8 +40,8 @@
"Share": "Поделиться",
"Share this monitor using a link with others": "Поделитесь этим монитором с другими по ссылке",
"Standard": "Стандартная",
"Started about %startedAt ago, lasted for about %lastedFor": "Началось около %startedAt назад, длилось около %lastedFor",
"Started about %startedAt ago, still ongoing": "Началось около %startedAt назад, все еще продолжается",
"Started about %startedAt, lasted for about %lastedFor": "Началось около %startedAt назад, длилось около %lastedFor",
"Started about %startedAt, still ongoing": "Началось около %startedAt назад, все еще продолжается",
"Starts in %startedAt": "Начнется через %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Начнется через %startedAt, продлится около %lastedFor",
"Status": "Статус",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "Đang giám sát",
"No Data": "Không có dữ liệu",
"No Incidents": "Không có sự cố",
"No Incident On %date": "Không có sự cố vào %date",
"No Incident in %date": "Không có sự cố vào %date",
"No Monitor Found": "Không tìm thấy trình theo dõi",
"No Updates Yet": "Chưa có cập nhật",
"Ongoing Incidents": "Sự cố đang diễn ra",
@@ -40,8 +40,8 @@
"Share": "Chia sẻ",
"Share this monitor using a link with others": "Chia sẻ trình theo dõi này với người khác bằng liên kết",
"Standard": "Tiêu chuẩn",
"Started about %startedAt ago, lasted for about %lastedFor": "Bắt đầu khoảng %startedAt trước, kéo dài khoảng %lastedFor",
"Started about %startedAt ago, still ongoing": "Bắt đầu khoảng %startedAt trước, vẫn đang diễn ra",
"Started about %startedAt, lasted for about %lastedFor": "Bắt đầu khoảng %startedAt trước, kéo dài khoảng %lastedFor",
"Started about %startedAt, still ongoing": "Bắt đầu khoảng %startedAt trước, vẫn đang diễn ra",
"Starts in %startedAt": "Bắt đầu trong %startedAt",
"Starts in %startedAt, will last for about %lastedFor": "Bắt đầu trong %startedAt, sẽ kéo dài khoảng %lastedFor",
"Status": "Trạng thái",
+3 -3
View File
@@ -30,7 +30,7 @@
"MONITORING": "正在监控",
"No Data": "无数据",
"No Incidents": "无事件",
"No Incident On %date": "%date 无事件",
"No Incident in %date": "%date 无事件",
"No Monitor Found": "未找到监控",
"No Updates Yet": "尚无更新",
"Ongoing Incidents": "正在处理的事件",
@@ -40,8 +40,8 @@
"Share": "分享",
"Share this monitor using a link with others": "通过链接与他人分享此监控",
"Standard": "标准",
"Started about %startedAt ago, lasted for about %lastedFor": "大约 %startedAt 前开始,持续了约 %lastedFor",
"Started about %startedAt ago, still ongoing": "大约 %startedAt 前开始,目前仍在进行中",
"Started about %startedAt, lasted for about %lastedFor": "大约 %startedAt 前开始,持续了约 %lastedFor",
"Started about %startedAt, still ongoing": "大约 %startedAt 前开始,目前仍在进行中",
"Starts in %startedAt": "%startedAt 后开始",
"Starts in %startedAt, will last for about %lastedFor": "%startedAt 后开始,将持续约 %lastedFor",
"Status": "状态",
+97 -1
View File
@@ -16,6 +16,7 @@ import db from "../db/db.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import crypto from "crypto";
import { format, subMonths, addMonths, startOfMonth } from "date-fns";
const saltRounds = 10;
const DUMMY_SECRET = "DUMMY_SECRET";
@@ -398,8 +399,13 @@ export const InterpolateData = (data, start, anchorStatus, e) => {
if (e) {
end = e;
}
let dataMap = data.reduce((acc, d) => {
acc[d.timestamp] = d;
return acc;
}, {});
for (let i = start; i <= end; i += 60) {
let nowData = data.find((d) => d.timestamp === i);
let nowData = dataMap[i];
if (!!nowData) {
status = nowData.status;
}
@@ -800,3 +806,93 @@ export const IsLoggedInSession = async (cookies) => {
user: userDB
};
};
export const GetSiteMap = async (cookies) => {
let siteMapData = [];
let siteURLData = await GetSiteDataByKey("siteURL");
let categories = await GetSiteDataByKey("categories");
let navs = await GetSiteDataByKey("nav");
if (!!siteURLData) {
siteMapData.push({
url: siteURLData,
lastmod: new Date().toISOString(),
priority: 1
});
}
//get today's date in January-2025 format date-fns
const today = format(new Date(), "MMMM-yyyy");
//last month
const lastMonth = format(subMonths(new Date(), 1), "MMMM-yyyy", { addMonths: -1 });
const nextMonth = format(addMonths(new Date(), 1), "MMMM-yyyy", { addMonths: -1 });
siteMapData.push({
url: siteURLData + "/incidents/" + today,
lastmod: startOfMonth(new Date()).toISOString(),
priority: 0.9
});
siteMapData.push({
url: siteURLData + "/incidents/" + lastMonth,
lastmod: startOfMonth(new Date()).toISOString(),
priority: 0.9
});
siteMapData.push({
url: siteURLData + "/incidents/" + nextMonth,
lastmod: startOfMonth(new Date()).toISOString(),
priority: 0.9
});
if (!!categories) {
for (let i = 0; i < categories.length; i++) {
if (categories[i].name !== "Home") {
siteMapData.push({
url: siteURLData + "?category=" + categories[i].name,
lastmod: new Date().toISOString(),
priority: 0.9
});
}
}
}
if (!!navs) {
for (let i = 0; i < navs.length; i++) {
if (navs[i].url.startsWith(siteURLData)) {
siteMapData.push({
url: navs[i].url,
lastmod: new Date().toISOString(),
priority: 0.9
});
} else if (navs[i].url.startsWith("/")) {
siteMapData.push({
url: siteURLData + navs[i].url,
lastmod: new Date().toISOString(),
priority: 0.9
});
}
}
}
let monitors = await GetMonitors({ status: "ACTIVE" });
for (let i = 0; i < monitors.length; i++) {
siteMapData.push({
url: siteURLData + "?monitor=" + monitors[i].tag,
lastmod: new Date(monitors[i].updated_at).toISOString(),
priority: 0.8
});
}
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${siteMapData
.map(
(page) => `
<url>
<loc>${page.url}</loc>
<lastmod>${page.lastmod}</lastmod>
<priority>${page.priority}</priority>
</url>
`
)
.join("")}
</urlset>`;
};
+1 -1
View File
@@ -342,7 +342,7 @@ const Minuter = async (monitor) => {
realTimeData[startOfMinute] = apiResponse;
if (apiResponse.type === TIMEOUT) {
apiQueue.push(async (cb) => {
await Wait(4000);
await Wait(500); //wait for 500ms
console.log(
"Retrying api call for " +
monitor.name +
+2 -1
View File
@@ -52,6 +52,7 @@
<svelte:window on:pagechange={pageChange} on:rightbar={updateTableOfContents} />
<svelte:head>
<title>Kener Documentation</title>
<link rel="icon" id="kener-app-favicon" href="{base}/logo96.png" />
<!-- Google tag (gtag.js) -->
@@ -86,7 +87,7 @@
<img src="https://kener.ing/logo.png" class="h-8 w-8" alt="" />
<span class="text-xl font-medium">Kener Documentation</span>
<span class="me-2 rounded border px-2.5 py-0.5 text-xs font-medium">
v3.0.2
v3.0.4
</span>
</a>
</div>
+19 -2
View File
@@ -6,11 +6,12 @@ import moment from "moment";
export async function load({ parent, url }) {
let monitors = await GetMonitors({ status: "ACTIVE" });
const query = url.searchParams;
const requiredCategory = query.get("category") || "Home";
const parentData = await parent();
const siteData = parentData.site;
let pageTitle = siteData.title;
let pageDescription = "";
monitors = SortMonitor(siteData.monitorSort, monitors);
const monitorsActive = [];
for (let i = 0; i < monitors.length; i++) {
@@ -51,6 +52,19 @@ export async function load({ parent, url }) {
//if not home page
let isCategoryPage = !!query.get("category") && query.get("category") !== "Home";
let isMonitorPage = !!query.get("monitor");
if (isMonitorPage && monitorsActive.length > 0) {
pageTitle = monitorsActive[0].name + " - " + pageTitle;
pageDescription = monitorsActive[0].description;
}
//if category page
if (isCategoryPage) {
let allCategories = siteData.categories;
let selectedCategory = allCategories.find((category) => category.name === requiredCategory);
if (selectedCategory) {
pageTitle = selectedCategory.name + " - " + pageTitle;
pageDescription = selectedCategory.description;
}
}
if (isCategoryPage || isMonitorPage) {
let eligibleTags = monitorsActive.map((monitor) => monitor.tag);
//filter incidents that have monitor_tag in monitors
@@ -85,11 +99,14 @@ export async function load({ parent, url }) {
return incident;
});
let unresolvedIncidents = allOpenIncidents.filter((incident) => incident.state !== "RESOLVED");
return {
monitors: monitorsActive,
unresolvedIncidents: allOpenIncidents,
categoryName: requiredCategory,
isCategoryPage: isCategoryPage,
isMonitorPage: isMonitorPage
isMonitorPage: isMonitorPage,
pageTitle: pageTitle,
pageDescription: pageDescription
};
}
+11 -3
View File
@@ -34,8 +34,10 @@
if (data.isCategoryPage) {
let category = data.site.categories.find((e) => e.name == data.categoryName);
data.site.hero.title = category.name;
data.site.hero.subtitle = category.description;
if (!!category) {
data.site.hero.title = category.name;
data.site.hero.subtitle = category.description;
}
}
onMount(() => {
@@ -43,6 +45,12 @@
});
</script>
<svelte:head>
<title>{data.pageTitle}</title>
{#if !!data.pageDescription}
<meta name="description" content={data.pageDescription} />
{/if}
</svelte:head>
<div class="mt-12"></div>
{#if data.site.hero && !data.isMonitorPage}
<section
@@ -183,7 +191,7 @@
window.location.href = `?category=${category.name}`;
}}
>
<Card.Root class="hover:bg-secondary">
<Card.Root class="mb-4 hover:bg-secondary">
<Card.Header class="bounce-right relative w-full cursor-pointer px-4 ">
<Card.Title class="w-full ">
{category.name}
@@ -50,6 +50,13 @@
let sortedIncidentSmartDates = Object.keys(incidentSmartDates).sort((a, b) => a - b);
</script>
<svelte:head>
<title>
{f(parse(data.thisMonthName, "MMMM-yyyy", new Date()), "MMMM, yyyy", selectedLang)}
{l(data.lang, "Incident Updates")} |
{data.site.title}
</title>
</svelte:head>
<div class="mt-12"></div>
<section class="mx-auto my-2 flex w-full max-w-[655px] flex-1 flex-col items-start justify-center">
<Button
@@ -98,7 +105,7 @@
</div>
<h1 class=" text-xl font-semibold leading-tight">
{l(data.lang, "No Incident On %date", {
{l(data.lang, "No Incident in %date", {
date: data.thisMonthName.replace("-", ", ")
})}
</h1>