mirror of
https://github.com/rajnandan1/kener.git
synced 2026-08-07 15:27:13 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65f039b7bd | |||
| 5c7b62e9f7 | |||
| 5e6e891ea6 | |||
| 82c904608b | |||
| f5260ceb86 | |||
| abb32fdd6f | |||
| 97aef5c5f5 | |||
| c3eb8ae7f4 | |||
| 72f74f9164 | |||
| 958676e5a7 | |||
| 51134670e5 | |||
| ecea2b220d | |||
| 212f4d5e7a | |||
| 2edb09bd13 | |||
| 6b9f073cb7 | |||
| 9f933a0f1c | |||
| 8a6f721bb4 | |||
| eeadcca6ed | |||
| 8e89c10906 | |||
| 833d16351c | |||
| 0c10552fa7 | |||
| 443afe2f6e | |||
| db48d98da7 | |||
| bf3150434a | |||
| 71c4bd26d2 |
+3
-1
@@ -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
|
||||
|
||||
#==========================================================#
|
||||
|
||||
@@ -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 <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>
|
||||
|
||||
|
||||
@@ -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
@@ -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.",
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 <script> or <iframe> 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 وارد شدهاید"
|
||||
}
|
||||
@@ -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 <script> or <iframe> 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
@@ -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": "자세히 보기",
|
||||
|
||||
@@ -62,5 +62,13 @@
|
||||
{
|
||||
"code": "es",
|
||||
"name": "Español"
|
||||
},
|
||||
{
|
||||
"code": "it",
|
||||
"name": "Italiano"
|
||||
},
|
||||
{
|
||||
"code": "fa",
|
||||
"name": "Persian (فارسی)"
|
||||
}
|
||||
]
|
||||
|
||||
+48
-48
@@ -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 <script> or <iframe> in your app.": "Встройте этот монитор используя <script> или <iframe> в ваше приложение.",
|
||||
"Embed": "Встроить",
|
||||
"Confirm Login": "Подтвердите вход",
|
||||
"Copy Code": "Скопировать код",
|
||||
"Copy Link": "Скопировать ссылку",
|
||||
"DEGRADED": "НЕСТАБИЛЬНО",
|
||||
"DOWN": "НЕ РАБОТАЕТ",
|
||||
"Dark": "Тёмная",
|
||||
"Days": "дней",
|
||||
"Embed this monitor using <script> or <iframe> 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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user