@oneuptime/common 11.3.28 → 11.4.1
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/AIRun.ts +50 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Server/API/AIAgentTaskAPI.ts +10 -24
- package/Server/API/AIInvestigationAPI.ts +148 -0
- package/Server/API/TelemetryAPI.ts +4 -3
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/AIAgentTaskService.ts +62 -0
- package/Server/Services/AlertService.ts +25 -0
- package/Server/Services/AnalyticsDatabaseService.ts +27 -0
- package/Server/Services/IncidentService.ts +25 -0
- package/Server/Services/IncidentStateTimelineService.ts +19 -0
- package/Server/Services/LogAggregationService.ts +29 -11
- package/Server/Services/MetricService.ts +603 -13
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +119 -11
- package/Server/Utils/AI/Sentinel/AlertInvestigationRunner.ts +141 -0
- package/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.ts +178 -0
- package/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.ts +105 -0
- package/Server/Utils/AI/Sentinel/README.md +10 -0
- package/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.ts +405 -0
- package/Server/Utils/AI/Sentinel/SentinelMemory.ts +167 -0
- package/Server/Utils/AI/Toolbox/Index.ts +11 -0
- package/Server/Utils/AI/Toolbox/SentinelActionTools.ts +577 -0
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +44 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +108 -2
- package/Tests/Server/API/BaseAPI.test.ts +1 -0
- package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +146 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +22 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +194 -0
- package/Tests/Types/AI/AIAgentTaskStatus.test.ts +86 -0
- package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +127 -0
- package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.test.ts +152 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleShiftUtil.test.ts +260 -0
- package/Tests/Types/Trace/TraceRecordingRuleDefinition.test.ts +308 -0
- package/Tests/UI/Components/Dropdown.test.tsx +17 -0
- package/Tests/UI/Components/EntityDropdown.test.tsx +130 -0
- package/Tests/UI/Components/Modal.test.tsx +144 -2
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +90 -0
- package/Tests/UI/Utils/Theme.test.ts +161 -0
- package/Types/BaseDatabase/AggregateBy.ts +12 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.ts +19 -0
- package/Types/Dashboard/DashboardTemplates.ts +9 -1
- package/Types/Date.ts +46 -0
- package/Types/Monitor/CriteriaFilter.ts +4 -0
- package/Types/Monitor/HttpPhaseTimings.ts +16 -0
- package/Types/Monitor/MonitorMetricType.ts +17 -0
- package/Types/Monitor/PingMonitor/PingMonitorResponse.ts +20 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +257 -0
- package/Types/Probe/ProbeMonitorResponse.ts +14 -0
- package/UI/Components/Calendar/Calendar.tsx +8 -2
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +5 -5
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +8 -5
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +4 -1
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +6 -3
- package/UI/Components/CodeBlock/CodeBlock.tsx +2 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +3 -0
- package/UI/Components/Divider/Divider.tsx +1 -1
- package/UI/Components/Dropdown/Dropdown.tsx +13 -4
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +110 -2
- package/UI/Components/ErrorBoundary.tsx +2 -1
- package/UI/Components/EventItem/EventItem.tsx +2 -2
- package/UI/Components/GanttChart/Bar/Index.tsx +1 -1
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +30 -23
- package/UI/Components/Header/Header.tsx +7 -0
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +2 -0
- package/UI/Components/Label/Label.tsx +2 -2
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +22 -10
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +9 -3
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +8 -8
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +44 -20
- package/UI/Components/Modal/ConfirmModal.tsx +1 -1
- package/UI/Components/Modal/Modal.tsx +213 -121
- package/UI/Components/Modal/ModalFooter.tsx +33 -22
- package/UI/Components/ModelTable/TableView.tsx +1 -1
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +20 -12
- package/UI/Components/Pill/Pill.tsx +21 -13
- package/UI/Components/StatusBubble/StatusBubble.tsx +3 -3
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +7 -1
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +9 -3
- package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +62 -4
- package/UI/Components/Workflow/Component.tsx +53 -33
- package/UI/Components/Workflow/ComponentPortViewer.tsx +6 -6
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +8 -8
- package/UI/Components/Workflow/ComponentsModal.tsx +16 -9
- package/UI/Components/Workflow/Workflow.tsx +13 -11
- package/UI/Utils/Theme.ts +140 -0
- package/Utils/Dashboard/Components/DashboardLogChartComponent.ts +104 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/Monitor/MonitorMetricType.ts +70 -2
- package/build/dist/Models/DatabaseModels/AIRun.js +52 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskAPI.js +8 -23
- package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +107 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.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/Services/AIAgentTaskService.js +59 -0
- package/build/dist/Server/Services/AIAgentTaskService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +24 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +19 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +24 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +21 -7
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +449 -7
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +59 -11
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js +119 -0
- package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js +147 -0
- package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js +93 -0
- package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js +311 -0
- package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +1 -0
- package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js +143 -0
- package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +6 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js +451 -0
- package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +29 -0
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +86 -2
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +9 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Date.js +32 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/HttpPhaseTimings.js +2 -0
- package/build/dist/Types/Monitor/HttpPhaseTimings.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js +15 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/PingMonitor/PingMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/PingMonitor/PingMonitorResponse.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +159 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +2 -2
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +7 -4
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +4 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +6 -3
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +3 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Divider/Divider.js +1 -1
- package/build/dist/UI/Components/Divider/Divider.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +10 -4
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +76 -3
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +2 -1
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/Bar/Index.js +1 -1
- package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +29 -23
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Header/Header.js +1 -0
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Label/Label.js +2 -2
- package/build/dist/UI/Components/Label/Label.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +20 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +8 -2
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +8 -8
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +40 -20
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +109 -51
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +13 -10
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +17 -12
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/Pill/Pill.js +12 -13
- package/build/dist/UI/Components/Pill/Pill.js.map +1 -1
- package/build/dist/UI/Components/StatusBubble/StatusBubble.js +3 -3
- package/build/dist/UI/Components/StatusBubble/StatusBubble.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +36 -6
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +43 -33
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +6 -6
- package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +8 -8
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +15 -9
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +13 -11
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Utils/Theme.js +106 -0
- package/build/dist/UI/Utils/Theme.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js +92 -0
- package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +70 -3
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import CalendarEvent from "../Calendar/CalendarEvent";
|
|
2
|
+
import OneUptimeDate from "../Date";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Turns the low-level calendar events produced by LayerUtil into the
|
|
6
|
+
* human-readable "shifts" the on-call schedule summaries render — e.g.
|
|
7
|
+
* "Alice is on call from Mon 9:00 AM to Tue 9:00 AM".
|
|
8
|
+
*
|
|
9
|
+
* LayerUtil emits one CalendarEvent per contiguous coverage segment. A single
|
|
10
|
+
* rotation turn can therefore be split into several events (a daily 9-5
|
|
11
|
+
* restriction produces one event per day), and the merged multi-layer schedule
|
|
12
|
+
* interleaves events from different users/layers. These helpers collapse those
|
|
13
|
+
* raw segments back into the shifts a human thinks in, and surface the gaps
|
|
14
|
+
* where nobody is on call.
|
|
15
|
+
*
|
|
16
|
+
* Everything here is pure and timezone-agnostic: it operates on the absolute
|
|
17
|
+
* instants already resolved by LayerUtil (which itself resolves restriction
|
|
18
|
+
* wall-clock windows in the schedule's timezone). Rendering code decides which
|
|
19
|
+
* timezone to display those instants in.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* The identity of the on-call person for an event. LayerUtil stores the user id
|
|
24
|
+
* in CalendarEvent.title before the UI relabels it, so callers pass the events
|
|
25
|
+
* straight through from getEvents/getMultiLayerEvents.
|
|
26
|
+
*/
|
|
27
|
+
export interface OnCallShift {
|
|
28
|
+
userId: string;
|
|
29
|
+
start: Date;
|
|
30
|
+
end: Date;
|
|
31
|
+
/*
|
|
32
|
+
* Total ACTIVE on-call seconds inside this shift, i.e. the sum of the covered
|
|
33
|
+
* segments' durations. For a contiguous shift this equals end - start. For a
|
|
34
|
+
* turn merged across off-hours (mergeAcrossGaps), it is the real time on call,
|
|
35
|
+
* which is smaller than the wall-clock span — so the summary can show honest
|
|
36
|
+
* coverage ("40h across the week") instead of the misleading span ("4d 8h").
|
|
37
|
+
*/
|
|
38
|
+
coverageSeconds: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CoverageGap {
|
|
42
|
+
start: Date;
|
|
43
|
+
end: Date;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface CurrentAndNextShift {
|
|
47
|
+
current: OnCallShift | null;
|
|
48
|
+
next: OnCallShift | null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* Two coverage segments are considered part of the same continuous shift when
|
|
53
|
+
* the gap between them is below this threshold. LayerUtil starts each following
|
|
54
|
+
* segment exactly one second after the previous one ends, so anything within a
|
|
55
|
+
* couple of minutes is "touching"; anything larger is a genuine off-hours gap
|
|
56
|
+
* (a restriction window closing, a rotation with no fallback layer, etc.).
|
|
57
|
+
*/
|
|
58
|
+
const CONTIGUITY_TOLERANCE_SECONDS: number = 90;
|
|
59
|
+
|
|
60
|
+
export default class ScheduleShiftUtil {
|
|
61
|
+
/*
|
|
62
|
+
* Collapse raw coverage events into shifts.
|
|
63
|
+
*
|
|
64
|
+
* - mergeAcrossGaps = false (default): only merges segments that actually
|
|
65
|
+
* touch, so genuine off-hours gaps remain visible. This is what the "final
|
|
66
|
+
* schedule" summary uses so it can honestly show when nobody is on call.
|
|
67
|
+
* - mergeAcrossGaps = true: merges every consecutive run of the same user
|
|
68
|
+
* into a single turn, absorbing the within-turn off-hours gaps. This is what
|
|
69
|
+
* the per-layer rotation summary uses so "Alice: Mon -> Fri" reads as one
|
|
70
|
+
* rotation turn instead of five separate day rows. The turn's coverageSeconds
|
|
71
|
+
* still reflects only the real active on-call time (e.g. 5x8h, not the full
|
|
72
|
+
* Mon->Fri wall-clock span), and the summary shows the layer's active-hours
|
|
73
|
+
* window as context.
|
|
74
|
+
*/
|
|
75
|
+
public static groupEventsIntoShifts(
|
|
76
|
+
events: Array<CalendarEvent>,
|
|
77
|
+
options?: { mergeAcrossGaps?: boolean | undefined } | undefined,
|
|
78
|
+
): Array<OnCallShift> {
|
|
79
|
+
if (!events || events.length === 0) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const mergeAcrossGaps: boolean = Boolean(options?.mergeAcrossGaps);
|
|
84
|
+
|
|
85
|
+
// Work on a copy sorted by start time; never mutate the caller's array.
|
|
86
|
+
const sorted: Array<CalendarEvent> = [...events]
|
|
87
|
+
.filter((event: CalendarEvent) => {
|
|
88
|
+
return (
|
|
89
|
+
Boolean(event.title) && Boolean(event.start) && Boolean(event.end)
|
|
90
|
+
);
|
|
91
|
+
})
|
|
92
|
+
.sort((a: CalendarEvent, b: CalendarEvent) => {
|
|
93
|
+
if (OneUptimeDate.isBefore(a.start, b.start)) {
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
if (OneUptimeDate.isAfter(a.start, b.start)) {
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const shifts: Array<OnCallShift> = [];
|
|
103
|
+
|
|
104
|
+
for (const event of sorted) {
|
|
105
|
+
const userId: string = event.title;
|
|
106
|
+
const eventSeconds: number = OneUptimeDate.getDifferenceInSeconds(
|
|
107
|
+
event.end,
|
|
108
|
+
event.start,
|
|
109
|
+
);
|
|
110
|
+
const last: OnCallShift | undefined = shifts[shifts.length - 1];
|
|
111
|
+
|
|
112
|
+
const sameUser: boolean = Boolean(last) && last!.userId === userId;
|
|
113
|
+
|
|
114
|
+
const isContiguous: boolean =
|
|
115
|
+
Boolean(last) &&
|
|
116
|
+
OneUptimeDate.getDifferenceInSeconds(last!.end, event.start) <=
|
|
117
|
+
CONTIGUITY_TOLERANCE_SECONDS &&
|
|
118
|
+
OneUptimeDate.isOnOrBefore(last!.end, event.end);
|
|
119
|
+
|
|
120
|
+
/*
|
|
121
|
+
* Extend the previous shift when it belongs to the same user AND either we
|
|
122
|
+
* are merging whole turns, or the two segments physically touch. Only
|
|
123
|
+
* extend the end forward — never pull it backwards — so overlapping
|
|
124
|
+
* segments (possible after the multi-layer priority merge) can't shrink a
|
|
125
|
+
* shift. Accumulate each merged segment's own duration into coverageSeconds
|
|
126
|
+
* so a turn merged across off-hours reports its real active time on call.
|
|
127
|
+
*/
|
|
128
|
+
if (last && sameUser && (mergeAcrossGaps || isContiguous)) {
|
|
129
|
+
if (OneUptimeDate.isAfter(event.end, last.end)) {
|
|
130
|
+
last.end = event.end;
|
|
131
|
+
}
|
|
132
|
+
last.coverageSeconds += eventSeconds;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
shifts.push({
|
|
137
|
+
userId,
|
|
138
|
+
start: event.start,
|
|
139
|
+
end: event.end,
|
|
140
|
+
coverageSeconds: eventSeconds,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return shifts;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/*
|
|
148
|
+
* The shift that contains `now` (the person on call right now) and the first
|
|
149
|
+
* shift that starts after `now` (up next). Either can be null: `current` is
|
|
150
|
+
* null when nobody is on call at this instant (a coverage gap), and `next` is
|
|
151
|
+
* null when the computed window does not reach far enough to include another
|
|
152
|
+
* shift.
|
|
153
|
+
*/
|
|
154
|
+
public static getCurrentAndNextShift(
|
|
155
|
+
shifts: Array<OnCallShift>,
|
|
156
|
+
now: Date,
|
|
157
|
+
): CurrentAndNextShift {
|
|
158
|
+
let current: OnCallShift | null = null;
|
|
159
|
+
let next: OnCallShift | null = null;
|
|
160
|
+
|
|
161
|
+
for (const shift of shifts) {
|
|
162
|
+
const hasStarted: boolean = OneUptimeDate.isOnOrBefore(shift.start, now);
|
|
163
|
+
const hasNotEnded: boolean = OneUptimeDate.isAfter(shift.end, now);
|
|
164
|
+
|
|
165
|
+
if (hasStarted && hasNotEnded) {
|
|
166
|
+
current = shift;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (OneUptimeDate.isAfter(shift.start, now)) {
|
|
171
|
+
if (!next || OneUptimeDate.isBefore(shift.start, next.start)) {
|
|
172
|
+
next = shift;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return { current, next };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/*
|
|
181
|
+
* Periods inside [windowStart, windowEnd] during which no shift provides
|
|
182
|
+
* coverage. Includes a leading gap (from windowStart until the first shift
|
|
183
|
+
* begins) and gaps between consecutive shifts. Trailing time after the last
|
|
184
|
+
* shift is intentionally NOT reported as a gap: the summary window is finite,
|
|
185
|
+
* so "nothing scheduled past the window" is an artifact of the window, not a
|
|
186
|
+
* real coverage hole.
|
|
187
|
+
*
|
|
188
|
+
* `shifts` are assumed sorted by start (as returned by groupEventsIntoShifts).
|
|
189
|
+
*/
|
|
190
|
+
public static getCoverageGaps(
|
|
191
|
+
shifts: Array<OnCallShift>,
|
|
192
|
+
windowStart: Date,
|
|
193
|
+
windowEnd: Date,
|
|
194
|
+
): Array<CoverageGap> {
|
|
195
|
+
const gaps: Array<CoverageGap> = [];
|
|
196
|
+
|
|
197
|
+
if (OneUptimeDate.isOnOrAfter(windowStart, windowEnd)) {
|
|
198
|
+
return gaps;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* A gap only "counts" when it is longer than the contiguity tolerance, so
|
|
203
|
+
* the one-second boundaries LayerUtil leaves between segments never show up
|
|
204
|
+
* as spurious coverage holes.
|
|
205
|
+
*/
|
|
206
|
+
const isRealGap: (start: Date, end: Date) => boolean = (
|
|
207
|
+
start: Date,
|
|
208
|
+
end: Date,
|
|
209
|
+
): boolean => {
|
|
210
|
+
return (
|
|
211
|
+
OneUptimeDate.isAfter(end, start) &&
|
|
212
|
+
OneUptimeDate.getDifferenceInSeconds(end, start) >
|
|
213
|
+
CONTIGUITY_TOLERANCE_SECONDS
|
|
214
|
+
);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (shifts.length === 0) {
|
|
218
|
+
if (isRealGap(windowStart, windowEnd)) {
|
|
219
|
+
gaps.push({ start: windowStart, end: windowEnd });
|
|
220
|
+
}
|
|
221
|
+
return gaps;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Leading gap: nobody on call from the window start until the first shift.
|
|
225
|
+
const firstShift: OnCallShift = shifts[0]!;
|
|
226
|
+
if (
|
|
227
|
+
OneUptimeDate.isAfter(firstShift.start, windowStart) &&
|
|
228
|
+
isRealGap(windowStart, firstShift.start)
|
|
229
|
+
) {
|
|
230
|
+
gaps.push({ start: windowStart, end: firstShift.start });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/*
|
|
234
|
+
* `coveredUntil` tracks the furthest point covered so far. Shifts can
|
|
235
|
+
* overlap (multi-layer merges), so we advance it monotonically and only
|
|
236
|
+
* record a gap when the next shift starts strictly after it.
|
|
237
|
+
*/
|
|
238
|
+
let coveredUntil: Date = firstShift.end;
|
|
239
|
+
|
|
240
|
+
for (let i: number = 1; i < shifts.length; i++) {
|
|
241
|
+
const shift: OnCallShift = shifts[i]!;
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
OneUptimeDate.isAfter(shift.start, coveredUntil) &&
|
|
245
|
+
isRealGap(coveredUntil, shift.start)
|
|
246
|
+
) {
|
|
247
|
+
gaps.push({ start: coveredUntil, end: shift.start });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (OneUptimeDate.isAfter(shift.end, coveredUntil)) {
|
|
251
|
+
coveredUntil = shift.end;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return gaps;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
@@ -8,10 +8,13 @@ import SslMonitorResponse from "../Monitor/SSLMonitor/SslMonitorResponse";
|
|
|
8
8
|
import SyntheticMonitorResponse from "../Monitor/SyntheticMonitors/SyntheticMonitorResponse";
|
|
9
9
|
import SnmpMonitorResponse from "../Monitor/SnmpMonitor/SnmpMonitorResponse";
|
|
10
10
|
import DnsMonitorResponse from "../Monitor/DnsMonitor/DnsMonitorResponse";
|
|
11
|
+
import PingMonitorResponse from "../Monitor/PingMonitor/PingMonitorResponse";
|
|
11
12
|
import DomainMonitorResponse from "../Monitor/DomainMonitor/DomainMonitorResponse";
|
|
12
13
|
import DnssecMonitorResponse from "../Monitor/DnssecMonitor/DnssecMonitorResponse";
|
|
13
14
|
import ExternalStatusPageMonitorResponse from "../Monitor/ExternalStatusPageMonitor/ExternalStatusPageMonitorResponse";
|
|
15
|
+
import HttpPhaseTimings from "../Monitor/HttpPhaseTimings";
|
|
14
16
|
import MonitorEvaluationSummary from "../Monitor/MonitorEvaluationSummary";
|
|
17
|
+
import NetworkPathTrace from "../Monitor/NetworkMonitor/NetworkPathTrace";
|
|
15
18
|
import ObjectID from "../ObjectID";
|
|
16
19
|
import Port from "../Port";
|
|
17
20
|
import ProbeAttempt from "./ProbeAttempt";
|
|
@@ -35,6 +38,17 @@ export default interface ProbeMonitorResponse {
|
|
|
35
38
|
syntheticMonitorResponse?: Array<SyntheticMonitorResponse> | undefined;
|
|
36
39
|
customCodeMonitorResponse?: CustomCodeMonitorResponse | undefined;
|
|
37
40
|
snmpResponse?: SnmpMonitorResponse | undefined;
|
|
41
|
+
pingResponse?: PingMonitorResponse | undefined;
|
|
42
|
+
/*
|
|
43
|
+
* Traceroute + DNS lookup captured by the probe when a Ping/IP/Port check
|
|
44
|
+
* fails — path evidence from the moment of failure.
|
|
45
|
+
*/
|
|
46
|
+
networkPathTrace?: NetworkPathTrace | undefined;
|
|
47
|
+
/*
|
|
48
|
+
* DNS / TCP / TLS / TTFB / download phase breakdown for Website and API
|
|
49
|
+
* checks. Absent when the request went through a proxy.
|
|
50
|
+
*/
|
|
51
|
+
httpTimings?: HttpPhaseTimings | undefined;
|
|
38
52
|
dnsResponse?: DnsMonitorResponse | undefined;
|
|
39
53
|
domainResponse?: DomainMonitorResponse | undefined;
|
|
40
54
|
dnssecResponse?: DnssecMonitorResponse | undefined;
|
|
@@ -21,6 +21,12 @@ export interface ComponentProps {
|
|
|
21
21
|
id?: string | undefined;
|
|
22
22
|
events: Array<CalendarEvent>;
|
|
23
23
|
defaultCalendarView?: DefaultCalendarView;
|
|
24
|
+
/*
|
|
25
|
+
* Which date the calendar initially opens on. Defaults to "now". Callers that
|
|
26
|
+
* render events shifted into a display timezone pass the same-shifted "now" so
|
|
27
|
+
* the grid opens on that zone's current day rather than the browser's.
|
|
28
|
+
*/
|
|
29
|
+
defaultDate?: Date | undefined;
|
|
24
30
|
onRangeChange: (startAndEndTime: StartAndEndTime) => void;
|
|
25
31
|
}
|
|
26
32
|
|
|
@@ -38,9 +44,9 @@ const CalendarElement: FunctionComponent<ComponentProps> = (
|
|
|
38
44
|
): ReactElement => {
|
|
39
45
|
const { defaultDate } = useMemo(() => {
|
|
40
46
|
return {
|
|
41
|
-
defaultDate: OneUptimeDate.getCurrentDate(),
|
|
47
|
+
defaultDate: props.defaultDate || OneUptimeDate.getCurrentDate(),
|
|
42
48
|
};
|
|
43
|
-
}, []);
|
|
49
|
+
}, [props.defaultDate]);
|
|
44
50
|
|
|
45
51
|
const eventStyleGetter: EventPropGetter<any> = (
|
|
46
52
|
event: CalendarEvent,
|
|
@@ -38,10 +38,10 @@ export interface Chart {
|
|
|
38
38
|
exemplarPoints?: Array<ExemplarPoint> | undefined;
|
|
39
39
|
onExemplarClick?: ((exemplar: ExemplarPoint) => void) | undefined;
|
|
40
40
|
/**
|
|
41
|
-
* Optional control panel rendered
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
41
|
+
* Optional control panel rendered directly below the chart body. Used by
|
|
42
|
+
* per-series-grouped metric charts to surface a search box, a sort
|
|
43
|
+
* control, per-series toggles, and a "show all" escape hatch so the chart
|
|
44
|
+
* stays usable at thousands of unique label combinations.
|
|
45
45
|
*/
|
|
46
46
|
seriesControls?: ReactElement | undefined;
|
|
47
47
|
}
|
|
@@ -308,10 +308,10 @@ const ChartGroup: FunctionComponent<ComponentProps> = (
|
|
|
308
308
|
{chart.description}
|
|
309
309
|
</p>
|
|
310
310
|
)}
|
|
311
|
-
{chart.seriesControls ? chart.seriesControls : null}
|
|
312
311
|
<div className="flex-1 flex flex-col min-h-80">
|
|
313
312
|
{getChartContent(chart, index)}
|
|
314
313
|
</div>
|
|
314
|
+
{chart.seriesControls ? chart.seriesControls : null}
|
|
315
315
|
</div>
|
|
316
316
|
);
|
|
317
317
|
})}
|
|
@@ -815,7 +815,10 @@ const AreaChart: React.ForwardRefExoticComponent<
|
|
|
815
815
|
wrapperStyle={{ outline: "none" }}
|
|
816
816
|
isAnimationActive={true}
|
|
817
817
|
animationDuration={100}
|
|
818
|
-
cursor={{
|
|
818
|
+
cursor={{
|
|
819
|
+
stroke: "var(--ou-chart-cursor, #d1d5db)",
|
|
820
|
+
strokeWidth: 1,
|
|
821
|
+
}}
|
|
819
822
|
offset={20}
|
|
820
823
|
position={{ y: 0 }}
|
|
821
824
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -903,11 +906,11 @@ const AreaChart: React.ForwardRefExoticComponent<
|
|
|
903
906
|
}
|
|
904
907
|
return [low, high];
|
|
905
908
|
}}
|
|
906
|
-
stroke="#94a3b8"
|
|
909
|
+
stroke="var(--ou-chart-tick, #94a3b8)"
|
|
907
910
|
strokeOpacity={0.3}
|
|
908
911
|
strokeWidth={1}
|
|
909
912
|
strokeDasharray="3 3"
|
|
910
|
-
fill="#94a3b8"
|
|
913
|
+
fill="var(--ou-chart-tick, #94a3b8)"
|
|
911
914
|
fillOpacity={0.12}
|
|
912
915
|
isAnimationActive={false}
|
|
913
916
|
connectNulls={false}
|
|
@@ -1064,7 +1067,7 @@ const AreaChart: React.ForwardRefExoticComponent<
|
|
|
1064
1067
|
y={exemplar.y}
|
|
1065
1068
|
r={5}
|
|
1066
1069
|
fill="#7c3aed"
|
|
1067
|
-
stroke="#ffffff"
|
|
1070
|
+
stroke="var(--ou-chart-marker-ring, #ffffff)"
|
|
1068
1071
|
strokeWidth={2}
|
|
1069
1072
|
style={{ cursor: "pointer" }}
|
|
1070
1073
|
onClick={() => {
|
|
@@ -1074,7 +1077,7 @@ const AreaChart: React.ForwardRefExoticComponent<
|
|
|
1074
1077
|
<Label
|
|
1075
1078
|
value="E"
|
|
1076
1079
|
position="center"
|
|
1077
|
-
fill="#ffffff"
|
|
1080
|
+
fill="var(--ou-chart-marker-ring, #ffffff)"
|
|
1078
1081
|
fontSize={8}
|
|
1079
1082
|
fontWeight={700}
|
|
1080
1083
|
/>
|
|
@@ -925,7 +925,10 @@ const BarChart: React.ForwardRefExoticComponent<
|
|
|
925
925
|
wrapperStyle={{ outline: "none" }}
|
|
926
926
|
isAnimationActive={true}
|
|
927
927
|
animationDuration={100}
|
|
928
|
-
cursor={{
|
|
928
|
+
cursor={{
|
|
929
|
+
fill: "var(--ou-chart-cursor, #d1d5db)",
|
|
930
|
+
opacity: "0.15",
|
|
931
|
+
}}
|
|
929
932
|
offset={20}
|
|
930
933
|
{...(layout === "horizontal"
|
|
931
934
|
? { position: { y: 0 } }
|
|
@@ -813,7 +813,10 @@ const LineChart: React.ForwardRefExoticComponent<
|
|
|
813
813
|
wrapperStyle={{ outline: "none" }}
|
|
814
814
|
isAnimationActive={true}
|
|
815
815
|
animationDuration={100}
|
|
816
|
-
cursor={{
|
|
816
|
+
cursor={{
|
|
817
|
+
stroke: "var(--ou-chart-cursor, #d1d5db)",
|
|
818
|
+
strokeWidth: 1,
|
|
819
|
+
}}
|
|
817
820
|
offset={20}
|
|
818
821
|
position={{ y: 0 }}
|
|
819
822
|
content={({ active, payload, label }: any) => {
|
|
@@ -1052,7 +1055,7 @@ const LineChart: React.ForwardRefExoticComponent<
|
|
|
1052
1055
|
y={exemplar.y}
|
|
1053
1056
|
r={5}
|
|
1054
1057
|
fill="#7c3aed"
|
|
1055
|
-
stroke="#ffffff"
|
|
1058
|
+
stroke="var(--ou-chart-marker-ring, #ffffff)"
|
|
1056
1059
|
strokeWidth={2}
|
|
1057
1060
|
style={{ cursor: "pointer" }}
|
|
1058
1061
|
onClick={() => {
|
|
@@ -1062,7 +1065,7 @@ const LineChart: React.ForwardRefExoticComponent<
|
|
|
1062
1065
|
<Label
|
|
1063
1066
|
value="E"
|
|
1064
1067
|
position="center"
|
|
1065
|
-
fill="#ffffff"
|
|
1068
|
+
fill="var(--ou-chart-marker-ring, #ffffff)"
|
|
1066
1069
|
fontSize={8}
|
|
1067
1070
|
fontWeight={700}
|
|
1068
1071
|
/>
|
|
@@ -36,8 +36,9 @@ const CodeBlock: FunctionComponent<ComponentProps> = (
|
|
|
36
36
|
{showCopyButton && typeof props.code === "string" && (
|
|
37
37
|
<button
|
|
38
38
|
onClick={handleCopy}
|
|
39
|
-
className="absolute top-2 right-2 p-2 rounded-md bg-gray-700 hover:bg-gray-600 text-gray-300 hover:text-white transition-all opacity-
|
|
39
|
+
className="absolute top-2 right-2 p-2 rounded-md bg-gray-700 hover:bg-gray-600 text-gray-300 hover:text-white transition-all opacity-70 hover:opacity-100 focus-visible:opacity-100 group-hover:opacity-100 z-10"
|
|
40
40
|
title={copied ? "Copied!" : "Copy to clipboard"}
|
|
41
|
+
aria-label={copied ? "Copied" : "Copy to clipboard"}
|
|
41
42
|
type="button"
|
|
42
43
|
>
|
|
43
44
|
<Icon
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Editor from "@monaco-editor/react";
|
|
2
2
|
import CodeType from "../../../Types/Code/CodeType";
|
|
3
3
|
import MarkdownUtil from "../../Utils/Markdown";
|
|
4
|
+
import { Theme, useTheme } from "../../Utils/Theme";
|
|
4
5
|
import React, {
|
|
5
6
|
FunctionComponent,
|
|
6
7
|
ReactElement,
|
|
@@ -36,6 +37,7 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
|
|
|
36
37
|
const [placeholder, setPlaceholder] = useState<string>("");
|
|
37
38
|
const [helpText, setHelpText] = useState<string | ReactElement>("");
|
|
38
39
|
const editorRef: React.MutableRefObject<any> = useRef<any>(null);
|
|
40
|
+
const theme: Theme = useTheme();
|
|
39
41
|
|
|
40
42
|
useEffect(() => {
|
|
41
43
|
let value: string | undefined = props.value;
|
|
@@ -138,6 +140,7 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
|
|
|
138
140
|
)}
|
|
139
141
|
|
|
140
142
|
<Editor
|
|
143
|
+
theme={theme === Theme.Dark ? "vs-dark" : "light"}
|
|
141
144
|
defaultLanguage={props.type}
|
|
142
145
|
height="30vh"
|
|
143
146
|
value={value}
|
|
@@ -41,6 +41,12 @@ export interface DropdownOptionGroup {
|
|
|
41
41
|
options: Array<DropdownOption>;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/*
|
|
45
|
+
* Modal surfaces use z-50. The portalled menu must sit above that stacking
|
|
46
|
+
* context so options are not painted underneath an anchored modal footer.
|
|
47
|
+
*/
|
|
48
|
+
export const DROPDOWN_MENU_Z_INDEX: number = 60;
|
|
49
|
+
|
|
44
50
|
export interface ComponentProps {
|
|
45
51
|
options: Array<DropdownOption | DropdownOptionGroup>;
|
|
46
52
|
initialValue?: undefined | DropdownOption | Array<DropdownOption>;
|
|
@@ -334,8 +340,8 @@ const Dropdown: FunctionComponent<ComponentProps> = (
|
|
|
334
340
|
} = (color?: string): { backgroundColor: string; color: string } => {
|
|
335
341
|
if (!color) {
|
|
336
342
|
return {
|
|
337
|
-
backgroundColor: "#e5e7eb",
|
|
338
|
-
color: "#374151",
|
|
343
|
+
backgroundColor: "var(--ou-surface-tertiary, #e5e7eb)",
|
|
344
|
+
color: "var(--ou-text-secondary, #374151)",
|
|
339
345
|
};
|
|
340
346
|
}
|
|
341
347
|
|
|
@@ -511,6 +517,9 @@ const Dropdown: FunctionComponent<ComponentProps> = (
|
|
|
511
517
|
setValue(value);
|
|
512
518
|
}, [props.value]);
|
|
513
519
|
|
|
520
|
+
const menuPortalTarget: HTMLElement | null =
|
|
521
|
+
typeof document === "undefined" ? null : document.body;
|
|
522
|
+
|
|
514
523
|
return (
|
|
515
524
|
<div
|
|
516
525
|
id={props.id}
|
|
@@ -710,11 +719,11 @@ const Dropdown: FunctionComponent<ComponentProps> = (
|
|
|
710
719
|
menuPortal: (base: CSSObjectWithLabel): CSSObjectWithLabel => {
|
|
711
720
|
return {
|
|
712
721
|
...base,
|
|
713
|
-
zIndex:
|
|
722
|
+
zIndex: DROPDOWN_MENU_Z_INDEX,
|
|
714
723
|
};
|
|
715
724
|
},
|
|
716
725
|
}}
|
|
717
|
-
menuPortalTarget={
|
|
726
|
+
menuPortalTarget={menuPortalTarget}
|
|
718
727
|
menuPosition="fixed"
|
|
719
728
|
isClearable={true}
|
|
720
729
|
isSearchable={true}
|