@oneuptime/common 10.0.63 → 10.0.65
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/AIAgent.ts +36 -0
- package/Models/DatabaseModels/AIAgentOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/AIAgentOwnerUser.ts +35 -0
- package/Models/DatabaseModels/AIAgentTask.ts +48 -0
- package/Models/DatabaseModels/AIAgentTaskLog.ts +9 -0
- package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +19 -0
- package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +11 -0
- package/Models/DatabaseModels/Alert.ts +104 -0
- package/Models/DatabaseModels/AlertCustomField.ts +20 -0
- package/Models/DatabaseModels/AlertEpisode.ts +118 -0
- package/Models/DatabaseModels/AlertEpisodeFeed.ts +42 -0
- package/Models/DatabaseModels/AlertEpisodeInternalNote.ts +36 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +51 -0
- package/Models/DatabaseModels/AlertEpisodeOwnerTeam.ts +36 -0
- package/Models/DatabaseModels/AlertEpisodeOwnerUser.ts +36 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +44 -0
- package/Models/DatabaseModels/AlertFeed.ts +42 -0
- package/Models/DatabaseModels/AlertGroupingRule.ts +82 -0
- package/Models/DatabaseModels/AlertInternalNote.ts +36 -0
- package/Models/DatabaseModels/AlertNoteTemplate.ts +29 -0
- package/Models/DatabaseModels/AlertOwnerTeam.ts +36 -0
- package/Models/DatabaseModels/AlertOwnerUser.ts +36 -0
- package/Models/DatabaseModels/AlertSeverity.ts +39 -0
- package/Models/DatabaseModels/AlertState.ts +49 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +44 -0
- package/Models/DatabaseModels/BillingPaymentMethod.ts +24 -0
- package/Models/DatabaseModels/CallLog.ts +31 -0
- package/Models/DatabaseModels/CodeRepository.ts +50 -0
- package/Models/DatabaseModels/Dashboard.ts +46 -0
- package/Models/DatabaseModels/DashboardDomain.ts +57 -0
- package/Models/DatabaseModels/DataMigration.ts +1 -0
- package/Models/DatabaseModels/DockerHost.ts +53 -0
- package/Models/DatabaseModels/Domain.ts +23 -0
- package/Models/DatabaseModels/EmailLog.ts +32 -0
- package/Models/DatabaseModels/Incident.ts +152 -0
- package/Models/DatabaseModels/IncidentCustomField.ts +20 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +135 -0
- package/Models/DatabaseModels/IncidentEpisodeFeed.ts +42 -0
- package/Models/DatabaseModels/IncidentEpisodeInternalNote.ts +36 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +51 -0
- package/Models/DatabaseModels/IncidentEpisodeOwnerTeam.ts +36 -0
- package/Models/DatabaseModels/IncidentEpisodeOwnerUser.ts +36 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +51 -0
- package/Models/DatabaseModels/IncidentEpisodeRoleMember.ts +45 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +51 -0
- package/Models/DatabaseModels/IncidentFeed.ts +42 -0
- package/Models/DatabaseModels/IncidentGroupingRule.ts +88 -0
- package/Models/DatabaseModels/IncidentInternalNote.ts +36 -0
- package/Models/DatabaseModels/IncidentMember.ts +45 -0
- package/Models/DatabaseModels/IncidentNoteTemplate.ts +29 -0
- package/Models/DatabaseModels/IncidentOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/IncidentOwnerUser.ts +36 -0
- package/Models/DatabaseModels/IncidentPostmortemTemplate.ts +29 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +51 -0
- package/Models/DatabaseModels/IncidentRole.ts +47 -0
- package/Models/DatabaseModels/IncidentSeverity.ts +39 -0
- package/Models/DatabaseModels/IncidentSla.ts +36 -0
- package/Models/DatabaseModels/IncidentSlaRule.ts +44 -0
- package/Models/DatabaseModels/IncidentState.ts +51 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +55 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +73 -0
- package/Models/DatabaseModels/IncidentTemplateOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/IncidentTemplateOwnerUser.ts +59 -0
- package/Models/DatabaseModels/IncomingCallLog.ts +20 -0
- package/Models/DatabaseModels/IncomingCallLogItem.ts +17 -0
- package/Models/DatabaseModels/IncomingCallPolicy.ts +74 -0
- package/Models/DatabaseModels/IncomingCallPolicyEscalationRule.ts +55 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +53 -0
- package/Models/DatabaseModels/Label.ts +22 -0
- package/Models/DatabaseModels/LlmLog.ts +28 -0
- package/Models/DatabaseModels/LlmProvider.ts +23 -0
- package/Models/DatabaseModels/LogDropFilter.ts +28 -0
- package/Models/DatabaseModels/LogPipeline.ts +24 -0
- package/Models/DatabaseModels/LogPipelineProcessor.ts +24 -0
- package/Models/DatabaseModels/LogSavedView.ts +14 -0
- package/Models/DatabaseModels/LogScrubRule.ts +30 -0
- package/Models/DatabaseModels/MetricType.ts +26 -0
- package/Models/DatabaseModels/Monitor.ts +105 -0
- package/Models/DatabaseModels/MonitorCustomField.ts +20 -0
- package/Models/DatabaseModels/MonitorFeed.ts +42 -0
- package/Models/DatabaseModels/MonitorGroup.ts +31 -0
- package/Models/DatabaseModels/MonitorGroupOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/MonitorGroupOwnerUser.ts +35 -0
- package/Models/DatabaseModels/MonitorGroupResource.ts +31 -0
- package/Models/DatabaseModels/MonitorOwnerTeam.ts +36 -0
- package/Models/DatabaseModels/MonitorOwnerUser.ts +36 -0
- package/Models/DatabaseModels/MonitorProbe.ts +33 -0
- package/Models/DatabaseModels/MonitorStatus.ts +47 -0
- package/Models/DatabaseModels/MonitorStatusTimeline.ts +44 -0
- package/Models/DatabaseModels/MonitorTest.ts +50 -0
- package/Models/DatabaseModels/OnCallDutyPolicy.ts +44 -0
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +20 -0
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRule.ts +39 -0
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.ts +35 -0
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.ts +35 -0
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.ts +35 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +87 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.ts +62 -0
- package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +42 -0
- package/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.ts +35 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +50 -0
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +51 -0
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.ts +43 -0
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +44 -0
- package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +41 -0
- package/Models/DatabaseModels/Probe.ts +38 -0
- package/Models/DatabaseModels/ProbeOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/ProbeOwnerUser.ts +35 -0
- package/Models/DatabaseModels/Project.ts +44 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +28 -0
- package/Models/DatabaseModels/ProjectSCIM.ts +26 -0
- package/Models/DatabaseModels/ProjectSCIMLog.ts +14 -0
- package/Models/DatabaseModels/ProjectSmtpConfig.ts +42 -0
- package/Models/DatabaseModels/ProjectSso.ts +26 -0
- package/Models/DatabaseModels/ProjectUserProfile.ts +10 -0
- package/Models/DatabaseModels/PromoCode.ts +10 -0
- package/Models/DatabaseModels/PushNotificationLog.ts +31 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +103 -0
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +20 -0
- package/Models/DatabaseModels/ScheduledMaintenanceFeed.ts +42 -0
- package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +36 -0
- package/Models/DatabaseModels/ScheduledMaintenanceNoteTemplate.ts +29 -0
- package/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.ts +35 -0
- package/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.ts +35 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +51 -0
- package/Models/DatabaseModels/ScheduledMaintenanceState.ts +55 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +50 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +98 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.ts +33 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +33 -0
- package/Models/DatabaseModels/Service.ts +75 -0
- package/Models/DatabaseModels/ServiceCodeRepository.ts +49 -0
- package/Models/DatabaseModels/ServiceDependency.ts +55 -0
- package/Models/DatabaseModels/ServiceMonitor.ts +55 -0
- package/Models/DatabaseModels/ServiceOwnerTeam.ts +31 -0
- package/Models/DatabaseModels/ServiceOwnerUser.ts +31 -0
- package/Models/DatabaseModels/SmsLog.ts +31 -0
- package/Models/DatabaseModels/StatusPage.ts +270 -0
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +61 -0
- package/Models/DatabaseModels/StatusPageAnnouncementTemplate.ts +46 -0
- package/Models/DatabaseModels/StatusPageCustomField.ts +20 -0
- package/Models/DatabaseModels/StatusPageDomain.ts +57 -0
- package/Models/DatabaseModels/StatusPageFooterLink.ts +37 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +53 -0
- package/Models/DatabaseModels/StatusPageHeaderLink.ts +37 -0
- package/Models/DatabaseModels/StatusPageHistoryChartBarColorRule.ts +35 -0
- package/Models/DatabaseModels/StatusPageOwnerTeam.ts +33 -0
- package/Models/DatabaseModels/StatusPageOwnerUser.ts +34 -0
- package/Models/DatabaseModels/StatusPagePrivateUser.ts +36 -0
- package/Models/DatabaseModels/StatusPageResource.ts +79 -0
- package/Models/DatabaseModels/StatusPageSCIM.ts +13 -0
- package/Models/DatabaseModels/StatusPageSCIMLog.ts +15 -0
- package/Models/DatabaseModels/StatusPageSso.ts +6 -0
- package/Models/DatabaseModels/StatusPageSubscriber.ts +79 -0
- package/Models/DatabaseModels/StatusPageSubscriberNotificationTemplate.ts +42 -0
- package/Models/DatabaseModels/StatusPageSubscriberNotificationTemplateStatusPage.ts +32 -0
- package/Models/DatabaseModels/TableView.ts +26 -0
- package/Models/DatabaseModels/Team.ts +25 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +10 -0
- package/Models/DatabaseModels/TeamMember.ts +16 -0
- package/Models/DatabaseModels/TeamMemberCustomField.ts +20 -0
- package/Models/DatabaseModels/TeamPermission.ts +22 -0
- package/Models/DatabaseModels/TelemetryException.ts +62 -0
- package/Models/DatabaseModels/WhatsAppLog.ts +32 -0
- package/Models/DatabaseModels/Workflow.ts +39 -0
- package/Models/DatabaseModels/WorkflowLog.ts +18 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +24 -0
- package/Models/DatabaseModels/WorkspaceNotificationLog.ts +37 -0
- package/Models/DatabaseModels/WorkspaceNotificationRule.ts +47 -0
- package/Models/DatabaseModels/WorkspaceNotificationSummary.ts +87 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +10 -0
- package/Server/Utils/Monitor/MonitorResource.ts +9 -0
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -6
- package/Types/Permission.ts +802 -23
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +288 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +14 -6
- package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +352 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +22 -22
- package/build/dist/Models/DatabaseModels/AIAgent.js +36 -0
- package/build/dist/Models/DatabaseModels/AIAgent.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js +35 -0
- package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentTask.js +48 -0
- package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +9 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +19 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +11 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Alert.js +104 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisode.js +118 -0
- package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +51 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +44 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +82 -0
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js +29 -0
- package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOwnerUser.js +36 -0
- package/build/dist/Models/DatabaseModels/AlertOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertSeverity.js +39 -0
- package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertState.js +49 -0
- package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +44 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js +24 -0
- package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CallLog.js +31 -0
- package/build/dist/Models/DatabaseModels/CallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +50 -0
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Dashboard.js +46 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardDomain.js +57 -0
- package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DataMigration.js +1 -0
- package/build/dist/Models/DatabaseModels/DataMigration.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +53 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Domain.js +23 -0
- package/build/dist/Models/DatabaseModels/Domain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EmailLog.js +32 -0
- package/build/dist/Models/DatabaseModels/EmailLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +152 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +135 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeInternalNote.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +51 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerTeam.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerUser.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +51 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js +45 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +51 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +88 -0
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentMember.js +45 -0
- package/build/dist/Models/DatabaseModels/IncidentMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentNoteTemplate.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentNoteTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/IncidentOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOwnerUser.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPostmortemTemplate.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentPostmortemTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +51 -0
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentRole.js +47 -0
- package/build/dist/Models/DatabaseModels/IncidentRole.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSeverity.js +39 -0
- package/build/dist/Models/DatabaseModels/IncidentSeverity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSla.js +36 -0
- package/build/dist/Models/DatabaseModels/IncidentSla.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js +44 -0
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentState.js +51 -0
- package/build/dist/Models/DatabaseModels/IncidentState.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +55 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +73 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerUser.js +59 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallLog.js +20 -0
- package/build/dist/Models/DatabaseModels/IncomingCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js +17 -0
- package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +74 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js +55 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +53 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Label.js +22 -0
- package/build/dist/Models/DatabaseModels/Label.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LlmLog.js +28 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LlmProvider.js +23 -0
- package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +28 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogPipeline.js +24 -0
- package/build/dist/Models/DatabaseModels/LogPipeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js +24 -0
- package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogSavedView.js +14 -0
- package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogScrubRule.js +30 -0
- package/build/dist/Models/DatabaseModels/LogScrubRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MetricType.js +26 -0
- package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +105 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/MonitorFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorGroup.js +31 -0
- package/build/dist/Models/DatabaseModels/MonitorGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorGroupOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/MonitorGroupOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorGroupOwnerUser.js +35 -0
- package/build/dist/Models/DatabaseModels/MonitorGroupOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorGroupResource.js +31 -0
- package/build/dist/Models/DatabaseModels/MonitorGroupResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorOwnerTeam.js +36 -0
- package/build/dist/Models/DatabaseModels/MonitorOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorOwnerUser.js +36 -0
- package/build/dist/Models/DatabaseModels/MonitorOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorProbe.js +33 -0
- package/build/dist/Models/DatabaseModels/MonitorProbe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorStatus.js +47 -0
- package/build/dist/Models/DatabaseModels/MonitorStatus.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +44 -0
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTest.js +50 -0
- package/build/dist/Models/DatabaseModels/MonitorTest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js +44 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRule.js +39 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js +35 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js +35 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +87 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js +62 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js +35 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +50 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +51 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js +43 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +44 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +41 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Probe.js +38 -0
- package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProbeOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/ProbeOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProbeOwnerUser.js +35 -0
- package/build/dist/Models/DatabaseModels/ProbeOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +44 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +28 -0
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSCIM.js +26 -0
- package/build/dist/Models/DatabaseModels/ProjectSCIM.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js +14 -0
- package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSmtpConfig.js +42 -0
- package/build/dist/Models/DatabaseModels/ProjectSmtpConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSso.js +26 -0
- package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectUserProfile.js +10 -0
- package/build/dist/Models/DatabaseModels/ProjectUserProfile.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PromoCode.js +10 -0
- package/build/dist/Models/DatabaseModels/PromoCode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PushNotificationLog.js +31 -0
- package/build/dist/Models/DatabaseModels/PushNotificationLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +103 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceFeed.js +42 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +36 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceNoteTemplate.js +29 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceNoteTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.js +35 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.js +35 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +51 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceState.js +55 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceState.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +50 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +98 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.js +33 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +33 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +75 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +49 -0
- package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceDependency.js +55 -0
- package/build/dist/Models/DatabaseModels/ServiceDependency.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceMonitor.js +55 -0
- package/build/dist/Models/DatabaseModels/ServiceMonitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceOwnerTeam.js +31 -0
- package/build/dist/Models/DatabaseModels/ServiceOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceOwnerUser.js +31 -0
- package/build/dist/Models/DatabaseModels/ServiceOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/SmsLog.js +31 -0
- package/build/dist/Models/DatabaseModels/SmsLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +270 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +61 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js +46 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js +57 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageFooterLink.js +37 -0
- package/build/dist/Models/DatabaseModels/StatusPageFooterLink.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +53 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageHeaderLink.js +37 -0
- package/build/dist/Models/DatabaseModels/StatusPageHeaderLink.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageHistoryChartBarColorRule.js +35 -0
- package/build/dist/Models/DatabaseModels/StatusPageHistoryChartBarColorRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOwnerTeam.js +33 -0
- package/build/dist/Models/DatabaseModels/StatusPageOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOwnerUser.js +34 -0
- package/build/dist/Models/DatabaseModels/StatusPageOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +36 -0
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +79 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSCIM.js +13 -0
- package/build/dist/Models/DatabaseModels/StatusPageSCIM.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js +15 -0
- package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSso.js +6 -0
- package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +79 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriberNotificationTemplate.js +42 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriberNotificationTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriberNotificationTemplateStatusPage.js +32 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriberNotificationTemplateStatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +26 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Team.js +25 -0
- package/build/dist/Models/DatabaseModels/Team.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +10 -0
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +16 -0
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +20 -0
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +22 -0
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +62 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WhatsAppLog.js +32 -0
- package/build/dist/Models/DatabaseModels/WhatsAppLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Workflow.js +39 -0
- package/build/dist/Models/DatabaseModels/Workflow.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +18 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +24 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js +37 -0
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js +47 -0
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js +87 -0
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +10 -0
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Tests/UI/Components/ProgressBar.test.js +1 -4
- package/build/dist/Tests/UI/Components/ProgressBar.test.js.map +1 -1
- package/build/dist/Types/Permission.js +788 -23
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +211 -0
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -0
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +3 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js +210 -0
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js.map +1 -0
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +11 -9
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import React, { ReactElement, useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
4
|
+
import Label from "../../../Models/DatabaseModels/Label";
|
|
5
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
6
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
7
|
+
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
|
8
|
+
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
9
|
+
import ListResult from "../../../Types/BaseDatabase/ListResult";
|
|
10
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
11
|
+
import API from "../../Utils/API/API";
|
|
12
|
+
import ModelAPI from "../../Utils/ModelAPI/ModelAPI";
|
|
13
|
+
import ProjectUtil from "../../Utils/Project";
|
|
14
|
+
import { ButtonStyleType } from "../Button/Button";
|
|
15
|
+
import BasicFormModal from "../FormModal/BasicFormModal";
|
|
16
|
+
import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
|
|
17
|
+
import {
|
|
18
|
+
BulkActionButtonSchema,
|
|
19
|
+
BulkActionFailed,
|
|
20
|
+
BulkActionOnClickProps,
|
|
21
|
+
} from "./BulkUpdateForm";
|
|
22
|
+
|
|
23
|
+
export interface BulkLabelActionsConfig<T extends BaseModel> {
|
|
24
|
+
modelType: { new (): T };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface BulkLabelActionsResult<T extends BaseModel> {
|
|
28
|
+
bulkActions: Array<BulkActionButtonSchema<T>>;
|
|
29
|
+
modals: ReactElement;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type BulkLabelMode = "add" | "remove";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reusable hook that provides "Add Labels" and "Remove Labels" bulk actions
|
|
36
|
+
* for any ModelTable whose model has a `labels` many-to-many relationship
|
|
37
|
+
* to the Label entity.
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* const { bulkActions, modals } = useBulkLabelActions({ modelType: Monitor });
|
|
41
|
+
* <ModelTable bulkActions={{ buttons: [...bulkActions, ...] }} />
|
|
42
|
+
* {modals}
|
|
43
|
+
*/
|
|
44
|
+
function useBulkLabelActions<T extends BaseModel>(
|
|
45
|
+
config: BulkLabelActionsConfig<T>,
|
|
46
|
+
): BulkLabelActionsResult<T> {
|
|
47
|
+
const [labels, setLabels] = useState<Array<Label>>([]);
|
|
48
|
+
const [showAddModal, setShowAddModal] = useState<boolean>(false);
|
|
49
|
+
const [showRemoveModal, setShowRemoveModal] = useState<boolean>(false);
|
|
50
|
+
const [bulkActionProps, setBulkActionProps] =
|
|
51
|
+
useState<BulkActionOnClickProps<T> | null>(null);
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const fetchLabels: () => Promise<void> = async (): Promise<void> => {
|
|
55
|
+
try {
|
|
56
|
+
const result: ListResult<Label> = await ModelAPI.getList<Label>({
|
|
57
|
+
modelType: Label,
|
|
58
|
+
query: {
|
|
59
|
+
projectId: ProjectUtil.getCurrentProjectId()!,
|
|
60
|
+
},
|
|
61
|
+
limit: LIMIT_PER_PROJECT,
|
|
62
|
+
skip: 0,
|
|
63
|
+
select: {
|
|
64
|
+
_id: true,
|
|
65
|
+
name: true,
|
|
66
|
+
color: true,
|
|
67
|
+
},
|
|
68
|
+
sort: {
|
|
69
|
+
name: SortOrder.Ascending,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
setLabels(result.data);
|
|
73
|
+
} catch {
|
|
74
|
+
// labels will remain empty; modal will show no options
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
fetchLabels();
|
|
79
|
+
}, []);
|
|
80
|
+
|
|
81
|
+
const applyLabels: (
|
|
82
|
+
labelIds: Array<string>,
|
|
83
|
+
mode: BulkLabelMode,
|
|
84
|
+
) => Promise<void> = async (
|
|
85
|
+
labelIds: Array<string>,
|
|
86
|
+
mode: BulkLabelMode,
|
|
87
|
+
): Promise<void> => {
|
|
88
|
+
if (!bulkActionProps) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { items, onProgressInfo, onBulkActionStart, onBulkActionEnd } =
|
|
93
|
+
bulkActionProps;
|
|
94
|
+
|
|
95
|
+
// Close the form modal first so the progress modal is visible
|
|
96
|
+
setShowAddModal(false);
|
|
97
|
+
setShowRemoveModal(false);
|
|
98
|
+
|
|
99
|
+
onBulkActionStart();
|
|
100
|
+
|
|
101
|
+
const totalItems: Array<T> = [...items];
|
|
102
|
+
const inProgressItems: Array<T> = [...items];
|
|
103
|
+
const successItems: Array<T> = [];
|
|
104
|
+
const failedItems: Array<BulkActionFailed<T>> = [];
|
|
105
|
+
|
|
106
|
+
for (const item of totalItems) {
|
|
107
|
+
inProgressItems.splice(inProgressItems.indexOf(item), 1);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
if (!item.id) {
|
|
111
|
+
throw new BadDataException("Item ID not found");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* Fetch current labels for this item so we can merge/subtract
|
|
116
|
+
* the selected label ids and avoid clobbering existing ones.
|
|
117
|
+
*/
|
|
118
|
+
const currentItem: T | null = await ModelAPI.getItem<T>({
|
|
119
|
+
modelType: config.modelType,
|
|
120
|
+
id: item.id,
|
|
121
|
+
select: {
|
|
122
|
+
labels: {
|
|
123
|
+
_id: true,
|
|
124
|
+
},
|
|
125
|
+
} as any,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const existingLabelIds: Array<string> = (
|
|
129
|
+
((currentItem as any)?.labels as Array<Label> | undefined) || []
|
|
130
|
+
)
|
|
131
|
+
.map((label: Label) => {
|
|
132
|
+
return label._id?.toString() || "";
|
|
133
|
+
})
|
|
134
|
+
.filter((id: string) => {
|
|
135
|
+
return id.length > 0;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
let newLabelIds: Array<string>;
|
|
139
|
+
|
|
140
|
+
if (mode === "add") {
|
|
141
|
+
newLabelIds = Array.from(
|
|
142
|
+
new Set<string>([...existingLabelIds, ...labelIds]),
|
|
143
|
+
);
|
|
144
|
+
} else {
|
|
145
|
+
newLabelIds = existingLabelIds.filter((id: string) => {
|
|
146
|
+
return !labelIds.includes(id);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
* No-op short-circuit: if nothing changed, still report as success
|
|
152
|
+
* so the user sees the item as processed.
|
|
153
|
+
*/
|
|
154
|
+
if (
|
|
155
|
+
newLabelIds.length === existingLabelIds.length &&
|
|
156
|
+
newLabelIds.every((id: string) => {
|
|
157
|
+
return existingLabelIds.includes(id);
|
|
158
|
+
})
|
|
159
|
+
) {
|
|
160
|
+
successItems.push(item);
|
|
161
|
+
} else {
|
|
162
|
+
await ModelAPI.updateById<T>({
|
|
163
|
+
id: item.id as ObjectID,
|
|
164
|
+
modelType: config.modelType,
|
|
165
|
+
data: {
|
|
166
|
+
labels: newLabelIds,
|
|
167
|
+
} as any,
|
|
168
|
+
});
|
|
169
|
+
successItems.push(item);
|
|
170
|
+
}
|
|
171
|
+
} catch (err) {
|
|
172
|
+
failedItems.push({
|
|
173
|
+
item: item,
|
|
174
|
+
failedMessage: API.getFriendlyMessage(err),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
onProgressInfo({
|
|
179
|
+
totalItems: totalItems,
|
|
180
|
+
failed: failedItems,
|
|
181
|
+
successItems: successItems,
|
|
182
|
+
inProgressItems: inProgressItems,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
onBulkActionEnd();
|
|
187
|
+
setBulkActionProps(null);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const labelDropdownOptions: Array<{ label: string; value: string }> =
|
|
191
|
+
labels.map((label: Label) => {
|
|
192
|
+
return {
|
|
193
|
+
label: label.name || "",
|
|
194
|
+
value: label._id?.toString() || "",
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const addLabelsAction: BulkActionButtonSchema<T> = {
|
|
199
|
+
title: "Add Labels",
|
|
200
|
+
buttonStyleType: ButtonStyleType.NORMAL,
|
|
201
|
+
icon: IconProp.Label,
|
|
202
|
+
onClick: async (actionProps: BulkActionOnClickProps<T>): Promise<void> => {
|
|
203
|
+
setBulkActionProps(actionProps);
|
|
204
|
+
setShowAddModal(true);
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const removeLabelsAction: BulkActionButtonSchema<T> = {
|
|
209
|
+
title: "Remove Labels",
|
|
210
|
+
buttonStyleType: ButtonStyleType.NORMAL,
|
|
211
|
+
icon: IconProp.Close,
|
|
212
|
+
onClick: async (actionProps: BulkActionOnClickProps<T>): Promise<void> => {
|
|
213
|
+
setBulkActionProps(actionProps);
|
|
214
|
+
setShowRemoveModal(true);
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const modals: ReactElement = (
|
|
219
|
+
<>
|
|
220
|
+
{showAddModal && (
|
|
221
|
+
<BasicFormModal
|
|
222
|
+
title="Add Labels"
|
|
223
|
+
description="Select labels to add to the selected items. Labels already attached to an item will be preserved."
|
|
224
|
+
onClose={() => {
|
|
225
|
+
setShowAddModal(false);
|
|
226
|
+
setBulkActionProps(null);
|
|
227
|
+
}}
|
|
228
|
+
submitButtonText="Add Labels"
|
|
229
|
+
onSubmit={async (formData: { labelIds: Array<string> }) => {
|
|
230
|
+
await applyLabels(formData.labelIds || [], "add");
|
|
231
|
+
}}
|
|
232
|
+
formProps={{
|
|
233
|
+
fields: [
|
|
234
|
+
{
|
|
235
|
+
field: {
|
|
236
|
+
labelIds: true,
|
|
237
|
+
},
|
|
238
|
+
title: "Select Labels",
|
|
239
|
+
description:
|
|
240
|
+
"These labels will be added to each selected item.",
|
|
241
|
+
fieldType: FormFieldSchemaType.MultiSelectDropdown,
|
|
242
|
+
required: true,
|
|
243
|
+
dropdownOptions: labelDropdownOptions,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
}}
|
|
247
|
+
/>
|
|
248
|
+
)}
|
|
249
|
+
|
|
250
|
+
{showRemoveModal && (
|
|
251
|
+
<BasicFormModal
|
|
252
|
+
title="Remove Labels"
|
|
253
|
+
description="Select labels to remove from the selected items. Items that do not have any of these labels will be skipped."
|
|
254
|
+
onClose={() => {
|
|
255
|
+
setShowRemoveModal(false);
|
|
256
|
+
setBulkActionProps(null);
|
|
257
|
+
}}
|
|
258
|
+
submitButtonText="Remove Labels"
|
|
259
|
+
onSubmit={async (formData: { labelIds: Array<string> }) => {
|
|
260
|
+
await applyLabels(formData.labelIds || [], "remove");
|
|
261
|
+
}}
|
|
262
|
+
formProps={{
|
|
263
|
+
fields: [
|
|
264
|
+
{
|
|
265
|
+
field: {
|
|
266
|
+
labelIds: true,
|
|
267
|
+
},
|
|
268
|
+
title: "Select Labels",
|
|
269
|
+
description:
|
|
270
|
+
"These labels will be removed from each selected item.",
|
|
271
|
+
fieldType: FormFieldSchemaType.MultiSelectDropdown,
|
|
272
|
+
required: true,
|
|
273
|
+
dropdownOptions: labelDropdownOptions,
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
}}
|
|
277
|
+
/>
|
|
278
|
+
)}
|
|
279
|
+
</>
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
bulkActions: [addLabelsAction, removeLabelsAction],
|
|
284
|
+
modals: modals,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export default useBulkLabelActions;
|
|
@@ -89,12 +89,20 @@ const BulkUpdateForm: <T extends GenericObject>(
|
|
|
89
89
|
const showProgressInfo: GetReactElementFunction = (): ReactElement => {
|
|
90
90
|
if (actionInProgress && progressInfo) {
|
|
91
91
|
return (
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
<div className="space-y-4">
|
|
93
|
+
<p className="text-sm text-gray-500">
|
|
94
|
+
Please wait while the bulk action is being performed. This may take
|
|
95
|
+
a moment.
|
|
96
|
+
</p>
|
|
97
|
+
<ProgressBar
|
|
98
|
+
count={
|
|
99
|
+
progressInfo.successItems.length + progressInfo.failed.length
|
|
100
|
+
}
|
|
101
|
+
totalCount={progressInfo.totalItems.length}
|
|
102
|
+
suffix={props.pluralLabel}
|
|
103
|
+
size={ProgressBarSize.Small}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
98
106
|
);
|
|
99
107
|
}
|
|
100
108
|
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import Button, { ButtonStyleType } from "../Button/Button";
|
|
2
|
+
import Color from "../../../Types/Color";
|
|
3
|
+
import Icon from "../Icon/Icon";
|
|
4
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
5
|
+
import React, {
|
|
6
|
+
FunctionComponent,
|
|
7
|
+
ReactElement,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
export interface CSVColumn {
|
|
13
|
+
key: string;
|
|
14
|
+
title: string;
|
|
15
|
+
required: boolean;
|
|
16
|
+
description?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type CSVRow = Record<string, string>;
|
|
20
|
+
|
|
21
|
+
export interface ComponentProps {
|
|
22
|
+
columns: Array<CSVColumn>;
|
|
23
|
+
onDataChanged: (data: Array<CSVRow>) => void;
|
|
24
|
+
templateFileName?: string | undefined;
|
|
25
|
+
description?: string | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ParseCSVFunction = (text: string) => Array<Array<string>>;
|
|
29
|
+
type DownloadTemplateFunction = () => void;
|
|
30
|
+
type HandleFileChangeFunction = (
|
|
31
|
+
event: React.ChangeEvent<HTMLInputElement>,
|
|
32
|
+
) => void;
|
|
33
|
+
|
|
34
|
+
const parseCSV: ParseCSVFunction = (text: string): Array<Array<string>> => {
|
|
35
|
+
const rows: Array<Array<string>> = [];
|
|
36
|
+
let current: string = "";
|
|
37
|
+
let inQuotes: boolean = false;
|
|
38
|
+
let row: Array<string> = [];
|
|
39
|
+
|
|
40
|
+
for (let i: number = 0; i < text.length; i++) {
|
|
41
|
+
const char: string = text[i]!;
|
|
42
|
+
const nextChar: string | undefined = text[i + 1];
|
|
43
|
+
|
|
44
|
+
if (inQuotes) {
|
|
45
|
+
if (char === '"' && nextChar === '"') {
|
|
46
|
+
current += '"';
|
|
47
|
+
i++;
|
|
48
|
+
} else if (char === '"') {
|
|
49
|
+
inQuotes = false;
|
|
50
|
+
} else {
|
|
51
|
+
current += char;
|
|
52
|
+
}
|
|
53
|
+
} else if (char === '"') {
|
|
54
|
+
inQuotes = true;
|
|
55
|
+
} else if (char === ",") {
|
|
56
|
+
row.push(current.trim());
|
|
57
|
+
current = "";
|
|
58
|
+
} else if (char === "\n" || (char === "\r" && nextChar === "\n")) {
|
|
59
|
+
row.push(current.trim());
|
|
60
|
+
current = "";
|
|
61
|
+
if (
|
|
62
|
+
row.some((cell: string) => {
|
|
63
|
+
return cell.length > 0;
|
|
64
|
+
})
|
|
65
|
+
) {
|
|
66
|
+
rows.push(row);
|
|
67
|
+
}
|
|
68
|
+
row = [];
|
|
69
|
+
if (char === "\r") {
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
current += char;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Push the last row
|
|
78
|
+
row.push(current.trim());
|
|
79
|
+
if (
|
|
80
|
+
row.some((cell: string) => {
|
|
81
|
+
return cell.length > 0;
|
|
82
|
+
})
|
|
83
|
+
) {
|
|
84
|
+
rows.push(row);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return rows;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const CSVFileUpload: FunctionComponent<ComponentProps> = (
|
|
91
|
+
props: ComponentProps,
|
|
92
|
+
): ReactElement => {
|
|
93
|
+
const [error, setError] = useState<string>("");
|
|
94
|
+
const [parsedRows, setParsedRows] = useState<Array<CSVRow>>([]);
|
|
95
|
+
const [fileName, setFileName] = useState<string>("");
|
|
96
|
+
const fileInputRef: React.RefObject<HTMLInputElement | null> =
|
|
97
|
+
useRef<HTMLInputElement>(null);
|
|
98
|
+
|
|
99
|
+
const downloadTemplate: DownloadTemplateFunction = (): void => {
|
|
100
|
+
const headerRow: string = props.columns
|
|
101
|
+
.map((col: CSVColumn) => {
|
|
102
|
+
return col.title;
|
|
103
|
+
})
|
|
104
|
+
.join(",");
|
|
105
|
+
const csvContent: string = headerRow + "\n";
|
|
106
|
+
const blob: Blob = new Blob([csvContent], { type: "text/csv" });
|
|
107
|
+
const url: string = window.URL.createObjectURL(blob);
|
|
108
|
+
const a: HTMLAnchorElement = document.createElement("a");
|
|
109
|
+
a.href = url;
|
|
110
|
+
a.download = props.templateFileName || "template.csv";
|
|
111
|
+
a.click();
|
|
112
|
+
window.URL.revokeObjectURL(url);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const handleFileChange: HandleFileChangeFunction = (
|
|
116
|
+
event: React.ChangeEvent<HTMLInputElement>,
|
|
117
|
+
): void => {
|
|
118
|
+
setError("");
|
|
119
|
+
setParsedRows([]);
|
|
120
|
+
setFileName("");
|
|
121
|
+
|
|
122
|
+
const file: File | undefined = event.target.files?.[0];
|
|
123
|
+
if (!file) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!file.name.toLowerCase().endsWith(".csv")) {
|
|
128
|
+
setError("Please upload a CSV file.");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
setFileName(file.name);
|
|
133
|
+
|
|
134
|
+
const reader: FileReader = new FileReader();
|
|
135
|
+
reader.onload = (e: ProgressEvent<FileReader>): void => {
|
|
136
|
+
const text: string = (e.target?.result as string) || "";
|
|
137
|
+
const rows: Array<Array<string>> = parseCSV(text);
|
|
138
|
+
|
|
139
|
+
if (rows.length < 2) {
|
|
140
|
+
setError("CSV file must have a header row and at least one data row.");
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const headerRow: Array<string> = rows[0]!;
|
|
145
|
+
|
|
146
|
+
// Map header titles to column keys
|
|
147
|
+
const columnMap: Map<number, CSVColumn> = new Map();
|
|
148
|
+
for (const col of props.columns) {
|
|
149
|
+
const index: number = headerRow.findIndex((h: string) => {
|
|
150
|
+
return h.toLowerCase() === col.title.toLowerCase();
|
|
151
|
+
});
|
|
152
|
+
if (index !== -1) {
|
|
153
|
+
columnMap.set(index, col);
|
|
154
|
+
} else if (col.required) {
|
|
155
|
+
setError(
|
|
156
|
+
`Required column "${col.title}" not found in CSV headers. Found: ${headerRow.join(", ")}`,
|
|
157
|
+
);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const dataRows: Array<CSVRow> = [];
|
|
163
|
+
const errors: Array<string> = [];
|
|
164
|
+
|
|
165
|
+
for (let i: number = 1; i < rows.length; i++) {
|
|
166
|
+
const row: Array<string> = rows[i]!;
|
|
167
|
+
const rowData: CSVRow = {};
|
|
168
|
+
let hasRequiredFields: boolean = true;
|
|
169
|
+
|
|
170
|
+
for (const [colIndex, col] of columnMap.entries()) {
|
|
171
|
+
const value: string = row[colIndex]?.trim() || "";
|
|
172
|
+
rowData[col.key] = value;
|
|
173
|
+
|
|
174
|
+
if (col.required && !value) {
|
|
175
|
+
hasRequiredFields = false;
|
|
176
|
+
errors.push(`Row ${i}: missing required field "${col.title}"`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (hasRequiredFields) {
|
|
181
|
+
dataRows.push(rowData);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (dataRows.length === 0) {
|
|
186
|
+
setError(
|
|
187
|
+
errors.length > 0
|
|
188
|
+
? `No valid rows found. ${errors.slice(0, 3).join(". ")}${errors.length > 3 ? ` and ${errors.length - 3} more errors.` : ""}`
|
|
189
|
+
: "No valid data rows found in the CSV file.",
|
|
190
|
+
);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (errors.length > 0 && dataRows.length > 0) {
|
|
195
|
+
// Some rows were skipped but we have valid data
|
|
196
|
+
setError(
|
|
197
|
+
`${errors.length} row(s) skipped due to missing required fields. ${dataRows.length} valid row(s) found.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
setParsedRows(dataRows);
|
|
202
|
+
props.onDataChanged(dataRows);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
reader.onerror = (): void => {
|
|
206
|
+
setError("Failed to read the CSV file. Please try again.");
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
reader.readAsText(file);
|
|
210
|
+
|
|
211
|
+
// Reset the input so the same file can be re-uploaded
|
|
212
|
+
event.target.value = "";
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<div className="space-y-4 w-full">
|
|
217
|
+
{props.description && (
|
|
218
|
+
<p className="text-sm text-gray-500">{props.description}</p>
|
|
219
|
+
)}
|
|
220
|
+
|
|
221
|
+
{/* Template download */}
|
|
222
|
+
<div className="flex items-center space-x-3">
|
|
223
|
+
<Button
|
|
224
|
+
title="Download CSV Template"
|
|
225
|
+
icon={IconProp.Download}
|
|
226
|
+
buttonStyle={ButtonStyleType.OUTLINE}
|
|
227
|
+
onClick={downloadTemplate}
|
|
228
|
+
/>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
{/* Column info */}
|
|
232
|
+
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
|
|
233
|
+
<p className="text-xs font-medium text-gray-700 mb-2">
|
|
234
|
+
Expected columns:
|
|
235
|
+
</p>
|
|
236
|
+
<div className="flex flex-wrap gap-2">
|
|
237
|
+
{props.columns.map((col: CSVColumn) => {
|
|
238
|
+
return (
|
|
239
|
+
<span
|
|
240
|
+
key={col.key}
|
|
241
|
+
className={`inline-flex items-center rounded px-2 py-1 text-xs font-medium ${
|
|
242
|
+
col.required
|
|
243
|
+
? "bg-indigo-100 text-indigo-700"
|
|
244
|
+
: "bg-gray-200 text-gray-600"
|
|
245
|
+
}`}
|
|
246
|
+
title={col.description}
|
|
247
|
+
>
|
|
248
|
+
{col.title}
|
|
249
|
+
{col.required && <span className="ml-1 text-red-500">*</span>}
|
|
250
|
+
</span>
|
|
251
|
+
);
|
|
252
|
+
})}
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
{/* File upload area */}
|
|
257
|
+
<div
|
|
258
|
+
className="flex w-full justify-center rounded-md border-2 border-dashed border-gray-300 bg-white px-6 py-8 cursor-pointer hover:border-indigo-400 transition"
|
|
259
|
+
onClick={() => {
|
|
260
|
+
return fileInputRef.current?.click();
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
<div className="flex flex-col items-center space-y-2 text-center">
|
|
264
|
+
<Icon icon={IconProp.File} className="h-10 w-10 text-gray-400" />
|
|
265
|
+
<div className="text-sm text-gray-600">
|
|
266
|
+
<span className="font-medium text-indigo-600">
|
|
267
|
+
Click to upload CSV
|
|
268
|
+
</span>{" "}
|
|
269
|
+
or drag and drop
|
|
270
|
+
</div>
|
|
271
|
+
<p className="text-xs text-gray-500">CSV files only</p>
|
|
272
|
+
<input
|
|
273
|
+
ref={fileInputRef as React.RefObject<HTMLInputElement>}
|
|
274
|
+
type="file"
|
|
275
|
+
accept=".csv"
|
|
276
|
+
className="sr-only"
|
|
277
|
+
onChange={handleFileChange}
|
|
278
|
+
/>
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
|
|
282
|
+
{/* File name */}
|
|
283
|
+
{fileName && !error && (
|
|
284
|
+
<div className="flex items-center rounded-lg bg-green-50 p-3">
|
|
285
|
+
<Icon
|
|
286
|
+
className="h-5 w-5 flex-shrink-0"
|
|
287
|
+
icon={IconProp.CheckCircle}
|
|
288
|
+
color={new Color("#16a34a")}
|
|
289
|
+
/>
|
|
290
|
+
<div className="ml-2 text-sm font-medium text-green-800">
|
|
291
|
+
{fileName} - {parsedRows.length} row(s) ready to import
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
)}
|
|
295
|
+
|
|
296
|
+
{/* Error */}
|
|
297
|
+
{error && (
|
|
298
|
+
<div className="rounded-lg bg-red-50 p-3">
|
|
299
|
+
<p className="text-sm text-red-700">{error}</p>
|
|
300
|
+
</div>
|
|
301
|
+
)}
|
|
302
|
+
|
|
303
|
+
{/* Preview table */}
|
|
304
|
+
{parsedRows.length > 0 && (
|
|
305
|
+
<div className="rounded-lg border border-gray-200 overflow-hidden">
|
|
306
|
+
<div className="bg-gray-50 px-4 py-2 text-xs font-medium text-gray-700">
|
|
307
|
+
Preview (first {Math.min(parsedRows.length, 5)} of{" "}
|
|
308
|
+
{parsedRows.length} rows)
|
|
309
|
+
</div>
|
|
310
|
+
<div className="overflow-x-auto">
|
|
311
|
+
<table className="min-w-full divide-y divide-gray-200">
|
|
312
|
+
<thead className="bg-gray-50">
|
|
313
|
+
<tr>
|
|
314
|
+
{props.columns.map((col: CSVColumn) => {
|
|
315
|
+
return (
|
|
316
|
+
<th
|
|
317
|
+
key={col.key}
|
|
318
|
+
className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase"
|
|
319
|
+
>
|
|
320
|
+
{col.title}
|
|
321
|
+
</th>
|
|
322
|
+
);
|
|
323
|
+
})}
|
|
324
|
+
</tr>
|
|
325
|
+
</thead>
|
|
326
|
+
<tbody className="divide-y divide-gray-200 bg-white">
|
|
327
|
+
{parsedRows.slice(0, 5).map((row: CSVRow, i: number) => {
|
|
328
|
+
return (
|
|
329
|
+
<tr key={i}>
|
|
330
|
+
{props.columns.map((col: CSVColumn) => {
|
|
331
|
+
return (
|
|
332
|
+
<td
|
|
333
|
+
key={col.key}
|
|
334
|
+
className="px-4 py-2 text-sm text-gray-900 truncate max-w-xs"
|
|
335
|
+
>
|
|
336
|
+
{row[col.key] || ""}
|
|
337
|
+
</td>
|
|
338
|
+
);
|
|
339
|
+
})}
|
|
340
|
+
</tr>
|
|
341
|
+
);
|
|
342
|
+
})}
|
|
343
|
+
</tbody>
|
|
344
|
+
</table>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
)}
|
|
348
|
+
</div>
|
|
349
|
+
);
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
export default CSVFileUpload;
|