mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
fix docker files
This commit is contained in:
@@ -10,7 +10,7 @@ const root: any = ReactDOM.createRoot(
|
||||
);
|
||||
|
||||
root.render(
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
@@ -316,14 +316,12 @@ export default class OneUptimeDate {
|
||||
date: string | Date,
|
||||
onlyShowDate?: boolean
|
||||
): string {
|
||||
|
||||
|
||||
let formatstring: string = 'MMM DD YYYY, HH:mm z';
|
||||
|
||||
if (onlyShowDate) {
|
||||
formatstring = 'MMM DD, YYYY';
|
||||
}
|
||||
|
||||
|
||||
return moment(date).format(formatstring);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ export class Service extends DatabaseService<Model> {
|
||||
protected override async onBeforeCreate(
|
||||
data: CreateBy<Model>
|
||||
): Promise<OnCreate<Model>> {
|
||||
|
||||
if (!data.data.statusPageId) {
|
||||
throw new BadDataException('Status Page ID is required.');
|
||||
}
|
||||
@@ -31,36 +30,37 @@ export class Service extends DatabaseService<Model> {
|
||||
const subscriber: Model | null = await this.findOneBy({
|
||||
query: {
|
||||
statusPageId: data.data.statusPageId,
|
||||
subscriberEmail: data.data.subscriberEmail
|
||||
subscriberEmail: data.data.subscriberEmail,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
isUnsubscribed: true
|
||||
isUnsubscribed: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true
|
||||
}
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (subscriber && !subscriber.isUnsubscribed) {
|
||||
throw new BadDataException("You are already subscribed to this status page.");
|
||||
throw new BadDataException(
|
||||
'You are already subscribed to this status page.'
|
||||
);
|
||||
}
|
||||
|
||||
// if the user is unsubscribed, delete this record and it'll create a new one.
|
||||
// if the user is unsubscribed, delete this record and it'll create a new one.
|
||||
|
||||
await this.deleteOneBy({
|
||||
query: {
|
||||
_id: subscriber?._id!
|
||||
_id: subscriber?._id!,
|
||||
},
|
||||
props: {
|
||||
ignoreHooks: true,
|
||||
isRoot: true
|
||||
}
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const statuspage: StatusPage | null =
|
||||
await StatusPageService.findOneById({
|
||||
id: data.data.statusPageId,
|
||||
@@ -80,8 +80,6 @@ export class Service extends DatabaseService<Model> {
|
||||
throw new BadDataException('Status Page not found');
|
||||
}
|
||||
|
||||
|
||||
|
||||
data.data.projectId = statuspage.projectId;
|
||||
|
||||
return { createBy: data, carryForward: statuspage };
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface ComponentProps {
|
||||
cardTitleRight?: string | undefined;
|
||||
cardColor: Color;
|
||||
eventTitle: string;
|
||||
eventResourcesAffected?: Array<string> | undefined,
|
||||
eventResourcesAffected?: Array<string> | undefined;
|
||||
eventDescription?: string | undefined;
|
||||
eventMiniDescription?: string | undefined;
|
||||
eventTimeline: Array<TimelineItem>;
|
||||
|
||||
@@ -23,10 +23,10 @@ const EventHistoryDayList: FunctionComponent<ComponentProps> = (
|
||||
borderBottomWidth: props.isLastItem ? '0px' : '1px',
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: '20px', paddingRight: '0px', width: "15%" }}>
|
||||
<div style={{ padding: '20px', paddingRight: '0px', width: '15%' }}>
|
||||
{OneUptimeDate.getDateAsLocalFormattedString(props.date, true)}
|
||||
</div>
|
||||
<div style={{ padding: '10px', paddingTop: '0px', width: "85%" }}>
|
||||
<div style={{ padding: '10px', paddingTop: '0px', width: '85%' }}>
|
||||
{props.items.map((item: ItemComponentProps, i: number) => {
|
||||
return <EventHistoryItem key={i} {...item} />;
|
||||
})}
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface TimelineItem {
|
||||
}
|
||||
export interface ComponentProps {
|
||||
eventTitle: string;
|
||||
eventResourcesAffected?: Array<string> | undefined,
|
||||
eventResourcesAffected?: Array<string> | undefined;
|
||||
eventDescription?: string | undefined;
|
||||
eventTimeline: Array<TimelineItem>;
|
||||
eventMiniDescription?: string | undefined;
|
||||
@@ -49,27 +49,28 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
||||
className="active-event-box-body"
|
||||
style={{ marginTop: '0px', paddingTop: '0px' }}
|
||||
>
|
||||
|
||||
{props.eventResourcesAffected && props.eventResourcesAffected?.length > 0 ? <div
|
||||
key={0}
|
||||
className="active-event-box-body-description"
|
||||
>
|
||||
{' '}
|
||||
<span
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
<b>Resources Affected</b> - {props.eventResourcesAffected?.join(",")}
|
||||
</span>{' '}
|
||||
</div> : <></>}
|
||||
|
||||
{props.eventResourcesAffected &&
|
||||
props.eventResourcesAffected?.length > 0 ? (
|
||||
<div key={0} className="active-event-box-body-description">
|
||||
{' '}
|
||||
<span
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
<b>Resources Affected</b> -{' '}
|
||||
{props.eventResourcesAffected?.join(',')}
|
||||
</span>{' '}
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{props.eventTimeline &&
|
||||
props.eventTimeline.map((item: TimelineItem, i: number) => {
|
||||
return (
|
||||
<div
|
||||
key={i+1}
|
||||
key={i + 1}
|
||||
className="active-event-box-body-description"
|
||||
>
|
||||
{' '}
|
||||
|
||||
@@ -661,7 +661,6 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
{icon === IconProp.Layout && (
|
||||
<Layout
|
||||
size={size}
|
||||
@@ -670,7 +669,7 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
{icon === IconProp.Compass && (
|
||||
{icon === IconProp.Compass && (
|
||||
<Compass
|
||||
size={size}
|
||||
strokeWidth={thick ? thick : ''}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM nginx:alpine
|
||||
FROM nginx:1.23.3-alpine
|
||||
|
||||
# Install bash.
|
||||
RUN apk update && apk add bash && apk add curl
|
||||
@@ -25,10 +25,15 @@ import Route from 'Common/Types/API/Route';
|
||||
import StatusPageAnnouncement from 'Model/Models/StatusPageAnnouncement';
|
||||
import HTTPResponse from 'Common/Types/API/HTTPResponse';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import EventItem, { ComponentProps as EventItemComponentProps } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import EventItem, {
|
||||
ComponentProps as EventItemComponentProps,
|
||||
} from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
|
||||
export const getAnnouncementEventItem = (announcement: StatusPageAnnouncement, isPreviewPage: boolean): EventItemComponentProps => {
|
||||
return ({
|
||||
export const getAnnouncementEventItem: Function = (
|
||||
announcement: StatusPageAnnouncement,
|
||||
isPreviewPage: boolean
|
||||
): EventItemComponentProps => {
|
||||
return {
|
||||
eventTitle: announcement.title || '',
|
||||
eventDescription: announcement.description,
|
||||
eventTimeline: [],
|
||||
@@ -37,14 +42,12 @@ export const getAnnouncementEventItem = (announcement: StatusPageAnnouncement, i
|
||||
footerDateTime: announcement.showAnnouncementAt,
|
||||
eventViewRoute: RouteUtil.populateRouteParams(
|
||||
isPreviewPage
|
||||
? (RouteMap[
|
||||
PageMap.PREVIEW_ANNOUNCEMENT_DETAIL
|
||||
] as Route)
|
||||
? (RouteMap[PageMap.PREVIEW_ANNOUNCEMENT_DETAIL] as Route)
|
||||
: (RouteMap[PageMap.ANNOUNCEMENT_DETAIL] as Route),
|
||||
announcement.id!
|
||||
),
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const Overview: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps
|
||||
@@ -54,9 +57,8 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
const [_statusPageResources, setStatusPageResources] = useState<
|
||||
Array<StatusPageResource>
|
||||
>([]);
|
||||
const [announcement, setAnnouncement] = useState<
|
||||
StatusPageAnnouncement | null
|
||||
>(null);
|
||||
const [announcement, setAnnouncement] =
|
||||
useState<StatusPageAnnouncement | null>(null);
|
||||
const [parsedData, setParsedData] =
|
||||
useState<EventItemComponentProps | null>(null);
|
||||
|
||||
@@ -71,7 +73,9 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
throw new BadDataException('Status Page ID is required');
|
||||
}
|
||||
|
||||
const announcementId = Navigation.getLastParam()?.toString().replace("/", "");
|
||||
const announcementId: string | undefined = Navigation.getLastParam()
|
||||
?.toString()
|
||||
.replace('/', '');
|
||||
|
||||
const response: HTTPResponse<JSONObject> =
|
||||
await BaseAPI.post<JSONObject>(
|
||||
@@ -106,7 +110,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
try {
|
||||
setError(
|
||||
(err as HTTPErrorResponse).message ||
|
||||
'Server Error. Please try again'
|
||||
'Server Error. Please try again'
|
||||
);
|
||||
} catch (e) {
|
||||
setError('Server Error. Please try again');
|
||||
@@ -126,7 +130,9 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
return;
|
||||
}
|
||||
|
||||
setParsedData(getAnnouncementEventItem(announcement, !!props.isPreviewPage));
|
||||
setParsedData(
|
||||
getAnnouncementEventItem(announcement, Boolean(props.isPreviewPage))
|
||||
);
|
||||
}, [isLoading]);
|
||||
|
||||
if (isLoading) {
|
||||
@@ -143,13 +149,12 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
||||
{announcement ? <EventItem {...parsedData} /> : <></>}
|
||||
{!announcement ? (
|
||||
<ErrorMessage
|
||||
error="No announcement found with this ID."
|
||||
/>
|
||||
) : <></>}
|
||||
<ErrorMessage error="No announcement found with this ID." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
try {
|
||||
setError(
|
||||
(err as HTTPErrorResponse).message ||
|
||||
'Server Error. Please try again'
|
||||
'Server Error. Please try again'
|
||||
);
|
||||
} catch (e) {
|
||||
setError('Server Error. Please try again');
|
||||
@@ -119,7 +119,12 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
};
|
||||
}
|
||||
|
||||
days[dayString]?.items.push(getAnnouncementEventItem(announcement, !!props.isPreviewPage));
|
||||
days[dayString]?.items.push(
|
||||
getAnnouncementEventItem(
|
||||
announcement,
|
||||
Boolean(props.isPreviewPage)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (const key in days) {
|
||||
@@ -145,16 +150,23 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
||||
{announcements && announcements.length > 0 ? <h3>Announcements</h3> : <></>}
|
||||
{announcements && announcements.length > 0 ? (
|
||||
<h3>Announcements</h3>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{announcements && announcements.length > 0 ? <EventHistoryList {...parsedData} /> : <></>}
|
||||
{announcements && announcements.length > 0 ? (
|
||||
<EventHistoryList {...parsedData} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{announcements.length === 0 ? (
|
||||
<ErrorMessage
|
||||
error="No announcements reported on this status page."
|
||||
/>
|
||||
) : <></>}
|
||||
<ErrorMessage error="No announcements reported on this status page." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@ import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
import LocalStorage from 'CommonUI/src/Utils/LocalStorage';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import BaseModel from 'Common/Models/BaseModel';
|
||||
import { ComponentProps as EventItemComponentProps } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import StatusPageResource from 'Model/Models/StatusPageResource';
|
||||
import Incident from 'Model/Models/Incident';
|
||||
import IncidentPublicNote from 'Model/Models/IncidentPublicNote';
|
||||
@@ -28,62 +27,86 @@ import RouteMap, { RouteUtil } from '../../Utils/RouteMap';
|
||||
import PageMap from '../../Utils/PageMap';
|
||||
import Route from 'Common/Types/API/Route';
|
||||
import HTTPResponse from 'Common/Types/API/HTTPResponse';
|
||||
import EventItem, { TimelineItem } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import EventItem, {
|
||||
TimelineItem,
|
||||
ComponentProps as EventItemComponentProps,
|
||||
} from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import Monitor from 'Model/Models/Monitor';
|
||||
|
||||
export const getIncidentEventItem: Function = (incident: Incident, incidentPublicNotes: Array<IncidentPublicNote>, incidentStateTimelines: Array<IncidentStateTimeline>, statusPageResources: Array<StatusPageResource>, isPreviewPage: boolean): EventItemComponentProps => {
|
||||
export const getIncidentEventItem: Function = (
|
||||
incident: Incident,
|
||||
incidentPublicNotes: Array<IncidentPublicNote>,
|
||||
incidentStateTimelines: Array<IncidentStateTimeline>,
|
||||
statusPageResources: Array<StatusPageResource>,
|
||||
isPreviewPage: boolean
|
||||
): EventItemComponentProps => {
|
||||
const timeline: Array<TimelineItem> = [];
|
||||
|
||||
for (const incidentPublicNote of incidentPublicNotes) {
|
||||
if (
|
||||
incidentPublicNote.incidentId?.toString() ===
|
||||
incident.id?.toString()
|
||||
) {
|
||||
timeline.push({
|
||||
text: (<span><b>Update</b> - <span>{incidentPublicNote?.note}</span></span>),
|
||||
date: incidentPublicNote?.createdAt!,
|
||||
isBold: false,
|
||||
});
|
||||
}
|
||||
for (const incidentPublicNote of incidentPublicNotes) {
|
||||
if (
|
||||
incidentPublicNote.incidentId?.toString() ===
|
||||
incident.id?.toString()
|
||||
) {
|
||||
timeline.push({
|
||||
text: (
|
||||
<span>
|
||||
<b>Update</b> - <span>{incidentPublicNote?.note}</span>
|
||||
</span>
|
||||
),
|
||||
date: incidentPublicNote?.createdAt!,
|
||||
isBold: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const incidentStateTimeline of incidentStateTimelines) {
|
||||
if (
|
||||
incidentStateTimeline.incidentId?.toString() ===
|
||||
incident.id?.toString()
|
||||
) {
|
||||
timeline.push({
|
||||
text: incidentStateTimeline.incidentState?.name || '',
|
||||
date: incidentStateTimeline?.createdAt!,
|
||||
isBold: true,
|
||||
});
|
||||
}
|
||||
for (const incidentStateTimeline of incidentStateTimelines) {
|
||||
if (
|
||||
incidentStateTimeline.incidentId?.toString() ===
|
||||
incident.id?.toString()
|
||||
) {
|
||||
timeline.push({
|
||||
text: incidentStateTimeline.incidentState?.name || '',
|
||||
date: incidentStateTimeline?.createdAt!,
|
||||
isBold: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
timeline.sort((a: TimelineItem, b: TimelineItem) => {
|
||||
return OneUptimeDate.isAfter(a.date, b.date) === true ? 1 : -1;
|
||||
timeline.sort((a: TimelineItem, b: TimelineItem) => {
|
||||
return OneUptimeDate.isAfter(a.date, b.date) === true ? 1 : -1;
|
||||
});
|
||||
|
||||
const monitorIds: Array<string | undefined> =
|
||||
incident.monitors?.map((monitor: Monitor) => {
|
||||
return monitor._id;
|
||||
}) || [];
|
||||
|
||||
const namesOfResources: Array<StatusPageResource> =
|
||||
statusPageResources.filter((resource: StatusPageResource) => {
|
||||
return monitorIds.includes(resource.monitorId?.toString());
|
||||
});
|
||||
|
||||
const monitorIds = incident.monitors?.map((monitor) => monitor._id) || [];
|
||||
const data: EventItemComponentProps = {
|
||||
eventTitle: incident.title || '',
|
||||
eventDescription: incident.description,
|
||||
eventResourcesAffected: namesOfResources.map(
|
||||
(i: StatusPageResource) => {
|
||||
return i.displayName || '';
|
||||
}
|
||||
),
|
||||
eventTimeline: timeline,
|
||||
eventType: 'Incident',
|
||||
eventViewRoute: RouteUtil.populateRouteParams(
|
||||
isPreviewPage
|
||||
? (RouteMap[PageMap.PREVIEW_INCIDENT_DETAIL] as Route)
|
||||
: (RouteMap[PageMap.INCIDENT_DETAIL] as Route),
|
||||
incident.id!
|
||||
),
|
||||
};
|
||||
|
||||
const namesOfResources = statusPageResources.filter((resource) => monitorIds.includes(resource.monitorId?.toString()));
|
||||
|
||||
const data = {
|
||||
eventTitle: incident.title || '',
|
||||
eventDescription: incident.description,
|
||||
eventResourcesAffected: namesOfResources.map((i) => i.displayName || ''),
|
||||
eventTimeline: timeline,
|
||||
eventType: 'Incident',
|
||||
eventViewRoute: RouteUtil.populateRouteParams(
|
||||
isPreviewPage
|
||||
? (RouteMap[PageMap.PREVIEW_INCIDENT_DETAIL] as Route)
|
||||
: (RouteMap[PageMap.INCIDENT_DETAIL] as Route),
|
||||
incident.id!
|
||||
),
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
const Detail: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps
|
||||
@@ -111,7 +134,9 @@ const Detail: FunctionComponent<PageComponentProps> = (
|
||||
'statusPageId'
|
||||
) as ObjectID;
|
||||
|
||||
const incidentId = Navigation.getLastParam()?.toString().replace("/", "");
|
||||
const incidentId: string | undefined = Navigation.getLastParam()
|
||||
?.toString()
|
||||
.replace('/', '');
|
||||
|
||||
if (!id) {
|
||||
throw new BadDataException('Status Page ID is required');
|
||||
@@ -158,7 +183,7 @@ const Detail: FunctionComponent<PageComponentProps> = (
|
||||
try {
|
||||
setError(
|
||||
(err as HTTPErrorResponse).message ||
|
||||
'Server Error. Please try again'
|
||||
'Server Error. Please try again'
|
||||
);
|
||||
} catch (e) {
|
||||
setError('Server Error. Please try again');
|
||||
@@ -174,12 +199,19 @@ const Detail: FunctionComponent<PageComponentProps> = (
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!incident) {
|
||||
return;
|
||||
}
|
||||
|
||||
setParsedData(getIncidentEventItem(incident, incidentPublicNotes, incidentStateTimelines, statusPageResources, props.isPreviewPage));
|
||||
setParsedData(
|
||||
getIncidentEventItem(
|
||||
incident,
|
||||
incidentPublicNotes,
|
||||
incidentStateTimelines,
|
||||
statusPageResources,
|
||||
props.isPreviewPage
|
||||
)
|
||||
);
|
||||
}, [isLoading]);
|
||||
|
||||
if (isLoading) {
|
||||
@@ -196,15 +228,14 @@ const Detail: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
||||
{incident ? <EventItem {...parsedData} /> : <></>}
|
||||
{!incident ? (
|
||||
<ErrorMessage
|
||||
error="No incident found with this ID."
|
||||
/>
|
||||
) : <></>}
|
||||
<ErrorMessage error="No incident found with this ID." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default Detail;
|
||||
export default Detail;
|
||||
|
||||
@@ -134,8 +134,16 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
items: [],
|
||||
};
|
||||
}
|
||||
|
||||
days[dayString]?.items.push(getIncidentEventItem(incident, incidentPublicNotes, incidentStateTimelines, statusPageResources, props.isPreviewPage));
|
||||
|
||||
days[dayString]?.items.push(
|
||||
getIncidentEventItem(
|
||||
incident,
|
||||
incidentPublicNotes,
|
||||
incidentStateTimelines,
|
||||
statusPageResources,
|
||||
props.isPreviewPage
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (const key in days) {
|
||||
@@ -161,16 +169,27 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{incidents && incidents.length > 0 ? <div>
|
||||
<h4>Incidents</h4>
|
||||
<p>Here is the incident history for all the resources on this status page.</p>
|
||||
</div> : <></>}
|
||||
{incidents && incidents.length > 0 ? <EventHistoryList {...parsedData} /> : <></>}
|
||||
{incidents && incidents.length > 0 ? (
|
||||
<div>
|
||||
<h4>Incidents</h4>
|
||||
<p>
|
||||
Here is the incident history for all the resources on
|
||||
this status page.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{incidents && incidents.length > 0 ? (
|
||||
<EventHistoryList {...parsedData} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{incidents.length === 0 ? (
|
||||
<ErrorMessage
|
||||
error="No incidents reported on this status page."
|
||||
/>
|
||||
) : <></>}
|
||||
<ErrorMessage error="No incidents reported on this status page." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ import Route from 'Common/Types/API/Route';
|
||||
import ScheduledMaintenanceGroup from '../../Types/ScheduledMaintenanceGroup';
|
||||
import { TimelineItem } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import HTTPResponse from 'Common/Types/API/HTTPResponse';
|
||||
import Monitor from 'Model/Models/Monitor';
|
||||
|
||||
const Overview: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps
|
||||
@@ -337,9 +338,15 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
throw new BadDataException('Incident Timeline not found.');
|
||||
}
|
||||
|
||||
const monitorIds = activeIncident.monitors?.map((monitor) => monitor._id) || [];
|
||||
|
||||
const namesOfResources = statusPageResources.filter((resource) => monitorIds.includes(resource.monitorId?.toString()));
|
||||
const monitorIds: Array<string | undefined> =
|
||||
activeIncident.monitors?.map((monitor: Monitor) => {
|
||||
return monitor._id;
|
||||
}) || [];
|
||||
|
||||
const namesOfResources: Array<StatusPageResource> =
|
||||
statusPageResources.filter((resource: StatusPageResource) => {
|
||||
return monitorIds.includes(resource.monitorId?.toString());
|
||||
});
|
||||
|
||||
const group: IncidentGroup = {
|
||||
incident: activeIncident,
|
||||
@@ -388,9 +395,19 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
throw new BadDataException('Incident Timeline not found.');
|
||||
}
|
||||
|
||||
const monitorIds = activeEvent.monitors?.map((monitor) => monitor._id) || [];
|
||||
|
||||
const namesOfResources = statusPageResources.filter((resource) => monitorIds.includes(resource.monitorId?.toString()));
|
||||
const monitorIds: Array<string | undefined> =
|
||||
activeEvent.monitors?.map((monitor: Monitor) => {
|
||||
return monitor._id;
|
||||
}) || [];
|
||||
|
||||
const namesOfResources: Array<StatusPageResource> =
|
||||
statusPageResources.filter(
|
||||
(resource: StatusPageResource) => {
|
||||
return monitorIds.includes(
|
||||
resource.monitorId?.toString()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const group: ScheduledMaintenanceGroup = {
|
||||
scheduledMaintenance: activeEvent,
|
||||
@@ -509,7 +526,11 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
if (incidentGroup.publicNote) {
|
||||
timeline.push({
|
||||
text: (<span><b>Update</b> - {incidentGroup.publicNote?.note}</span>),
|
||||
text: (
|
||||
<span>
|
||||
<b>Update</b> - {incidentGroup.publicNote?.note}
|
||||
</span>
|
||||
),
|
||||
date: incidentGroup.publicNote?.createdAt!,
|
||||
isBold: false,
|
||||
});
|
||||
@@ -572,7 +593,16 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
incidentGroup.incidentSeverity.color ||
|
||||
Red
|
||||
}
|
||||
eventResourcesAffected={incidentGroup.incidentResources.map((i)=> i.displayName?.toString() || '') || []}
|
||||
eventResourcesAffected={
|
||||
incidentGroup.incidentResources.map(
|
||||
(i: StatusPageResource) => {
|
||||
return (
|
||||
i.displayName?.toString() ||
|
||||
''
|
||||
);
|
||||
}
|
||||
) || []
|
||||
}
|
||||
eventTitle={
|
||||
incidentGroup.incident.title || ''
|
||||
}
|
||||
@@ -624,8 +654,16 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
eventTimeline={getScheduledEventGroupEventTimeline(
|
||||
scheduledEventGroup
|
||||
)}
|
||||
eventResourcesAffected={scheduledEventGroup.scheduledEventResources.map((i)=> i.displayName?.toString() || '') || []}
|
||||
|
||||
eventResourcesAffected={
|
||||
scheduledEventGroup.scheduledEventResources.map(
|
||||
(i: StatusPageResource) => {
|
||||
return (
|
||||
i.displayName?.toString() ||
|
||||
''
|
||||
);
|
||||
}
|
||||
) || []
|
||||
}
|
||||
footerDateTime={
|
||||
scheduledEventGroup.scheduledMaintenance
|
||||
.endsAt!
|
||||
|
||||
@@ -27,11 +27,18 @@ import RouteMap, { RouteUtil } from '../../Utils/RouteMap';
|
||||
import PageMap from '../../Utils/PageMap';
|
||||
import Route from 'Common/Types/API/Route';
|
||||
import HTTPResponse from 'Common/Types/API/HTTPResponse';
|
||||
import EventItem, { TimelineItem } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import EventItem, {
|
||||
TimelineItem,
|
||||
ComponentProps as EventItemComponentProps,
|
||||
} from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import { ComponentProps as EventItemComponentProps } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
|
||||
export const getScheduledEventEventItem: Function = (scheduledMaintenance: ScheduledMaintenance,scheduledMaintenanceEventsPublicNotes: Array<ScheduledMaintenancePublicNote>, scheduledMaintenanceStateTimelines: Array<ScheduledMaintenanceStateTimeline>, isPreviewPage: boolean ) => {
|
||||
export const getScheduledEventEventItem: Function = (
|
||||
scheduledMaintenance: ScheduledMaintenance,
|
||||
scheduledMaintenanceEventsPublicNotes: Array<ScheduledMaintenancePublicNote>,
|
||||
scheduledMaintenanceStateTimelines: Array<ScheduledMaintenanceStateTimeline>,
|
||||
isPreviewPage: boolean
|
||||
) => {
|
||||
/// get timeline.
|
||||
|
||||
const timeline: Array<TimelineItem> = [];
|
||||
@@ -68,22 +75,19 @@ export const getScheduledEventEventItem: Function = (scheduledMaintenance: Sched
|
||||
return OneUptimeDate.isAfter(a.date, b.date) === true ? 1 : -1;
|
||||
});
|
||||
|
||||
return {
|
||||
return {
|
||||
eventTitle: scheduledMaintenance.title || '',
|
||||
eventDescription: scheduledMaintenance.description,
|
||||
eventTimeline: timeline,
|
||||
eventType: 'Scheduled Maintenance',
|
||||
eventViewRoute: RouteUtil.populateRouteParams(
|
||||
isPreviewPage
|
||||
? (RouteMap[
|
||||
PageMap.PREVIEW_SCHEDULED_EVENT_DETAIL
|
||||
] as Route)
|
||||
isPreviewPage
|
||||
? (RouteMap[PageMap.PREVIEW_SCHEDULED_EVENT_DETAIL] as Route)
|
||||
: (RouteMap[PageMap.SCHEDULED_EVENT_DETAIL] as Route),
|
||||
scheduledMaintenance.id!
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const Overview: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps
|
||||
@@ -117,8 +121,10 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
throw new BadDataException('Status Page ID is required');
|
||||
}
|
||||
|
||||
const eventId = Navigation.getLastParam()?.toString().replace("/", "");
|
||||
|
||||
const eventId: string | undefined = Navigation.getLastParam()
|
||||
?.toString()
|
||||
.replace('/', '');
|
||||
|
||||
const response: HTTPResponse<JSONObject> =
|
||||
await BaseAPI.post<JSONObject>(
|
||||
URL.fromString(DASHBOARD_API_URL.toString()).addRoute(
|
||||
@@ -136,7 +142,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
] as JSONArray) || [],
|
||||
ScheduledMaintenancePublicNote
|
||||
);
|
||||
const scheduledMaintenanceEvent:ScheduledMaintenance =
|
||||
const scheduledMaintenanceEvent: ScheduledMaintenance =
|
||||
BaseModel.fromJSONObject(
|
||||
(data['scheduledMaintenanceEvent'] as JSONObject) || [],
|
||||
ScheduledMaintenance
|
||||
@@ -149,7 +155,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
const scheduledMaintenanceStateTimelines: Array<ScheduledMaintenanceStateTimeline> =
|
||||
BaseModel.fromJSONArray(
|
||||
(data['scheduledMaintenanceStateTimelines'] as JSONArray) ||
|
||||
[],
|
||||
[],
|
||||
ScheduledMaintenanceStateTimeline
|
||||
);
|
||||
|
||||
@@ -169,7 +175,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
try {
|
||||
setError(
|
||||
(err as HTTPErrorResponse).message ||
|
||||
'Server Error. Please try again'
|
||||
'Server Error. Please try again'
|
||||
);
|
||||
} catch (e) {
|
||||
setError('Server Error. Please try again');
|
||||
@@ -187,8 +193,15 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
if (!scheduledMaintenanceEvent) {
|
||||
return;
|
||||
}
|
||||
setParsedData(getScheduledEventEventItem(scheduledMaintenanceEvent, scheduledMaintenanceEventsPublicNotes, scheduledMaintenanceStateTimelines, !!props.isPreviewPage));
|
||||
}
|
||||
setParsedData(
|
||||
getScheduledEventEventItem(
|
||||
scheduledMaintenanceEvent,
|
||||
scheduledMaintenanceEventsPublicNotes,
|
||||
scheduledMaintenanceStateTimelines,
|
||||
Boolean(props.isPreviewPage)
|
||||
)
|
||||
);
|
||||
}, [isLoading]);
|
||||
|
||||
if (isLoading) {
|
||||
@@ -205,14 +218,13 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
||||
{scheduledMaintenanceEvent ? <EventItem {...parsedData} /> : <></>}
|
||||
{!scheduledMaintenanceEvent ? (
|
||||
<ErrorMessage
|
||||
error="No incident found with this ID."
|
||||
/>
|
||||
) : <></>}
|
||||
</Page>
|
||||
{scheduledMaintenanceEvent ? <EventItem {...parsedData} /> : <></>}
|
||||
{!scheduledMaintenanceEvent ? (
|
||||
<ErrorMessage error="No incident found with this ID." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -28,11 +28,7 @@ import ScheduledMaintenancePublicNote from 'Model/Models/ScheduledMaintenancePub
|
||||
import OneUptimeDate from 'Common/Types/Date';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import ScheduledMaintenanceStateTimeline from 'Model/Models/ScheduledMaintenanceStateTimeline';
|
||||
import RouteMap, { RouteUtil } from '../../Utils/RouteMap';
|
||||
import PageMap from '../../Utils/PageMap';
|
||||
import Route from 'Common/Types/API/Route';
|
||||
import HTTPResponse from 'Common/Types/API/HTTPResponse';
|
||||
import { TimelineItem } from 'CommonUI/src/Components/EventItem/EventItem';
|
||||
import { getScheduledEventEventItem } from './Detail';
|
||||
|
||||
const Overview: FunctionComponent<PageComponentProps> = (
|
||||
@@ -96,7 +92,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
const scheduledMaintenanceStateTimelines: Array<ScheduledMaintenanceStateTimeline> =
|
||||
BaseModel.fromJSONArray(
|
||||
(data['scheduledMaintenanceStateTimelines'] as JSONArray) ||
|
||||
[],
|
||||
[],
|
||||
ScheduledMaintenanceStateTimeline
|
||||
);
|
||||
|
||||
@@ -116,7 +112,7 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
try {
|
||||
setError(
|
||||
(err as HTTPErrorResponse).message ||
|
||||
'Server Error. Please try again'
|
||||
'Server Error. Please try again'
|
||||
);
|
||||
} catch (e) {
|
||||
setError('Server Error. Please try again');
|
||||
@@ -149,8 +145,15 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
items: [],
|
||||
};
|
||||
}
|
||||
|
||||
days[dayString]?.items.push(getScheduledEventEventItem(scheduledMaintenance, scheduledMaintenanceEventsPublicNotes, scheduledMaintenanceStateTimelines, !!props.isPreviewPage));
|
||||
|
||||
days[dayString]?.items.push(
|
||||
getScheduledEventEventItem(
|
||||
scheduledMaintenance,
|
||||
scheduledMaintenanceEventsPublicNotes,
|
||||
scheduledMaintenanceStateTimelines,
|
||||
Boolean(props.isPreviewPage)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (const key in days) {
|
||||
@@ -176,16 +179,25 @@ const Overview: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
||||
{scheduledMaintenanceEvents && scheduledMaintenanceEvents.length > 0 ? <h3>Scheduled Maintenance Events</h3> : <></>}
|
||||
{scheduledMaintenanceEvents &&
|
||||
scheduledMaintenanceEvents.length > 0 ? (
|
||||
<h3>Scheduled Maintenance Events</h3>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{scheduledMaintenanceEvents && scheduledMaintenanceEvents.length > 0 ? <EventHistoryList {...parsedData} /> : <></>}
|
||||
{scheduledMaintenanceEvents &&
|
||||
scheduledMaintenanceEvents.length > 0 ? (
|
||||
<EventHistoryList {...parsedData} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{scheduledMaintenanceEvents.length === 0 ? (
|
||||
<ErrorMessage
|
||||
error="No events reported on this status page."
|
||||
/>
|
||||
) : <></>}
|
||||
<ErrorMessage error="No events reported on this status page." />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,5 +11,5 @@ export default interface IncidentGroup {
|
||||
publicNote?: IncidentPublicNote | undefined | null;
|
||||
incidentState: IncidentState;
|
||||
incidentStateTimeline: IncidentStateTimeline;
|
||||
incidentResources: Array<StatusPageResource>
|
||||
incidentResources: Array<StatusPageResource>;
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ export default interface ScheduledMaintenanceGroup {
|
||||
publicNote?: ScheduledMaintenancePublicNote | undefined | null;
|
||||
scheduledMaintenanceState: ScheduledMaintenanceState;
|
||||
scheduledMaintenanceStateTimeline: ScheduledMaintenanceStateTimeline;
|
||||
scheduledEventResources: Array<StatusPageResource>
|
||||
scheduledEventResources: Array<StatusPageResource>;
|
||||
}
|
||||
|
||||
@@ -107,4 +107,4 @@
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user