@oneuptime/common 7.0.3148 → 7.0.3153

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.
Files changed (222) hide show
  1. package/Models/DatabaseModels/Alert.ts +1010 -0
  2. package/Models/DatabaseModels/AlertCustomField.ts +340 -0
  3. package/Models/DatabaseModels/AlertInternalNote.ts +371 -0
  4. package/Models/DatabaseModels/AlertNoteTemplate.ts +352 -0
  5. package/Models/DatabaseModels/AlertOwnerTeam.ts +416 -0
  6. package/Models/DatabaseModels/AlertOwnerUser.ts +415 -0
  7. package/Models/DatabaseModels/AlertSeverity.ts +426 -0
  8. package/Models/DatabaseModels/AlertState.ts +502 -0
  9. package/Models/DatabaseModels/AlertStateTimeline.ts +525 -0
  10. package/Models/DatabaseModels/Incident.ts +2 -11
  11. package/Models/DatabaseModels/Index.ts +34 -12
  12. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +55 -0
  13. package/Models/DatabaseModels/TableView.ts +452 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.ts +51 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.ts +553 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  17. package/Server/Services/AlertCustomFieldService.ts +9 -0
  18. package/Server/Services/AlertInternalNoteService.ts +10 -0
  19. package/Server/Services/AlertNoteTemplateService.ts +9 -0
  20. package/Server/Services/AlertOwnerTeamService.ts +10 -0
  21. package/Server/Services/AlertOwnerUserService.ts +10 -0
  22. package/Server/Services/AlertService.ts +568 -0
  23. package/Server/Services/AlertSeverityService.ts +154 -0
  24. package/Server/Services/AlertStateService.ts +227 -0
  25. package/Server/Services/AlertStateTimelineService.ts +334 -0
  26. package/Server/Services/CallLogService.ts +4 -1
  27. package/Server/Services/DatabaseService.ts +17 -20
  28. package/Server/Services/EmailLogService.ts +4 -1
  29. package/Server/Services/IncidentService.ts +4 -1
  30. package/Server/Services/IncidentStateTimelineService.ts +4 -1
  31. package/Server/Services/Index.ts +23 -0
  32. package/Server/Services/MonitorStatusTimelineService.ts +4 -1
  33. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +4 -1
  34. package/Server/Services/OnCallDutyPolicyService.ts +15 -0
  35. package/Server/Services/ProjectService.ts +99 -1
  36. package/Server/Services/ScheduledMaintenanceService.ts +4 -1
  37. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +4 -1
  38. package/Server/Services/ShortLinkService.ts +4 -1
  39. package/Server/Services/SmsLogService.ts +4 -1
  40. package/Server/Services/TableViewService.ts +10 -0
  41. package/Server/Services/TelemetryUsageBillingService.ts +4 -1
  42. package/Server/Services/UserNotificationSettingService.ts +58 -0
  43. package/Server/Services/UserOnCallLogService.ts +4 -1
  44. package/Server/Services/WorkflowLogService.ts +4 -1
  45. package/Server/Types/Workflow/Components/API/Post.ts +25 -0
  46. package/Server/Utils/Monitor/MonitorAlert.ts +273 -0
  47. package/Server/Utils/Monitor/MonitorIncident.ts +298 -0
  48. package/Server/Utils/Monitor/MonitorResource.ts +67 -387
  49. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +120 -0
  50. package/Server/Utils/Realtime.ts +1 -35
  51. package/Types/Email/EmailTemplateType.ts +7 -0
  52. package/Types/Icon/IconProp.ts +1 -0
  53. package/Types/Monitor/CriteriaAlert.ts +11 -0
  54. package/Types/Monitor/MonitorCriteria.ts +2 -0
  55. package/Types/Monitor/MonitorCriteriaInstance.ts +134 -1
  56. package/Types/Monitor/MonitorStep.ts +1 -0
  57. package/Types/Monitor/MonitorSteps.ts +1 -0
  58. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  59. package/Types/Permission.ts +369 -1
  60. package/Types/Telemetry/TelemetryQuery.ts +10 -0
  61. package/Types/UserNotification/UserNotificationEventType.ts +1 -0
  62. package/UI/Components/Card/Card.tsx +40 -31
  63. package/UI/Components/Card/CardButtons/MoreButton.ts +15 -0
  64. package/UI/Components/HeaderAlert/HeaderAlert.tsx +75 -16
  65. package/UI/Components/HeaderAlert/HeaderAlertGroup.tsx +50 -0
  66. package/UI/Components/HeaderAlert/HeaderModelAlert.tsx +5 -1
  67. package/UI/Components/Icon/Icon.tsx +8 -0
  68. package/UI/Components/ModelDetail/CardModelDetail.tsx +4 -2
  69. package/UI/Components/ModelTable/BaseModelTable.tsx +70 -2
  70. package/UI/Components/ModelTable/TableView.tsx +317 -0
  71. package/UI/Components/MoreMenu/Divider.tsx +7 -0
  72. package/UI/Components/MoreMenu/MoreMenu.tsx +54 -0
  73. package/UI/Components/MoreMenu/MoreMenuItem.tsx +37 -0
  74. package/UI/Components/MoreMenu/MoreMenuSection.tsx +22 -0
  75. package/UI/Components/Toggle/Toggle.tsx +14 -0
  76. package/build/dist/Models/DatabaseModels/Alert.js +1028 -0
  77. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -0
  78. package/build/dist/Models/DatabaseModels/AlertCustomField.js +360 -0
  79. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -0
  80. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +391 -0
  81. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -0
  82. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js +372 -0
  83. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js.map +1 -0
  84. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js +434 -0
  85. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js.map +1 -0
  86. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js +433 -0
  87. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js.map +1 -0
  88. package/build/dist/Models/DatabaseModels/AlertSeverity.js +450 -0
  89. package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -0
  90. package/build/dist/Models/DatabaseModels/AlertState.js +530 -0
  91. package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -0
  92. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +548 -0
  93. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -0
  94. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  95. package/build/dist/Models/DatabaseModels/Index.js +29 -9
  96. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  97. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +55 -0
  98. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  99. package/build/dist/Models/DatabaseModels/TableView.js +475 -0
  100. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -0
  101. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js +24 -0
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js.map +1 -0
  103. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js +198 -0
  104. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js.map +1 -0
  105. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  107. package/build/dist/Server/Services/AlertCustomFieldService.js +9 -0
  108. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -0
  109. package/build/dist/Server/Services/AlertInternalNoteService.js +9 -0
  110. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -0
  111. package/build/dist/Server/Services/AlertNoteTemplateService.js +9 -0
  112. package/build/dist/Server/Services/AlertNoteTemplateService.js.map +1 -0
  113. package/build/dist/Server/Services/AlertOwnerTeamService.js +9 -0
  114. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -0
  115. package/build/dist/Server/Services/AlertOwnerUserService.js +9 -0
  116. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -0
  117. package/build/dist/Server/Services/AlertService.js +418 -0
  118. package/build/dist/Server/Services/AlertService.js.map +1 -0
  119. package/build/dist/Server/Services/AlertSeverityService.js +108 -0
  120. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -0
  121. package/build/dist/Server/Services/AlertStateService.js +158 -0
  122. package/build/dist/Server/Services/AlertStateService.js.map +1 -0
  123. package/build/dist/Server/Services/AlertStateTimelineService.js +267 -0
  124. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -0
  125. package/build/dist/Server/Services/CallLogService.js +4 -1
  126. package/build/dist/Server/Services/CallLogService.js.map +1 -1
  127. package/build/dist/Server/Services/DatabaseService.js +9 -9
  128. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  129. package/build/dist/Server/Services/EmailLogService.js +4 -1
  130. package/build/dist/Server/Services/EmailLogService.js.map +1 -1
  131. package/build/dist/Server/Services/IncidentService.js +4 -1
  132. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  133. package/build/dist/Server/Services/IncidentStateTimelineService.js +4 -1
  134. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  135. package/build/dist/Server/Services/Index.js +21 -0
  136. package/build/dist/Server/Services/Index.js.map +1 -1
  137. package/build/dist/Server/Services/MonitorStatusTimelineService.js +4 -1
  138. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  139. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +4 -1
  140. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  141. package/build/dist/Server/Services/OnCallDutyPolicyService.js +8 -0
  142. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  143. package/build/dist/Server/Services/ProjectService.js +80 -1
  144. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  145. package/build/dist/Server/Services/ScheduledMaintenanceService.js +4 -1
  146. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  147. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +4 -1
  148. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  149. package/build/dist/Server/Services/ShortLinkService.js +4 -1
  150. package/build/dist/Server/Services/ShortLinkService.js.map +1 -1
  151. package/build/dist/Server/Services/SmsLogService.js +4 -1
  152. package/build/dist/Server/Services/SmsLogService.js.map +1 -1
  153. package/build/dist/Server/Services/TableViewService.js +9 -0
  154. package/build/dist/Server/Services/TableViewService.js.map +1 -0
  155. package/build/dist/Server/Services/TelemetryUsageBillingService.js +4 -1
  156. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  157. package/build/dist/Server/Services/UserNotificationSettingService.js +49 -0
  158. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  159. package/build/dist/Server/Services/UserOnCallLogService.js +4 -1
  160. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  161. package/build/dist/Server/Services/WorkflowLogService.js +4 -1
  162. package/build/dist/Server/Services/WorkflowLogService.js.map +1 -1
  163. package/build/dist/Server/Types/Workflow/Components/API/Post.js +14 -0
  164. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  165. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +177 -0
  166. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -0
  167. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +187 -0
  168. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -0
  169. package/build/dist/Server/Utils/Monitor/MonitorResource.js +46 -254
  170. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  171. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +79 -0
  172. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -0
  173. package/build/dist/Server/Utils/Realtime.js +3 -28
  174. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  175. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  176. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  177. package/build/dist/Types/Icon/IconProp.js +1 -0
  178. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  179. package/build/dist/Types/Monitor/CriteriaAlert.js +2 -0
  180. package/build/dist/Types/Monitor/CriteriaAlert.js.map +1 -0
  181. package/build/dist/Types/Monitor/MonitorCriteria.js +1 -0
  182. package/build/dist/Types/Monitor/MonitorCriteria.js.map +1 -1
  183. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +120 -1
  184. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  185. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  186. package/build/dist/Types/Monitor/MonitorSteps.js.map +1 -1
  187. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
  188. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  189. package/build/dist/Types/Permission.js +323 -1
  190. package/build/dist/Types/Permission.js.map +1 -1
  191. package/build/dist/Types/Telemetry/TelemetryQuery.js +2 -0
  192. package/build/dist/Types/Telemetry/TelemetryQuery.js.map +1 -0
  193. package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
  194. package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
  195. package/build/dist/UI/Components/Card/Card.js +3 -2
  196. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  197. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js +12 -0
  198. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js.map +1 -0
  199. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +53 -9
  200. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  201. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js +25 -0
  202. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js.map +1 -0
  203. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js +1 -1
  204. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js.map +1 -1
  205. package/build/dist/UI/Components/Icon/Icon.js +3 -0
  206. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  207. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  208. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +46 -0
  209. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  210. package/build/dist/UI/Components/ModelTable/TableView.js +183 -0
  211. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -0
  212. package/build/dist/UI/Components/MoreMenu/Divider.js +6 -0
  213. package/build/dist/UI/Components/MoreMenu/Divider.js.map +1 -0
  214. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +19 -0
  215. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -0
  216. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +13 -0
  217. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -0
  218. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js +10 -0
  219. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js.map +1 -0
  220. package/build/dist/UI/Components/Toggle/Toggle.js +7 -1
  221. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  222. package/package.json +2 -2
