@oneuptime/common 12.0.13 → 12.0.14
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/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -0
- package/Server/Services/LogAggregationService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.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/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +5 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React, { FunctionComponent, ReactElement } from "react";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Width variants for skeleton lines. Cycled by index (never Math.random) so
|
|
5
|
+
* the shimmer is stable across re-renders - random widths re-roll on every
|
|
6
|
+
* render, which reads as flicker - and so tests can assert exact widths.
|
|
7
|
+
*/
|
|
8
|
+
const WIDTH_VARIANTS: Array<string> = ["w-3/4", "w-1/2", "w-2/3"];
|
|
9
|
+
|
|
10
|
+
export type GetSkeletonWidthClassFunction = (index: number) => string;
|
|
11
|
+
|
|
12
|
+
export const getSkeletonWidthClass: GetSkeletonWidthClassFunction = (
|
|
13
|
+
index: number,
|
|
14
|
+
): string => {
|
|
15
|
+
return WIDTH_VARIANTS[Math.abs(index) % WIDTH_VARIANTS.length] as string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface ComponentProps {
|
|
19
|
+
className?: string | undefined;
|
|
20
|
+
/*
|
|
21
|
+
* When set, a deterministic width variant (w-3/4 / w-1/2 / w-2/3, cycling)
|
|
22
|
+
* is appended so a stack of lines looks like ragged text instead of a
|
|
23
|
+
* uniform block. Leave undefined when className already sizes the block.
|
|
24
|
+
*/
|
|
25
|
+
widthVariantIndex?: number | undefined;
|
|
26
|
+
dataTestId?: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* A single pulsing placeholder block. Purely decorative - the wrapper that
|
|
31
|
+
* composes skeletons into a loading state owns the role="status" / sr-only
|
|
32
|
+
* announcement, so each block hides itself from the accessibility tree.
|
|
33
|
+
*/
|
|
34
|
+
const Skeleton: FunctionComponent<ComponentProps> = (
|
|
35
|
+
props: ComponentProps,
|
|
36
|
+
): ReactElement => {
|
|
37
|
+
const widthClass: string =
|
|
38
|
+
props.widthVariantIndex === undefined
|
|
39
|
+
? ""
|
|
40
|
+
: ` ${getSkeletonWidthClass(props.widthVariantIndex)}`;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
data-testid={props.dataTestId || "skeleton"}
|
|
45
|
+
aria-hidden={true}
|
|
46
|
+
className={`animate-pulse rounded bg-gray-200${
|
|
47
|
+
props.className ? ` ${props.className}` : ""
|
|
48
|
+
}${widthClass}`}
|
|
49
|
+
></div>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default Skeleton;
|
|
@@ -7,7 +7,6 @@ import BulkUpdateForm, {
|
|
|
7
7
|
BulkActionButtonSchema,
|
|
8
8
|
BulkActionOnClickProps,
|
|
9
9
|
} from "../BulkUpdate/BulkUpdateForm";
|
|
10
|
-
import ComponentLoader from "../ComponentLoader/ComponentLoader";
|
|
11
10
|
import ErrorMessage from "../ErrorMessage/ErrorMessage";
|
|
12
11
|
import FilterViewer from "../Filters/FilterViewer";
|
|
13
12
|
import Filter from "../Filters/Types/Filter";
|
|
@@ -15,6 +14,7 @@ import FilterData from "../Filters/Types/FilterData";
|
|
|
15
14
|
import Pagination from "../Pagination/Pagination";
|
|
16
15
|
import TableBody from "./TableBody";
|
|
17
16
|
import TableHeader from "./TableHeader";
|
|
17
|
+
import TableSkeletonRows from "./TableSkeletonRows";
|
|
18
18
|
import Columns from "./Types/Columns";
|
|
19
19
|
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
20
20
|
import GenericObject from "../../../Types/GenericObject";
|
|
@@ -211,22 +211,34 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
211
211
|
colspan = 1;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
/*
|
|
215
|
+
* A refetch with rows already on screen (pagination, sort, refresh - the
|
|
216
|
+
* parent never clears `data` while fetching) keeps those rows visible and
|
|
217
|
+
* dims them instead of tearing the layout down to placeholders. Skeletons
|
|
218
|
+
* are only for a load with nothing to show yet.
|
|
219
|
+
*/
|
|
220
|
+
const isRefetchingWithData: boolean =
|
|
221
|
+
props.isLoading && props.data.length > 0;
|
|
222
|
+
|
|
214
223
|
const getTablebody: GetReactElementFunction = (): ReactElement => {
|
|
215
|
-
if (props.isLoading) {
|
|
224
|
+
if (props.isLoading && props.data.length === 0) {
|
|
216
225
|
return (
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
</tr>
|
|
225
|
-
</tbody>
|
|
226
|
+
<TableSkeletonRows
|
|
227
|
+
columns={props.columns}
|
|
228
|
+
enableDragAndDrop={props.enableDragAndDrop}
|
|
229
|
+
isBulkActionsEnabled={isBulkActionsEnabled}
|
|
230
|
+
itemsOnPage={props.itemsOnPage}
|
|
231
|
+
isMobile={isMobile}
|
|
232
|
+
/>
|
|
226
233
|
);
|
|
227
234
|
}
|
|
228
235
|
|
|
229
|
-
|
|
236
|
+
/*
|
|
237
|
+
* Loading still wins over error and empty (same priority as before the
|
|
238
|
+
* skeletons): while a refetch is in flight the stale rows render, never a
|
|
239
|
+
* stale error or a premature "no items".
|
|
240
|
+
*/
|
|
241
|
+
if (!props.isLoading && props.error) {
|
|
230
242
|
return (
|
|
231
243
|
<tbody>
|
|
232
244
|
<tr>
|
|
@@ -260,7 +272,7 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
260
272
|
);
|
|
261
273
|
}
|
|
262
274
|
|
|
263
|
-
if (props.filterError) {
|
|
275
|
+
if (!props.isLoading && props.filterError) {
|
|
264
276
|
return <></>;
|
|
265
277
|
}
|
|
266
278
|
|
|
@@ -418,38 +430,56 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
418
430
|
: "overflow-hidden border-t border-gray-200"
|
|
419
431
|
}
|
|
420
432
|
>
|
|
421
|
-
{
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
433
|
+
{/*
|
|
434
|
+
* Dims the stale rows (header included) while a refetch is in
|
|
435
|
+
* flight and blocks clicks on them - a sort or row action
|
|
436
|
+
* against data about to be replaced is a race. The wrapper
|
|
437
|
+
* sits OUTSIDE the <table> because a <div> cannot legally wrap
|
|
438
|
+
* a <tbody> inside one.
|
|
439
|
+
*/}
|
|
440
|
+
<div
|
|
441
|
+
data-testid="table-content"
|
|
442
|
+
className={
|
|
443
|
+
isRefetchingWithData
|
|
444
|
+
? "opacity-60 pointer-events-none transition-opacity duration-150"
|
|
445
|
+
: "transition-opacity duration-150"
|
|
446
|
+
}
|
|
447
|
+
>
|
|
448
|
+
{isMobile ? (
|
|
449
|
+
// Mobile view: render as list
|
|
450
|
+
<div className="min-w-full divide-y divide-gray-200">
|
|
451
|
+
{getTablebody()}
|
|
452
|
+
</div>
|
|
453
|
+
) : (
|
|
454
|
+
// Desktop view: render as table
|
|
455
|
+
<table className="min-w-full divide-y divide-gray-200">
|
|
456
|
+
<TableHeader
|
|
457
|
+
id={`${props.id}-header`}
|
|
458
|
+
columns={props.columns}
|
|
459
|
+
onSortChanged={props.onSortChanged}
|
|
460
|
+
enableDragAndDrop={props.enableDragAndDrop}
|
|
461
|
+
sortBy={props.sortBy}
|
|
462
|
+
sortOrder={props.sortOrder}
|
|
463
|
+
isBulkActionsEnabled={isBulkActionsEnabled}
|
|
464
|
+
onAllItemsDeselected={() => {
|
|
465
|
+
setIsAllItemsSelected(false);
|
|
466
|
+
props.onBulkClearAllItems?.();
|
|
467
|
+
}}
|
|
468
|
+
onAllItemsOnThePageSelected={() => {
|
|
469
|
+
if (props.onBulkSelectItemsOnCurrentPage) {
|
|
470
|
+
props.onBulkSelectItemsOnCurrentPage();
|
|
471
|
+
}
|
|
472
|
+
}}
|
|
473
|
+
isAllItemsOnThePageSelected={isAllItemsOnThePageSelected}
|
|
474
|
+
isSomeItemsOnThePageSelected={
|
|
475
|
+
isSomeItemsOnThePageSelected
|
|
444
476
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
</table>
|
|
452
|
-
)}
|
|
477
|
+
hasTableItems={selectableRowsOnThePage.length > 0}
|
|
478
|
+
/>
|
|
479
|
+
{getTablebody()}
|
|
480
|
+
</table>
|
|
481
|
+
)}
|
|
482
|
+
</div>
|
|
453
483
|
</div>
|
|
454
484
|
</div>
|
|
455
485
|
</div>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import Skeleton from "../Skeleton/Skeleton";
|
|
2
|
+
import Column from "./Types/Column";
|
|
3
|
+
import Columns from "./Types/Columns";
|
|
4
|
+
import GenericObject from "../../../Types/GenericObject";
|
|
5
|
+
import React, { ReactElement } from "react";
|
|
6
|
+
|
|
7
|
+
export interface ComponentProps<T extends GenericObject> {
|
|
8
|
+
columns: Columns<T>;
|
|
9
|
+
/*
|
|
10
|
+
* The same feature flags TableHeader renders leading cells for. The
|
|
11
|
+
* skeleton must mirror them exactly or its cells sit misaligned under the
|
|
12
|
+
* header while loading.
|
|
13
|
+
*/
|
|
14
|
+
enableDragAndDrop?: undefined | boolean;
|
|
15
|
+
isBulkActionsEnabled?: undefined | boolean;
|
|
16
|
+
itemsOnPage: number;
|
|
17
|
+
/*
|
|
18
|
+
* Mobile renders card-shaped placeholders inside the table's mobile <div>
|
|
19
|
+
* wrapper - <tbody> markup is invalid there - and drops hideOnMobile
|
|
20
|
+
* columns, same as TableHeader and TableRow do.
|
|
21
|
+
*/
|
|
22
|
+
isMobile: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type TableSkeletonRowsFunction = <T extends GenericObject>(
|
|
26
|
+
props: ComponentProps<T>,
|
|
27
|
+
) => ReactElement;
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* Layout-preserving placeholder rows for the table's first load: one pulsing
|
|
31
|
+
* cell per visible column (plus the drag-handle / bulk-select extras) so the
|
|
32
|
+
* page keeps the table's shape instead of collapsing to a centered spinner.
|
|
33
|
+
*/
|
|
34
|
+
const TableSkeletonRows: TableSkeletonRowsFunction = <T extends GenericObject>(
|
|
35
|
+
props: ComponentProps<T>,
|
|
36
|
+
): ReactElement => {
|
|
37
|
+
// Enough rows to look like a page of data without painting offscreen ones.
|
|
38
|
+
const rowCount: number = Math.max(1, Math.min(props.itemsOnPage || 0, 10));
|
|
39
|
+
const rowIndexes: Array<number> = Array.from(Array(rowCount).keys());
|
|
40
|
+
|
|
41
|
+
// Same filter as TableHeader / TableRow so cell counts always agree.
|
|
42
|
+
const visibleColumns: Columns<T> = props.columns.filter(
|
|
43
|
+
(column: Column<T>) => {
|
|
44
|
+
return !(column.hideOnMobile && props.isMobile);
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (props.isMobile) {
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
data-testid="table-skeleton-loader"
|
|
52
|
+
role="status"
|
|
53
|
+
aria-live="polite"
|
|
54
|
+
className="divide-y divide-gray-200 bg-white"
|
|
55
|
+
>
|
|
56
|
+
<span className="sr-only">Loading...</span>
|
|
57
|
+
{rowIndexes.map((rowIndex: number) => {
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
key={rowIndex}
|
|
61
|
+
className="p-4 bg-white border-b border-gray-200"
|
|
62
|
+
>
|
|
63
|
+
<div className="space-y-3">
|
|
64
|
+
{visibleColumns.map(
|
|
65
|
+
(_column: Column<T>, columnIndex: number) => {
|
|
66
|
+
return (
|
|
67
|
+
<div
|
|
68
|
+
key={columnIndex}
|
|
69
|
+
className="flex flex-col space-y-1"
|
|
70
|
+
>
|
|
71
|
+
<Skeleton className="h-3 w-24" />
|
|
72
|
+
<Skeleton
|
|
73
|
+
className="h-4"
|
|
74
|
+
widthVariantIndex={rowIndex + columnIndex}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
},
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
})}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<tbody
|
|
90
|
+
data-testid="table-skeleton-loader"
|
|
91
|
+
role="status"
|
|
92
|
+
aria-live="polite"
|
|
93
|
+
className="divide-y divide-gray-200 bg-white"
|
|
94
|
+
>
|
|
95
|
+
{rowIndexes.map((rowIndex: number) => {
|
|
96
|
+
return (
|
|
97
|
+
<tr key={rowIndex}>
|
|
98
|
+
{props.enableDragAndDrop && (
|
|
99
|
+
<td className="ml-5 py-4 w-10 align-top">
|
|
100
|
+
<Skeleton className="ml-6 h-5 w-5" />
|
|
101
|
+
</td>
|
|
102
|
+
)}
|
|
103
|
+
{props.isBulkActionsEnabled && (
|
|
104
|
+
<td className="w-10 py-3.5 align-top">
|
|
105
|
+
<div className="ml-5">
|
|
106
|
+
<Skeleton className="h-4 w-4" />
|
|
107
|
+
</div>
|
|
108
|
+
</td>
|
|
109
|
+
)}
|
|
110
|
+
{visibleColumns.map((_column: Column<T>, columnIndex: number) => {
|
|
111
|
+
/*
|
|
112
|
+
* Cell classes copied from TableRow's real cells so the
|
|
113
|
+
* skeleton's rhythm and padding match the rows that replace it.
|
|
114
|
+
*/
|
|
115
|
+
let className: string =
|
|
116
|
+
"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-500 sm:pl-6 align-top";
|
|
117
|
+
if (columnIndex === visibleColumns.length - 1) {
|
|
118
|
+
className =
|
|
119
|
+
"whitespace-nowrap py-4 pl-4 pr-6 text-sm font-medium text-gray-500 sm:pl-6 align-top";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<td key={columnIndex} className={className}>
|
|
124
|
+
{rowIndex === 0 && columnIndex === 0 && (
|
|
125
|
+
<span className="sr-only">Loading...</span>
|
|
126
|
+
)}
|
|
127
|
+
<Skeleton
|
|
128
|
+
className="h-4"
|
|
129
|
+
widthVariantIndex={rowIndex + columnIndex}
|
|
130
|
+
/>
|
|
131
|
+
</td>
|
|
132
|
+
);
|
|
133
|
+
})}
|
|
134
|
+
</tr>
|
|
135
|
+
);
|
|
136
|
+
})}
|
|
137
|
+
</tbody>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export default TableSkeletonRows;
|
|
@@ -31,7 +31,7 @@ const TabElement: FunctionComponent<ComponentProps> = (
|
|
|
31
31
|
const backgroundColor: string = "bg-gray-100";
|
|
32
32
|
|
|
33
33
|
const baseClasses: string =
|
|
34
|
-
"rounded-md px-3 py-2 text-sm font-medium cursor-pointer inline-flex whitespace-nowrap flex-shrink-0";
|
|
34
|
+
"rounded-md px-3 py-2 text-sm font-medium cursor-pointer inline-flex whitespace-nowrap flex-shrink-0 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2";
|
|
35
35
|
const stateClasses: string = props.isSelected
|
|
36
36
|
? `${backgroundColor} text-gray-700`
|
|
37
37
|
: "text-gray-500 hover:text-gray-700";
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
FunctionComponent,
|
|
3
|
+
ReactElement,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
2
8
|
import Icon from "../Icon/Icon";
|
|
3
9
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
4
10
|
import useTranslateValue from "../../Utils/Translation";
|
|
@@ -17,14 +23,78 @@ export interface ComponentProps {
|
|
|
17
23
|
onClose?: undefined | (() => void);
|
|
18
24
|
type?: undefined | ToastType;
|
|
19
25
|
icon?: IconProp | undefined;
|
|
20
|
-
index?: undefined | number;
|
|
21
26
|
}
|
|
22
27
|
|
|
28
|
+
/* How long the exit fade runs before the toast actually unmounts. */
|
|
29
|
+
const EXIT_DURATION_IN_MS: number = 150;
|
|
30
|
+
|
|
23
31
|
const Component: FunctionComponent<ComponentProps> = (
|
|
24
32
|
props: ComponentProps,
|
|
25
33
|
): ReactElement => {
|
|
26
34
|
const { translateString } = useTranslateValue();
|
|
27
35
|
const [show, setShow] = useState<boolean>(true);
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* The toast is mounted in its closed state (faded, nudged down) and flipped
|
|
39
|
+
* open one frame later so the browser has something to transition from —
|
|
40
|
+
* the same pattern Modal uses for its entrance.
|
|
41
|
+
*/
|
|
42
|
+
const [hasEntered, setHasEntered] = useState<boolean>(false);
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* Dismissal fades the card out first and only unmounts (and notifies the
|
|
46
|
+
* owner) once the fade has finished, so the toast never blinks away.
|
|
47
|
+
*/
|
|
48
|
+
const [isLeaving, setIsLeaving] = useState<boolean>(false);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const open: () => void = (): void => {
|
|
52
|
+
setHasEntered(true);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const frame: number = requestAnimationFrame(open);
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* A hidden or throttled tab never runs an animation frame; the timer
|
|
59
|
+
* skips the transition rather than leaving the toast at zero opacity.
|
|
60
|
+
*/
|
|
61
|
+
const fallbackTimer: ReturnType<typeof setTimeout> = setTimeout(open, 80);
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
cancelAnimationFrame(frame);
|
|
65
|
+
clearTimeout(fallbackTimer);
|
|
66
|
+
};
|
|
67
|
+
}, []);
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* The latest onClose lives in a ref so the exit effect can depend on
|
|
71
|
+
* isLeaving alone. Owners may recreate onClose every render, and a dep on
|
|
72
|
+
* it would restart the unmount timer whenever a sibling toast re-renders
|
|
73
|
+
* the stack mid-exit — leaving an invisible pointer-events-auto card
|
|
74
|
+
* intercepting clicks past its original deadline.
|
|
75
|
+
*/
|
|
76
|
+
const onCloseRef: React.MutableRefObject<(() => void) | undefined> = useRef<
|
|
77
|
+
(() => void) | undefined
|
|
78
|
+
>(props.onClose);
|
|
79
|
+
onCloseRef.current = props.onClose;
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!isLeaving) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const exitTimer: ReturnType<typeof setTimeout> = setTimeout(() => {
|
|
87
|
+
setShow(false);
|
|
88
|
+
if (onCloseRef.current) {
|
|
89
|
+
onCloseRef.current();
|
|
90
|
+
}
|
|
91
|
+
}, EXIT_DURATION_IN_MS);
|
|
92
|
+
|
|
93
|
+
return () => {
|
|
94
|
+
clearTimeout(exitTimer);
|
|
95
|
+
};
|
|
96
|
+
}, [isLeaving]);
|
|
97
|
+
|
|
28
98
|
let typeCssClass: string = "text-gray-400";
|
|
29
99
|
let iconType: IconProp = IconProp.Info;
|
|
30
100
|
|
|
@@ -53,65 +123,60 @@ const Component: FunctionComponent<ComponentProps> = (
|
|
|
53
123
|
iconType = props.icon;
|
|
54
124
|
}
|
|
55
125
|
|
|
56
|
-
|
|
126
|
+
/*
|
|
127
|
+
* Settled state carries no transform class at all — leaving a translate on
|
|
128
|
+
* the card would make it the containing block for position:fixed
|
|
129
|
+
* descendants (the Modal invariant).
|
|
130
|
+
*/
|
|
131
|
+
let motionClassName: string = "translate-y-2 opacity-0";
|
|
57
132
|
|
|
58
|
-
if (
|
|
59
|
-
|
|
133
|
+
if (isLeaving) {
|
|
134
|
+
motionClassName = "opacity-0";
|
|
135
|
+
} else if (hasEntered) {
|
|
136
|
+
motionClassName = "opacity-100";
|
|
60
137
|
}
|
|
61
138
|
|
|
62
139
|
if (show) {
|
|
63
140
|
return (
|
|
64
141
|
<div
|
|
65
142
|
data-testid="toast"
|
|
66
|
-
|
|
67
|
-
className={`pointer-events-none fixed z-40 top-${top} left-0 right-0 flex items-end px-4 py-6 sm:items-start sm:p-6`}
|
|
143
|
+
className={`pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5 transition duration-150 ease-out motion-reduce:transition-none ${motionClassName}`}
|
|
68
144
|
>
|
|
69
|
-
<div className="
|
|
70
|
-
<div className="
|
|
71
|
-
<div className="
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
}}
|
|
106
|
-
data-testid="close-button"
|
|
107
|
-
type="button"
|
|
108
|
-
className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
109
|
-
>
|
|
110
|
-
<span className="sr-only">Close</span>
|
|
111
|
-
<Icon className={`h-5 w-5`} icon={IconProp.Close} />
|
|
112
|
-
</button>
|
|
113
|
-
</div>
|
|
114
|
-
</div>
|
|
145
|
+
<div className="p-4">
|
|
146
|
+
<div className="flex items-start">
|
|
147
|
+
<div className="flex-shrink-0">
|
|
148
|
+
<Icon
|
|
149
|
+
className={`h-6 w-6 ${typeCssClass}`}
|
|
150
|
+
data-testid="toast-icon"
|
|
151
|
+
icon={iconType}
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
<div className="ml-3 w-0 flex-1 pt-0.5">
|
|
155
|
+
<p
|
|
156
|
+
data-testid="title"
|
|
157
|
+
className="text-sm font-medium text-gray-900"
|
|
158
|
+
>
|
|
159
|
+
{translateString(props.title)}
|
|
160
|
+
</p>
|
|
161
|
+
<p
|
|
162
|
+
data-testid="description"
|
|
163
|
+
className="mt-1 text-sm text-gray-500"
|
|
164
|
+
>
|
|
165
|
+
{translateString(props.description)}
|
|
166
|
+
</p>
|
|
167
|
+
</div>
|
|
168
|
+
<div className="ml-4 flex flex-shrink-0">
|
|
169
|
+
<button
|
|
170
|
+
onClick={() => {
|
|
171
|
+
setIsLeaving(true);
|
|
172
|
+
}}
|
|
173
|
+
data-testid="close-button"
|
|
174
|
+
type="button"
|
|
175
|
+
className="inline-flex rounded-md bg-white text-gray-400 transition-colors duration-150 ease-out hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
176
|
+
>
|
|
177
|
+
<span className="sr-only">Close</span>
|
|
178
|
+
<Icon className={`h-5 w-5`} icon={IconProp.Close} />
|
|
179
|
+
</button>
|
|
115
180
|
</div>
|
|
116
181
|
</div>
|
|
117
182
|
</div>
|