@oneuptime/common 12.0.9 → 12.0.11
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/NetworkDevice.ts +44 -0
- package/Models/DatabaseModels/NetworkDeviceLink.ts +116 -0
- package/Models/DatabaseModels/RunnerJob.ts +17 -2
- package/Server/API/LlmProviderAPI.ts +8 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +240 -0
- package/Server/Services/NetworkDeviceLinkService.ts +338 -2
- package/Server/Services/NetworkDeviceService.ts +265 -12
- package/Server/Services/RunnerJobService.ts +24 -1
- package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +19 -5
- package/Server/Types/Database/JSONColumnQuery.ts +42 -4
- package/Server/Utils/LLM/LLMService.ts +108 -19
- package/Server/Utils/Monitor/MonitorAlert.ts +22 -115
- package/Server/Utils/Monitor/MonitorIncident.ts +7 -337
- package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +27 -2
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +32 -0
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +469 -0
- package/Server/Utils/SSRFProtection.ts +5 -4
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +186 -38
- package/Tests/App/AdminDashboard/AdminUsersBulkAddToProject.test.tsx +955 -0
- package/Tests/App/AdminDashboard/BulkAddUsersToProject.test.ts +778 -0
- package/Tests/App/AdminDashboard/BulkAddUsersToProjectModal.test.tsx +1051 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +420 -112
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +81 -6
- package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +543 -0
- package/Tests/App/Dashboard/PayAsYouGoFreePlan.test.ts +125 -0
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +612 -0
- package/Tests/App/Dashboard/SloWidgetChartRendering.test.tsx +536 -0
- package/Tests/App/Dashboard/UserElementEmail.test.tsx +447 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +284 -0
- package/Tests/Models/AnalyticsModels/CommonModel.test.ts +312 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +250 -0
- package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +46 -18
- package/Tests/Server/Services/NetworkDeviceLabelRuleRun.test.ts +618 -0
- package/Tests/Server/Services/NetworkDeviceLinkParentValidation.test.ts +1043 -0
- package/Tests/Server/Services/NetworkSiteAssignmentRuleRun.test.ts +706 -0
- package/Tests/Server/Services/RunnerJobEnqueue.test.ts +412 -0
- package/Tests/Server/Types/Billing/PayAsYouGoMeteredPricing.test.ts +125 -0
- package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +508 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +2 -2
- package/Tests/Server/Utils/AI/LLMServiceRetryPolicy.test.ts +450 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +556 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +547 -0
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +30 -0
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +699 -0
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +55 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +668 -0
- package/Tests/Types/API/URLMalformedTolerance.test.ts +301 -0
- package/Tests/Types/API/URLTelScheme.test.ts +261 -0
- package/Tests/Types/API/URLUnsupportedScheme.test.ts +148 -0
- package/Tests/Types/Billing/PayAsYouGoPricing.test.ts +64 -0
- package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +107 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +62 -0
- package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +184 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +124 -0
- package/Tests/Types/Workflow/BaseModelComponents.test.ts +17 -0
- package/Tests/UI/Components/Button.test.tsx +279 -0
- package/Tests/UI/Components/Charts/ChartXAxisDataKey.test.tsx +256 -0
- package/Tests/UI/Components/Charts/DataPointUtil.test.ts +323 -0
- package/Tests/UI/Components/DictionaryValuePlaceholderAndSuggestions.test.tsx +595 -0
- package/Tests/UI/Components/Icon.test.tsx +57 -0
- package/Tests/UI/Components/List.test.tsx +20 -3
- package/Tests/UI/Components/LogsSavedViewsDropdown.test.tsx +304 -0
- package/Tests/UI/Components/LogsViewerClearSavedView.test.tsx +179 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +349 -1
- package/Tests/UI/Components/Pagination.test.tsx +721 -146
- package/Tests/UI/Components/PaginationIntegration.test.tsx +386 -0
- package/Tests/UI/Components/PaginationUtil.test.ts +417 -0
- package/Tests/UI/Components/TelemetrySavedViewsDropdown.test.tsx +343 -0
- package/Tests/UI/Components/Workflow/ColumnEditor/ColumnControl.test.ts +289 -0
- package/Tests/UI/Components/Workflow/ColumnEditor/ColumnOperators.test.ts +271 -0
- package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRow.test.ts +119 -0
- package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.test.ts +968 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +766 -0
- package/Tests/UI/Utils/RunNetworkRule.test.ts +320 -0
- package/Tests/Utils/APIRetryPolicy.test.ts +823 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +502 -0
- package/Tests/Utils/Monitor/NetworkTopologyDeclaredHierarchy.test.ts +759 -0
- package/Tests/Utils/NetworkAutomation/RuleRunSummary.test.ts +286 -0
- package/Tests/Utils/Schema/BaseSchema.test.ts +651 -0
- package/Types/API/Protocol.ts +9 -0
- package/Types/API/URL.ts +286 -20
- package/Types/Billing/PayAsYouGoPricing.ts +47 -0
- package/Types/CustomField/CustomFieldType.ts +28 -0
- package/Types/Monitor/MonitorType.ts +11 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
- package/Types/NetworkAutomation/RuleRunResult.ts +121 -0
- package/Types/Runbook/RunbookStepType.ts +23 -0
- package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +7 -0
- package/UI/Components/Button/Button.tsx +14 -22
- package/UI/Components/Charts/Area/AreaChart.tsx +4 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +4 -2
- package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +13 -0
- package/UI/Components/Charts/Line/LineChart.tsx +4 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +6 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +15 -12
- package/UI/Components/Dictionary/Dictionary.tsx +4 -39
- package/UI/Components/Icon/Icon.tsx +1 -1
- package/UI/Components/LogsViewer/LogsViewer.tsx +5 -1
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +8 -0
- package/UI/Components/LogsViewer/components/LogsPagination.tsx +29 -91
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +2 -0
- package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +66 -1
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +55 -0
- package/UI/Components/Pagination/Pagination.tsx +373 -328
- package/UI/Components/Pagination/PaginationUtil.ts +263 -0
- package/UI/Components/Pagination/Screenshots/README.md +15 -0
- package/UI/Components/Pagination/Screenshots/pagination-before-after.png +0 -0
- package/UI/Components/Pagination/Screenshots/pagination-go-to-page-modal.png +0 -0
- package/UI/Components/Pagination/Screenshots/pagination-long-list.png +0 -0
- package/UI/Components/Pagination/Screenshots/pagination-mobile.png +0 -0
- package/UI/Components/Pagination/Screenshots/pagination-telemetry.png +0 -0
- package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +66 -1
- package/UI/Components/TelemetryViewer/components/TelemetryPagination.tsx +38 -92
- package/UI/Components/TextArea/TextArea.tsx +3 -0
- package/UI/Components/Workflow/ArgumentsForm.tsx +18 -1
- package/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.tsx +177 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.tsx +243 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnControl.ts +255 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.tsx +178 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnOperators.ts +206 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnRow.ts +157 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.ts +517 -0
- package/UI/Components/Workflow/ColumnEditor/ColumnValueInput.tsx +482 -0
- package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +131 -0
- package/UI/Components/Workflow/ColumnEditor/ModelRecordForm.tsx +163 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +284 -100
- package/UI/Utils/NetworkAutomation/RunNetworkRule.ts +122 -0
- package/Utils/API.ts +243 -36
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +45 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +42 -2
- package/Utils/NetworkAutomation/RuleRunSummary.ts +147 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +45 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +115 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +17 -2
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +9 -1
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js +33 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +202 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLinkService.js +253 -1
- package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +223 -12
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +20 -2
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +12 -5
- package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
- package/build/dist/Server/Types/Database/JSONColumnQuery.js +40 -4
- package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +78 -22
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -98
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +7 -254
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +14 -2
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +27 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +285 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +5 -4
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +128 -35
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Types/API/Protocol.js +9 -0
- package/build/dist/Types/API/Protocol.js.map +1 -1
- package/build/dist/Types/API/URL.js +241 -18
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/PayAsYouGoPricing.js +41 -0
- package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldType.js +26 -0
- package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +10 -0
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js +39 -0
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +21 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +10 -16
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +2 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +2 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +12 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +2 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +17 -10
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Dictionary/Dictionary.js +4 -18
- package/build/dist/UI/Components/Dictionary/Dictionary.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/Components/LogsViewer/LogsViewer.js +3 -3
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +5 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js +14 -44
- package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +20 -2
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +42 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/Pagination/Pagination.js +174 -199
- package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
- package/build/dist/UI/Components/Pagination/PaginationUtil.js +160 -0
- package/build/dist/UI/Components/Pagination/PaginationUtil.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +20 -2
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js +23 -47
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +14 -2
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js +86 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js +119 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js +206 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js +57 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js +150 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js +67 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js +309 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js +204 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +66 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js +83 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +187 -68
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
- package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js +75 -0
- package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js.map +1 -0
- package/build/dist/Utils/API.js +175 -34
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +37 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +25 -3
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js +78 -0
- package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js.map +1 -0
- package/package.json +1 -1
|
@@ -27,6 +27,12 @@ export interface ComponentProps {
|
|
|
27
27
|
isLoadingSuggestions?: boolean | undefined;
|
|
28
28
|
loadingMessage?: string | undefined;
|
|
29
29
|
noSuggestionsMessage?: string | undefined;
|
|
30
|
+
/*
|
|
31
|
+
* The id of the element that names this input. Without it a picker that draws
|
|
32
|
+
* its own label - the workflow record editor, where the field's name sits in
|
|
33
|
+
* the column beside the box - leaves the input unnamed to a screen reader.
|
|
34
|
+
*/
|
|
35
|
+
ariaLabelledby?: string | undefined;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
const BASE_INPUT_CLASS: string =
|
|
@@ -458,6 +464,7 @@ const AutocompleteTextInput: FunctionComponent<ComponentProps> = (
|
|
|
458
464
|
className={getInputClassName()}
|
|
459
465
|
data-testid={props.dataTestId}
|
|
460
466
|
disabled={props.disabled}
|
|
467
|
+
aria-labelledby={props.ariaLabelledby}
|
|
461
468
|
aria-autocomplete="list"
|
|
462
469
|
aria-controls={listboxIdRef.current}
|
|
463
470
|
aria-expanded={showMenu}
|
|
@@ -158,47 +158,39 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
158
158
|
|
|
159
159
|
if (buttonStyle === ButtonStyleType.DANGER) {
|
|
160
160
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-transparent bg-red-600 text-base font-medium text-white shadow-sm ${
|
|
161
|
-
disabled ? "hover:bg-red-700"
|
|
161
|
+
disabled ? "" : "hover:bg-red-700"
|
|
162
162
|
} focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 md:ml-3 md:w-auto md:text-sm`;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
if (buttonStyle === ButtonStyleType.DANGER_OUTLINE) {
|
|
166
166
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-red-700 bg-white text-base font-medium text-red-700 shadow-sm ${
|
|
167
|
-
disabled ? "hover:bg-red-50"
|
|
167
|
+
disabled ? "" : "hover:bg-red-50"
|
|
168
168
|
} focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 md:mt-0 md:ml-3 md:w-auto md:text-sm`;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
if (buttonStyle === ButtonStyleType.PRIMARY) {
|
|
172
172
|
loadingIconClassName += ` text-indigo-100`;
|
|
173
|
-
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-transparent
|
|
174
|
-
disabled ? "
|
|
175
|
-
} focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 md:ml-3 md:w-auto md:text-sm`;
|
|
176
|
-
|
|
177
|
-
if (disabled) {
|
|
178
|
-
buttonStyleCssClass += ` bg-indigo-300`;
|
|
179
|
-
}
|
|
173
|
+
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-transparent ${
|
|
174
|
+
disabled ? "bg-indigo-300" : "bg-indigo-600 hover:bg-indigo-700"
|
|
175
|
+
} text-base font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 md:ml-3 md:w-auto md:text-sm`;
|
|
180
176
|
}
|
|
181
177
|
|
|
182
178
|
if (buttonStyle === ButtonStyleType.SECONDARY) {
|
|
183
179
|
loadingIconClassName += ` text-indigo-500`;
|
|
184
|
-
buttonStyleCssClass = `inline-flex items-center rounded-md border border-transparent
|
|
185
|
-
disabled ? "
|
|
186
|
-
} focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`;
|
|
187
|
-
|
|
188
|
-
if (disabled) {
|
|
189
|
-
buttonStyleCssClass += ` bg-indigo-300`;
|
|
190
|
-
}
|
|
180
|
+
buttonStyleCssClass = `inline-flex items-center rounded-md border border-transparent ${
|
|
181
|
+
disabled ? "bg-indigo-300" : "bg-indigo-100 hover:bg-indigo-200"
|
|
182
|
+
} text-sm font-medium text-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`;
|
|
191
183
|
}
|
|
192
184
|
|
|
193
185
|
if (buttonStyle === ButtonStyleType.ICON_LIGHT) {
|
|
194
186
|
buttonStyleCssClass = `rounded-md bg-white text-gray-400 ${
|
|
195
|
-
disabled ? "hover:text-gray-500"
|
|
187
|
+
disabled ? "" : "hover:text-gray-500"
|
|
196
188
|
} focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`;
|
|
197
189
|
}
|
|
198
190
|
|
|
199
191
|
if (buttonStyle === ButtonStyleType.ICON) {
|
|
200
192
|
buttonStyleCssClass = `rounded-md bg-transparent text-gray-600 ${
|
|
201
|
-
disabled ? "hover:text-gray-900"
|
|
193
|
+
disabled ? "" : "hover:text-gray-900"
|
|
202
194
|
} focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`;
|
|
203
195
|
}
|
|
204
196
|
|
|
@@ -225,25 +217,25 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
225
217
|
|
|
226
218
|
if (buttonStyle === ButtonStyleType.SUCCESS) {
|
|
227
219
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-transparent bg-green-600 text-base font-medium text-white shadow-sm ${
|
|
228
|
-
disabled ? "hover:bg-green-700"
|
|
220
|
+
disabled ? "" : "hover:bg-green-700"
|
|
229
221
|
} focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 md:ml-3 md:w-auto md:text-sm`;
|
|
230
222
|
}
|
|
231
223
|
|
|
232
224
|
if (buttonStyle === ButtonStyleType.SUCCESS_OUTLINE) {
|
|
233
225
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-green-700 bg-white text-base font-medium text-green-700 shadow-sm ${
|
|
234
|
-
disabled ? "hover:bg-green-50"
|
|
226
|
+
disabled ? "" : "hover:bg-green-50"
|
|
235
227
|
} focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 md:mt-0 md:ml-3 md:w-auto md:text-sm`;
|
|
236
228
|
}
|
|
237
229
|
|
|
238
230
|
if (buttonStyle === ButtonStyleType.WARNING) {
|
|
239
231
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-transparent bg-yellow-600 text-base font-medium text-white shadow-sm ${
|
|
240
|
-
disabled ? "hover:bg-yellow-700"
|
|
232
|
+
disabled ? "" : "hover:bg-yellow-700"
|
|
241
233
|
} focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2 md:ml-3 md:w-auto md:text-sm`;
|
|
242
234
|
}
|
|
243
235
|
|
|
244
236
|
if (buttonStyle === ButtonStyleType.WARNING_OUTLINE) {
|
|
245
237
|
buttonStyleCssClass = `inline-flex w-full justify-center rounded-md border border-yellow-700 bg-white text-base font-medium text-yellow-700 shadow-sm ${
|
|
246
|
-
disabled ? "hover:bg-yellow-50"
|
|
238
|
+
disabled ? "" : "hover:bg-yellow-50"
|
|
247
239
|
} focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2 md:mt-0 md:ml-3 md:w-auto md:text-sm`;
|
|
248
240
|
}
|
|
249
241
|
|
|
@@ -13,7 +13,9 @@ import SeriesPoint from "../Types/SeriesPoints";
|
|
|
13
13
|
import { XAxis } from "../Types/XAxis/XAxis";
|
|
14
14
|
import YAxis from "../Types/YAxis/YAxis";
|
|
15
15
|
import ChartCurve from "../Types/ChartCurve";
|
|
16
|
-
import ChartDataPoint
|
|
16
|
+
import ChartDataPoint, {
|
|
17
|
+
CHART_DATA_POINT_X_AXIS_KEY,
|
|
18
|
+
} from "../ChartLibrary/Types/ChartDataPoint";
|
|
17
19
|
import FormattedExemplarPoint from "../ChartLibrary/Types/FormattedExemplarPoint";
|
|
18
20
|
import FormattedReferenceRegion from "../ChartLibrary/Types/FormattedReferenceRegion";
|
|
19
21
|
import FormattedTimeReferenceLine from "../ChartLibrary/Types/FormattedTimeReferenceLine";
|
|
@@ -185,7 +187,7 @@ const AreaChartElement: FunctionComponent<AreaInternalProps> = (
|
|
|
185
187
|
<AreaChart
|
|
186
188
|
data={records}
|
|
187
189
|
tickGap={30}
|
|
188
|
-
index={
|
|
190
|
+
index={CHART_DATA_POINT_X_AXIS_KEY}
|
|
189
191
|
categories={categories}
|
|
190
192
|
colors={
|
|
191
193
|
props.colors && props.colors.length > 0
|
|
@@ -12,7 +12,9 @@ import React, {
|
|
|
12
12
|
import SeriesPoint from "../Types/SeriesPoints";
|
|
13
13
|
import { XAxis } from "../Types/XAxis/XAxis";
|
|
14
14
|
import YAxis from "../Types/YAxis/YAxis";
|
|
15
|
-
import ChartDataPoint
|
|
15
|
+
import ChartDataPoint, {
|
|
16
|
+
CHART_DATA_POINT_X_AXIS_KEY,
|
|
17
|
+
} from "../ChartLibrary/Types/ChartDataPoint";
|
|
16
18
|
import FormattedReferenceRegion from "../ChartLibrary/Types/FormattedReferenceRegion";
|
|
17
19
|
import FormattedTimeReferenceLine from "../ChartLibrary/Types/FormattedTimeReferenceLine";
|
|
18
20
|
import DataPointUtil from "../Utils/DataPoint";
|
|
@@ -119,7 +121,7 @@ const BarChartElement: FunctionComponent<BarInternalProps> = (
|
|
|
119
121
|
<BarChart
|
|
120
122
|
data={records}
|
|
121
123
|
tickGap={30}
|
|
122
|
-
index={
|
|
124
|
+
index={CHART_DATA_POINT_X_AXIS_KEY}
|
|
123
125
|
categories={categories}
|
|
124
126
|
colors={
|
|
125
127
|
props.colors && props.colors.length > 0
|
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const CHART_DATA_POINT_DATE_KEY: string = "__date";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Per-row field carrying the FORMATTED x-axis label.
|
|
10
|
+
*
|
|
11
|
+
* This is the recharts `XAxis` dataKey — the Line / Bar / Area wrappers all
|
|
12
|
+
* pass it down as their `index` prop. `DataPointUtil` must therefore write
|
|
13
|
+
* the label under exactly this key: a row keyed anything else leaves every
|
|
14
|
+
* point with an undefined category, and recharts then draws no line, bar or
|
|
15
|
+
* area at all (the axes and grid still render, so the chart looks alive but
|
|
16
|
+
* empty). Keeping the single constant on both sides is what stops that from
|
|
17
|
+
* being an invisible coupling between two distant files.
|
|
18
|
+
*/
|
|
19
|
+
export const CHART_DATA_POINT_X_AXIS_KEY: string = "Time";
|
|
20
|
+
|
|
8
21
|
export default interface ChartDataPoint {
|
|
9
22
|
[x: string]: number | string;
|
|
10
23
|
}
|
|
@@ -13,7 +13,9 @@ import SeriesPoint from "../Types/SeriesPoints";
|
|
|
13
13
|
import { XAxis } from "../Types/XAxis/XAxis";
|
|
14
14
|
import YAxis from "../Types/YAxis/YAxis";
|
|
15
15
|
import ChartCurve from "../Types/ChartCurve";
|
|
16
|
-
import ChartDataPoint
|
|
16
|
+
import ChartDataPoint, {
|
|
17
|
+
CHART_DATA_POINT_X_AXIS_KEY,
|
|
18
|
+
} from "../ChartLibrary/Types/ChartDataPoint";
|
|
17
19
|
import FormattedExemplarPoint from "../ChartLibrary/Types/FormattedExemplarPoint";
|
|
18
20
|
import FormattedReferenceRegion from "../ChartLibrary/Types/FormattedReferenceRegion";
|
|
19
21
|
import FormattedTimeReferenceLine from "../ChartLibrary/Types/FormattedTimeReferenceLine";
|
|
@@ -165,7 +167,7 @@ const LineChartElement: FunctionComponent<LineInternalProps> = (
|
|
|
165
167
|
<LineChart
|
|
166
168
|
data={records}
|
|
167
169
|
tickGap={30}
|
|
168
|
-
index={
|
|
170
|
+
index={CHART_DATA_POINT_X_AXIS_KEY}
|
|
169
171
|
categories={categories}
|
|
170
172
|
colors={
|
|
171
173
|
props.colors && props.colors.length > 0
|
|
@@ -16,6 +16,12 @@ export interface XAxisOptions {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface XAxis {
|
|
19
|
+
/*
|
|
20
|
+
* Human-readable name for the axis. Purely descriptive: the per-row key
|
|
21
|
+
* the charts read is CHART_DATA_POINT_X_AXIS_KEY, never this string. It
|
|
22
|
+
* used to double as that key, which meant a caller passing anything but
|
|
23
|
+
* "Time" got a chart with axes and no series drawn on them.
|
|
24
|
+
*/
|
|
19
25
|
legend: string;
|
|
20
26
|
options: XAxisOptions;
|
|
21
27
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import BadDataException from "../../../../Types/Exception/BadDataException";
|
|
11
11
|
import ChartDataPoint, {
|
|
12
12
|
CHART_DATA_POINT_DATE_KEY,
|
|
13
|
+
CHART_DATA_POINT_X_AXIS_KEY,
|
|
13
14
|
} from "../ChartLibrary/Types/ChartDataPoint";
|
|
14
15
|
import SeriesPoints from "../Types/SeriesPoints";
|
|
15
16
|
import { XAxis, XAxisAggregateType } from "../Types/XAxis/XAxis";
|
|
@@ -30,18 +31,14 @@ export default class DataPointUtil {
|
|
|
30
31
|
xAxis: XAxis;
|
|
31
32
|
yAxis: YAxis;
|
|
32
33
|
}): Array<ChartDataPoint> {
|
|
33
|
-
const {
|
|
34
|
-
data.xAxis,
|
|
35
|
-
);
|
|
34
|
+
const { intervals, formatter } = this.initializeXAxisData(data.xAxis);
|
|
36
35
|
const arrayOfData: ChartDataPoint[] = this.initializeArrayOfData(
|
|
37
36
|
intervals,
|
|
38
|
-
xAxisLegend,
|
|
39
37
|
formatter,
|
|
40
38
|
);
|
|
41
39
|
this.processSeriesData(
|
|
42
40
|
data.seriesPoints,
|
|
43
41
|
arrayOfData,
|
|
44
|
-
xAxisLegend,
|
|
45
42
|
formatter,
|
|
46
43
|
data.xAxis.options.aggregateType,
|
|
47
44
|
);
|
|
@@ -51,13 +48,11 @@ export default class DataPointUtil {
|
|
|
51
48
|
private static initializeXAxisData(xAxis: XAxis): {
|
|
52
49
|
xAxisMax: XAxisMaxMin;
|
|
53
50
|
xAxisMin: XAxisMaxMin;
|
|
54
|
-
xAxisLegend: string;
|
|
55
51
|
intervals: Array<Date>;
|
|
56
52
|
formatter: (value: Date) => string;
|
|
57
53
|
} {
|
|
58
54
|
const xAxisMax: XAxisMaxMin = xAxis.options.max;
|
|
59
55
|
const xAxisMin: XAxisMaxMin = xAxis.options.min;
|
|
60
|
-
const xAxisLegend: string = xAxis.legend;
|
|
61
56
|
const intervals: Array<Date> = XAxisUtil.getPrecisionIntervals({
|
|
62
57
|
xAxisMax,
|
|
63
58
|
xAxisMin,
|
|
@@ -66,18 +61,25 @@ export default class DataPointUtil {
|
|
|
66
61
|
xAxisMax,
|
|
67
62
|
xAxisMin,
|
|
68
63
|
});
|
|
69
|
-
return { xAxisMax, xAxisMin,
|
|
64
|
+
return { xAxisMax, xAxisMin, intervals, formatter };
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
private static initializeArrayOfData(
|
|
73
68
|
intervals: Array<Date>,
|
|
74
|
-
xAxisLegend: string,
|
|
75
69
|
formatter: (value: Date) => string,
|
|
76
70
|
): Array<ChartDataPoint> {
|
|
77
71
|
const arrayOfData: Array<ChartDataPoint> = [];
|
|
78
72
|
for (const interval of intervals) {
|
|
79
73
|
const dataPoint: ChartDataPoint = {};
|
|
80
|
-
|
|
74
|
+
/*
|
|
75
|
+
* Always the canonical key, NEVER `xAxis.legend`. The wrappers hand
|
|
76
|
+
* recharts this exact key as the XAxis dataKey, so keying rows off a
|
|
77
|
+
* caller-supplied string meant one caller passing anything else
|
|
78
|
+
* (the SLO dashboard widget passed "") produced rows recharts could
|
|
79
|
+
* not read — every point landed on an undefined category and the
|
|
80
|
+
* line silently vanished while the axes still drew.
|
|
81
|
+
*/
|
|
82
|
+
dataPoint[CHART_DATA_POINT_X_AXIS_KEY] = formatter(interval);
|
|
81
83
|
/*
|
|
82
84
|
* The formatted label is not round-trippable back to a Date, so
|
|
83
85
|
* keep the raw bucket start on the row — charts use it to recover
|
|
@@ -92,7 +94,6 @@ export default class DataPointUtil {
|
|
|
92
94
|
private static processSeriesData(
|
|
93
95
|
seriesPoints: Array<SeriesPoints>,
|
|
94
96
|
arrayOfData: Array<ChartDataPoint>,
|
|
95
|
-
xAxisLegend: string,
|
|
96
97
|
formatter: (value: Date) => string,
|
|
97
98
|
aggregateType: XAxisAggregateType,
|
|
98
99
|
): { [key: string]: SeriesData } {
|
|
@@ -123,7 +124,9 @@ export default class DataPointUtil {
|
|
|
123
124
|
|
|
124
125
|
const target: ChartDataPoint | undefined = arrayOfData.find(
|
|
125
126
|
(chartDataPoint: ChartDataPoint) => {
|
|
126
|
-
return
|
|
127
|
+
return (
|
|
128
|
+
chartDataPoint[CHART_DATA_POINT_X_AXIS_KEY] === formattedDate
|
|
129
|
+
);
|
|
127
130
|
},
|
|
128
131
|
);
|
|
129
132
|
if (!target) {
|
|
@@ -36,20 +36,6 @@ export interface ComponentProps {
|
|
|
36
36
|
valueTypes?: Array<ValueType>; // by default it'll be Text
|
|
37
37
|
keys?: Array<string> | undefined;
|
|
38
38
|
valueSuggestions?: Record<string, Array<string>> | undefined;
|
|
39
|
-
/*
|
|
40
|
-
* Per-key placeholder for the value input, falling back to valuePlaceholder
|
|
41
|
-
* for any key not listed. The record editor uses this to show the model's own
|
|
42
|
-
* example value against the column it belongs to, which is a far better
|
|
43
|
-
* answer to "what goes in this box" than one generic word repeated down the
|
|
44
|
-
* column.
|
|
45
|
-
*/
|
|
46
|
-
valuePlaceholders?: Record<string, string> | undefined;
|
|
47
|
-
/*
|
|
48
|
-
* Suggestions offered on a row whose key has no entry in valueSuggestions.
|
|
49
|
-
* Used for suggestions that are about the form rather than the column - the
|
|
50
|
-
* workflow's {{...}} references, which are equally valid in any row.
|
|
51
|
-
*/
|
|
52
|
-
defaultValueSuggestions?: Array<string> | undefined;
|
|
53
39
|
onKeySelected?: ((key: string) => void) | undefined;
|
|
54
40
|
isLoadingKeys?: boolean | undefined;
|
|
55
41
|
loadingValueKeys?: Array<string> | undefined;
|
|
@@ -245,33 +231,12 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
245
231
|
return "";
|
|
246
232
|
};
|
|
247
233
|
|
|
248
|
-
type ValuePlaceholderForFunction = (key: string) => string | undefined;
|
|
249
|
-
|
|
250
|
-
const valuePlaceholderFor: ValuePlaceholderForFunction = (
|
|
251
|
-
key: string,
|
|
252
|
-
): string | undefined => {
|
|
253
|
-
return (
|
|
254
|
-
(key ? props.valuePlaceholders?.[key] : undefined) ||
|
|
255
|
-
props.valuePlaceholder
|
|
256
|
-
);
|
|
257
|
-
};
|
|
258
|
-
|
|
259
234
|
type ValueSuggestionsForFunction = (key: string) => Array<string> | undefined;
|
|
260
235
|
|
|
261
236
|
const valueSuggestionsFor: ValueSuggestionsForFunction = (
|
|
262
237
|
key: string,
|
|
263
238
|
): Array<string> | undefined => {
|
|
264
|
-
|
|
265
|
-
? props.valueSuggestions?.[key]
|
|
266
|
-
: undefined;
|
|
267
|
-
|
|
268
|
-
/*
|
|
269
|
-
* Column-specific suggestions win outright rather than merging: a column
|
|
270
|
-
* with a known set of values should not have workflow references mixed into
|
|
271
|
-
* that set, and a row with no such set is exactly where a reference is the
|
|
272
|
-
* likely thing to type.
|
|
273
|
-
*/
|
|
274
|
-
return forKey && forKey.length > 0 ? forKey : props.defaultValueSuggestions;
|
|
239
|
+
return key ? props.valueSuggestions?.[key] : undefined;
|
|
275
240
|
};
|
|
276
241
|
|
|
277
242
|
const operatorDropdownOptions: Array<DropdownOption> =
|
|
@@ -452,7 +417,7 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
452
417
|
operatorOption.expectsMultiValue && (
|
|
453
418
|
<Dropdown
|
|
454
419
|
isMultiSelect={true}
|
|
455
|
-
placeholder={
|
|
420
|
+
placeholder={props.valuePlaceholder}
|
|
456
421
|
value={(Array.isArray(item.value) ? item.value : []).map(
|
|
457
422
|
(selectedValue: string) => {
|
|
458
423
|
return { label: selectedValue, value: selectedValue };
|
|
@@ -499,7 +464,7 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
499
464
|
placeholder={
|
|
500
465
|
operatorOption.expectsNumericValue
|
|
501
466
|
? "Number"
|
|
502
|
-
:
|
|
467
|
+
: props.valuePlaceholder
|
|
503
468
|
}
|
|
504
469
|
suggestions={
|
|
505
470
|
operatorOption.expectsNumericValue
|
|
@@ -540,7 +505,7 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
540
505
|
{!hideValueInput && item.type === ValueType.Number && (
|
|
541
506
|
<Input
|
|
542
507
|
value={item.value.toString()}
|
|
543
|
-
placeholder={
|
|
508
|
+
placeholder={props.valuePlaceholder}
|
|
544
509
|
onChange={(value: string) => {
|
|
545
510
|
const newData: Array<Item> = [...data];
|
|
546
511
|
const parsedValue: number = parseInt(value);
|
|
@@ -932,7 +932,7 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
|
|
932
932
|
<path
|
|
933
933
|
strokeLinecap="round"
|
|
934
934
|
strokeLinejoin="round"
|
|
935
|
-
d="
|
|
935
|
+
d="M15.75 19.5L8.25 12l7.5-7.5"
|
|
936
936
|
/>,
|
|
937
937
|
);
|
|
938
938
|
} else if (icon === IconProp.Window) {
|
|
@@ -134,6 +134,8 @@ export interface ComponentProps {
|
|
|
134
134
|
savedViews?: Array<LogsSavedViewOption> | undefined;
|
|
135
135
|
selectedSavedViewId?: string | null;
|
|
136
136
|
onSavedViewSelect?: ((viewId: string) => void) | undefined;
|
|
137
|
+
// Deselect the active saved view and reset the explorer to its default.
|
|
138
|
+
onClearSavedView?: (() => void) | undefined;
|
|
137
139
|
onCreateSavedView?: (() => void) | undefined;
|
|
138
140
|
onEditSavedView?: ((viewId: string) => void) | undefined;
|
|
139
141
|
onDeleteSavedView?: ((viewId: string) => void) | undefined;
|
|
@@ -1044,6 +1046,7 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
|
|
|
1044
1046
|
savedViews: props.savedViews,
|
|
1045
1047
|
selectedSavedViewId: props.selectedSavedViewId,
|
|
1046
1048
|
onSavedViewSelect: props.onSavedViewSelect,
|
|
1049
|
+
onClearSavedView: props.onClearSavedView,
|
|
1047
1050
|
onCreateSavedView: props.onCreateSavedView,
|
|
1048
1051
|
onEditSavedView: props.onEditSavedView,
|
|
1049
1052
|
onDeleteSavedView: props.onDeleteSavedView,
|
|
@@ -1157,6 +1160,7 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
|
|
|
1157
1160
|
savedViews={props.savedViews}
|
|
1158
1161
|
selectedSavedViewId={props.selectedSavedViewId}
|
|
1159
1162
|
onSavedViewSelect={props.onSavedViewSelect}
|
|
1163
|
+
onClearSavedView={props.onClearSavedView}
|
|
1160
1164
|
onFacetSearchChange={props.onFacetSearchChange}
|
|
1161
1165
|
/>
|
|
1162
1166
|
)}
|
|
@@ -1226,7 +1230,7 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
|
|
|
1226
1230
|
pageSizeOptions={PAGE_SIZE_OPTIONS}
|
|
1227
1231
|
onPageChange={handlePageChange}
|
|
1228
1232
|
onPageSizeChange={handlePageSizeChange}
|
|
1229
|
-
isDisabled={props.isLoading
|
|
1233
|
+
isDisabled={props.isLoading}
|
|
1230
1234
|
/>
|
|
1231
1235
|
</div>
|
|
1232
1236
|
</div>
|
|
@@ -30,6 +30,8 @@ export interface LogsFacetSidebarProps {
|
|
|
30
30
|
savedViews?: Array<LogsSavedViewOption> | undefined;
|
|
31
31
|
selectedSavedViewId?: string | null | undefined;
|
|
32
32
|
onSavedViewSelect?: ((viewId: string) => void) | undefined;
|
|
33
|
+
// Toggling the applied view off here has to clear it, not re-apply it.
|
|
34
|
+
onClearSavedView?: (() => void) | undefined;
|
|
33
35
|
/*
|
|
34
36
|
* Called (debounced) when typing in a resource facet's search box. Lets
|
|
35
37
|
* the parent re-issue the facets request with the typed text scoped to
|
|
@@ -283,7 +285,13 @@ const LogsFacetSidebar: FunctionComponent<LogsFacetSidebarProps> = (
|
|
|
283
285
|
? "bg-indigo-50 text-indigo-700"
|
|
284
286
|
: "text-gray-600 hover:bg-gray-50 hover:text-gray-800"
|
|
285
287
|
}`}
|
|
288
|
+
aria-pressed={isSelected}
|
|
286
289
|
onClick={() => {
|
|
290
|
+
if (isSelected && props.onClearSavedView) {
|
|
291
|
+
props.onClearSavedView();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
287
295
|
props.onSavedViewSelect?.(view.id);
|
|
288
296
|
}}
|
|
289
297
|
>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Pagination from "../../Pagination/Pagination";
|
|
1
2
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
2
3
|
|
|
3
4
|
export interface LogsPaginationProps {
|
|
@@ -10,101 +11,38 @@ export interface LogsPaginationProps {
|
|
|
10
11
|
isDisabled?: boolean;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* The logs footer is the shared pagination control in its compact skin, so
|
|
16
|
+
* "rows per page" and jump-to-page behave the same here as they do under
|
|
17
|
+
* every table in the product.
|
|
18
|
+
*/
|
|
13
19
|
const LogsPagination: FunctionComponent<LogsPaginationProps> = (
|
|
14
20
|
props: LogsPaginationProps,
|
|
15
21
|
): ReactElement => {
|
|
16
|
-
const totalPages: number = Math.max(
|
|
17
|
-
1,
|
|
18
|
-
Math.ceil(
|
|
19
|
-
props.totalItems === 0
|
|
20
|
-
? 1
|
|
21
|
-
: props.totalItems / Math.max(props.pageSize, 1),
|
|
22
|
-
),
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const safeCurrentPage: number = Math.min(props.currentPage, totalPages);
|
|
26
|
-
|
|
27
|
-
const firstItemIndex: number =
|
|
28
|
-
props.totalItems === 0 ? 0 : (safeCurrentPage - 1) * props.pageSize + 1;
|
|
29
|
-
const lastItemIndex: number =
|
|
30
|
-
props.totalItems === 0
|
|
31
|
-
? 0
|
|
32
|
-
: Math.min(props.totalItems, safeCurrentPage * props.pageSize);
|
|
33
|
-
|
|
34
|
-
const disablePrev: boolean =
|
|
35
|
-
props.isDisabled || props.totalItems === 0 || safeCurrentPage <= 1;
|
|
36
|
-
const disableNext: boolean =
|
|
37
|
-
props.isDisabled || props.totalItems === 0 || safeCurrentPage >= totalPages;
|
|
38
|
-
|
|
39
22
|
return (
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
props.onPageSizeChange(size);
|
|
64
|
-
}}
|
|
65
|
-
disabled={props.isDisabled}
|
|
66
|
-
>
|
|
67
|
-
{props.pageSizeOptions.map((option: number) => {
|
|
68
|
-
return (
|
|
69
|
-
<option key={option} value={option}>
|
|
70
|
-
{option}
|
|
71
|
-
</option>
|
|
72
|
-
);
|
|
73
|
-
})}
|
|
74
|
-
</select>
|
|
75
|
-
</label>
|
|
76
|
-
|
|
77
|
-
<div className="inline-flex items-center gap-1 rounded-lg border border-gray-200 bg-white p-0.5">
|
|
78
|
-
<button
|
|
79
|
-
type="button"
|
|
80
|
-
className="rounded-md px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-300 disabled:cursor-not-allowed disabled:opacity-40"
|
|
81
|
-
onClick={() => {
|
|
82
|
-
if (!disablePrev) {
|
|
83
|
-
props.onPageChange(Math.max(1, safeCurrentPage - 1));
|
|
84
|
-
}
|
|
85
|
-
}}
|
|
86
|
-
disabled={disablePrev}
|
|
87
|
-
>
|
|
88
|
-
Previous
|
|
89
|
-
</button>
|
|
90
|
-
<span className="px-3 text-[11px] text-gray-400">
|
|
91
|
-
Page {safeCurrentPage} / {totalPages}
|
|
92
|
-
</span>
|
|
93
|
-
<button
|
|
94
|
-
type="button"
|
|
95
|
-
className="rounded-md px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-300 disabled:cursor-not-allowed disabled:opacity-40"
|
|
96
|
-
onClick={() => {
|
|
97
|
-
if (!disableNext) {
|
|
98
|
-
props.onPageChange(Math.min(totalPages, safeCurrentPage + 1));
|
|
99
|
-
}
|
|
100
|
-
}}
|
|
101
|
-
disabled={disableNext}
|
|
102
|
-
>
|
|
103
|
-
Next
|
|
104
|
-
</button>
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
23
|
+
<Pagination
|
|
24
|
+
dataTestId="logs-pagination"
|
|
25
|
+
singularLabel="log"
|
|
26
|
+
pluralLabel="logs"
|
|
27
|
+
currentPageNumber={props.currentPage}
|
|
28
|
+
totalItemsCount={props.totalItems}
|
|
29
|
+
itemsOnPage={props.pageSize}
|
|
30
|
+
itemsOnPageOptions={props.pageSizeOptions}
|
|
31
|
+
isCompact={true}
|
|
32
|
+
className="bg-gray-50/50"
|
|
33
|
+
isLoading={false}
|
|
34
|
+
isError={false}
|
|
35
|
+
isDisabled={Boolean(props.isDisabled)}
|
|
36
|
+
onNavigateToPage={(pageNumber: number, itemsOnPage: number) => {
|
|
37
|
+
if (itemsOnPage !== props.pageSize) {
|
|
38
|
+
props.onPageSizeChange(itemsOnPage);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (pageNumber !== props.currentPage) {
|
|
42
|
+
props.onPageChange(pageNumber);
|
|
43
|
+
}
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
108
46
|
);
|
|
109
47
|
};
|
|
110
48
|
|
|
@@ -28,6 +28,7 @@ export interface LogsViewerToolbarProps {
|
|
|
28
28
|
savedViews?: Array<LogsSavedViewOption> | undefined;
|
|
29
29
|
selectedSavedViewId?: string | null | undefined;
|
|
30
30
|
onSavedViewSelect?: ((viewId: string) => void) | undefined;
|
|
31
|
+
onClearSavedView?: (() => void) | undefined;
|
|
31
32
|
onEditSavedView?: ((viewId: string) => void) | undefined;
|
|
32
33
|
onDeleteSavedView?: ((viewId: string) => void) | undefined;
|
|
33
34
|
onUpdateCurrentSavedView?: (() => void) | undefined;
|
|
@@ -153,6 +154,7 @@ const LogsViewerToolbar: FunctionComponent<LogsViewerToolbarProps> = (
|
|
|
153
154
|
savedViews={props.savedViews}
|
|
154
155
|
selectedSavedViewId={props.selectedSavedViewId}
|
|
155
156
|
onSelect={props.onSavedViewSelect}
|
|
157
|
+
onClear={props.onClearSavedView}
|
|
156
158
|
onCreate={props.onCreateSavedView}
|
|
157
159
|
onEdit={props.onEditSavedView}
|
|
158
160
|
onDelete={props.onDeleteSavedView}
|