@oneuptime/common 7.0.4220 → 7.0.4222
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/AnalyticsModels/AnalyticsBaseModel/CommonModel.ts +4 -0
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +498 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +0 -2
- package/Models/DatabaseModels/WorkspaceNotificationRule.ts +2 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +0 -2
- package/Models/DatabaseModels/WorkspaceSetting.ts +0 -2
- package/Models/DatabaseModels/WorkspaceUserAuthToken.ts +0 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1747305098533-MigrationName.ts +69 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Services/Index.ts +3 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +25 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +29 -0
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +73 -0
- package/Server/Services/OnCallDutyPolicyTimeLogService.ts +175 -0
- package/Server/Services/TeamMemberService.ts +10 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +1 -1
- package/Server/Types/Database/QueryHelper.ts +15 -0
- package/Server/Types/Database/QueryUtil.ts +18 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +5 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +16 -0
- package/Tests/Types/JSON.test.ts +2 -0
- package/Types/BaseDatabase/GreaterThan.ts +11 -0
- package/Types/BaseDatabase/GreaterThanOrEqual.ts +11 -0
- package/Types/BaseDatabase/GreaterThanOrNull.ts +39 -0
- package/Types/BaseDatabase/LessThan.ts +11 -0
- package/Types/BaseDatabase/LessThanOrEqual.ts +11 -0
- package/Types/BaseDatabase/LessThanOrNull.ts +39 -0
- package/Types/Date.ts +18 -0
- package/Types/JSON.ts +8 -0
- package/Types/Permission.ts +11 -0
- package/Types/SerializableObjectDictionary.ts +4 -0
- package/Types/Time/RangeStartAndEndDateTime.ts +98 -0
- package/Types/Time/TimeRange.ts +15 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +3 -3
- package/UI/Components/Date/RangeStartAndEndDateEdit.tsx +64 -0
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +86 -0
- package/UI/Components/Filters/FilterViewer.tsx +5 -5
- package/UI/Components/Table/LocalTable.tsx +74 -0
- package/UI/Components/Table/Table.tsx +33 -24
- package/UI/Components/Table/TableBody.tsx +5 -1
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +522 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +0 -2
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js +2 -2
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +0 -2
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceSetting.js +0 -2
- package/build/dist/Models/DatabaseModels/WorkspaceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceUserAuthToken.js +0 -2
- package/build/dist/Models/DatabaseModels/WorkspaceUserAuthToken.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1747305098533-MigrationName.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1747305098533-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +20 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +24 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +58 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js +107 -0
- package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js.map +1 -0
- package/build/dist/Server/Services/TeamMemberService.js +9 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +8 -8
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +21 -7
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +12 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +5 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +14 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Tests/Types/JSON.test.js +2 -0
- package/build/dist/Tests/Types/JSON.test.js.map +1 -1
- package/build/dist/Types/BaseDatabase/GreaterThan.js +8 -0
- package/build/dist/Types/BaseDatabase/GreaterThan.js.map +1 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrEqual.js +8 -0
- package/build/dist/Types/BaseDatabase/GreaterThanOrEqual.js.map +1 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrNull.js +29 -0
- package/build/dist/Types/BaseDatabase/GreaterThanOrNull.js.map +1 -0
- package/build/dist/Types/BaseDatabase/LessThan.js +8 -0
- package/build/dist/Types/BaseDatabase/LessThan.js.map +1 -1
- package/build/dist/Types/BaseDatabase/LessThanOrEqual.js +8 -0
- package/build/dist/Types/BaseDatabase/LessThanOrEqual.js.map +1 -1
- package/build/dist/Types/BaseDatabase/LessThanOrNull.js +29 -0
- package/build/dist/Types/BaseDatabase/LessThanOrNull.js.map +1 -0
- package/build/dist/Types/Date.js +12 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/JSON.js +2 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/Permission.js +8 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +4 -0
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Time/RangeStartAndEndDateTime.js +48 -0
- package/build/dist/Types/Time/RangeStartAndEndDateTime.js.map +1 -0
- package/build/dist/Types/Time/TimeRange.js +16 -0
- package/build/dist/Types/Time/TimeRange.js.map +1 -0
- package/build/dist/UI/Components/Date/RangeStartAndEndDateEdit.js +32 -0
- package/build/dist/UI/Components/Date/RangeStartAndEndDateEdit.js.map +1 -0
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +43 -0
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -0
- package/build/dist/UI/Components/Filters/FilterViewer.js +3 -3
- package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
- package/build/dist/UI/Components/Table/LocalTable.js +32 -0
- package/build/dist/UI/Components/Table/LocalTable.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +19 -8
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +3 -0
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import CompareBase, { CompareType } from "../Database/CompareBase";
|
|
2
|
+
import OneUptimeDate from "../Date";
|
|
3
|
+
import BadDataException from "../Exception/BadDataException";
|
|
4
|
+
import { JSONObject, ObjectType } from "../JSON";
|
|
5
|
+
|
|
6
|
+
export default class LessThanOrNull<
|
|
7
|
+
T extends CompareType,
|
|
8
|
+
> extends CompareBase<T> {
|
|
9
|
+
public constructor(value: T) {
|
|
10
|
+
super(value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public override toJSON(): JSONObject {
|
|
14
|
+
return {
|
|
15
|
+
_type: ObjectType.LessThanOrNull,
|
|
16
|
+
value: (this as LessThanOrNull<T>).toString(),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public override toString(): string {
|
|
21
|
+
let value: T = this.value;
|
|
22
|
+
|
|
23
|
+
if (value instanceof Date) {
|
|
24
|
+
value = OneUptimeDate.asDateForDatabaseQuery(value) as T;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return value.toString();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public static override fromJSON<T extends CompareType>(
|
|
31
|
+
json: JSONObject,
|
|
32
|
+
): LessThanOrNull<T> {
|
|
33
|
+
if (json["_type"] === ObjectType.LessThanOrNull) {
|
|
34
|
+
return new LessThanOrNull<T>(json["value"] as T);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
throw new BadDataException("Invalid JSON: " + JSON.stringify(json));
|
|
38
|
+
}
|
|
39
|
+
}
|
package/Types/Date.ts
CHANGED
|
@@ -10,6 +10,24 @@ export const Moment: typeof moment = moment;
|
|
|
10
10
|
|
|
11
11
|
export default class OneUptimeDate {
|
|
12
12
|
// get date time from unix timestamp
|
|
13
|
+
|
|
14
|
+
public static getHoursAndMinutesFromMinutes(minutes: number): string {
|
|
15
|
+
const hours: number = Math.floor(minutes / 60);
|
|
16
|
+
const mins: number = minutes % 60;
|
|
17
|
+
|
|
18
|
+
let formattedString: string = "";
|
|
19
|
+
|
|
20
|
+
if (hours > 0) {
|
|
21
|
+
formattedString += hours + " hours ";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (mins > 0) {
|
|
25
|
+
formattedString += mins + " minutes";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return formattedString.trim() || "0 minutes";
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
public static fromUnixTimestamp(timestamp: number): Date {
|
|
14
32
|
return new Date(timestamp * 1000);
|
|
15
33
|
}
|
package/Types/JSON.ts
CHANGED
|
@@ -28,6 +28,8 @@ import StartAndEndTime from "./Time/StartAndEndTime";
|
|
|
28
28
|
import Version from "./Version";
|
|
29
29
|
import { BaseEntity } from "typeorm";
|
|
30
30
|
import DashboardViewConfig from "./Dashboard/DashboardViewConfig";
|
|
31
|
+
import LessThanOrNull from "./BaseDatabase/LessThanOrNull";
|
|
32
|
+
import GreaterThanOrNull from "./BaseDatabase/GreaterThanOrNull";
|
|
31
33
|
|
|
32
34
|
export enum ObjectType {
|
|
33
35
|
ObjectID = "ObjectID",
|
|
@@ -54,6 +56,8 @@ export enum ObjectType {
|
|
|
54
56
|
Search = "Search",
|
|
55
57
|
GreaterThan = "GreaterThan",
|
|
56
58
|
GreaterThanOrEqual = "GreaterThanOrEqual",
|
|
59
|
+
GreaterThanOrNull = "GreaterThanOrNull",
|
|
60
|
+
LessThanOrNull = "LessThanOrNull",
|
|
57
61
|
LessThan = "LessThan",
|
|
58
62
|
LessThanOrEqual = "LessThanOrEqual",
|
|
59
63
|
Port = "Port",
|
|
@@ -119,6 +123,10 @@ export type JSONValue =
|
|
|
119
123
|
| Array<GreaterThan<CompareType>>
|
|
120
124
|
| GreaterThanOrEqual<CompareType>
|
|
121
125
|
| Array<GreaterThanOrEqual<CompareType>>
|
|
126
|
+
| LessThanOrNull<CompareType>
|
|
127
|
+
| Array<LessThanOrNull<CompareType>>
|
|
128
|
+
| GreaterThanOrNull<CompareType>
|
|
129
|
+
| Array<GreaterThanOrNull<CompareType>>
|
|
122
130
|
| PositiveNumber
|
|
123
131
|
| Array<PositiveNumber>
|
|
124
132
|
| LessThan<CompareType>
|
package/Types/Permission.ts
CHANGED
|
@@ -532,6 +532,8 @@ enum Permission {
|
|
|
532
532
|
DeleteOnCallDutyPolicyUserOverride = "DeleteOnCallDutyPolicyUserOverride",
|
|
533
533
|
ReadOnCallDutyPolicyUserOverride = "ReadOnCallDutyPolicyUserOverride",
|
|
534
534
|
|
|
535
|
+
ReadOnCallDutyPolicyTimeLog = "ReadOnCallDutyPolicyTimeLog",
|
|
536
|
+
|
|
535
537
|
// Resource Permissions (Team Permission)
|
|
536
538
|
CreateProjectOnCallDutyPolicyEscalationRuleUser = "CreateProjectOnCallDutyPolicyEscalationRuleUser",
|
|
537
539
|
EditProjectOnCallDutyPolicyEscalationRuleUser = "EditProjectOnCallDutyPolicyEscalationRuleUser",
|
|
@@ -2424,6 +2426,15 @@ export class PermissionHelper {
|
|
|
2424
2426
|
isAccessControlPermission: false,
|
|
2425
2427
|
},
|
|
2426
2428
|
|
|
2429
|
+
{
|
|
2430
|
+
permission: Permission.ReadOnCallDutyPolicyTimeLog,
|
|
2431
|
+
title: "Create On-Call Policy Time Log",
|
|
2432
|
+
description:
|
|
2433
|
+
"This permission can read on-call policy time log this project.",
|
|
2434
|
+
isAssignableToTenant: true,
|
|
2435
|
+
isAccessControlPermission: false,
|
|
2436
|
+
},
|
|
2437
|
+
|
|
2427
2438
|
{
|
|
2428
2439
|
permission: Permission.CreateOnCallDutyPolicyUserOverride,
|
|
2429
2440
|
title: "Create On-Call Duty Policy User Override",
|
|
@@ -9,6 +9,8 @@ import Includes from "./BaseDatabase/Includes";
|
|
|
9
9
|
import IsNull from "./BaseDatabase/IsNull";
|
|
10
10
|
import LessThan from "./BaseDatabase/LessThan";
|
|
11
11
|
import LessThanOrEqual from "./BaseDatabase/LessThanOrEqual";
|
|
12
|
+
import LessThanOrNull from "./BaseDatabase/LessThanOrNull";
|
|
13
|
+
import GreaterThanOrNull from "./BaseDatabase/GreaterThanOrNull";
|
|
12
14
|
import NotEqual from "./BaseDatabase/NotEqual";
|
|
13
15
|
import NotNull from "./BaseDatabase/NotNull";
|
|
14
16
|
import Search from "./BaseDatabase/Search";
|
|
@@ -54,6 +56,8 @@ const SerializableObjectDictionary: Dictionary<any> = {
|
|
|
54
56
|
[ObjectType.GreaterThanOrEqual]: GreaterThanOrEqual,
|
|
55
57
|
[ObjectType.LessThan]: LessThan,
|
|
56
58
|
[ObjectType.LessThanOrEqual]: LessThanOrEqual,
|
|
59
|
+
[ObjectType.LessThanOrNull]: LessThanOrNull,
|
|
60
|
+
[ObjectType.GreaterThanOrNull]: GreaterThanOrNull,
|
|
57
61
|
[ObjectType.Port]: Port,
|
|
58
62
|
[ObjectType.Hostname]: Hostname,
|
|
59
63
|
[ObjectType.HashedString]: HashedString,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import InBetween from "Common/Types/BaseDatabase/InBetween";
|
|
2
|
+
import TimeRange from "./TimeRange";
|
|
3
|
+
import OneUptimeDate from "Common/Types/Date";
|
|
4
|
+
|
|
5
|
+
export default interface RangeStartAndEndDateTime {
|
|
6
|
+
startAndEndDate?: InBetween<Date> | undefined;
|
|
7
|
+
range: TimeRange;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class RangeStartAndEndDateTimeUtil {
|
|
11
|
+
public static getStartAndEndDate(
|
|
12
|
+
dashboardStartAndEndDate: RangeStartAndEndDateTime,
|
|
13
|
+
): InBetween<Date> {
|
|
14
|
+
const currentDate: Date = OneUptimeDate.getCurrentDate();
|
|
15
|
+
|
|
16
|
+
// 30 mins.
|
|
17
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_THIRTY_MINS) {
|
|
18
|
+
return new InBetween<Date>(
|
|
19
|
+
OneUptimeDate.addRemoveMinutes(currentDate, -30),
|
|
20
|
+
currentDate,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_ONE_HOUR) {
|
|
25
|
+
return new InBetween<Date>(
|
|
26
|
+
OneUptimeDate.addRemoveHours(currentDate, -1),
|
|
27
|
+
currentDate,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// two hours.
|
|
32
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_TWO_HOURS) {
|
|
33
|
+
return new InBetween<Date>(
|
|
34
|
+
OneUptimeDate.addRemoveHours(currentDate, -2),
|
|
35
|
+
currentDate,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// three hours
|
|
40
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_THREE_HOURS) {
|
|
41
|
+
return new InBetween<Date>(
|
|
42
|
+
OneUptimeDate.addRemoveHours(currentDate, -3),
|
|
43
|
+
currentDate,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_ONE_DAY) {
|
|
48
|
+
return new InBetween<Date>(
|
|
49
|
+
OneUptimeDate.addRemoveDays(currentDate, -1),
|
|
50
|
+
currentDate,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// two days .
|
|
55
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_TWO_DAYS) {
|
|
56
|
+
return new InBetween<Date>(
|
|
57
|
+
OneUptimeDate.addRemoveDays(currentDate, -2),
|
|
58
|
+
currentDate,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_ONE_WEEK) {
|
|
63
|
+
return new InBetween<Date>(
|
|
64
|
+
OneUptimeDate.addRemoveDays(currentDate, -7),
|
|
65
|
+
currentDate,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// two weeks.
|
|
70
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_TWO_WEEKS) {
|
|
71
|
+
return new InBetween<Date>(
|
|
72
|
+
OneUptimeDate.addRemoveDays(currentDate, -14),
|
|
73
|
+
currentDate,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_ONE_MONTH) {
|
|
78
|
+
return new InBetween<Date>(
|
|
79
|
+
OneUptimeDate.addRemoveMonths(currentDate, -1),
|
|
80
|
+
currentDate,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// three months.
|
|
85
|
+
if (dashboardStartAndEndDate.range === TimeRange.PAST_THREE_MONTHS) {
|
|
86
|
+
return new InBetween<Date>(
|
|
87
|
+
OneUptimeDate.addRemoveMonths(currentDate, -3),
|
|
88
|
+
currentDate,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// custom
|
|
93
|
+
return (
|
|
94
|
+
dashboardStartAndEndDate.startAndEndDate ||
|
|
95
|
+
new InBetween<Date>(currentDate, currentDate)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
enum Range {
|
|
2
|
+
PAST_THIRTY_MINS = "Past 30 Mins",
|
|
3
|
+
PAST_ONE_HOUR = "Past 1 Hour",
|
|
4
|
+
PAST_TWO_HOURS = "Past 2 Hours",
|
|
5
|
+
PAST_THREE_HOURS = "Past 3 Hours",
|
|
6
|
+
PAST_ONE_DAY = "Past 1 Day",
|
|
7
|
+
PAST_TWO_DAYS = "Past 2 Days",
|
|
8
|
+
PAST_ONE_WEEK = "Past 1 Week",
|
|
9
|
+
PAST_TWO_WEEKS = "Past 2 Weeks",
|
|
10
|
+
PAST_ONE_MONTH = "Past 1 Month",
|
|
11
|
+
PAST_THREE_MONTHS = "Past 3 Months",
|
|
12
|
+
CUSTOM = "Custom",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default Range;
|
|
@@ -62,9 +62,9 @@ export interface ComponentProps<T extends GenericObject> {
|
|
|
62
62
|
pluralLabel: string;
|
|
63
63
|
onClearSelectionClick: () => void;
|
|
64
64
|
buttons: Array<BulkActionButtonSchema<T>>;
|
|
65
|
-
onActionStart?: () => void;
|
|
66
|
-
onActionEnd?: () => void;
|
|
67
|
-
itemToString?: (item: T) => string;
|
|
65
|
+
onActionStart?: (() => void) | undefined;
|
|
66
|
+
onActionEnd?: (() => void) | undefined;
|
|
67
|
+
itemToString?: ((item: T) => string) | undefined;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
const BulkUpdateForm: <T extends GenericObject>(
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { FunctionComponent, ReactElement } from "react";
|
|
2
|
+
import RangeStartAndEndDateTime from "Common/Types/Time/RangeStartAndEndDateTime";
|
|
3
|
+
import StartAndEndDate, {
|
|
4
|
+
StartAndEndDateType,
|
|
5
|
+
} from "Common/UI/Components/Date/StartAndEndDate";
|
|
6
|
+
import InBetween from "Common/Types/BaseDatabase/InBetween";
|
|
7
|
+
import TimeRange from "Common/Types/Time/TimeRange";
|
|
8
|
+
import Dropdown, {
|
|
9
|
+
DropdownOption,
|
|
10
|
+
DropdownValue,
|
|
11
|
+
} from "Common/UI/Components/Dropdown/Dropdown";
|
|
12
|
+
import DropdownUtil from "Common/UI/Utils/Dropdown";
|
|
13
|
+
|
|
14
|
+
export interface ComponentProps {
|
|
15
|
+
value?: RangeStartAndEndDateTime | undefined;
|
|
16
|
+
onChange: (startAndEndDate: RangeStartAndEndDateTime) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DashboardStartAndEndDateEditElement: FunctionComponent<ComponentProps> = (
|
|
20
|
+
props: ComponentProps,
|
|
21
|
+
): ReactElement => {
|
|
22
|
+
const dropdownOptions: DropdownOption[] =
|
|
23
|
+
DropdownUtil.getDropdownOptionsFromEnum(TimeRange);
|
|
24
|
+
const defaultDropdownOption: DropdownOption =
|
|
25
|
+
dropdownOptions.find((option: DropdownOption) => {
|
|
26
|
+
return option.value === TimeRange.PAST_ONE_HOUR;
|
|
27
|
+
}) || dropdownOptions[0]!;
|
|
28
|
+
const selectedDropdownnOption: DropdownOption =
|
|
29
|
+
dropdownOptions.find((option: DropdownOption) => {
|
|
30
|
+
return option.value === props.value?.range;
|
|
31
|
+
}) || defaultDropdownOption;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div>
|
|
35
|
+
<Dropdown
|
|
36
|
+
value={selectedDropdownnOption}
|
|
37
|
+
onChange={(range: DropdownValue | Array<DropdownValue> | null) => {
|
|
38
|
+
props.onChange({
|
|
39
|
+
range: range as TimeRange,
|
|
40
|
+
});
|
|
41
|
+
}}
|
|
42
|
+
options={dropdownOptions}
|
|
43
|
+
/>
|
|
44
|
+
{/* Start and End Date */}
|
|
45
|
+
{props.value?.range === TimeRange.CUSTOM && (
|
|
46
|
+
<StartAndEndDate
|
|
47
|
+
type={StartAndEndDateType.DateTime}
|
|
48
|
+
value={props.value?.startAndEndDate || undefined}
|
|
49
|
+
hideTimeButtons={true}
|
|
50
|
+
onValueChanged={(startAndEndDate: InBetween<Date> | null) => {
|
|
51
|
+
if (startAndEndDate) {
|
|
52
|
+
props.onChange({
|
|
53
|
+
range: TimeRange.CUSTOM,
|
|
54
|
+
startAndEndDate,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
)}
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default DashboardStartAndEndDateEditElement;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React, { FunctionComponent, ReactElement, useState } from "react";
|
|
2
|
+
import RangeStartAndEndDateTime from "Common/Types/Time/RangeStartAndEndDateTime";
|
|
3
|
+
import TimeRange from "Common/Types/Time/TimeRange";
|
|
4
|
+
import OneUptimeDate from "Common/Types/Date";
|
|
5
|
+
import IconProp from "Common/Types/Icon/IconProp";
|
|
6
|
+
import { GetReactElementFunction } from "Common/UI/Types/FunctionTypes";
|
|
7
|
+
import HeaderAlert, {
|
|
8
|
+
HeaderAlertType,
|
|
9
|
+
} from "Common/UI/Components/HeaderAlert/HeaderAlert";
|
|
10
|
+
import ColorSwatch from "Common/Types/ColorSwatch";
|
|
11
|
+
import RangeStartAndEndDateEdit from "./RangeStartAndEndDateEdit";
|
|
12
|
+
import Modal from "../Modal/Modal";
|
|
13
|
+
|
|
14
|
+
export interface ComponentProps {
|
|
15
|
+
dashboardStartAndEndDate: RangeStartAndEndDateTime;
|
|
16
|
+
onChange: (startAndEndDate: RangeStartAndEndDateTime) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DashboardStartAndEndDateView: FunctionComponent<ComponentProps> = (
|
|
20
|
+
props: ComponentProps,
|
|
21
|
+
): ReactElement => {
|
|
22
|
+
const [tempStartAndEndDate, setTempStartAndEndDate] =
|
|
23
|
+
useState<RangeStartAndEndDateTime | null>(null);
|
|
24
|
+
const [showTimeSelectModal, setShowTimeSelectModal] =
|
|
25
|
+
useState<boolean>(false);
|
|
26
|
+
|
|
27
|
+
const isCustomRange: boolean =
|
|
28
|
+
props.dashboardStartAndEndDate.range === TimeRange.CUSTOM;
|
|
29
|
+
|
|
30
|
+
const getContent: GetReactElementFunction = (): ReactElement => {
|
|
31
|
+
const title: string = isCustomRange
|
|
32
|
+
? `${OneUptimeDate.getDateAsLocalFormattedString(
|
|
33
|
+
props.dashboardStartAndEndDate.startAndEndDate?.startValue ||
|
|
34
|
+
OneUptimeDate.getCurrentDate(),
|
|
35
|
+
)} - ${OneUptimeDate.getDateAsLocalFormattedString(
|
|
36
|
+
props.dashboardStartAndEndDate.startAndEndDate?.endValue ||
|
|
37
|
+
OneUptimeDate.getCurrentDate(),
|
|
38
|
+
)}`
|
|
39
|
+
: props.dashboardStartAndEndDate.range;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<HeaderAlert
|
|
44
|
+
icon={IconProp.Clock}
|
|
45
|
+
onClick={() => {
|
|
46
|
+
setTempStartAndEndDate(props.dashboardStartAndEndDate);
|
|
47
|
+
setShowTimeSelectModal(true);
|
|
48
|
+
}}
|
|
49
|
+
title={title}
|
|
50
|
+
alertType={HeaderAlertType.INFO}
|
|
51
|
+
colorSwatch={ColorSwatch.Blue}
|
|
52
|
+
tooltip="Click to change the date and time range of data on this dashboard."
|
|
53
|
+
/>
|
|
54
|
+
{showTimeSelectModal && (
|
|
55
|
+
<Modal
|
|
56
|
+
title="Select Start and End Time"
|
|
57
|
+
onClose={() => {
|
|
58
|
+
setTempStartAndEndDate(null);
|
|
59
|
+
setShowTimeSelectModal(false);
|
|
60
|
+
}}
|
|
61
|
+
onSubmit={() => {
|
|
62
|
+
if (tempStartAndEndDate) {
|
|
63
|
+
props.onChange(tempStartAndEndDate);
|
|
64
|
+
}
|
|
65
|
+
setShowTimeSelectModal(false);
|
|
66
|
+
setTempStartAndEndDate(null);
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<div className="mt-5">
|
|
70
|
+
<RangeStartAndEndDateEdit
|
|
71
|
+
value={tempStartAndEndDate || undefined}
|
|
72
|
+
onChange={(startAndEndDate: RangeStartAndEndDateTime) => {
|
|
73
|
+
setTempStartAndEndDate(startAndEndDate);
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
</Modal>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return <div>{getContent()}</div>;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default DashboardStartAndEndDateView;
|
|
@@ -25,8 +25,8 @@ export interface ComponentProps<T extends GenericObject> {
|
|
|
25
25
|
showFilterModal: boolean;
|
|
26
26
|
onFilterChanged?: undefined | ((filterData: FilterData<T>) => void);
|
|
27
27
|
filterError?: string | undefined;
|
|
28
|
-
onFilterModalClose
|
|
29
|
-
onFilterModalOpen
|
|
28
|
+
onFilterModalClose?: (() => void) | undefined;
|
|
29
|
+
onFilterModalOpen?: (() => void) | undefined;
|
|
30
30
|
isModalLoading?: boolean;
|
|
31
31
|
onFilterRefreshClick?: undefined | (() => void);
|
|
32
32
|
filterData?: FilterData<T> | undefined;
|
|
@@ -399,7 +399,7 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
399
399
|
<Button
|
|
400
400
|
onClick={() => {
|
|
401
401
|
changeFilterData({});
|
|
402
|
-
props.onFilterModalClose();
|
|
402
|
+
props.onFilterModalClose && props.onFilterModalClose();
|
|
403
403
|
}}
|
|
404
404
|
className="font-medium text-gray-900"
|
|
405
405
|
icon={IconProp.Close}
|
|
@@ -421,7 +421,7 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
421
421
|
} by the following criteria:`}
|
|
422
422
|
submitButtonText={`Apply Filters`}
|
|
423
423
|
onClose={() => {
|
|
424
|
-
props.onFilterModalClose();
|
|
424
|
+
props.onFilterModalClose && props.onFilterModalClose();
|
|
425
425
|
}}
|
|
426
426
|
onSubmit={() => {
|
|
427
427
|
setTempFilterDataForModal({});
|
|
@@ -430,7 +430,7 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
430
430
|
...tempFilterDataForModal,
|
|
431
431
|
});
|
|
432
432
|
}
|
|
433
|
-
props.onFilterModalClose();
|
|
433
|
+
props.onFilterModalClose && props.onFilterModalClose();
|
|
434
434
|
}}
|
|
435
435
|
>
|
|
436
436
|
<FiltersForm
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { ReactElement } from "react";
|
|
2
|
+
import GenericObject from "../../../Types/GenericObject";
|
|
3
|
+
import Columns from "./Types/Columns";
|
|
4
|
+
import Table from "./Table";
|
|
5
|
+
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
6
|
+
|
|
7
|
+
export interface ComponentProps<T extends GenericObject> {
|
|
8
|
+
data: Array<T>;
|
|
9
|
+
columns: Columns<T>;
|
|
10
|
+
id: string;
|
|
11
|
+
singularLabel: string;
|
|
12
|
+
pluralLabel: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type TableFunction = <T extends GenericObject>(
|
|
16
|
+
props: ComponentProps<T>,
|
|
17
|
+
) => ReactElement;
|
|
18
|
+
|
|
19
|
+
const LocalTable: TableFunction = <T extends GenericObject>(
|
|
20
|
+
props: ComponentProps<T>,
|
|
21
|
+
): ReactElement => {
|
|
22
|
+
const [currentPage, setCurrentPage] = React.useState<number>(1);
|
|
23
|
+
const [itemsPerPage, setItemsPerPage] = React.useState<number>(10);
|
|
24
|
+
const [sortOrder, setSortOrder] = React.useState<SortOrder>(
|
|
25
|
+
SortOrder.Ascending,
|
|
26
|
+
);
|
|
27
|
+
const [sortBy, setSortBy] = React.useState<keyof T | null>(null);
|
|
28
|
+
|
|
29
|
+
const [dataSlice, setDataSlice] = React.useState<Array<T>>(
|
|
30
|
+
props.data.slice(0, itemsPerPage),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
const startIndex: number = (currentPage - 1) * itemsPerPage;
|
|
35
|
+
const endIndex: number = startIndex + itemsPerPage;
|
|
36
|
+
setDataSlice(props.data.slice(startIndex, endIndex));
|
|
37
|
+
}, [currentPage, itemsPerPage, props.data]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Table
|
|
41
|
+
data={dataSlice}
|
|
42
|
+
columns={props.columns}
|
|
43
|
+
totalItemsCount={props.data.length}
|
|
44
|
+
currentPageNumber={currentPage}
|
|
45
|
+
error={""}
|
|
46
|
+
isLoading={false}
|
|
47
|
+
itemsOnPage={itemsPerPage}
|
|
48
|
+
onNavigateToPage={(pageNumber: number, itemsPerPage: number) => {
|
|
49
|
+
setCurrentPage(pageNumber);
|
|
50
|
+
setItemsPerPage(itemsPerPage);
|
|
51
|
+
}}
|
|
52
|
+
id={props.id}
|
|
53
|
+
disablePagination={false}
|
|
54
|
+
singularLabel={props.singularLabel}
|
|
55
|
+
pluralLabel={props.pluralLabel}
|
|
56
|
+
sortOrder={sortOrder}
|
|
57
|
+
sortBy={sortBy}
|
|
58
|
+
onSortChanged={(sortBy: keyof T | null, sortOrder: SortOrder) => {
|
|
59
|
+
setSortOrder(sortOrder);
|
|
60
|
+
setSortBy(sortBy);
|
|
61
|
+
const sortedData: T[] = [...props.data].sort((a: T, b: T) => {
|
|
62
|
+
if (sortOrder === SortOrder.Ascending) {
|
|
63
|
+
return a[sortBy as keyof T] > b[sortBy as keyof T] ? 1 : -1;
|
|
64
|
+
}
|
|
65
|
+
return a[sortBy as keyof T] < b[sortBy as keyof T] ? 1 : -1;
|
|
66
|
+
});
|
|
67
|
+
setDataSlice(sortedData.slice(0, itemsPerPage));
|
|
68
|
+
setCurrentPage(1);
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default LocalTable;
|
|
@@ -51,8 +51,8 @@ export interface ComponentProps<T extends GenericObject> {
|
|
|
51
51
|
filterError?: string | undefined;
|
|
52
52
|
onFilterChanged?: undefined | ((filterData: FilterData<T>) => void);
|
|
53
53
|
onFilterRefreshClick?: undefined | (() => void);
|
|
54
|
-
onFilterModalClose
|
|
55
|
-
onFilterModalOpen
|
|
54
|
+
onFilterModalClose?: (() => void) | undefined;
|
|
55
|
+
onFilterModalOpen?: (() => void) | undefined;
|
|
56
56
|
filterData?: undefined | FilterData<T>;
|
|
57
57
|
|
|
58
58
|
enableDragAndDrop?: boolean | undefined;
|
|
@@ -61,17 +61,17 @@ export interface ComponentProps<T extends GenericObject> {
|
|
|
61
61
|
onDragDrop?: ((id: string, newIndex: number) => void) | undefined;
|
|
62
62
|
|
|
63
63
|
// bulk actions
|
|
64
|
-
bulkActions
|
|
65
|
-
bulkSelectedItems
|
|
66
|
-
onBulkSelectedItemAdded
|
|
67
|
-
onBulkSelectedItemRemoved
|
|
68
|
-
onBulkSelectAllItems
|
|
69
|
-
onBulkSelectItemsOnCurrentPage
|
|
70
|
-
onBulkClearAllItems
|
|
71
|
-
matchBulkSelectedItemByField
|
|
72
|
-
onBulkActionEnd
|
|
73
|
-
onBulkActionStart
|
|
74
|
-
bulkItemToString
|
|
64
|
+
bulkActions?: BulkActionProps<T> | undefined;
|
|
65
|
+
bulkSelectedItems?: Array<T> | undefined;
|
|
66
|
+
onBulkSelectedItemAdded?: ((item: T) => void) | undefined;
|
|
67
|
+
onBulkSelectedItemRemoved?: ((item: T) => void) | undefined;
|
|
68
|
+
onBulkSelectAllItems?: (() => void) | undefined;
|
|
69
|
+
onBulkSelectItemsOnCurrentPage?: (() => void) | undefined;
|
|
70
|
+
onBulkClearAllItems?: (() => void) | undefined;
|
|
71
|
+
matchBulkSelectedItemByField?: keyof T | undefined; // which field to use to match selected items. For exmaple this could be '_id'
|
|
72
|
+
onBulkActionEnd?: (() => void) | undefined;
|
|
73
|
+
onBulkActionStart?: (() => void) | undefined;
|
|
74
|
+
bulkItemToString?: ((item: T) => string) | undefined;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
type TableFunction = <T extends GenericObject>(
|
|
@@ -81,7 +81,7 @@ type TableFunction = <T extends GenericObject>(
|
|
|
81
81
|
const Table: TableFunction = <T extends GenericObject>(
|
|
82
82
|
props: ComponentProps<T>,
|
|
83
83
|
): ReactElement => {
|
|
84
|
-
const isBulkActionsEnabled: boolean =
|
|
84
|
+
const isBulkActionsEnabled: boolean | undefined =
|
|
85
85
|
props.bulkActions &&
|
|
86
86
|
props.bulkActions.buttons &&
|
|
87
87
|
props.bulkActions.buttons.length > 0;
|
|
@@ -90,7 +90,9 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
90
90
|
const [bulkSelectedItems, setBulkSelectedItems] = useState<Array<T>>([]);
|
|
91
91
|
|
|
92
92
|
useEffect(() => {
|
|
93
|
-
|
|
93
|
+
if (props.bulkSelectedItems) {
|
|
94
|
+
setBulkSelectedItems(props.bulkSelectedItems);
|
|
95
|
+
}
|
|
94
96
|
}, [props.bulkSelectedItems]);
|
|
95
97
|
|
|
96
98
|
let colspan: number = props.columns.length || 0;
|
|
@@ -165,14 +167,17 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
165
167
|
onItemSelected={(item: T) => {
|
|
166
168
|
// set bulk selected items.
|
|
167
169
|
setBulkSelectedItems([...bulkSelectedItems, item]);
|
|
168
|
-
props.onBulkSelectedItemAdded(item);
|
|
170
|
+
props.onBulkSelectedItemAdded?.(item);
|
|
169
171
|
}}
|
|
170
172
|
onItemDeselected={(item: T) => {
|
|
171
173
|
// set bulk selected items.
|
|
174
|
+
if (props.matchBulkSelectedItemByField === undefined) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
172
177
|
const index: number = bulkSelectedItems.findIndex((x: T) => {
|
|
173
178
|
return (
|
|
174
|
-
x[props.matchBulkSelectedItemByField]?.toString() ===
|
|
175
|
-
item[props.matchBulkSelectedItemByField]?.toString()
|
|
179
|
+
x[props.matchBulkSelectedItemByField!]?.toString() ===
|
|
180
|
+
item[props.matchBulkSelectedItemByField!]?.toString()
|
|
176
181
|
);
|
|
177
182
|
});
|
|
178
183
|
|
|
@@ -180,7 +185,7 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
180
185
|
bulkSelectedItems.splice(index, 1);
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
props.onBulkSelectedItemRemoved(item);
|
|
188
|
+
props.onBulkSelectedItemRemoved?.(item);
|
|
184
189
|
}}
|
|
185
190
|
selectedItems={bulkSelectedItems}
|
|
186
191
|
matchBulkSelectedItemByField={props.matchBulkSelectedItemByField}
|
|
@@ -193,6 +198,9 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
193
198
|
|
|
194
199
|
props.data.forEach((item: T) => {
|
|
195
200
|
const index: number = bulkSelectedItems.findIndex((x: T) => {
|
|
201
|
+
if (props.matchBulkSelectedItemByField === undefined) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
196
204
|
return (
|
|
197
205
|
x[props.matchBulkSelectedItemByField]?.toString() ===
|
|
198
206
|
item[props.matchBulkSelectedItemByField]?.toString()
|
|
@@ -224,11 +232,11 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
224
232
|
<BulkUpdateForm
|
|
225
233
|
buttons={props.bulkActions.buttons}
|
|
226
234
|
onClearSelectionClick={() => {
|
|
227
|
-
props.onBulkClearAllItems();
|
|
235
|
+
props.onBulkClearAllItems && props.onBulkClearAllItems();
|
|
228
236
|
setIsAllItemsSelected(false);
|
|
229
237
|
}}
|
|
230
238
|
onSelectAllClick={() => {
|
|
231
|
-
props.onBulkSelectAllItems();
|
|
239
|
+
props.onBulkSelectAllItems && props.onBulkSelectAllItems();
|
|
232
240
|
setIsAllItemsSelected(true);
|
|
233
241
|
}}
|
|
234
242
|
selectedItems={bulkSelectedItems}
|
|
@@ -239,7 +247,7 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
239
247
|
onActionEnd={() => {
|
|
240
248
|
setIsAllItemsSelected(false);
|
|
241
249
|
setBulkSelectedItems([]);
|
|
242
|
-
props.onBulkActionEnd();
|
|
250
|
+
props.onBulkActionEnd && props.onBulkActionEnd();
|
|
243
251
|
}}
|
|
244
252
|
itemToString={props.bulkItemToString}
|
|
245
253
|
/>
|
|
@@ -271,10 +279,11 @@ const Table: TableFunction = <T extends GenericObject>(
|
|
|
271
279
|
isBulkActionsEnabled={isBulkActionsEnabled}
|
|
272
280
|
onAllItemsDeselected={() => {
|
|
273
281
|
setIsAllItemsSelected(false);
|
|
274
|
-
props.onBulkClearAllItems();
|
|
282
|
+
props.onBulkClearAllItems && props.onBulkClearAllItems();
|
|
275
283
|
}}
|
|
276
284
|
onAllItemsOnThePageSelected={() => {
|
|
277
|
-
props.onBulkSelectItemsOnCurrentPage
|
|
285
|
+
props.onBulkSelectItemsOnCurrentPage &&
|
|
286
|
+
props.onBulkSelectItemsOnCurrentPage();
|
|
278
287
|
}}
|
|
279
288
|
isAllItemsOnThePageSelected={isAllItemsOnThePageSelected}
|
|
280
289
|
hasTableItems={props.data.length > 0}
|