@oneuptime/common 8.0.5579 → 8.0.5581
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AlertInternalNote.ts +58 -1
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +1 -0
- package/Models/DatabaseModels/File.ts +1 -1
- package/Models/DatabaseModels/IncidentInternalNote.ts +58 -1
- package/Models/DatabaseModels/IncidentPublicNote.ts +58 -1
- package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +58 -1
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +58 -1
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +49 -0
- package/Server/API/AlertInternalNoteAPI.ts +96 -0
- package/Server/API/IncidentInternalNoteAPI.ts +96 -0
- package/Server/API/IncidentPublicNoteAPI.ts +96 -0
- package/Server/API/ScheduledMaintenanceInternalNoteAPI.ts +100 -0
- package/Server/API/ScheduledMaintenancePublicNoteAPI.ts +100 -0
- package/Server/API/StatusPageAPI.ts +585 -59
- package/Server/API/StatusPageAnnouncementAPI.ts +98 -0
- package/Server/API/UserAPI.ts +95 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.ts +81 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/ProjectAuthorization.ts +3 -1
- package/Server/Services/AlertInternalNoteService.ts +75 -2
- package/Server/Services/IncidentInternalNoteService.ts +76 -2
- package/Server/Services/IncidentPublicNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenanceService.ts +10 -7
- package/Server/Services/StatusPagePrivateUserService.ts +10 -7
- package/Server/Services/StatusPageService.ts +12 -7
- package/Server/Services/StatusPageSubscriberService.ts +19 -13
- package/Server/Utils/FileAttachmentMarkdownUtil.ts +98 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +9 -1
- package/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.ts +34 -0
- package/Server/Utils/Monitor/DataToProcess.ts +3 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +13 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
- package/Server/Utils/Monitor/MonitorResource.ts +18 -0
- package/Server/Utils/Response.ts +13 -0
- package/Server/Utils/Telemetry.ts +15 -0
- package/Types/File/MimeType.ts +18 -0
- package/Types/Monitor/CriteriaFilter.ts +3 -0
- package/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.ts +12 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
- package/Types/Monitor/MonitorStep.ts +30 -0
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +94 -0
- package/Types/Monitor/MonitorType.ts +10 -1
- package/Types/Telemetry/TelemetryQuery.ts +2 -1
- package/Types/Telemetry/TelemetryType.ts +1 -0
- package/UI/Components/AttachmentList/EventAttachmentList.tsx +121 -0
- package/UI/Components/EventItem/EventItem.tsx +22 -0
- package/UI/Components/Feed/FeedItem.tsx +9 -16
- package/UI/Components/FilePicker/FilePicker.tsx +441 -145
- package/UI/Components/Forms/Fields/FormField.tsx +32 -15
- package/UI/Components/Forms/FormSummary.tsx +168 -1
- package/UI/Components/Forms/ModelForm.tsx +46 -24
- package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
- package/UI/Components/Icon/Icon.tsx +1 -1
- package/UI/Utils/API/RequestOptions.ts +2 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +18 -0
- package/UI/Utils/User.ts +8 -0
- package/Utils/API.ts +11 -1
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/File.js +1 -1
- package/build/dist/Models/DatabaseModels/File.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +49 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +49 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +48 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Server/API/AlertInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/AlertInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/IncidentInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/IncidentInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/IncidentPublicNoteAPI.js +68 -0
- package/build/dist/Server/API/IncidentPublicNoteAPI.js.map +1 -0
- package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js +68 -0
- package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +488 -85
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAnnouncementAPI.js +68 -0
- package/build/dist/Server/API/StatusPageAnnouncementAPI.js.map +1 -0
- package/build/dist/Server/API/UserAPI.js +66 -0
- package/build/dist/Server/API/UserAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +4 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertInternalNoteService.js +54 -2
- package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentInternalNoteService.js +54 -2
- package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +54 -2
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +54 -2
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +54 -2
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +6 -5
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +6 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +7 -4
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +11 -7
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js +67 -0
- package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +6 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js +34 -0
- package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +6 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +8 -0
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +8 -1
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +18 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +20 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +58 -0
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +9 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
- package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +42 -0
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -0
- package/build/dist/UI/Components/EventItem/EventItem.js +5 -1
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +6 -4
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/FilePicker/FilePicker.js +262 -77
- package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +24 -12
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/FormSummary.js +77 -1
- package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +32 -18
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +1 -1
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +30 -45
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/User.js +7 -0
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/API.js +3 -0
- package/build/dist/Utils/API.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import ExceptionInstance from "../../Models/AnalyticsModels/ExceptionInstance";
|
|
2
|
+
import InBetween from "../BaseDatabase/InBetween";
|
|
3
|
+
import Includes from "../BaseDatabase/Includes";
|
|
4
|
+
import Query from "../BaseDatabase/Query";
|
|
5
|
+
import Search from "../BaseDatabase/Search";
|
|
6
|
+
import OneUptimeDate from "../Date";
|
|
7
|
+
import { JSONObject } from "../JSON";
|
|
8
|
+
import ObjectID from "../ObjectID";
|
|
9
|
+
|
|
10
|
+
export default interface MonitorStepExceptionMonitor {
|
|
11
|
+
telemetryServiceIds: Array<ObjectID>;
|
|
12
|
+
exceptionTypes: Array<string>;
|
|
13
|
+
message: string;
|
|
14
|
+
includeResolved: boolean;
|
|
15
|
+
includeArchived: boolean;
|
|
16
|
+
lastXSecondsOfExceptions: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class MonitorStepExceptionMonitorUtil {
|
|
20
|
+
public static toAnalyticsQuery(
|
|
21
|
+
monitorStepExceptionMonitor: MonitorStepExceptionMonitor,
|
|
22
|
+
): Query<ExceptionInstance> {
|
|
23
|
+
const query: Query<ExceptionInstance> = {};
|
|
24
|
+
|
|
25
|
+
if (
|
|
26
|
+
monitorStepExceptionMonitor.telemetryServiceIds &&
|
|
27
|
+
monitorStepExceptionMonitor.telemetryServiceIds.length > 0
|
|
28
|
+
) {
|
|
29
|
+
query.serviceId = new Includes(
|
|
30
|
+
monitorStepExceptionMonitor.telemetryServiceIds,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
monitorStepExceptionMonitor.exceptionTypes &&
|
|
36
|
+
monitorStepExceptionMonitor.exceptionTypes.length > 0
|
|
37
|
+
) {
|
|
38
|
+
query.exceptionType = new Includes(
|
|
39
|
+
monitorStepExceptionMonitor.exceptionTypes,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (monitorStepExceptionMonitor.message) {
|
|
44
|
+
query.message = new Search(monitorStepExceptionMonitor.message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (monitorStepExceptionMonitor.lastXSecondsOfExceptions) {
|
|
48
|
+
const endDate: Date = OneUptimeDate.getCurrentDate();
|
|
49
|
+
const startDate: Date = OneUptimeDate.addRemoveSeconds(
|
|
50
|
+
endDate,
|
|
51
|
+
monitorStepExceptionMonitor.lastXSecondsOfExceptions * -1,
|
|
52
|
+
);
|
|
53
|
+
query.time = new InBetween(startDate, endDate);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return query;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public static getDefault(): MonitorStepExceptionMonitor {
|
|
60
|
+
return {
|
|
61
|
+
telemetryServiceIds: [],
|
|
62
|
+
exceptionTypes: [],
|
|
63
|
+
message: "",
|
|
64
|
+
includeResolved: false,
|
|
65
|
+
includeArchived: false,
|
|
66
|
+
lastXSecondsOfExceptions: 60,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public static fromJSON(json: JSONObject): MonitorStepExceptionMonitor {
|
|
71
|
+
return {
|
|
72
|
+
telemetryServiceIds: ObjectID.fromJSONArray(
|
|
73
|
+
(json["telemetryServiceIds"] as Array<JSONObject>) || [],
|
|
74
|
+
),
|
|
75
|
+
exceptionTypes: (json["exceptionTypes"] as Array<string>) || [],
|
|
76
|
+
message: (json["message"] as string) || "",
|
|
77
|
+
includeResolved: Boolean(json["includeResolved"]) || false,
|
|
78
|
+
includeArchived: Boolean(json["includeArchived"]) || false,
|
|
79
|
+
lastXSecondsOfExceptions:
|
|
80
|
+
(json["lastXSecondsOfExceptions"] as number | undefined) || 60,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public static toJSON(monitor: MonitorStepExceptionMonitor): JSONObject {
|
|
85
|
+
return {
|
|
86
|
+
telemetryServiceIds: ObjectID.toJSONArray(monitor.telemetryServiceIds),
|
|
87
|
+
exceptionTypes: monitor.exceptionTypes,
|
|
88
|
+
message: monitor.message,
|
|
89
|
+
includeResolved: monitor.includeResolved,
|
|
90
|
+
includeArchived: monitor.includeArchived,
|
|
91
|
+
lastXSecondsOfExceptions: monitor.lastXSecondsOfExceptions,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -20,6 +20,7 @@ enum MonitorType {
|
|
|
20
20
|
Logs = "Logs",
|
|
21
21
|
Metrics = "Metrics",
|
|
22
22
|
Traces = "Traces",
|
|
23
|
+
Exceptions = "Exceptions",
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export default MonitorType;
|
|
@@ -35,7 +36,8 @@ export class MonitorTypeHelper {
|
|
|
35
36
|
return (
|
|
36
37
|
monitorType === MonitorType.Logs ||
|
|
37
38
|
monitorType === MonitorType.Metrics ||
|
|
38
|
-
monitorType === MonitorType.Traces
|
|
39
|
+
monitorType === MonitorType.Traces ||
|
|
40
|
+
monitorType === MonitorType.Exceptions
|
|
39
41
|
);
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -123,6 +125,12 @@ export class MonitorTypeHelper {
|
|
|
123
125
|
title: "Logs",
|
|
124
126
|
description: "This monitor type lets you monitor logs from any source.",
|
|
125
127
|
},
|
|
128
|
+
{
|
|
129
|
+
monitorType: MonitorType.Exceptions,
|
|
130
|
+
title: "Exceptions",
|
|
131
|
+
description:
|
|
132
|
+
"This monitor type lets you monitor exceptions and error groups from any source.",
|
|
133
|
+
},
|
|
126
134
|
{
|
|
127
135
|
monitorType: MonitorType.Traces,
|
|
128
136
|
title: "Traces",
|
|
@@ -198,6 +206,7 @@ export class MonitorTypeHelper {
|
|
|
198
206
|
MonitorType.Logs,
|
|
199
207
|
MonitorType.Metrics,
|
|
200
208
|
MonitorType.Traces,
|
|
209
|
+
MonitorType.Exceptions,
|
|
201
210
|
];
|
|
202
211
|
}
|
|
203
212
|
|
|
@@ -3,9 +3,10 @@ import Span from "../../Models/AnalyticsModels/Span";
|
|
|
3
3
|
import Query from "../BaseDatabase/Query";
|
|
4
4
|
import MetricViewData from "../Metrics/MetricViewData";
|
|
5
5
|
import TelemetryType from "./TelemetryType";
|
|
6
|
+
import ExceptionInstance from "../../Models/AnalyticsModels/ExceptionInstance";
|
|
6
7
|
|
|
7
8
|
export interface TelemetryQuery {
|
|
8
9
|
telemetryType: TelemetryType;
|
|
9
|
-
telemetryQuery: Query<Log> | Query<Span> | null;
|
|
10
|
+
telemetryQuery: Query<Log> | Query<Span> | Query<ExceptionInstance> | null;
|
|
10
11
|
metricViewData: MetricViewData | null;
|
|
11
12
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, { FunctionComponent, ReactElement } from "react";
|
|
2
|
+
|
|
3
|
+
export interface EventAttachment {
|
|
4
|
+
name: string;
|
|
5
|
+
downloadUrl: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface EventAttachmentListProps {
|
|
9
|
+
attachments: Array<EventAttachment>;
|
|
10
|
+
title?: string;
|
|
11
|
+
variant?: "section" | "inline";
|
|
12
|
+
showHeader?: boolean;
|
|
13
|
+
showCount?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getAttachmentExtensionLabel(fileName?: string | null): string | null {
|
|
18
|
+
if (!fileName) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const trimmedName: string = fileName.trim();
|
|
23
|
+
const lastDotIndex: number = trimmedName.lastIndexOf(".");
|
|
24
|
+
|
|
25
|
+
if (lastDotIndex === -1 || lastDotIndex === trimmedName.length - 1) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return trimmedName.substring(lastDotIndex + 1).toUpperCase();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type AttachmentCardProps = {
|
|
33
|
+
attachment: EventAttachment;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const AttachmentCard: FunctionComponent<AttachmentCardProps> = (
|
|
37
|
+
props: AttachmentCardProps,
|
|
38
|
+
): ReactElement => {
|
|
39
|
+
const { attachment } = props;
|
|
40
|
+
const extensionLabel: string | null = getAttachmentExtensionLabel(
|
|
41
|
+
attachment.name,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<li>
|
|
46
|
+
<a
|
|
47
|
+
href={attachment.downloadUrl}
|
|
48
|
+
target="_blank"
|
|
49
|
+
rel="noopener noreferrer"
|
|
50
|
+
title={attachment.name}
|
|
51
|
+
className="group flex items-center justify-between gap-3 rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm text-gray-900 transition hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-200"
|
|
52
|
+
>
|
|
53
|
+
<span className="flex items-center gap-3 min-w-0">
|
|
54
|
+
<span className="flex flex-col min-w-0">
|
|
55
|
+
<span className="text-sm font-medium text-gray-900 truncate">
|
|
56
|
+
{attachment.name || "Attachment"}
|
|
57
|
+
</span>
|
|
58
|
+
{extensionLabel && (
|
|
59
|
+
<span className="text-[11px] font-semibold uppercase tracking-wide text-gray-400">
|
|
60
|
+
{extensionLabel}
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
</span>
|
|
64
|
+
</span>
|
|
65
|
+
|
|
66
|
+
<span className="flex flex-shrink-0 items-center text-gray-500 text-xs font-semibold uppercase tracking-wide">
|
|
67
|
+
Download
|
|
68
|
+
</span>
|
|
69
|
+
</a>
|
|
70
|
+
</li>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const EventAttachmentList: FunctionComponent<EventAttachmentListProps> = (
|
|
75
|
+
props: EventAttachmentListProps,
|
|
76
|
+
): ReactElement | null => {
|
|
77
|
+
const {
|
|
78
|
+
attachments,
|
|
79
|
+
title = "Attachments",
|
|
80
|
+
variant = "section",
|
|
81
|
+
showHeader = true,
|
|
82
|
+
showCount = true,
|
|
83
|
+
className = "",
|
|
84
|
+
} = props;
|
|
85
|
+
|
|
86
|
+
if (!attachments || attachments.length === 0) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const attachmentsList: ReactElement = (
|
|
91
|
+
<ul className="space-y-2">
|
|
92
|
+
{attachments.map((attachment: EventAttachment, index: number) => {
|
|
93
|
+
return <AttachmentCard attachment={attachment} key={index} />;
|
|
94
|
+
})}
|
|
95
|
+
</ul>
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
if (variant === "inline") {
|
|
99
|
+
return <div className={className}>{attachmentsList}</div>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
className={`mt-4 rounded-2xl border border-gray-100 bg-gray-50/80 p-4 ${className}`.trim()}
|
|
105
|
+
>
|
|
106
|
+
{showHeader && (
|
|
107
|
+
<div className="flex items-center justify-between text-xs font-semibold uppercase tracking-wide text-gray-500">
|
|
108
|
+
<span>{title}</span>
|
|
109
|
+
{showCount && (
|
|
110
|
+
<span className="rounded-full bg-white px-2 py-0.5 text-[11px] font-semibold text-gray-600">
|
|
111
|
+
{attachments.length}
|
|
112
|
+
</span>
|
|
113
|
+
)}
|
|
114
|
+
</div>
|
|
115
|
+
)}
|
|
116
|
+
<div className="mt-3">{attachmentsList}</div>
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export default EventAttachmentList;
|
|
@@ -2,6 +2,7 @@ import Icon from "../Icon/Icon";
|
|
|
2
2
|
import Link from "../Link/Link";
|
|
3
3
|
import MarkdownViewer from "../Markdown.tsx/LazyMarkdownViewer";
|
|
4
4
|
import Pill from "../Pill/Pill";
|
|
5
|
+
import EventAttachmentList from "../AttachmentList/EventAttachmentList";
|
|
5
6
|
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
6
7
|
import Route from "../../../Types/API/Route";
|
|
7
8
|
import URL from "../../../Types/API/URL";
|
|
@@ -16,6 +17,11 @@ export enum TimelineItemType {
|
|
|
16
17
|
Note = "Note",
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
export interface TimelineAttachment {
|
|
21
|
+
name: string;
|
|
22
|
+
downloadUrl: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
export interface TimelineItem {
|
|
20
26
|
date: Date;
|
|
21
27
|
note?: string;
|
|
@@ -23,6 +29,7 @@ export interface TimelineItem {
|
|
|
23
29
|
state?: BaseModel;
|
|
24
30
|
icon: IconProp;
|
|
25
31
|
iconColor: Color;
|
|
32
|
+
attachments?: Array<TimelineAttachment>;
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
export interface EventItemLabel {
|
|
@@ -46,6 +53,7 @@ export interface ComponentProps {
|
|
|
46
53
|
anotherStatusColor?: Color | undefined;
|
|
47
54
|
eventSecondDescription: string;
|
|
48
55
|
labels?: Array<EventItemLabel> | undefined;
|
|
56
|
+
eventAttachments?: Array<TimelineAttachment> | undefined;
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
const EventItem: FunctionComponent<ComponentProps> = (
|
|
@@ -102,6 +110,10 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
102
110
|
</div>
|
|
103
111
|
)}
|
|
104
112
|
|
|
113
|
+
{props.eventAttachments && props.eventAttachments.length > 0 && (
|
|
114
|
+
<EventAttachmentList attachments={props.eventAttachments} />
|
|
115
|
+
)}
|
|
116
|
+
|
|
105
117
|
{props.eventSecondDescription && (
|
|
106
118
|
<div className="mt-3 text-gray-500 text-sm active-event-box-body-second-description">
|
|
107
119
|
{props.eventSecondDescription}
|
|
@@ -278,6 +290,16 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
278
290
|
<p>
|
|
279
291
|
<MarkdownViewer text={item.note || ""} />
|
|
280
292
|
</p>
|
|
293
|
+
{item.attachments &&
|
|
294
|
+
item.attachments.length > 0 && (
|
|
295
|
+
<EventAttachmentList
|
|
296
|
+
attachments={item.attachments}
|
|
297
|
+
variant="inline"
|
|
298
|
+
showHeader={false}
|
|
299
|
+
showCount={false}
|
|
300
|
+
className="mt-3"
|
|
301
|
+
/>
|
|
302
|
+
)}
|
|
281
303
|
</div>
|
|
282
304
|
</div>
|
|
283
305
|
</div>
|
|
@@ -4,7 +4,7 @@ import { GetReactElementFunction } from "../../Types/FunctionTypes";
|
|
|
4
4
|
import Image from "../Image/Image";
|
|
5
5
|
import Route from "../../../Types/API/Route";
|
|
6
6
|
import BlankProfilePic from "../../Images/users/blank-profile.svg";
|
|
7
|
-
import
|
|
7
|
+
import UserUtil from "../../Utils/User";
|
|
8
8
|
import ObjectID from "../../../Types/ObjectID";
|
|
9
9
|
import OneUptimeDate from "../../../Types/Date";
|
|
10
10
|
import Tooltip from "../Tooltip/Tooltip";
|
|
@@ -60,23 +60,16 @@ const FeedItem: FunctionComponent<ComponentProps> = (
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
const getUserIcon: GetReactElementFunction = (): ReactElement => {
|
|
63
|
+
const userImageRoute: Route = props.user?.id
|
|
64
|
+
? UserUtil.getProfilePictureRoute(props.user.id as ObjectID)
|
|
65
|
+
: Route.fromString(`${BlankProfilePic}`);
|
|
66
|
+
|
|
63
67
|
return (
|
|
64
68
|
<div>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/>
|
|
70
|
-
)}
|
|
71
|
-
|
|
72
|
-
{props.user?.profilePictureId && (
|
|
73
|
-
<Image
|
|
74
|
-
className="flex size-10 items-center justify-center rounded-full bg-gray-400 ring-8 ring-white"
|
|
75
|
-
imageUrl={FileUtil.getFileRoute(
|
|
76
|
-
props.user!.profilePictureId as ObjectID,
|
|
77
|
-
)}
|
|
78
|
-
/>
|
|
79
|
-
)}
|
|
69
|
+
<Image
|
|
70
|
+
className="flex size-10 items-center justify-center rounded-full bg-gray-400 ring-8 ring-white"
|
|
71
|
+
imageUrl={userImageRoute}
|
|
72
|
+
/>
|
|
80
73
|
|
|
81
74
|
{props.icon && (
|
|
82
75
|
<span className="absolute -bottom-0.5 -right-1 rounded-tl bg-white px-0.5 py-px">
|