@@ -1,34 +1,93 @@
1
- import Icon from "../Icon/Icon";
1
+ import Icon, { ThickProp } from "../Icon/Icon";
2
2
  import IconProp from "Common/Types/Icon/IconProp";
3
3
  import React, { ReactElement } from "react";
4
+ import Tooltip from "../Tooltip/Tooltip";
5
+ import { GetReactElementFunction } from "../../Types/FunctionTypes";
6
+
7
+ export enum HeaderAlertType {
8
+ SUCCESS = "Success",
9
+ ERROR = "Error",
10
+ WARNING = "Warning",
11
+ INFO = "Info",
12
+ }
4
13
 
5
14
  export interface ComponentProps {
6
15
  icon: IconProp;
7
16
  onClick?: (() => void) | undefined;
8
17
  title: string;
9
18
  className?: string | undefined;
19
+ alertType: HeaderAlertType;
20
+ tooltip?: string | undefined;
10
21
  }
11
22
 
12
23
  const HeaderAlert: (props: ComponentProps) => ReactElement = (
13
24
  props: ComponentProps,
14
25
  ): ReactElement => {
15
- return (
16
- <div
17
- className={`rounded-md ${props.className} p-3 pr-4`}
18
- onClick={() => {
19
- props.onClick && props.onClick();
20
- }}
21
- >
22
- <div className="flex ">
23
- <div className="flex-shrink-0">
24
- <Icon icon={props.icon} className="h-5 w-5 text-white" />
25
- </div>
26
- <div className="ml-1 flex-1 md:flex md:justify-between">
27
- <p className={`text-sm text-white`}>{props.title}</p>
26
+ let textColor: string = "text-indigo-500"; // default color info.
27
+
28
+ switch (props.alertType) {
29
+ case HeaderAlertType.SUCCESS:
30
+ textColor = "text-green-500 hover:text-green-600";
31
+ break;
32
+ case HeaderAlertType.ERROR:
33
+ textColor = "text-red-500 hover:text-red-600";
34
+ break;
35
+ case HeaderAlertType.WARNING:
36
+ textColor = "text-yellow-500 hover:text-yellow-600";
37
+ break;
38
+ case HeaderAlertType.INFO:
39
+ textColor = "text-indigo-500 hover:text-indigo-600";
40
+ break;
41
+ }
42
+
43
+ let bgColor: string = "bg-gray";
44
+
45
+ switch (props.alertType) {
46
+ case HeaderAlertType.SUCCESS:
47
+ bgColor = "bg-green";
48
+ break;
49
+ case HeaderAlertType.ERROR:
50
+ bgColor = "bg-red";
51
+ break;
52
+ case HeaderAlertType.WARNING:
53
+ bgColor = "bg-yellow";
54
+ break;
55
+ case HeaderAlertType.INFO:
56
+ bgColor = "bg-indigo";
57
+ break;
58
+ }
59
+
60
+ const getElement: GetReactElementFunction = (): ReactElement => {
61
+ return (
62
+ <div
63
+ className={`cursor-pointer ${bgColor}-50 hover:${bgColor}-200 mr-2 ml-2 p-1 h-7 pl-2 pr-2 rounded-full ${props.className}`}
64
+ onClick={() => {
65
+ props.onClick && props.onClick();
66
+ }}
67
+ >
68
+ <div className="flex ">
69
+ <div className={`flex-shrink-0 mt-0.5 ${textColor}`}>
70
+ <Icon
71
+ icon={props.icon}
72
+ thick={ThickProp.Thick}
73
+ className={`h-4 w-4 stroke-[3px] font-bold ${textColor}`}
74
+ />
75
+ </div>
76
+ <div className="ml-1 flex-1 md:flex md:justify-between">
77
+ <p className={`text-sm font-semibold ${textColor}`}>
78
+ {props.title}
79
+ </p>
80
+ </div>
28
81
  </div>
29
82
  </div>
30
- </div>
31
- );
83
+ );
84
+ };
85
+
86
+ if (props.tooltip) {
87
+ return <Tooltip text={props.tooltip}>{getElement()}</Tooltip>;
88
+ }
89
+
90
+ return getElement();
32
91
  };
