mirror of
https://github.com/rajnandan1/kener.git
synced 2026-05-05 01:59:33 -05:00
feat: introducing event type maintenance as asked in #224
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
export function up(knex) {
|
||||
return knex.schema.alterTable("incidents", function (table) {
|
||||
table.text("incident_type").defaultTo("INCIDENT");
|
||||
});
|
||||
}
|
||||
|
||||
export function down(knex) {
|
||||
return knex.schema.alterTable("incidents", function (table) {
|
||||
table.dropColumn("incident_type");
|
||||
});
|
||||
}
|
||||
@@ -834,3 +834,18 @@ textarea::placeholder {
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-maintenance-in-progress {
|
||||
background-color: #f9f3c2;
|
||||
}
|
||||
|
||||
.text-maintenance-in-progress-text {
|
||||
color: #ff6868;
|
||||
}
|
||||
.text-upcoming-maintenance {
|
||||
color: #f0a04b;
|
||||
}
|
||||
|
||||
.text-maintenance-completed {
|
||||
color: #6499e9;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
if (incident.end_date_time) {
|
||||
endTime = new Date(incident.end_date_time * 1000);
|
||||
}
|
||||
|
||||
let incidentType = incident.incident_type;
|
||||
const lastedFor = fd(startTime, endTime, selectedLang);
|
||||
const startedAt = fdn(startTime, selectedLang);
|
||||
|
||||
@@ -23,6 +23,35 @@
|
||||
if (nowTime < startTime) {
|
||||
isFuture = true;
|
||||
}
|
||||
|
||||
let incidentDateSummary = "";
|
||||
let maintenanceBadge = "";
|
||||
let maintenanceBadgeColor = "";
|
||||
if (!isFuture && incident.state != "RESOLVED") {
|
||||
incidentDateSummary = l(lang, "Started about %startedAt, still ongoing", {
|
||||
startedAt
|
||||
});
|
||||
maintenanceBadge = "Maintenance in Progress";
|
||||
maintenanceBadgeColor = "text-maintenance-in-progress";
|
||||
} else if (!isFuture && incident.state == "RESOLVED") {
|
||||
incidentDateSummary = l(lang, "Started %startedAt, lasted for %lastedFor", {
|
||||
startedAt,
|
||||
lastedFor
|
||||
});
|
||||
maintenanceBadge = "Maintenance Completed";
|
||||
maintenanceBadgeColor = "text-maintenance-completed";
|
||||
} else if (isFuture && incident.state != "RESOLVED") {
|
||||
incidentDateSummary = l(lang, "Starts %startedAt", { startedAt });
|
||||
maintenanceBadge = "Upcoming Maintenance";
|
||||
maintenanceBadgeColor = "text-upcoming-maintenance";
|
||||
} else if (isFuture && incident.state == "RESOLVED") {
|
||||
incidentDateSummary = l(lang, "Starts %startedAt, will last for %lastedFor", {
|
||||
startedAt,
|
||||
lastedFor
|
||||
});
|
||||
maintenanceBadge = "Upcoming Maintenance";
|
||||
maintenanceBadgeColor = "text-upcoming-maintenance";
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="newincident relative grid w-full grid-cols-12 gap-2 px-0 py-0 last:border-b-0">
|
||||
@@ -30,47 +59,31 @@
|
||||
<Accordion.Root bind:value={index} class="accor">
|
||||
<Accordion.Item value="incident-0">
|
||||
<Accordion.Trigger class="px-4 hover:bg-muted hover:no-underline">
|
||||
<div class="justify-start text-left hover:no-underline">
|
||||
<p
|
||||
class="scroll-m-20 text-xs font-semibold leading-5 tracking-normal badge-{incident.state}"
|
||||
>
|
||||
{l(lang, incident.state)}
|
||||
</p>
|
||||
<div class="w-full text-left hover:no-underline">
|
||||
{#if incidentType == "INCIDENT"}
|
||||
<p
|
||||
class="scroll-m-20 text-xs font-semibold leading-5 tracking-normal badge-{incident.state}"
|
||||
>
|
||||
{l(lang, incident.state)}
|
||||
</p>
|
||||
{:else if incidentType == "MAINTENANCE"}
|
||||
<p
|
||||
class="{maintenanceBadgeColor} scroll-m-20 text-xs font-semibold leading-5 tracking-normal"
|
||||
>
|
||||
{l(lang, maintenanceBadge)}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<p class="scroll-m-20 text-lg font-medium tracking-tight">
|
||||
{incident.title}
|
||||
</p>
|
||||
|
||||
<p
|
||||
class="scroll-m-20 text-sm font-medium tracking-wide text-muted-foreground"
|
||||
>
|
||||
{#if !isFuture && incident.state != "RESOLVED"}
|
||||
<span>
|
||||
{l(lang, "Started about %startedAt, still ongoing", {
|
||||
startedAt
|
||||
})}
|
||||
</span>
|
||||
{:else if !isFuture && incident.state == "RESOLVED"}
|
||||
<span>
|
||||
{l(
|
||||
lang,
|
||||
"Started %startedAt, lasted for %lastedFor",
|
||||
{ startedAt, lastedFor }
|
||||
)}
|
||||
</span>
|
||||
{:else if isFuture && incident.state != "RESOLVED"}
|
||||
<span>
|
||||
{l(lang, "Starts %startedAt", { startedAt })}
|
||||
</span>
|
||||
{:else if isFuture && incident.state == "RESOLVED"}
|
||||
<span>
|
||||
{l(
|
||||
lang,
|
||||
"Starts %startedAt, will last for %lastedFor",
|
||||
{ startedAt, lastedFor }
|
||||
)}
|
||||
</span>
|
||||
{/if}
|
||||
</p>
|
||||
{#if !!incidentDateSummary}
|
||||
<p
|
||||
class="scroll-m-20 text-sm font-medium tracking-wide text-muted-foreground"
|
||||
>
|
||||
{incidentDateSummary}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</Accordion.Trigger>
|
||||
<Accordion.Content>
|
||||
@@ -100,30 +113,55 @@
|
||||
{l(lang, "Updates")}
|
||||
</p>
|
||||
{#if incident.comments.length > 0}
|
||||
<ol class="relative mt-2 pl-14">
|
||||
{#each incident.comments as comment}
|
||||
<li class="relative border-l pb-4 pl-[4.5rem] last:border-0">
|
||||
<div
|
||||
class="absolute top-0 w-28 -translate-x-32 rounded border bg-secondary px-1.5 py-1 text-center text-xs font-semibold"
|
||||
{#if incidentType == "INCIDENT"}
|
||||
<ol class="relative mt-2 pl-14">
|
||||
{#each incident.comments as comment}
|
||||
<li
|
||||
class="relative border-l pb-4 pl-[4.5rem] last:border-0"
|
||||
>
|
||||
{l(lang, comment.state)}
|
||||
</div>
|
||||
<time
|
||||
class=" mb-1 text-sm font-medium leading-none text-muted-foreground"
|
||||
>
|
||||
{f(
|
||||
new Date(comment.commented_at * 1000),
|
||||
"MMMM do yyyy, h:mm:ss a",
|
||||
selectedLang
|
||||
)}
|
||||
</time>
|
||||
<div
|
||||
class="absolute top-0 w-28 -translate-x-32 rounded border bg-secondary px-1.5 py-1 text-center text-xs font-semibold"
|
||||
>
|
||||
{l(lang, comment.state)}
|
||||
</div>
|
||||
|
||||
<p class="mb-4 text-sm font-normal">
|
||||
{comment.comment}
|
||||
</p>
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
<time
|
||||
class=" mb-1 text-sm font-medium leading-none text-muted-foreground"
|
||||
>
|
||||
{f(
|
||||
new Date(comment.commented_at * 1000),
|
||||
"MMMM do yyyy, h:mm:ss a",
|
||||
selectedLang
|
||||
)}
|
||||
</time>
|
||||
|
||||
<p class="mb-4 text-sm font-normal">
|
||||
{comment.comment}
|
||||
</p>
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
{:else if incidentType == "MAINTENANCE"}
|
||||
<ol class="relative mt-2 pl-0">
|
||||
{#each incident.comments as comment}
|
||||
<li class="relative pb-2 last:border-0">
|
||||
<time
|
||||
class=" mb-1 text-sm font-medium leading-none text-muted-foreground"
|
||||
>
|
||||
{f(
|
||||
new Date(comment.commented_at * 1000),
|
||||
"MMMM do yyyy, h:mm:ss a",
|
||||
selectedLang
|
||||
)}
|
||||
</time>
|
||||
|
||||
<p class="mb-2 text-sm font-normal">
|
||||
{comment.comment}
|
||||
</p>
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
{/if}
|
||||
{:else}
|
||||
<p class="text-sm font-medium">
|
||||
{l(lang, "No Updates Yet")}
|
||||
|
||||
+28
-9
@@ -3,7 +3,21 @@
|
||||
import { format, formatDistance, formatDistanceToNow, formatDuration } from "date-fns";
|
||||
import { ru, enUS, hi, de, zhCN, vi, ja, nl, da, fr, ko, ptBR, tr } from "date-fns/locale";
|
||||
|
||||
const locales = { ru, en: enUS, hi, de, "zh-CN": zhCN, vi, ja, nl, dk: da, fr, ko, "pt-BR": ptBR, tr };
|
||||
const locales = {
|
||||
ru,
|
||||
en: enUS,
|
||||
hi,
|
||||
de,
|
||||
"zh-CN": zhCN,
|
||||
vi,
|
||||
ja,
|
||||
nl,
|
||||
dk: da,
|
||||
fr,
|
||||
ko,
|
||||
"pt-BR": ptBR,
|
||||
tr
|
||||
};
|
||||
|
||||
const f = function (date, formatStr, locale) {
|
||||
return format(date, formatStr, {
|
||||
@@ -27,16 +41,21 @@ const fdm = function (duration, locale) {
|
||||
};
|
||||
|
||||
const l = function (sessionLangMap, key, args = {}) {
|
||||
let obj = sessionLangMap[key];
|
||||
try {
|
||||
let obj = sessionLangMap[key];
|
||||
|
||||
// Replace placeholders in the string using the args object
|
||||
if (obj && typeof obj === "string") {
|
||||
obj = obj.replace(/%\w+/g, (placeholder) => {
|
||||
const argKey = placeholder.slice(1); // Remove the `%` to get the key
|
||||
return args[argKey] !== undefined ? args[argKey] : placeholder;
|
||||
});
|
||||
// Replace placeholders in the string using the args object
|
||||
if (obj && typeof obj === "string") {
|
||||
obj = obj.replace(/%\w+/g, (placeholder) => {
|
||||
const argKey = placeholder.slice(1); // Remove the `%` to get the key
|
||||
return args[argKey] !== undefined ? args[argKey] : placeholder;
|
||||
});
|
||||
}
|
||||
return obj || key;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return key;
|
||||
}
|
||||
return obj || key;
|
||||
};
|
||||
const summaryTime = function (summaryStatus) {
|
||||
if (summaryStatus == "No Data") {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Hell",
|
||||
"Link Copied": "Link kopiert",
|
||||
"LIVE Status": "LIVE-Status",
|
||||
"MAINTENANCE": "WARTUNG",
|
||||
"Mode": "Modus",
|
||||
"MONITORING": "ÜBERWACHUNG",
|
||||
"No Data": "Keine Daten",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Laufende Vorfälle",
|
||||
"Pinging": "Pingen",
|
||||
"Recent Incidents": "Kürzliche Vorfälle",
|
||||
"Recent Maintenances": "Kürzliche Wartungen",
|
||||
"RESOLVED": "GELÖST",
|
||||
"Share": "Teilen",
|
||||
"Share this monitor using a link with others": "Teilen Sie diesen Monitor mit einem Link mit anderen",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "VERFÜGBAR",
|
||||
"Updates": "Updates",
|
||||
"Uptime": "Verfügbarkeit",
|
||||
"%status for %duration": "%status für %duration"
|
||||
"%status for %duration": "%status für %duration",
|
||||
"Maintenance in Progress": "Wartung läuft",
|
||||
"Maintenance Completed": "Wartung abgeschlossen",
|
||||
"Upcoming Maintenance": "Bevorstehende Wartung",
|
||||
"Browse Events": "Ereignisse durchsuchen"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Lys",
|
||||
"Link Copied": "Link Kopieret",
|
||||
"LIVE Status": "LIVE-status",
|
||||
"MAINTENANCE": "VEDLIGEHOLDELSE",
|
||||
"Mode": "Tilstand",
|
||||
"MONITORING": "OVERVÅGNING",
|
||||
"No Data": "Ingen Data",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Igangværende Hændelser",
|
||||
"Pinging": "Pinger",
|
||||
"Recent Incidents": "Seneste Hændelser",
|
||||
"Recent Maintenances": "Seneste Vedligeholdelser",
|
||||
"RESOLVED": "LØST",
|
||||
"Share": "Del",
|
||||
"Share this monitor using a link with others": "Del denne monitor ved hjælp af et link med andre",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "OPPE",
|
||||
"Updates": "Opdateringer",
|
||||
"Uptime": "Oppetid",
|
||||
"%status for %duration": "%status i %duration"
|
||||
"%status for %duration": "%status i %duration",
|
||||
"Maintenance in Progress": "Vedligeholdelse i gang",
|
||||
"Maintenance Completed": "Vedligeholdelse afsluttet",
|
||||
"Upcoming Maintenance": "Kommende vedligeholdelse",
|
||||
"Browse Events": "Gennemse begivenheder"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Light",
|
||||
"Link Copied": "Link Copied",
|
||||
"LIVE Status": "LIVE Status",
|
||||
"MAINTENANCE": "MAINTENANCE",
|
||||
"Mode": "Mode",
|
||||
"MONITORING": "MONITORING",
|
||||
"No Data": "No Data",
|
||||
@@ -35,7 +36,9 @@
|
||||
"No Updates Yet": "No Updates Yet",
|
||||
"Ongoing Incidents": "Ongoing Incidents",
|
||||
"Pinging": "Pinging",
|
||||
"Browse Events": "Browse Events",
|
||||
"Recent Incidents": "Recent Incidents",
|
||||
"Recent Maintenances": "Recent Maintenances",
|
||||
"RESOLVED": "RESOLVED",
|
||||
"Share": "Share",
|
||||
"Share this monitor using a link with others": "Share this monitor using a link with others",
|
||||
@@ -51,5 +54,8 @@
|
||||
"UP": "UP",
|
||||
"Updates": "Updates",
|
||||
"Uptime": "Uptime",
|
||||
"%status for %duration": "%status for %duration"
|
||||
}
|
||||
"%status for %duration": "%status for %duration",
|
||||
"Maintenance in Progress": "Maintenance in Progress",
|
||||
"Maintenance Completed": "Maintenance Completed",
|
||||
"Upcoming Maintenance": "Upcoming Maintenance"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Clair",
|
||||
"Link Copied": "Lien copié",
|
||||
"LIVE Status": "Statut LIVE",
|
||||
"MAINTENANCE": "Maintenance",
|
||||
"Mode": "Mode",
|
||||
"MONITORING": "En surveillance",
|
||||
"No Data": "Pas de données",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Incidents en cours",
|
||||
"Pinging": "Ping en cours",
|
||||
"Recent Incidents": "Incidents récents",
|
||||
"Recent Maintenances": "Maintenances récentes",
|
||||
"RESOLVED": "Résolu",
|
||||
"Share": "Partager",
|
||||
"Share this monitor using a link with others": "Partagez ce moniteur avec un lien à d'autres personnes",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "En ligne",
|
||||
"Updates": "Mises à jour",
|
||||
"Uptime": "Temps de fonctionnement",
|
||||
"%status for %duration": "%status pendant %duration"
|
||||
"%status for %duration": "%status pendant %duration",
|
||||
"Maintenance in Progress": "Maintenance en cours",
|
||||
"Maintenance Completed": "Maintenance terminée",
|
||||
"Upcoming Maintenance": "Maintenance à venir",
|
||||
"Browse Events": "Parcourir les événements"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "लाइट",
|
||||
"Link Copied": "लिंक कॉपी किया गया",
|
||||
"LIVE Status": "लाइव स्टेटस",
|
||||
"MAINTENANCE": "मेंटेनेंस",
|
||||
"Mode": "मोड",
|
||||
"MONITORING": "निगरानी",
|
||||
"No Data": "कोई डेटा नहीं",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "चल रही घटनाएँ",
|
||||
"Pinging": "पिंगिंग",
|
||||
"Recent Incidents": "हाल की घटनाएँ",
|
||||
"Recent Maintenances": "हाल की मेंटेनेंस",
|
||||
"RESOLVED": "सुलझाया गया",
|
||||
"Share": "साझा करें",
|
||||
"Share this monitor using a link with others": "इस मॉनिटर को दूसरों के साथ लिंक के माध्यम से साझा करें",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "अप",
|
||||
"Updates": "अपडेट्स",
|
||||
"Uptime": "अपटाइम",
|
||||
"%status for %duration": "%duration के लिए %status"
|
||||
"%status for %duration": "%duration के लिए %status",
|
||||
"Maintenance in Progress": "मेंटेनेंस जारी है",
|
||||
"Maintenance Completed": "मेंटेनेंस पूर्ण हुआ",
|
||||
"Upcoming Maintenance": "आगामी मेंटेनेंस",
|
||||
"Browse Events": "ईवेंट ब्राउज़ करें"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "ライト",
|
||||
"Link Copied": "リンクがコピーされました",
|
||||
"LIVE Status": "ライブステータス",
|
||||
"MAINTENANCE": "メンテナンス",
|
||||
"Mode": "モード",
|
||||
"MONITORING": "モニタリング中",
|
||||
"No Data": "データなし",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "進行中のインシデント",
|
||||
"Pinging": "ピング中",
|
||||
"Recent Incidents": "最近のインシデント",
|
||||
"Recent Maintenances": "最近のメンテナンス",
|
||||
"RESOLVED": "解決済み",
|
||||
"Share": "共有",
|
||||
"Share this monitor using a link with others": "このモニターをリンクで他の人と共有",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "稼働中",
|
||||
"Updates": "更新",
|
||||
"Uptime": "稼働時間",
|
||||
"%status for %duration": "%duration の間 %status"
|
||||
"%status for %duration": "%duration の間 %status",
|
||||
"Maintenance in Progress": "メンテナンス中",
|
||||
"Maintenance Completed": "メンテナンス完了",
|
||||
"Upcoming Maintenance": "今後のメンテナンス",
|
||||
"Browse Events": "イベントを閲覧"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "라이트",
|
||||
"Link Copied": "링크 복사됨",
|
||||
"LIVE Status": "실시간 상태",
|
||||
"MAINTENANCE": "유지보수",
|
||||
"Mode": "모드",
|
||||
"MONITORING": "감시 중",
|
||||
"No Data": "데이터 없음",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "진행중 사건",
|
||||
"Pinging": "핑 요청",
|
||||
"Recent Incidents": "최근 사건",
|
||||
"Recent Maintenances": "최근 유지보수",
|
||||
"RESOLVED": "해결됨",
|
||||
"Share": "공유",
|
||||
"Share this monitor using a link with others": "링크를 사용하여 다른 사람들과 이 모니터링 데이터를 공유해보세요",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "작동 중",
|
||||
"Updates": "업데이트",
|
||||
"Uptime": "업타임",
|
||||
"%status for %duration": "%duration 동안 %status 상태였음"
|
||||
"%status for %duration": "%duration 동안 %status 상태였음",
|
||||
"Maintenance in Progress": "유지보수 진행 중",
|
||||
"Maintenance Completed": "유지보수 완료",
|
||||
"Upcoming Maintenance": "예정된 유지보수",
|
||||
"Browse Events": "이벤트 찾아보기"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Licht",
|
||||
"Link Copied": "Link gekopieerd",
|
||||
"LIVE Status": "LIVE status",
|
||||
"MAINTENANCE": "ONDERHOUD",
|
||||
"Mode": "Modus",
|
||||
"MONITORING": "MONITOREN",
|
||||
"No Data": "Geen gegevens",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Lopende incidenten",
|
||||
"Pinging": "Pingen",
|
||||
"Recent Incidents": "Recente incidenten",
|
||||
"Recent Maintenances": "Recente onderhoudsbeurten",
|
||||
"RESOLVED": "OPGELOST",
|
||||
"Share": "Delen",
|
||||
"Share this monitor using a link with others": "Deel deze monitor met anderen via een link",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "BEREIKBAAR",
|
||||
"Updates": "Updates",
|
||||
"Uptime": "Uptime",
|
||||
"%status for %duration": "%status voor %duration"
|
||||
}
|
||||
"%status for %duration": "%status voor %duration",
|
||||
"Maintenance in Progress": "Onderhoud bezig",
|
||||
"Maintenance Completed": "Onderhoud voltooid",
|
||||
"Upcoming Maintenance": "Aankomend onderhoud",
|
||||
"Browse Events": "Evenementen bekijken"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Claro",
|
||||
"Link Copied": "Link Copiado",
|
||||
"LIVE Status": "Status AO VIVO",
|
||||
"MAINTENANCE": "MANUTENÇÃO",
|
||||
"Mode": "Modo",
|
||||
"MONITORING": "MONITORANDO",
|
||||
"No Data": "Sem dados",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Incidentes em Andamento",
|
||||
"Pinging": "Animado",
|
||||
"Recent Incidents": "Incidentes Recentes",
|
||||
"Recent Maintenances": "Manutenções Recentes",
|
||||
"RESOLVED": "RESOLVIDO",
|
||||
"Share": "Compartilhar",
|
||||
"Share this monitor using a link with others": "Compartilhar este monitor através do link",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "OPERACIONAL",
|
||||
"Updates": "Atualizações",
|
||||
"Uptime": "Tempo de Atividade",
|
||||
"%status for %duration": "%status por %duration"
|
||||
"%status for %duration": "%status por %duration",
|
||||
"Maintenance in Progress": "Manutenção em Progresso",
|
||||
"Maintenance Completed": "Manutenção Concluída",
|
||||
"Upcoming Maintenance": "Manutenção Agendada",
|
||||
"Browse Events": "Navegar Eventos"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Светлая",
|
||||
"Link Copied": "Ссылка скопирована",
|
||||
"LIVE Status": "ЖИВОЙ статус",
|
||||
"MAINTENANCE": "ОБСЛУЖИВАНИЕ",
|
||||
"Mode": "Режим",
|
||||
"MONITORING": "МОНИТОРИНГ",
|
||||
"No Data": "Нет данных",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Текущие инциденты",
|
||||
"Pinging": "Пингуется",
|
||||
"Recent Incidents": "Недавние инциденты",
|
||||
"Recent Maintenances": "Последние обслуживания",
|
||||
"RESOLVED": "РЕШЕНО",
|
||||
"Share": "Поделиться",
|
||||
"Share this monitor using a link with others": "Поделитесь этим монитором с другими по ссылке",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "РАБОТАЕТ",
|
||||
"Updates": "Обновления",
|
||||
"Uptime": "Время работы",
|
||||
"%status for %duration": "%status в течение %duration"
|
||||
"%status for %duration": "%status в течение %duration",
|
||||
"Maintenance in Progress": "Техническое обслуживание",
|
||||
"Maintenance Completed": "Техническое обслуживание завершено",
|
||||
"Upcoming Maintenance": "Предстоящее техническое обслуживание",
|
||||
"Browse Events": "Просмотр событий"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Açık",
|
||||
"Link Copied": "Bağlantı Kopyalandı",
|
||||
"LIVE Status": "CANLI Durum",
|
||||
"MAINTENANCE": "BAKIM",
|
||||
"Mode": "Mod",
|
||||
"MONITORING": "İZLEME",
|
||||
"No Data": "Veri Yok",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Devam Eden Olaylar",
|
||||
"Pinging": "Pinging",
|
||||
"Recent Incidents": "Son Olaylar",
|
||||
"Recent Maintenances": "Son Bakımlar",
|
||||
"RESOLVED": "ÇÖZÜLDÜ",
|
||||
"Share": "Paylaş",
|
||||
"Share this monitor using a link with others": "Bu servisi bir bağlantı kullanarak başkalarıyla paylaşın",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "ÇALIŞIYOR",
|
||||
"Updates": "Güncellemeler",
|
||||
"Uptime": "Çalışma Süresi",
|
||||
"%status for %duration": "%duration boyunca %status"
|
||||
}
|
||||
"%status for %duration": "%duration boyunca %status",
|
||||
"Maintenance in Progress": "Bakım Devam Ediyor",
|
||||
"Maintenance Completed": "Bakım Tamamlandı",
|
||||
"Upcoming Maintenance": "Yaklaşan Bakım",
|
||||
"Browse Events": "Etkinliklere Göz At"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "Sáng",
|
||||
"Link Copied": "Liên kết đã được sao chép",
|
||||
"LIVE Status": "Trạng thái TRỰC TIẾP",
|
||||
"MAINTENANCE": "Bảo trì",
|
||||
"Mode": "Chế độ",
|
||||
"MONITORING": "Đang giám sát",
|
||||
"No Data": "Không có dữ liệu",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "Sự cố đang diễn ra",
|
||||
"Pinging": "Đang kiểm tra",
|
||||
"Recent Incidents": "Sự cố gần đây",
|
||||
"Recent Maintenances": "Bảo trì gần đây",
|
||||
"RESOLVED": "Đã giải quyết",
|
||||
"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",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "Hoạt động",
|
||||
"Updates": "Cập nhật",
|
||||
"Uptime": "Thời gian hoạt động",
|
||||
"%status for %duration": "%status trong %duration"
|
||||
"%status for %duration": "%status trong %duration",
|
||||
"Maintenance in Progress": "Bảo trì đang diễn ra",
|
||||
"Maintenance Completed": "Bảo trì đã hoàn thành",
|
||||
"Upcoming Maintenance": "Bảo trì sắp tới",
|
||||
"Browse Events": "Duyệt sự kiện"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"Light": "浅色",
|
||||
"Link Copied": "链接已复制",
|
||||
"LIVE Status": "实时状态",
|
||||
"MAINTENANCE": "维护",
|
||||
"Mode": "模式",
|
||||
"MONITORING": "正在监控",
|
||||
"No Data": "无数据",
|
||||
@@ -36,6 +37,7 @@
|
||||
"Ongoing Incidents": "正在处理的事件",
|
||||
"Pinging": "正在测试",
|
||||
"Recent Incidents": "最近的事件",
|
||||
"Recent Maintenances": "最近的维护",
|
||||
"RESOLVED": "已解决",
|
||||
"Share": "分享",
|
||||
"Share this monitor using a link with others": "通过链接与他人分享此监控",
|
||||
@@ -51,5 +53,9 @@
|
||||
"UP": "可用",
|
||||
"Updates": "更新",
|
||||
"Uptime": "正常运行时间",
|
||||
"%status for %duration": "%duration 内的 %status"
|
||||
"%status for %duration": "%duration 内的 %status",
|
||||
"Maintenance in Progress": "维护进行中",
|
||||
"Maintenance Completed": "维护已完成",
|
||||
"Upcoming Maintenance": "即将进行的维护",
|
||||
"Browse Events": "浏览事件"
|
||||
}
|
||||
|
||||
@@ -490,11 +490,17 @@ export const CreateIncident = async (data) => {
|
||||
start_date_time: data.start_date_time,
|
||||
status: !!data.status ? data.status : "OPEN",
|
||||
end_date_time: !!data.end_date_time ? data.end_date_time : null,
|
||||
state: !!data.state ? data.state : "INVESTIGATING"
|
||||
state: !!data.state ? data.state : "INVESTIGATING",
|
||||
incident_type: !!data.incident_type ? data.incident_type : "INCIDENT"
|
||||
};
|
||||
|
||||
//incident_type == INCIDENT delete endDateTime
|
||||
if (incident.incident_type === "INCIDENT") {
|
||||
incident.end_date_time = null;
|
||||
}
|
||||
|
||||
//if endDateTime is provided and it is less than startDateTime, throw error
|
||||
if (incident.end_date_time && incident.end_date_time < incident.start_date_time) {
|
||||
if (!!incident.end_date_time && incident.end_date_time < incident.start_date_time) {
|
||||
throw new Error("End date time cannot be less than start date time");
|
||||
}
|
||||
|
||||
@@ -638,9 +644,9 @@ export const AddIncidentComment = async (incident_id, comment, state, commented_
|
||||
}
|
||||
|
||||
let c = await db.insertIncidentComment(incident_id, comment, state, commented_at);
|
||||
|
||||
let incidentType = incidentExists.incident_type;
|
||||
//update incident state
|
||||
if (c) {
|
||||
if (c && incidentType === "INCIDENT") {
|
||||
let incidentUpdate = {
|
||||
state: state
|
||||
};
|
||||
|
||||
@@ -51,7 +51,10 @@ const defaultEval = `(async function (statusCode, responseTime, responseData) {
|
||||
|
||||
async function manualIncident(monitor) {
|
||||
let startTs = GetMinuteStartNowTimestampUTC();
|
||||
let impactArr = await db.getIncidentsByMonitorTagRealtime(monitor.tag, startTs);
|
||||
let incidentArr = await db.getIncidentsByMonitorTagRealtime(monitor.tag, startTs);
|
||||
let maintenanceArr = await db.getMaintenanceByMonitorTagRealtime(monitor.tag, startTs);
|
||||
|
||||
let impactArr = incidentArr.concat(maintenanceArr);
|
||||
|
||||
let impact = "";
|
||||
if (impactArr.length == 0) {
|
||||
|
||||
@@ -394,7 +394,8 @@ class DbImpl {
|
||||
status: data.status,
|
||||
state: data.state,
|
||||
created_at: this.knex.fn.now(),
|
||||
updated_at: this.knex.fn.now()
|
||||
updated_at: this.knex.fn.now(),
|
||||
incident_type: data.incident_type
|
||||
});
|
||||
}
|
||||
|
||||
@@ -549,11 +550,29 @@ class DbImpl {
|
||||
)
|
||||
.innerJoin("incident_monitors as im", "i.id", "im.incident_id")
|
||||
.where("im.monitor_tag", monitor_tag)
|
||||
.andWhere("i.start_date_time", "<", timestamp)
|
||||
.andWhere("i.start_date_time", "<=", timestamp)
|
||||
.andWhere("i.status", "OPEN")
|
||||
.andWhere("i.incident_type", "INCIDENT")
|
||||
.andWhere("i.state", "!=", "RESOLVED");
|
||||
}
|
||||
|
||||
async getMaintenanceByMonitorTagRealtime(monitor_tag, timestamp) {
|
||||
return await this.knex("incidents as i")
|
||||
.select(
|
||||
"i.id as id",
|
||||
"i.start_date_time as start_date_time",
|
||||
"i.end_date_time as end_date_time",
|
||||
"im.monitor_impact"
|
||||
)
|
||||
.innerJoin("incident_monitors as im", "i.id", "im.incident_id")
|
||||
.where("im.monitor_tag", monitor_tag)
|
||||
.andWhere("i.start_date_time", "<=", timestamp)
|
||||
.andWhere("i.end_date_time", ">=", timestamp)
|
||||
.andWhere("i.status", "OPEN")
|
||||
.andWhere("i.incident_type", "MAINTENANCE")
|
||||
.andWhere("i.state", "=", "RESOLVED");
|
||||
}
|
||||
|
||||
//given array of ids get incidents
|
||||
async getIncidentsByIds(ids) {
|
||||
return await this.knex("incidents").whereIn("id", ids).andWhere("status", "OPEN");
|
||||
|
||||
@@ -137,7 +137,6 @@ const FetchData = async function (site, monitor, localTz, selectedLang, lang) {
|
||||
|
||||
_90Day[ts].timestamp = ts;
|
||||
_90Day[ts].cssClass = cssClass;
|
||||
|
||||
_90Day[ts].summaryStatus = l(lang, summaryTime(summaryStatus), {
|
||||
status: l(lang, summaryStatus),
|
||||
duration: summaryDuration
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
import { base } from "$app/paths";
|
||||
|
||||
export async function load({ parent, url }) {
|
||||
throw redirect(302, base + "/docs/home");
|
||||
}
|
||||
@@ -98,11 +98,17 @@ export async function load({ parent, url }) {
|
||||
});
|
||||
return incident;
|
||||
});
|
||||
let unresolvedIncidents = allOpenIncidents.filter((incident) => incident.state !== "RESOLVED");
|
||||
|
||||
let allRecentIncidents = allOpenIncidents.filter(
|
||||
(incident) => incident.incident_type == "INCIDENT"
|
||||
);
|
||||
let allRecentMaintenances = allOpenIncidents.filter(
|
||||
(incident) => incident.incident_type == "MAINTENANCE"
|
||||
);
|
||||
return {
|
||||
monitors: monitorsActive,
|
||||
unresolvedIncidents: allOpenIncidents,
|
||||
allRecentIncidents,
|
||||
allRecentMaintenances,
|
||||
categoryName: requiredCategory,
|
||||
isCategoryPage: isCategoryPage,
|
||||
isMonitorPage: isMonitorPage,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import { onMount } from "svelte";
|
||||
import ShareMenu from "$lib/components/shareMenu.svelte";
|
||||
import { scale } from "svelte/transition";
|
||||
import { format } from "date-fns";
|
||||
|
||||
export let data;
|
||||
let shareMenusToggle = false;
|
||||
@@ -43,6 +44,14 @@
|
||||
onMount(() => {
|
||||
pageLoaded = true;
|
||||
});
|
||||
let kindFilter = "INCIDENT";
|
||||
function kindOfIncidents(kind) {
|
||||
kindFilter = kind;
|
||||
}
|
||||
|
||||
if (data.allRecentIncidents.length == 0) {
|
||||
kindOfIncidents("MAINTENANCE");
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -96,16 +105,47 @@
|
||||
</Button>
|
||||
</section>
|
||||
{/if}
|
||||
{#if data.unresolvedIncidents.length > 0}
|
||||
{#if data.allRecentIncidents.length + data.allRecentMaintenances.length > 0}
|
||||
<section
|
||||
class="mx-auto mb-2 flex w-full max-w-[655px] flex-1 flex-col items-start justify-center bg-transparent"
|
||||
id=""
|
||||
>
|
||||
<div class="grid w-full grid-cols-2 gap-4">
|
||||
<div class="col-span-2 text-center md:col-span-1 md:text-left">
|
||||
<Badge variant="outline" class="border-0 pl-0">
|
||||
{l(data.lang, "Ongoing Incidents")}
|
||||
</Badge>
|
||||
{#if kindFilter == "INCIDENT"}
|
||||
{#if data.allRecentIncidents.length > 0}
|
||||
<Button class="h-8 text-sm" on:click={() => kindOfIncidents("INCIDENT")}>
|
||||
{l(data.lang, "Recent Incidents")}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if data.allRecentMaintenances.length > 0}
|
||||
<Button
|
||||
variant="secondary"
|
||||
class="h-8 text-sm"
|
||||
on:click={() => kindOfIncidents("MAINTENANCE")}
|
||||
>
|
||||
{l(data.lang, "Recent Maintenances")}
|
||||
</Button>
|
||||
{/if}
|
||||
{:else}
|
||||
{#if data.allRecentIncidents.length > 0}
|
||||
<Button
|
||||
variant="secondary"
|
||||
class="h-8 text-sm"
|
||||
on:click={() => kindOfIncidents("INCIDENT")}
|
||||
>
|
||||
{l(data.lang, "Recent Incidents")}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if data.allRecentMaintenances.length > 0}
|
||||
<Button
|
||||
class="h-8 text-sm"
|
||||
on:click={() => kindOfIncidents("MAINTENANCE")}
|
||||
>
|
||||
{l(data.lang, "Recent Maintenances")}
|
||||
</Button>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -114,8 +154,19 @@
|
||||
id=""
|
||||
>
|
||||
<Card.Root class="w-full">
|
||||
<Card.Content class=" newincidents w-full overflow-hidden p-0">
|
||||
{#each data.unresolvedIncidents as incident, index}
|
||||
{#if kindFilter == "INCIDENT"}
|
||||
<Card.Content class=" newincidents w-full overflow-hidden p-0">
|
||||
{#each data.allRecentIncidents as incident, index}
|
||||
<Incident
|
||||
{incident}
|
||||
lang={data.lang}
|
||||
index="incident-{index}"
|
||||
selectedLang={data.selectedLang}
|
||||
/>
|
||||
{/each}
|
||||
</Card.Content>
|
||||
{:else if kindFilter == "MAINTENANCE"}
|
||||
{#each data.allRecentMaintenances as incident, index}
|
||||
<Incident
|
||||
{incident}
|
||||
lang={data.lang}
|
||||
@@ -123,7 +174,7 @@
|
||||
selectedLang={data.selectedLang}
|
||||
/>
|
||||
{/each}
|
||||
</Card.Content>
|
||||
{/if}
|
||||
</Card.Root>
|
||||
</section>
|
||||
{/if}
|
||||
@@ -186,8 +237,10 @@
|
||||
class="relative z-10 mx-auto mb-8 w-full max-w-[890px] flex-1 flex-col items-start backdrop-blur-[2px] md:w-[655px]"
|
||||
>
|
||||
{#each data.site.categories.filter((e) => e.name != "Home") as category}
|
||||
<div
|
||||
on:click={() => {
|
||||
<a
|
||||
href={`?category=${category.name}`}
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
window.location.href = `?category=${category.name}`;
|
||||
}}
|
||||
>
|
||||
@@ -210,7 +263,7 @@
|
||||
</Card.Description>
|
||||
</Card.Header>
|
||||
</Card.Root>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</section>
|
||||
{/if}
|
||||
@@ -218,21 +271,23 @@
|
||||
class="mx-auto mb-2 flex w-full max-w-[655px] flex-1 flex-col items-start justify-center bg-transparent"
|
||||
id=""
|
||||
>
|
||||
<div
|
||||
on:click={() => {
|
||||
window.location.href = `${base}/incidents`;
|
||||
<a
|
||||
href="{base}/incidents/{format(new Date(), 'MMMM-yyyy')}"
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
window.location.href = `${base}/incidents/${format(new Date(), "MMMM-yyyy")}`;
|
||||
}}
|
||||
class="bounce-right grid w-full cursor-pointer grid-cols-2 justify-between gap-4 rounded-md border bg-card px-4 py-2 text-sm font-medium hover:bg-secondary"
|
||||
>
|
||||
<div class="col-span-1 text-left">
|
||||
{l(data.lang, "Recent Incidents")}
|
||||
{l(data.lang, "Browse Events")}
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="arrow float-right mt-0.5">
|
||||
<ArrowRight class="h-4 w-4 text-muted-foreground hover:text-primary" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
{#if shareMenusToggle}
|
||||
<div
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
id: "/(manage)/manage/(app)/app/alerts"
|
||||
},
|
||||
{
|
||||
name: "Incidents",
|
||||
name: "Events",
|
||||
url: `${base}/manage/app/incidents`,
|
||||
id: "/(manage)/manage/(app)/app/incidents"
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { Label } from "$lib/components/ui/label";
|
||||
import { Button } from "$lib/components/ui/button";
|
||||
import * as Alert from "$lib/components/ui/alert";
|
||||
|
||||
import * as RadioGroup from "$lib/components/ui/radio-group";
|
||||
import moment from "moment";
|
||||
import { DateInput } from "date-picker-svelte";
|
||||
import { clickOutsideAction, slide } from "svelte-legos";
|
||||
@@ -81,7 +81,6 @@
|
||||
}
|
||||
return i;
|
||||
});
|
||||
|
||||
totalPages = Math.ceil(resp.total.count / limit);
|
||||
} catch (error) {
|
||||
alert("Error: " + error);
|
||||
@@ -102,9 +101,12 @@
|
||||
endDatetime: null,
|
||||
startDatetime: null,
|
||||
start_date_time: null,
|
||||
endDatetime: null,
|
||||
ent_date_time: null,
|
||||
status: "OPEN",
|
||||
state: "INVESTIGATING",
|
||||
firstComment: ""
|
||||
firstComment: "",
|
||||
incident_type: "INCIDENT"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -120,7 +122,8 @@
|
||||
end_date_time: newIncident.endDatetime,
|
||||
status: newIncident.status,
|
||||
state: newIncident.state,
|
||||
id: newIncident.id
|
||||
id: newIncident.id,
|
||||
incident_type: newIncident.incident_type
|
||||
};
|
||||
//convert data.start_date_time to timestamp
|
||||
if (!!!toPost.start_date_time) {
|
||||
@@ -128,12 +131,14 @@
|
||||
return;
|
||||
}
|
||||
toPost.start_date_time = parseInt(new Date(toPost.start_date_time).getTime() / 1000);
|
||||
if (!!!toPost.end_date_time) {
|
||||
delete toPost.end_date_time;
|
||||
} else {
|
||||
if (!!toPost.end_date_time) {
|
||||
toPost.end_date_time = parseInt(new Date(toPost.end_date_time).getTime() / 1000);
|
||||
}
|
||||
|
||||
if (toPost.incident_type == "MAINTENANCE") {
|
||||
toPost.state = "RESOLVED";
|
||||
}
|
||||
|
||||
formStateCreate = "loading";
|
||||
try {
|
||||
let data = await fetch(base + "/manage/app/api/", {
|
||||
@@ -155,7 +160,7 @@
|
||||
if (!!!newIncident.id) {
|
||||
newComment.comment = newIncident.firstComment;
|
||||
newComment.id = 0;
|
||||
newComment.state = newIncident.state;
|
||||
newComment.state = toPost.state;
|
||||
newComment.commented_at = newIncident.startDatetime;
|
||||
|
||||
await addNewComment(resp.incident_id);
|
||||
@@ -403,8 +408,10 @@
|
||||
</Select.Group>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
<div class="mx-2">
|
||||
{#if loadingData}
|
||||
<Loader class="ml-2 mt-2 inline h-6 w-6 animate-spin" />
|
||||
<Loader class="float-right ml-2 mt-2 inline h-6 w-6 animate-spin" />
|
||||
{/if}
|
||||
</div>
|
||||
<Button
|
||||
@@ -414,7 +421,7 @@
|
||||
}}
|
||||
>
|
||||
<Plus class="mr-2 inline h-6 w-6" />
|
||||
New Incident
|
||||
New Event
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -563,9 +570,17 @@
|
||||
</td>
|
||||
|
||||
<td class="whitespace-nowrap px-6 py-4 text-xs font-semibold">
|
||||
<span class="badge-{incident.state} rounded px-1.5 py-1"
|
||||
>{incident.state}</span
|
||||
>
|
||||
{#if incident.incident_type == "MAINTENANCE"}
|
||||
<span class="badge-MAINTENANCE rounded px-1.5 py-1">
|
||||
MAINTENANCE
|
||||
</span>
|
||||
{:else}
|
||||
<span
|
||||
class="badge-{incident.state} rounded px-1.5 py-1"
|
||||
>
|
||||
{incident.state}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 text-xs font-semibold">
|
||||
<div class="flex gap-x-1.5">
|
||||
@@ -639,21 +654,53 @@
|
||||
<div class="rounded-md border p-4">
|
||||
<div>
|
||||
{#if newIncident.id}
|
||||
<h2 class="text-lg font-medium">Edit Incident</h2>
|
||||
<h2 class="text-lg font-medium">Edit Event</h2>
|
||||
{:else}
|
||||
<h2 class="text-lg font-medium">Add New Incident</h2>
|
||||
<h2 class="text-lg font-medium">Add New Event</h2>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="mt-4 text-sm font-medium">Event Type</p>
|
||||
<div class="mt-2 flex gap-4">
|
||||
<RadioGroup.Root
|
||||
class=" flex gap-x-2 {!!newIncident.id ? 'opacity-70' : ''}"
|
||||
bind:value={newIncident.incident_type}
|
||||
disabled={!!newIncident.id}
|
||||
>
|
||||
<Label
|
||||
for="type-INCIDENT"
|
||||
class="flex cursor-pointer items-center space-x-2 rounded-md border {newIncident.incident_type ==
|
||||
'INCIDENT'
|
||||
? 'bg-secondary shadow-md'
|
||||
: ''} p-3"
|
||||
>
|
||||
<RadioGroup.Item value="INCIDENT" id="type-INCIDENT" />
|
||||
<span>Incident</span>
|
||||
</Label>
|
||||
<Label
|
||||
for="type-MAINTENANCE"
|
||||
class="flex cursor-pointer items-center space-x-2 rounded-md border p-3 {newIncident.incident_type ==
|
||||
'MAINTENANCE'
|
||||
? 'bg-secondary shadow-md'
|
||||
: ''}"
|
||||
>
|
||||
<RadioGroup.Item value="MAINTENANCE" id="type-MAINTENANCE" />
|
||||
<span> Maintenance </span>
|
||||
</Label>
|
||||
</RadioGroup.Root>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-row gap-4">
|
||||
<div class="w-full">
|
||||
<Label class="text-sm">
|
||||
Incident Title
|
||||
<span class="capitalize">{newIncident.incident_type}</span>
|
||||
Title
|
||||
<span class="text-red-500">*</span>
|
||||
<span
|
||||
class="float-right mt-2 text-xs font-semibold badge-{newIncident.state}"
|
||||
>
|
||||
{newIncident.state}
|
||||
</span>
|
||||
{#if newIncident.incident_type == "INCIDENT"}
|
||||
<span
|
||||
class="float-right mt-2 text-xs font-semibold badge-{newIncident.state}"
|
||||
>
|
||||
{newIncident.state}
|
||||
</span>
|
||||
{/if}
|
||||
</Label>
|
||||
<Input
|
||||
class="mt-2"
|
||||
@@ -667,7 +714,8 @@
|
||||
<div class="mt-4 flex flex-row gap-4">
|
||||
<div class="w-full">
|
||||
<Label class="text-sm">
|
||||
Incident Summary
|
||||
<span class="capitalize">{newIncident.incident_type}</span>
|
||||
Summary
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Input
|
||||
@@ -678,20 +726,37 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-4 flex gap-4">
|
||||
<div class="col-span-1">
|
||||
<Label class="mb-2 text-sm" for="start_date_time">
|
||||
Incident Start Date Time
|
||||
<span class="capitalize">{newIncident.incident_type}</span> Start
|
||||
Date Time
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<DateInput
|
||||
bind:value={newIncident.startDatetime}
|
||||
id="start_date_time"
|
||||
timePrecision="minute"
|
||||
disabled={!!newIncident.id}
|
||||
class="mt-2 text-sm"
|
||||
/>
|
||||
</div>
|
||||
{#if newIncident.incident_type == "MAINTENANCE"}
|
||||
<div class="col-span-1">
|
||||
<Label class="mb-2 text-sm" for="start_date_time">
|
||||
<span class="capitalize">{newIncident.incident_type}</span> End
|
||||
Date Time
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<DateInput
|
||||
bind:value={newIncident.endDatetime}
|
||||
id="end_date_time"
|
||||
timePrecision="minute"
|
||||
class="mt-2 text-sm"
|
||||
min={newIncident.startDatetime}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid h-16 w-full grid-cols-6 gap-2 border-t pt-4">
|
||||
@@ -708,7 +773,9 @@
|
||||
newIncident.title.trim().length == 0 ||
|
||||
!!!newIncident.startDatetime ||
|
||||
(!!!newIncident.id &&
|
||||
newIncident.firstComment.trim().length == 0)}
|
||||
newIncident.firstComment.trim().length == 0) ||
|
||||
(!!!newIncident.endDatetime &&
|
||||
newIncident.incident_type == "MAINTENANCE")}
|
||||
>
|
||||
Save
|
||||
{#if formStateCreate === "loading"}
|
||||
@@ -730,42 +797,44 @@
|
||||
addNewComment();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="bg-hover state-{newComment.state} mt-2 grid grid-cols-4 overflow-hidden rounded-md border text-xs font-medium"
|
||||
>
|
||||
{#if currentIncident.incident_type == "INCIDENT"}
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("INVESTIGATING");
|
||||
}}
|
||||
class="bg-hover state-{newComment.state} mt-2 grid grid-cols-4 overflow-hidden rounded-md border text-xs font-medium"
|
||||
>
|
||||
INVESTIGATING
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("INVESTIGATING");
|
||||
}}
|
||||
>
|
||||
INVESTIGATING
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("IDENTIFIED");
|
||||
}}
|
||||
>
|
||||
IDENTIFIED
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("MONITORING");
|
||||
}}
|
||||
>
|
||||
MONITORING
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("RESOLVED");
|
||||
}}
|
||||
>
|
||||
RESOLVED
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("IDENTIFIED");
|
||||
}}
|
||||
>
|
||||
IDENTIFIED
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("MONITORING");
|
||||
}}
|
||||
>
|
||||
MONITORING
|
||||
</div>
|
||||
<div
|
||||
class="col-span-1 cursor-pointer px-2 py-2 text-center hover:underline"
|
||||
on:click={() => {
|
||||
setCommentState("RESOLVED");
|
||||
}}
|
||||
>
|
||||
RESOLVED
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="mt-4 flex w-full gap-4">
|
||||
<div class="text-sm font-medium leading-7">Time Stamp</div>
|
||||
<DateInput
|
||||
@@ -840,9 +909,11 @@
|
||||
<div
|
||||
class="text-xs font-semibold text-muted-foreground"
|
||||
>
|
||||
<span class="badge-{comment.state}">
|
||||
{comment.state}
|
||||
</span>
|
||||
{#if currentIncident.incident_type == "INCIDENT"}
|
||||
<span class="badge-{comment.state}">
|
||||
{comment.state}
|
||||
</span>
|
||||
{/if}
|
||||
{moment(comment.commented_at * 1000).format(
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user