Compare commits

..

25 Commits

Author SHA1 Message Date
Raj Nandan Sharma 65f039b7bd refactor(docker): enhance build process and organize template files fixes #429 2025-08-05 22:36:31 +05:30
Raj Nandan Sharma 5c7b62e9f7 Merge pull request #451 from moaazbhnas228/fix/heartbeat-grace-period
Fix: Heartbeat monitor respects cron-based grace periods
2025-08-05 22:21:37 +05:30
Raj Nandan Sharma 5e6e891ea6 Merge pull request #473 from rajnandan1/fix/441
Fix/441
2025-08-05 22:00:06 +05:30
Raj Nandan Sharma 82c904608b refactor(subscriptions): simplify condition for subscription trigger ID check 2025-08-05 21:59:22 +05:30
Raj Nandan Sharma f5260ceb86 chore(package): update version to 3.2.19 2025-08-05 21:18:32 +05:30
Raj Nandan Sharma abb32fdd6f fix(subscriptions): improve status toggle handling
Refactors the subscription status toggle to use a dedicated handler, ensuring correct behavior when toggling status for both new and existing triggers. Enhances user experience by automatically saving and reloading data when needed.
2025-08-05 21:17:09 +05:30
Raj Nandan Sharma 97aef5c5f5 Merge pull request #461 from antonio-sessa/fix/issue_456
fix: enhance monitor rearrangement with scrollable container
2025-08-05 11:06:47 +05:30
Raj Nandan Sharma c3eb8ae7f4 Merge pull request #467 from Baw-Appie/patch-1
Update Korean translations for clarity and consistency
2025-08-05 11:06:15 +05:30
Raj Nandan Sharma 72f74f9164 Merge pull request #469 from faridvatani/feature/persian-support
feat(i18n): add Persian language support
2025-08-05 11:05:50 +05:30
Farid Vatani 958676e5a7 feat(i18n): add Persian language support 2025-07-21 14:27:42 +03:30
JiHun Oh 51134670e5 Update Korean translations for clarity and consistency 2025-07-19 11:02:39 +00:00
JiHun Oh ecea2b220d Update ko.json 2025-07-19 19:51:27 +09:00
antonio-sessa 212f4d5e7a fix: enhance monitor rearrangement with scrollable container 2025-07-14 09:30:41 +02:00
Raj Nandan Sharma 2edb09bd13 Merge pull request #455 from xgenos/fix-issue-332
fixed the issue#332 with more optimized ORIGIN env calls
2025-07-11 10:10:07 +05:30
Biswa Kalyan Bhuyan 6b9f073cb7 fix: fixed the issue#332 with more optimized ORIGIN env calls 2025-07-02 19:15:52 +05:30
Moaaz Bhnas 9f933a0f1c Fixed returned status/type on heartbeat error 2025-07-02 09:21:58 +03:00
Moaaz Bhnas 8a6f721bb4 previousRun() 2025-07-01 09:03:50 +03:00
Moaaz Bhnas eeadcca6ed Used croner instead of cron-parser 2025-07-01 08:59:04 +03:00
Moaaz Bhnas 8e89c10906 Small change 2025-07-01 08:53:46 +03:00
Moaaz Bhnas 833d16351c FIX: heartbeat latency 2025-07-01 08:49:32 +03:00
Raj Nandan Sharma 0c10552fa7 Merge pull request #448 from federico-it/main
feat(i18n): add Italian language support
2025-06-30 21:30:05 +05:30
Raj Nandan Sharma 443afe2f6e Merge pull request #447 from sendmiche/patch-1
The translation has been made more suitable for the Russian language.
2025-06-30 21:29:33 +05:30
Federico db48d98da7 feat(i18n): add Italian language support 2025-06-20 17:44:28 +02:00
sendmiche bf3150434a The translation has been made more suitable for the Russian language. 2025-06-20 12:30:59 +03:00
github-actions 71c4bd26d2 Auto-generate README.md with release versions 2025-06-12 04:47:55 +00:00
14 changed files with 345 additions and 108 deletions
+3 -1
View File
@@ -63,8 +63,10 @@ RUN rm -rf src/routes/\(docs\) \
mkdir -p uploads database && \
chmod -R 750 uploads database
# Build the application and remove `devDependencies`
# Build the application and copy templates to build directory
RUN npm run build && \
mkdir -p build/server/templates && \
cp -r src/lib/server/templates/* build/server/templates/ && \
npm prune --omit=dev
#==========================================================#
+9 -9
View File
@@ -79,7 +79,7 @@ npm run dev
Official Docker images for **Kener** are available on [Docker Hub](https://hub.docker.com/r/rajnandan1/kener). Multiple versions are maintained to support different use cases.
<a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.17"><img src="https://img.shields.io/badge/Latest_Stable_Release-3.2.17-blue" alt="Kener latest stable version: 3.2.17" /></a>
<a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.18"><img src="https://img.shields.io/badge/Latest_Stable_Release-3.2.18-blue" alt="Kener latest stable version: 3.2.18" /></a>
#### Available Tags
@@ -93,38 +93,38 @@ Official Docker images for **Kener** are available on [Docker Hub](https://hub.d
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=latest" target="_blank"><code>latest</code></td>
<td>Latest stable release (aka 3.2.17)</td>
<td>Latest stable release (aka 3.2.18)</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.17" target="_blank"><code>3.2.17</code></a></td>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.18" target="_blank"><code>3.2.18</code></a></td>
<td>Specific release version</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2" target="_blank"><code>3.2</code></a></td>
<td>Major-minor version tag pointing to the latest patch (3.2.17) release within that minor version (3.2.x)</td>
<td>Major-minor version tag pointing to the latest patch (3.2.18) release within that minor version (3.2.x)</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3" target="_blank"><code>3</code></a></td>
<td>Major version tag pointing to the latest stable (3.2.17) release within that major version (3.x.x)</td>
<td>Major version tag pointing to the latest stable (3.2.18) release within that major version (3.x.x)</td>
</tr>
<tr>
<td align="left" colspan="2" style="color:#0D597F;text-align:left;">Alpine Linux 3.21 w/ Node.js v23.7.0 &nbsp;<strong><em>(smallest image size)</em></strong></td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=alpine" target="_blank"><code>alpine</code></td>
<td>Latest stable release (aka 3.2.17)</td>
<td>Latest stable release (aka 3.2.18)</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.17-alpine" target="_blank"><code>3.2.17-alpine</code></a></td>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2.18-alpine" target="_blank"><code>3.2.18-alpine</code></a></td>
<td>Specific release version</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3.2-alpine" target="_blank"><code>3.2-alpine</code></a></td>
<td>Major-minor version tag pointing to the latest patch (3.2.17) release within that minor version (3.2.x)</td>
<td>Major-minor version tag pointing to the latest patch (3.2.18) release within that minor version (3.2.x)</td>
</tr>
<tr>
<td><a href="https://hub.docker.com/r/rajnandan1/kener/tags?page=1&ordering=last_updated&name=3-alpine" target="_blank"><code>3-alpine</code></a></td>
<td>Major version tag pointing to the latest stable (3.2.17) release within that major version (3.x.x)</td>
<td>Major version tag pointing to the latest stable (3.2.18) release within that major version (3.x.x)</td>
</tr>
</table>
+4
View File
@@ -15,6 +15,10 @@ const base = process.env.KENER_BASE_PATH || "";
const app = express();
const db = knex(knexOb);
if (process.env.ORIGIN) {
process.env.SVELTEKIT_ORIGIN = process.env.ORIGIN;
}
app.use((req, res, next) => {
if (req.path.startsWith("/embed")) {
res.setHeader("Content-Security-Policy", "frame-ancestors *");
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kener",
"version": "3.2.18",
"version": "3.2.19",
"private": false,
"license": "MIT",
"description": "Kener is a modern, open-source status page application built with Node.js. It provides real-time monitoring, uptime tracking, incident management, and beautiful dashboards. Perfect for DevOps teams, SaaS providers, and businesses needing reliable service status communication with minimal setup.",
+1 -1
View File
@@ -481,7 +481,7 @@
<div class="content px-4 py-4">
<h2 class="text-lg font-semibold">Rearrange Monitors</h2>
<div
class="mt-4"
class="mt-4 max-h-[80vh] overflow-y-auto"
use:dndzone={{ items: monitors, flipDurationMs, dropTargetStyle }}
on:consider={handleSort}
on:finalize={handleSort}
+3 -1
View File
@@ -1,7 +1,7 @@
// @ts-nocheck
import { format, formatDistance, formatDistanceToNow, formatDuration } from "date-fns";
import { ru, enUS, hi, de, zhCN, vi, ja, nl, da, fr, ko, ptBR, tr, nb, pl, es } from "date-fns/locale";
import { ru, enUS, hi, de, zhCN, vi, ja, nl, da, fr, ko, ptBR, tr, nb, pl, es, it, faIR } from "date-fns/locale";
import { formatInTimeZone } from "date-fns-tz";
const locales = {
@@ -21,6 +21,8 @@ const locales = {
"nb-NO": nb,
pl,
es,
it,
fa: faIR,
};
const f = function (date, formatStr, locale, tz) {
+92
View File
@@ -0,0 +1,92 @@
{
"%status for %duration": "%status به مدت %duration",
"120 Days": "۱۲۰ روزه",
"14 Days": "۱۴ روزه",
"150 Days": "۱۵۰ روزه",
"180 Days": "۱۸۰ روزه",
"30 Days": "۳۰ روزه",
"60 Days": "۶۰ روزه",
"7 Days": "۷ روزه",
"90 Days": "۹۰ روزه",
"Availability per Component": "دسترس‌پذیری هر کامپوننت",
"All Systems are Degraded": "همه سامانه‌ها دچار اختلال‌اند",
"All Systems are Down": "همه سامانه‌ها از کار افتاده‌اند",
"All Systems are Operational": "همه سامانه‌ها در حال کار هستند",
"All Systems are in Maintenance": "همه سامانه‌ها در حال تعمیر هستند",
"Back": "بازگشت",
"Badge Copied": "نشان کپی شد",
"Badge": "نشان",
"Browse Events": "مشاهده رویدادها",
"Change Email": "تغییر ایمیل",
"Code Copied": "کد کپی شد",
"Confirm Login": "تأیید ورود",
"Copy Code": "کپی کد",
"Copy Link": "کپی لینک",
"DEGRADED": "اختلال",
"DOWN": "از کار افتاده",
"Dark": "تاریک",
"Days": "روزها",
"Embed this monitor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app.": "این مانیتور را با استفاده از <script> یا <iframe> در برنامه‌تان قرار دهید.",
"Embed": "درج",
"Enter the code": "کد را وارد کنید",
"Enter your email": "ایمیل خود را وارد کنید",
"Enter your email to log in. If you are not subscribed, you will be prompted to subscribe.": "برای ورود، ایمیل خود را وارد کنید. اگر عضو نیستید، از شما خواسته می‌شود عضو شوید.",
"Get SVG badge for this monitor": "دریافت نشان SVG برای این مانیتور",
"Get a LIVE Status for this monitor": "دریافت وضعیت زنده این مانیتور",
"IDENTIFIED": "شناسایی شده",
"INVESTIGATING": "در حال بررسی",
"Incident Updates": "به‌روزرسانی‌های حادثه",
"LIVE Status": "وضعیت زنده",
"Lasted for about %lastedFor": "حدوداً به مدت %lastedFor ادامه داشت",
"Light": "روشن",
"Link Copied": "لینک کپی شد",
"Login": "ورود",
"MAINTENANCE": "تعمیر و نگهداری",
"MONITORING": "در حال پایش",
"Maintenance Completed": "تعمیرات به پایان رسید",
"Maintenance in Progress": "تعمیرات در حال انجام است",
"Manage Subscription": "مدیریت اشتراک",
"Mode": "حالت",
"No Data": "بدون داده",
"No Incident in %date": "هیچ حادثه‌ای در %date وجود ندارد",
"No Incidents": "هیچ حادثه‌ای وجود ندارد",
"No Monitor Found": "هیچ مانیتوری یافت نشد",
"No Updates Yet": "هنوز به‌روزرسانی‌ای وجود ندارد",
"Ongoing Incidents": "حوادث در حال وقوع",
"Pinging": "در حال پینگ گرفتن",
"Please select specific monitors to receive updates from.": "لطفاً مانیتورهای خاصی را برای دریافت به‌روزرسانی انتخاب کنید.",
"RESOLVED": "حل شده",
"Recent Incidents": "حوادث اخیر",
"Recent Maintenances": "تعمیرات اخیر",
"Share this monitor using a link with others": "این مانیتور را با لینک با دیگران به اشتراک بگذارید",
"Share": "اشتراک‌گذاری",
"Some Systems are not working as expected": "برخی سامانه‌ها به‌درستی کار نمی‌کنند",
"Some Systems Degraded": "برخی سامانه‌ها دچار اختلال‌اند",
"Some Systems Down": "برخی سامانه‌ها از کار افتاده‌اند",
"Some Systems in Maintenance": "برخی سامانه‌ها در حال تعمیر هستند",
"Standard": "معمولی",
"Started %startedAt, lasted for %lastedFor": "شروع در %startedAt، به مدت %lastedFor ادامه داشت",
"Started %startedAt, still ongoing": "شروع در %startedAt، هنوز ادامه دارد",
"Started %startedAt, will last for %lastedFor more": "شروع در %startedAt، تا %lastedFor دیگر ادامه خواهد داشت",
"Starts %startedAt, will last for %lastedFor": "شروع در %startedAt، به مدت %lastedFor ادامه دارد",
"Starts %startedAt": "شروع در %startedAt",
"Status OK": "وضعیت خوب",
"Status": "وضعیت",
"Subscribe": "اشتراک",
"Subscribe to Updates": "مشترک شدن در به‌روزرسانی‌ها",
"Subscribe to all monitors": "اشتراک همه مانیتورها",
"Switch to your timezone": "تغییر به منطقه زمانی شما",
"Theme": "تم",
"There are no upcoming maintenances": "هیچ تعمیر آینده‌ای وجود ندارد",
"Timezone set to %tz": "منطقه زمانی روی %tz تنظیم شد",
"Today": "امروز",
"UP": "فعال",
"Update Subscription": "به‌روزرسانی اشتراک",
"Upcoming Maintenance": "تعمیر آینده",
"Upcoming Maintenances": "تعمیرات آینده",
"Updates": "به‌روزرسانی‌ها",
"Uptime": "زمان کارکرد",
"View in detail": "مشاهده جزئیات",
"We have sent a code to your email. Please enter it below to confirm your login": "کدی به ایمیل شما ارسال کردیم. لطفاً برای تأیید ورود آن را وارد کنید.",
"You are logged in as %email": "شما با ایمیل %email وارد شده‌اید"
}
+93
View File
@@ -0,0 +1,93 @@
{
"%status for %duration": "%status per %duration",
"120 Days": "120 Giorni",
"14 Days": "14 Giorni",
"150 Days": "150 Giorni",
"180 Days": "180 Giorni",
"30 Days": "30 Giorni",
"60 Days": "60 Giorni",
"7 Days": "7 Giorni",
"90 Days": "90 Giorni",
"Availability per Component": "Disponibilità per componente",
"All Systems are Degraded": "Tutti i sistemi sono degradati",
"All Systems are Down": "Tutti i sistemi sono inattivi",
"All Systems are Operational": "Tutti i sistemi sono operativi",
"All Systems are in Maintenance": "Tutti i sistemi sono in manutenzione",
"Back": "Indietro",
"Badge Copied": "Badge copiato",
"Badge": "Badge",
"Browse Events": "Sfoglia eventi",
"Change Email": "Cambia email",
"Code Copied": "Codice copiato",
"Confirm Login": "Conferma accesso",
"Copy Code": "Copia codice",
"Copy Link": "Copia link",
"DEGRADED": "DEGRADATO",
"DOWN": "NON DISPONIBILE",
"Dark": "Scuro",
"Days": "Giorni",
"Embed this monitor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app.": "Incorpora questo monitor usando <script> o <iframe> nella tua app.",
"Embed": "Incorpora",
"Enter the code": "Inserisci il codice",
"Enter your email": "Inserisci la tua email",
"Enter your email to log in. If you are not subscribed, you will be prompted to subscribe.": "Inserisci la tua email per accedere. Se non sei iscritto, ti verrà chiesto di iscriverti.",
"Get SVG badge for this monitor": "Ottieni badge SVG per questo monitor",
"Get a LIVE Status for this monitor": "Ottieni lo stato LIVE per questo monitor",
"IDENTIFIED": "IDENTIFICATO",
"INVESTIGATING": "IN ANALISI",
"Incident Updates": "Aggiornamenti incidenti",
"LIVE Status": "Stato LIVE",
"Lasted for about %lastedFor": "Durato circa %lastedFor",
"Light": "Chiaro",
"Link Copied": "Link copiato",
"Login": "Accedi",
"MAINTENANCE": "MANUTENZIONE",
"MONITORING": "MONITORAGGIO",
"Maintenance Completed": "Manutenzione completata",
"Maintenance in Progress": "Manutenzione in corso",
"Manage Subscription": "Gestisci iscrizione",
"Mode": "Modalità",
"No Data": "Nessun dato",
"No Incident in %date": "Nessun incidente in %date",
"No Incidents": "Nessun incidente",
"No Monitor Found": "Nessun monitor trovato",
"No Updates Yet": "Nessun aggiornamento ancora",
"Ongoing Incidents": "Incidenti in corso",
"Pinging": "Ping in corso",
"Please select specific monitors to receive updates from.": "Seleziona i monitor specifici da cui ricevere aggiornamenti.",
"RESOLVED": "RISOLTO",
"Recent Incidents": "Incidenti recenti",
"Recent Maintenances": "Manutenzioni recenti",
"Share this monitor using a link with others": "Condividi questo monitor tramite un link con altri",
"Share": "Condividi",
"Some Systems are not working as expected": "Alcuni sistemi non funzionano come previsto",
"Some Systems Degraded": "Alcuni sistemi degradati",
"Some Systems Down": "Alcuni sistemi inattivi",
"Some Systems in Maintenance": "Alcuni sistemi in manutenzione",
"Standard": "Standard",
"Started %startedAt, lasted for %lastedFor": "Iniziato il %startedAt, durato %lastedFor",
"Started %startedAt, still ongoing": "Iniziato il %startedAt, ancora in corso",
"Started %startedAt, will last for %lastedFor more": "Iniziato il %startedAt, durerà ancora %lastedFor",
"Starts %startedAt, will last for %lastedFor": "Inizia il %startedAt, durerà %lastedFor",
"Starts %startedAt": "Inizia il %startedAt",
"Status OK": "Stato OK",
"Status": "Stato",
"Subscribe": "Iscriviti",
"Subscribe to Updates": "Iscriviti agli aggiornamenti",
"Subscribe to all monitors": "Iscriviti a tutti i monitor",
"Switch to your timezone": "Passa al tuo fuso orario",
"Theme": "Tema",
"There are no upcoming maintenances": "Non ci sono manutenzioni imminenti",
"Timezone set to %tz": "Fuso orario impostato su %tz",
"Today": "Oggi",
"UP": "ATTIVO",
"Update Subscription": "Aggiorna iscrizione",
"Upcoming Maintenance": "Manutenzione imminente",
"Upcoming Maintenances": "Manutenzioni imminenti",
"Updates": "Aggiornamenti",
"Uptime": "Tempo di attività",
"View in detail": "Visualizza nel dettaglio",
"We have sent a code to your email. Please enter it below to confirm your login": "Abbiamo inviato un codice alla tua email. Inseriscilo qui sotto per confermare l'accesso",
"You are logged in as %email": "Sei connesso come %email"
}
+36 -36
View File
@@ -1,26 +1,26 @@
{
"%status for %duration": "%duration 동안 %status 상태였음",
"120 Days": "120 일",
"14 Days": "14 일",
"150 Days": "150 일",
"180 Days": "180 일",
"30 Days": "30 일",
"60 Days": "60 일",
"7 Days": "7 일",
"90 Days": "90 일",
"Availability per Component": "항목당 가용성",
"%status for %duration": "%duration 동안 %status 상태",
"120 Days": "120일",
"14 Days": "14일",
"150 Days": "150일",
"180 Days": "180일",
"30 Days": "30일",
"60 Days": "60일",
"7 Days": "7일",
"90 Days": "90일",
"Availability per Component": "항목 당 가용성",
"All Systems are Degraded": "모든 시스템이 성능 저하 상태입니다",
"All Systems are Down": "모든 시스템이 중단되었습니다",
"All Systems are Operational": "모든 시스템이 정상 작동 중입니다",
"All Systems are in Maintenance": "모든 시스템이 유지보수 중입니다",
"All Systems are in Maintenance": "모든 시스템이 유지 보수 중입니다",
"Back": "뒤로",
"Badge Copied": "배지 복사됨",
"Badge Copied": "배지 복사 됨",
"Badge": "배지",
"Browse Events": "이벤트 찾아보기",
"Change Email": "이메일 변경",
"Code Copied": "소스코드 복사됨",
"Code Copied": "소스 코드 복사됨",
"Confirm Login": "로그인 확인",
"Copy Code": "소스코드 복사",
"Copy Code": "소스 코드 복사",
"Copy Link": "링크 복사",
"DEGRADED": "성능 저하됨",
"DOWN": "중단",
@@ -31,59 +31,59 @@
"Enter the code": "코드를 입력하세요",
"Enter your email": "이메일을 입력하세요",
"Enter your email to log in. If you are not subscribed, you will be prompted to subscribe.": "로그인하려면 이메일을 입력하세요. 구독하지 않은 경우 구독 요청이 표시됩니다.",
"Get SVG badge for this monitor": "이 모니터링 항목에 대한 SVG 배지를 구해보세요.",
"Get a LIVE Status for this monitor": "이 모니터링 항목에 대한 실시간 상태를 구해보세요.",
"IDENTIFIED": "확인됨",
"Get SVG badge for this monitor": "이 모니터링 항목에 대한 SVG 배지를 얻어보세요.",
"Get a LIVE Status for this monitor": "이 모니터링 항목에 대한 실시간 상태를 얻어보세요.",
"IDENTIFIED": "확인 됨",
"INVESTIGATING": "조사 중",
"Incident Updates": "사건 보고서",
"LIVE Status": "실시간 상태",
"Lasted for about %lastedFor": "%lastedFor 동안 지속",
"Light": "라이트",
"Link Copied": "링크 복사됨",
"Light": "밝게",
"Link Copied": "링크 복사 됨",
"Login": "로그인",
"MAINTENANCE": "유지보수",
"MONITORING": "감시 중",
"Maintenance Completed": "유지보수 완료",
"Maintenance in Progress": "유지보수 진행 중",
"Maintenance Completed": "유지 보수 완료",
"Maintenance in Progress": "유지 보수 진행 중",
"Manage Subscription": "구독 관리",
"Mode": "모드",
"No Data": "데이터 없음",
"No Incident in %date": "%date 에는 아무 사건도 없었음",
"No Incident in %date": "%date에는 아무 사건도 없었음",
"No Incidents": "사건 없음",
"No Monitor Found": "모니터링 항목을 찾을 수 없음",
"No Updates Yet": "아직 아무 업데이트도 없음",
"Ongoing Incidents": "진행중 사건",
"Ongoing Incidents": "진행 중 사건",
"Pinging": "핑 요청",
"Please select specific monitors to receive updates from.": "업데이트를 받을 특정 모니터를 선택하세요.",
"RESOLVED": "해결됨",
"RESOLVED": "해결 됨",
"Recent Incidents": "최근 사건",
"Recent Maintenances": "최근 유지보수",
"Recent Maintenances": "최근 유지 보수",
"Share this monitor using a link with others": "링크를 사용하여 다른 사람들과 이 모니터링 데이터를 공유해보세요",
"Share": "공유",
"Some Systems are not working as expected": "일부 시스템이 예상대로 작동하지 않습니다",
"Some Systems Degraded": "일부 시스템이 성능 저하 상태입니다",
"Some Systems Down": "일부 시스템이 중단되었습니다",
"Some Systems in Maintenance": "일부 시스템이 유지보수 중입니다",
"Some Systems in Maintenance": "일부 시스템이 유지 보수 중입니다",
"Standard": "기본",
"Started %startedAt, lasted for %lastedFor": "%startedAt에 시작되었으며, %lastedFor 동안 지속되습니다",
"Started %startedAt, still ongoing": "%startedAt에 시작되었으며, 아직 진행중입니다",
"Started %startedAt, will last for %lastedFor more": "%startedAt에 시작되었으며, %lastedFor 더 지속될 예정입니다",
"Starts %startedAt, will last for %lastedFor": "%startedAt에 시작되었으며, %lastedFor 까지 지속될 예정입니다",
"Starts %startedAt": "%startedAt 에 시작되었습니다",
"Started %startedAt, lasted for %lastedFor": "%startedAt에 시작되었으며, %lastedFor 동안 지속되고 있습니다",
"Started %startedAt, still ongoing": "%startedAt에 시작되었으며, 아직 진행 중입니다",
"Started %startedAt, will last for %lastedFor more": "%startedAt에 시작되었으며, %lastedFor 더 지속될 예정입니다",
"Starts %startedAt, will last for %lastedFor": "%startedAt에 시작되며, %lastedFor 지속될 예정입니다",
"Starts %startedAt": "%startedAt에 시작되었습니다",
"Status OK": "양호",
"Status": "상태",
"Subscribe": "구독",
"Subscribe to Updates": "업데이트 구독하기",
"Subscribe to all monitors": "모든 모니터 구독",
"Switch to your timezone": "귀하의 시간대로 변경",
"Switch to your timezone": " 시간대로 변경",
"Theme": "테마",
"There are no upcoming maintenances": "예정된 유지보수가 없습니다",
"Timezone set to %tz": "시간대 설정 %tz",
"There are no upcoming maintenances": "예정된 유지 보수가 없습니다",
"Timezone set to %tz": "%tz(으)로 시간대 설정",
"Today": "오늘",
"UP": "작동 중",
"Update Subscription": "구독 업데이트",
"Upcoming Maintenance": "예정된 유지보수",
"Upcoming Maintenances": "예정된 유지보수 목록",
"Upcoming Maintenance": "예정된 유지 보수",
"Upcoming Maintenances": "예정된 유지 보수 목록",
"Updates": "업데이트",
"Uptime": "업타임",
"View in detail": "자세히 보기",
+8
View File
@@ -62,5 +62,13 @@
{
"code": "es",
"name": "Español"
},
{
"code": "it",
"name": "Italiano"
},
{
"code": "fa",
"name": "Persian (فارسی)"
}
]
+48 -48
View File
@@ -1,75 +1,75 @@
{
"%status for %duration": "%status в течение %duration",
"14 Days": "14 Дней",
"30 Days": "30 Дней",
"60 Days": "60 Дней",
"7 Days": "7 Дней",
"90 Days": "90 Дней",
"120 Days": "120 Дней",
"150 Days": "150 Дней",
"180 Days": "180 Дней",
"120 Days": "120 дней",
"14 Days": "14 дней",
"150 Days": "150 дней",
"180 Days": "180 дней",
"30 Days": "30 дней",
"60 Days": "60 дней",
"7 Days": "7 дней",
"90 Days": "90 дней",
"Availability per Component": "Доступность по компонентам",
"All Systems are Degraded": "Все системы работают с ухудшенной производительностью",
"All Systems are Down": "Все системы недоступны",
"All Systems are Operational": "Все системы работают нормально",
"All Systems are in Maintenance": "Все системы на обслуживании",
"All Systems are Degraded": "Системы работают нестабильно",
"All Systems are Down": "Системы не работают",
"All Systems are Operational": "Системы работают нормально",
"All Systems are in Maintenance": "Системы на обслуживании",
"Back": "Назад",
"Badge Copied": "Значок скопирован",
"Badge": "Значок",
"Browse Events": "Просмотр событий",
"Change Email": "Изменить email",
"Change Email": "Изменить электронную почту",
"Code Copied": "Код скопирован",
"Confirm Login": "Подтвердить вход",
"Copy Code": "Копировать код",
"Copy Link": "Копировать ссылку",
"DEGRADED": "УХУДШЕНО",
"DOWN": "НЕДОСТУПНО",
"Dark": "Темная",
"Days": "Дней",
"Embed this monitor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app.": "Встройте этот монитор используя <script> или <iframe> в ваше приложение.",
"Embed": "Встроить",
"Confirm Login": "Подтвердите вход",
"Copy Code": "Скопировать код",
"Copy Link": "Скопировать ссылку",
"DEGRADED": "НЕСТАБИЛЬНО",
"DOWN": "НЕ РАБОТАЕТ",
"Dark": "Тёмная",
"Days": "дней",
"Embed this monitor using &#x3C;script&#x3E; or &#x3C;iframe&#x3E; in your app.": "Встройте этот монитор с помощью <script> или <iframe> в ваше приложение.",
"Embed": "Вставить",
"Enter the code": "Введите код",
"Enter your email": "Введите ваш email",
"Enter your email to log in. If you are not subscribed, you will be prompted to subscribe.": "Введите ваш email для входа. Если вы не подписаны, вам будет предложено подписаться.",
"Get SVG badge for this monitor": "Получить SVG значок для этого монитора",
"Get a LIVE Status for this monitor": "Получить ЖИВОЙ статус для этого монитора",
"Get a LIVE Status for this monitor": "Получить текущий статус для этого монитора",
"IDENTIFIED": "ВЫЯВЛЕНО",
"INVESTIGATING": ССЛЕДУЕТСЯ",
"Incident Updates": "Обновления инцидента",
"LIVE Status": "ЖИВОЙ статус",
"Lasted for about %lastedFor": "Длилось около %lastedFor",
"INVESTIGATING": ЗУЧАЕТСЯ",
"Incident Updates": "Обновления инцидентов",
"LIVE Status": "Текущий статус",
"Lasted for about %lastedFor": "Продолжалось около %lastedFor",
"Light": "Светлая",
"Link Copied": "Ссылка скопирована",
"Login": "Войти",
"MAINTENANCE": "ОБСЛУЖИВАНИЕ",
"MONITORING": "МОНИТОРИНГ",
"Maintenance Completed": "Техническое обслуживание завершено",
"Maintenance in Progress": "Техническое обслуживание",
"Maintenance Completed": "Обслуживание завершено",
"Maintenance in Progress": "Обслуживание в процессе",
"Manage Subscription": "Управление подпиской",
"Mode": "Режим",
"No Data": "Нет данных",
"No Incident in %date": "Нет инцидентов на %date",
"No Incidents": "Нет инцидентов",
"No Incident in %date": "Нет инцидентов за %date",
"No Incidents": "Инцидентов нет",
"No Monitor Found": "Монитор не найден",
"No Updates Yet": "Пока нет обновлений",
"No Updates Yet": "Обновлений пока нет",
"Ongoing Incidents": "Текущие инциденты",
"Pinging": ингуется",
"Please select specific monitors to receive updates from.": "Выберите конкретные мониторы для получения обновлений.",
"Pinging": роверка доступности",
"Please select specific monitors to receive updates from.": "Пожалуйста, выберите мониторы для получения обновлений.",
"RESOLVED": "РЕШЕНО",
"Recent Incidents": "Недавние инциденты",
"Recent Maintenances": "Последние обслуживания",
"Share this monitor using a link with others": "Поделитесь этим монитором с другими по ссылке",
"Share": "Поделиться",
"Some Systems are not working as expected": "Некоторые системы работают не так, как ожидалось",
"Some Systems Degraded": "Некоторые системы работают с ухудшенной производительностью",
"Some Systems are not working as expected": "Некоторые системы работают нестабильно",
"Some Systems Degraded": "Некоторые системы работают нестабильно",
"Some Systems Down": "Некоторые системы недоступны",
"Some Systems in Maintenance": "Некоторые системы на обслуживании",
"Standard": "Стандартная",
"Started %startedAt, lasted for %lastedFor": "Началось около %startedAt назад, длилось около %lastedFor",
"Started %startedAt, still ongoing": "Началось около %startedAt назад, все еще продолжается",
"Started %startedAt, will last for %lastedFor more": "Начнется около %startedAt, продлится еще около %lastedFor",
"Starts %startedAt, will last for %lastedFor": "Начнется через %startedAt, продлится около %lastedFor",
"Starts %startedAt": "Начнется через %startedAt",
"Started %startedAt, lasted for %lastedFor": "Началось %startedAt, продолжалось %lastedFor",
"Started %startedAt, still ongoing": "Началось %startedAt, всё ещё продолжается",
"Started %startedAt, will last for %lastedFor more": "Началось %startedAt, продлится ещё около %lastedFor",
"Starts %startedAt, will last for %lastedFor": "Начнётся %startedAt, продлится %lastedFor",
"Starts %startedAt": "Начнётся %startedAt",
"Status OK": "Статус ОК",
"Status": "Статус",
"Subscribe": "Подписаться",
@@ -77,16 +77,16 @@
"Subscribe to all monitors": "Подписаться на все мониторы",
"Switch to your timezone": "Переключиться на ваш часовой пояс",
"Theme": "Тема",
"There are no upcoming maintenances": "Нет предстоящих технических обслуживаний",
"Timezone set to %tz": "Часовой пояс установлен на %tz",
"There are no upcoming maintenances": "Предстоящих обслуживаний нет",
"Timezone set to %tz": "Часовой пояс установлен: %tz",
"Today": "Сегодня",
"UP": "РАБОТАЕТ",
"Update Subscription": "Обновить подписку",
"Upcoming Maintenance": "Предстоящее техническое обслуживание",
"Upcoming Maintenances": "Предстоящие технические обслуживания",
"Upcoming Maintenance": "Предстоящее обслуживание",
"Upcoming Maintenances": "Предстоящие обслуживания",
"Updates": "Обновления",
"Uptime": "Время работы",
"View in detail": "Подробный просмотр",
"We have sent a code to your email. Please enter it below to confirm your login": "Мы отправили код на ваш email. Пожалуйста, введите его ниже для подтверждения входа",
"Uptime": "Время безотказной работы",
"View in detail": "Подробнее",
"We have sent a code to your email. Please enter it below to confirm your login": "Мы отправили код на вашу почту. Введите его ниже для подтверждения входа",
"You are logged in as %email": "Вы вошли как %email"
}
+30 -2
View File
@@ -2,6 +2,7 @@
import { UP, DOWN, DEGRADED, REALTIME, TIMEOUT, ERROR, MANUAL } from "../constants.js";
import { GetMinuteStartNowTimestampUTC } from "../tool.js";
import { GetLastHeartbeat } from "../controllers/controller.js";
import { Cron } from "croner";
class HeartbeatCall {
monitor;
@@ -11,12 +12,37 @@ class HeartbeatCall {
}
async execute() {
let nowMinute = GetMinuteStartNowTimestampUTC();
let nowMinute = GetMinuteStartNowTimestampUTC(); // current time in seconds (minute start)
let latestData = await GetLastHeartbeat(this.monitor.tag);
if (!latestData) {
return {};
}
let latency = nowMinute - latestData.timestamp;
// Use croner to calculate expected heartbeat time
let expectedTime;
try {
const cronJob = Cron(this.monitor.cron);
const prevDate = cronJob.previousRun();
expectedTime = Math.floor(prevDate.getTime() / 1000); // seconds
} catch (err) {
return {
status: DOWN,
latency: 0,
type: ERROR,
};
}
// If heartbeat was received after or at expected time, it's UP
if (latestData.timestamp >= expectedTime) {
return {
status: UP,
latency: nowMinute - latestData.timestamp,
type: REALTIME,
};
}
// Calculate how late the expected heartbeat is
let latency = nowMinute - expectedTime;
let downRemainingMinutes = Number(this.monitor.type_data.downRemainingMinutes);
if (latency > downRemainingMinutes * 60) {
return {
@@ -25,6 +51,7 @@ class HeartbeatCall {
type: REALTIME,
};
}
let degradedRemainingMinutes = Number(this.monitor.type_data.degradedRemainingMinutes);
if (latency > degradedRemainingMinutes * 60) {
return {
@@ -33,6 +60,7 @@ class HeartbeatCall {
type: REALTIME,
};
}
return {
status: UP,
latency: latency,
@@ -137,6 +137,19 @@
});
}
async function handleActiveInactive(e) {
if (subscriptionTrigger.id) {
subscriptionTrigger.subscription_trigger_status = e.target.checked ? "ACTIVE" : "INACTIVE";
updateSubscriptionTriggerStatus(subscriptionTrigger.id, subscriptionTrigger.subscription_trigger_status);
} else {
await saveSubscriptionTrigger();
pageLoading = true;
await loadSubscriptionTrigger();
await loadSubscribers();
pageLoading = false;
}
}
// Reactive statement to calculate totalPages
</script>
@@ -147,7 +160,7 @@
Events Subscription
{#if pageLoading}
<Loader size="16" class="absolute right-0 top-0 animate-spin text-gray-500" />
{:else if canSendEmail && !!subscriptionTrigger.id}
{:else if canSendEmail}
<label class="absolute right-0 top-0 flex cursor-pointer items-center justify-between gap-2 text-sm">
<Label class="text-xs font-medium ">
{subscriptionTrigger.subscription_trigger_status == "ACTIVE" ? "Active" : "Inactive"}
@@ -158,14 +171,7 @@
disabled={!canSendEmail}
class="peer sr-only"
checked={subscriptionTrigger.subscription_trigger_status == "ACTIVE"}
on:change={(e) => {
subscriptionTrigger.subscription_trigger_status = e.target.checked ? "ACTIVE" : "INACTIVE";
// Call the API to update the subscription status
updateSubscriptionTriggerStatus(
subscriptionTrigger.id,
subscriptionTrigger.subscription_trigger_status
);
}}
on:change={handleActiveInactive}
/>
<div
class="peer relative h-6 w-11 rounded-full bg-gray-200 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-600 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-blue-800 rtl:peer-checked:after:-translate-x-full"
+2
View File
@@ -10,6 +10,7 @@ const PORT = Number(process.env.PORT) || 3000;
const base = process.env.KENER_BASE_PATH || "";
const VITE_BUILD_ENV = process.env.VITE_BUILD_ENV || "development"; // Default to "development"
const isProduction = VITE_BUILD_ENV === "production";
const ORIGIN = process.env.ORIGIN || `http://localhost:${PORT}`;
export default defineConfig(({ mode }) => ({
optimizeDeps: {
@@ -49,6 +50,7 @@ export default defineConfig(({ mode }) => ({
version(),
],
server: {
allowedHosts: [new URL(ORIGIN).hostname],
port: PORT,
watch: {
ignored: ["**/src/lib/server/data/**"], // Adjust the path to the file you want to ignore