33
92
 
34
93
  export default HeaderAlert;
@@ -0,0 +1,50 @@
1
+ import React, { ReactElement } from "react";
2
+
3
+ export interface ComponentProps {
4
+ children: Array<ReactElement | false>;
5
+ }
6
+
7
+ const HeaderAlertGroup: (props: ComponentProps) => ReactElement = (
8
+ props: ComponentProps,
9
+ ): ReactElement => {
10
+ let children: Array<ReactElement | false> = props.children || [];
11
+
12
+ children = children.filter((child: ReactElement | false) => {
13
+ if (!child) {
14
+ return false;
15
+ }
16
+
17
+ // check if this child has inner div.
18
+ if (child.props.children) {
19
+ return true;
20
+ }
21
+
22
+ return true;
23
+ });
24
+
25
+ if (!children || children.length === 0) {
26
+ return <></>;
27
+ }
28
+
29
+ // const className: string = "rounded-lg m-3 h-10 pr-0 pl-0 flex border-2 border-gray-200";
30
+ const className: string = "rounded-lg m-3 mt-5 h-10 pr-0 pl-0 flex";
31
+
32
+ return (
33
+ <div className={className}>
34
+ {children.map((child: ReactElement | false, index: number) => {
35
+ // const isLastElement: boolean = index === props.children.length - 1;
36
+
37
+ return (
38
+ <div key={index} className="flex">
39
+ {child}
40
+ {/* {!isLastElement && (
41
+ <div className="border-r-2 border-gray-200"></div>
42
+ )} */}
43
+ </div>
44
+ );
45
+ })}
46
+ </div>
47
+ );
48
+ };
49
+
50
+ export default HeaderAlertGroup;
@@ -1,7 +1,7 @@
1
1
  import API from "../../Utils/API/API";
2
2
  import Query from "../../../Types/BaseDatabase/Query";
3
3
  import ModelAPI, { RequestOptions } from "../../Utils/ModelAPI/ModelAPI";
4
- import HeaderAlert from "./HeaderAlert";
4
+ import HeaderAlert, { HeaderAlertType } from "./HeaderAlert";
5
5
  import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
6
6
  import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
7
7
  import IconProp from "Common/Types/Icon/IconProp";
@@ -18,6 +18,8 @@ export interface ComponentProps<TBaseModel extends BaseModel> {
18
18
  onClick?: (() => void) | undefined;
19
19
  refreshToggle?: string | undefined;
20
20
  className?: string | undefined;
21
+ alertType: HeaderAlertType;
22
+ tooltip?: string | undefined;
21
23
  }
22
24
 
23
25
  const HeaderModelAlert: <TBaseModel extends BaseModel>(
@@ -84,6 +86,8 @@ const HeaderModelAlert: <TBaseModel extends BaseModel>(
84
86
  icon={props.icon}
85
87
  onClick={props.onClick}
86
88
  className={props.className}
89
+ alertType={props.alertType}
90
+ tooltip={props.tooltip}
87
91
  />
88
92
  );
89
93
  };
@@ -194,6 +194,14 @@ const Icon: FunctionComponent<ComponentProps> = ({
194
194
  d="M6.429 9.75 2.25 12l4.179 2.25m0-4.5 5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L21.75 12l-4.179 2.25m0 0 4.179 2.25L12 21.75 2.25 16.5l4.179-2.25m11.142 0-5.571 3-5.571-3"
195
195
  />,
196
196
  );
197
+ } else if (icon === IconProp.ExclaimationCircle) {
198
+ return getSvgWrapper(
199
+ <path
200
+ strokeLinecap="round"
201
+ strokeLinejoin="round"
202
+ d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
203
+ />,
204
+ );
197
205
  } else if (icon === IconProp.Reload) {
198
206
  return getSvgWrapper(
199
207
  <path
@@ -39,7 +39,9 @@ const CardModelDetail: <TBaseModel extends BaseModel>(
39
39
  ) => ReactElement = <TBaseModel extends BaseModel>(
40
40
  props: ComponentProps<TBaseModel>,
41
41
  ): ReactElement => {
42
- const [cardButtons, setCardButtons] = useState<Array<CardButtonSchema>>([]);
42
+ const [cardButtons, setCardButtons] = useState<
43
+ Array<CardButtonSchema | ReactElement>
44
+ >([]);
43
45
  const [showModel, setShowModal] = useState<boolean>(false);
44
46
  const [item, setItem] = useState<TBaseModel | null>(null);
45
47
  const [refresher, setRefresher] = useState<boolean>(false);
@@ -65,7 +67,7 @@ const CardModelDetail: <TBaseModel extends BaseModel>(
65
67
  ),
66
68
  ) || User.isMasterAdmin();
67
69
 
68
- let cardButtons: Array<CardButtonSchema> = [];
70
+ let cardButtons: Array<CardButtonSchema | ReactElement> = [];
69
71
 
70
72
  if (props.isEditable && hasPermissionToEdit) {
71
73
  cardButtons.push({
@@ -84,6 +84,8 @@ import React, {
84
84
  useEffect,
85
85
  useState,
86
86
  } from "react";
87
+ import TableViewElement from "./TableView";
88
+ import TableView from "../../../Models/DatabaseModels/TableView";
87
89
 
88
90
  export enum ShowAs {
89
91
  Table,
@@ -91,6 +93,10 @@ export enum ShowAs {
91
93
  OrderedStatesList,
92
94
  }
93
95
 
96
+ export interface SaveFilterProps {
97
+ tableId: string;
98
+ }
99
+
94
100
  export interface BaseTableCallbacks<
95
101
  TBaseModel extends BaseModel | AnalyticsBaseModel,
96
102
  > {
@@ -207,6 +213,8 @@ export interface BaseTableProps<
207
213
  onShowFormType?: (formType: ModalType) => void;
208
214
 
209
215
  initialFilterData?: FilterData<TBaseModel> | undefined;
216
+
217
+ saveFilterProps?: SaveFilterProps | undefined;
210
218
  }
211
219
 
212
220
  export interface ComponentProps<
@@ -254,7 +262,9 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
254
262
  Array<ClassicFilterType<TBaseModel>>
255
263
  >([]);
256
264
 
257
- const [cardButtons, setCardButtons] = useState<Array<CardButtonSchema>>([]);
265
+ const [cardButtons, setCardButtons] = useState<
266
+ Array<CardButtonSchema | ReactElement>
267
+ >([]);
258
268
 
259
269
  const [actionButtonSchema, setActionButtonSchema] = useState<
260
270
  Array<ActionButtonSchema<TBaseModel>>
@@ -784,9 +794,63 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
784
794
  return selectFields;
785
795
  };
786
796
 
797
+ const getSaveFilterDropdown: GetReactElementFunction = (): ReactElement => {
798
+ if (!props.saveFilterProps) {
799
+ return <></>;
800
+ }
801
+
802
+ if (props.saveFilterProps && props.saveFilterProps.tableId) {
803
+ const currentTableView: TableView = new TableView();
804
+ currentTableView.query = (query || {}) as any;
805
+ currentTableView.itemsOnPage = itemsOnPage || 10;
806
+
807
+ if (sortBy && sortOrder) {
808
+ currentTableView.sort = {
809
+ [sortBy as string]: sortOrder,
810
+ };
811
+ } else {
812
+ currentTableView.sort = {};
813
+ }
814
+
815
+ return (
816
+ <TableViewElement
817
+ tableId={props.saveFilterProps.tableId}
818
+ currentTableView={currentTableView}
819
+ onViewChange={(tableView: TableView | null) => {
820
+ if (tableView) {
821
+ const sortBy: string | undefined = Object.keys(
822
+ tableView.sort || {},
823
+ )[0];
824
+ let sortOrder: SortOrder = SortOrder.Descending;
825
+
826
+ if (sortBy && tableView.sort) {
827
+ sortOrder =
828
+ ((tableView.sort as any)[sortBy as any] as any) ||
829
+ SortOrder.Descending;
830
+ }
831
+
832
+ // then set query, sort and items on the page
833
+ setQuery(tableView.query || {});
834
+ setItemsOnPage(tableView.itemsOnPage || 10);
835
+ setSortBy(sortBy as keyof TBaseModel);
836
+ setSortOrder(sortOrder);
837
+ } else {
838
+ setQuery({});
839
+ setSortBy(null);
840
+ setSortOrder(SortOrder.Descending);
841
+ setItemsOnPage(10);
842
+ }
843
+ }}
844
+ />
845
+ );
846
+ }
847
+
848
+ return <></>;
849
+ };
850
+
787
851
  const setHeaderButtons: VoidFunction = (): void => {
788
852
  // add header buttons.
789
- let headerbuttons: Array<CardButtonSchema> = [];
853
+ let headerbuttons: Array<CardButtonSchema | ReactElement> = [];
790
854
 
791
855
  if (props.cardProps?.buttons && props.cardProps?.buttons.length > 0) {
792
856
  headerbuttons = [...props.cardProps.buttons];
@@ -854,6 +918,10 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
854
918
  });
855
919
  }
856
920
 
921
+ if (props.saveFilterProps) {
922
+ headerbuttons.push(getSaveFilterDropdown());
923
+ }
924
+
857
925
  setCardButtons(headerbuttons);
858
926
  };
859
927
 
@@ -0,0 +1,317 @@
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useEffect,
5
+ useState,
6
+ } from "react";
7
+ import TableView from "../../../Models/DatabaseModels/TableView";
8
+ import ObjectID from "../../../Types/ObjectID";
9
+ import MoreMenu from "../MoreMenu/MoreMenu";
10
+ import MoreMenuItem from "../MoreMenu/MoreMenuItem";
11
+ import ListResult from "../../Utils/BaseDatabase/ListResult";
12
+ import ModelAPI from "../../Utils/ModelAPI/ModelAPI";
13
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
14
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
15
+ import API from "../../../Utils/API";
16
+ import MoreMenuSection from "../MoreMenu/MoreMenuSection";
17
+ import Button, { ButtonStyleType } from "../Button/Button";
18
+ import IconProp from "../../../Types/Icon/IconProp";
19
+ import { BarLoader } from "react-spinners";
20
+ import ConfirmModal from "../Modal/ConfirmModal";
21
+ import ModelFormModal from "../ModelFormModal/ModelFormModal";
22
+ import { FormType } from "../Forms/ModelForm";
23
+ import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
24
+ import { PromiseVoidFunction } from "../../../Types/FunctionTypes";
25
+ import { GetReactElementFunction } from "../../Types/FunctionTypes";
26
+ import ProjectUtil from "../../Utils/Project";
27
+ import User from "../../Utils/User";
28
+
29
+ export interface ComponentProps {
30
+ tableId: string;
31
+ onViewChange: (tableView: TableView | null) => void;
32
+ currentTableView: TableView | null;
33
+ }
34
+
35
+ const TableViewElement: FunctionComponent<ComponentProps> = (
36
+ props: ComponentProps,
37
+ ): ReactElement => {
38
+ const [error, setError] = useState<string>("");
39
+ const [isLoading, setIsLoading] = useState<boolean>(false);
40
+ const [allTableViews, setAllTableViews] = useState<Array<TableView>>([]);
41
+ const [tableViewToDelete, setTableViewToDelete] = useState<
42
+ TableView | undefined
43
+ >(undefined);
44
+ const [tableViewToEdit, setTableViewToEdit] = useState<TableView | undefined>(
45
+ undefined,
46
+ );
47
+ const [showCreateNewViewModal, setShowCreateNewViewModel] =
48
+ useState<boolean>(false);
49
+
50
+ const [currentlySelectedView, setCurrentlySelectedView] =
51
+ useState<TableView | null>(null);
52
+
53
+ // load all the filters for this user and for this project.
54
+ const fetchTableViews: PromiseVoidFunction = async (): Promise<void> => {
55
+ try {
56
+ setError("");
57
+ setIsLoading(true);
58
+
59
+ const tableViews: ListResult<TableView> = await ModelAPI.getList({
60
+ modelType: TableView,
61
+ query: {
62
+ projectId: ProjectUtil.getCurrentProjectId()!,
63
+ createdByUserId: User.getUserId(),
64
+ tableId: props.tableId,
65
+ },
66
+ limit: LIMIT_PER_PROJECT,
67
+ skip: 0,
68
+ select: {
69
+ sort: true,
70
+ itemsOnPage: true,
71
+ query: true,
72
+ name: true,
73
+ },
74
+ sort: {
75
+ name: SortOrder.Ascending,
76
+ },
77
+ });
78
+
79
+ setAllTableViews(tableViews.data);
80
+ } catch (err) {
81
+ setError(API.getFriendlyErrorMessage(err as Error));
82
+ }
83
+
84
+ setIsLoading(false);
85
+ };
86
+
87
+ type DeleteTableViewFunction = (tableView: TableView) => Promise<void>;
88
+
89
+ const deleteTableView: DeleteTableViewFunction = async (
90
+ tableView: TableView,
91
+ ): Promise<void> => {
92
+ const tableViewId: ObjectID = tableView.id!;
93
+
94
+ try {
95
+ setError("");
96
+ setIsLoading(true);
97
+
98
+ await ModelAPI.deleteItem({
99
+ modelType: TableView,
100
+ id: tableViewId,
101
+ });
102
+
103
+ await fetchTableViews();
104
+ } catch (err) {
105
+ setError(API.getFriendlyErrorMessage(err as Error));
106
+ }
107
+
108
+ setIsLoading(false);
109
+ };
110
+
111
+ useEffect(() => {
112
+ fetchTableViews().catch((err: Error) => {
113
+ setError(API.getFriendlyErrorMessage(err as Error));
114
+ });
115
+ }, []);
116
+
117
+ type GetRightElementForTableViewMenuItemFunction = (
118
+ item: TableView,
119
+ ) => React.JSX.Element;
120
+
121
+ const getRightElementForTableViewMenuItem: GetRightElementForTableViewMenuItemFunction =
122
+ (item: TableView): ReactElement => {
123
+ return (
124
+ <div className="flex">
125
+ <Button
126
+ icon={IconProp.Edit}
127
+ buttonStyle={ButtonStyleType.ICON_LIGHT}
128
+ onClick={() => {
129
+ setTableViewToEdit(item);
130
+ }}
131
+ />
132
+
133
+ <Button
134
+ icon={IconProp.Trash}
135
+ buttonStyle={ButtonStyleType.ICON_LIGHT}
136
+ onClick={() => {
137
+ setTableViewToDelete(item);
138
+ }}
139
+ />
140
+ </div>
141
+ );
142
+ };
143
+
144
+ type GetViewItemsFunction = () => Array<ReactElement>;
145
+
146
+ const getViewItems: GetViewItemsFunction = (): Array<ReactElement> => {
147
+ return allTableViews.map((item: TableView, index: number) => {
148
+ return (
149
+ <MoreMenuItem
150
+ key={index}
151
+ rightElement={getRightElementForTableViewMenuItem(item)}
152
+ text={item.name || ""}
153
+ onClick={() => {
154
+ props.onViewChange && props.onViewChange(item);
155
+ setCurrentlySelectedView(item);
156
+ }}
157
+ />
158
+ );
159
+ });
160
+ };
161
+
162
+ const getMenuContents: GetReactElementFunction = (): ReactElement => {
163
+ if (isLoading) {
164
+ return <BarLoader />;
165
+ }
166
+
167
+ return (
168
+ <>
169
+ {allTableViews.length > 0 ? (
170
+ <MoreMenuSection title="Saved Views">
171
+ {getViewItems()}
172
+ </MoreMenuSection>
173
+ ) : (
174
+ <></>
175
+ )}
176
+
177
+ {currentlySelectedView ? (
178
+ <MoreMenuItem
179
+ text="Deselect View"
180
+ onClick={() => {
181
+ setCurrentlySelectedView(null);
182
+ props.onViewChange && props.onViewChange(null);
183
+ }}
184
+ ></MoreMenuItem>
185
+ ) : (
186
+ <></>
187
+ )}
188
+
189
+ <MoreMenuItem
190
+ text="Save View"
191
+ onClick={() => {
192
+ setShowCreateNewViewModel(true);
193
+ }}
194
+ ></MoreMenuItem>
195
+ </>
196
+ );
197
+ };
198
+
199
+ if (error) {
200
+ return (
201
+ <ConfirmModal
202
+ title={`Something went wrong...`}
203
+ description={error}
204
+ isLoading={false}
205
+ submitButtonText={"Close"}
206
+ onSubmit={() => {
207
+ return setError("");
208
+ }}
209
+ />
210
+ );
211
+ }
212
+
213
+ if (tableViewToEdit) {
214
+ return (
215
+ <ModelFormModal<TableView>
216
+ modelType={TableView}
217
+ modelIdToEdit={tableViewToEdit.id!}
218
+ name="Edit View"
219
+ title="Edit View"
220
+ description="You can rename this table view to any name you like."
221
+ onClose={() => {
222
+ setTableViewToEdit(undefined);
223
+ }}
224
+ submitButtonText="Save Changes"
225
+ onSuccess={async () => {
226
+ setTableViewToEdit(undefined);
227
+ await fetchTableViews();
228
+ }}
229
+ formProps={{
230
+ name: "Edit View",
231
+ modelType: TableView,
232
+ id: "edit-table-view",
233
+ fields: [
234
+ {
235
+ field: {
236
+ name: true,
237
+ },
238
+ fieldType: FormFieldSchemaType.Text,
239
+ placeholder: "Name of the view",
240
+ description: "Please enter the new name of the view",
241
+ title: "Name",
242
+ required: true,
243
+ },
244
+ ],
245
+ formType: FormType.Update,
246
+ }}
247
+ />
248
+ );
249
+ }
250
+
251
+ if (tableViewToDelete) {
252
+ return (
253
+ <ConfirmModal
254
+ description={`Are you sure you want to delete view - ${tableViewToDelete.name}?`}
255
+ title={`Delete ${tableViewToDelete.name}`}
256
+ isLoading={isLoading}
257
+ onSubmit={async () => {
258
+ await deleteTableView(tableViewToDelete);
259
+ setTableViewToDelete(undefined);
260
+ }}
261
+ onClose={() => {
262
+ setTableViewToDelete(undefined);
263
+ }}
264
+ submitButtonText={`Delete`}
265
+ submitButtonType={ButtonStyleType.DANGER}
266
+ />
267
+ );
268
+ }
269
+
270
+ if (showCreateNewViewModal) {
271
+ return (
272
+ <ModelFormModal<TableView>
273
+ modelType={TableView}
274
+ name="Save New View"
275
+ title="Save New View"
276
+ description="You can save the current table settings as a new view."
277
+ onClose={() => {
278
+ setShowCreateNewViewModel(false);
279
+ }}
280
+ submitButtonText="Save Changes"
281
+ onBeforeCreate={(tableView: TableView) => {
282
+ tableView.tableId = props.tableId;
283
+ tableView.query = props.currentTableView?.query || {};
284
+ tableView.itemsOnPage = props.currentTableView?.itemsOnPage || 10;
285
+ tableView.sort = props.currentTableView?.sort || {};
286
+ return Promise.resolve(tableView);
287
+ }}
288
+ onSuccess={async () => {
289
+ setShowCreateNewViewModel(false);
290
+ await fetchTableViews();
291
+ }}
292
+ formProps={{
293
+ name: "Save New View",
294
+ modelType: TableView,
295
+ id: "save-table-view",
296
+ fields: [
297
+ {
298
+ field: {
299
+ name: true,
300
+ },
301
+ fieldType: FormFieldSchemaType.Text,
302
+ placeholder: "Name of the view",
303
+ description: "Please enter the new name of the view",
304
+ title: "Name",
305
+ required: true,
306
+ },
307
+ ],
308
+ formType: FormType.Create,
309
+ }}
310
+ />
311
+ );
312
+ }
313
+
314
+ return <MoreMenu>{getMenuContents()}</MoreMenu>;
315
+ };
316
+
317
+ export default TableViewElement;
@@ -0,0 +1,7 @@
1
+ import React, { FunctionComponent, ReactElement } from "react";
2
+
3
+ const MoreMenuDivider: FunctionComponent = (): ReactElement => {
4
+ return <div className="py-1" role="none"></div>;
5
+ };
6
+
7
+ export default MoreMenuDivider;