@onewelcome/react-lib-components 8.6.0 → 8.7.0

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 (153) hide show
  1. package/dist/cjs/Button/BaseButton.cjs.js +1 -1
  2. package/dist/cjs/Button/BaseButton.cjs.js.map +1 -1
  3. package/dist/cjs/ContextMenu/ContextMenu.cjs.js +1 -1
  4. package/dist/cjs/ContextMenu/ContextMenu.cjs.js.map +1 -1
  5. package/dist/cjs/DataGrid/DataGridFilters/DataGridDateFilter.cjs.js +2 -0
  6. package/dist/cjs/DataGrid/DataGridFilters/DataGridDateFilter.cjs.js.map +1 -0
  7. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterTag.cjs.js +1 -1
  8. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterTag.cjs.js.map +1 -1
  9. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilters.interfaces.cjs.js.map +1 -1
  10. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbar.cjs.js +1 -1
  11. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbar.cjs.js.map +1 -1
  12. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.cjs.js +2 -0
  13. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.cjs.js.map +1 -0
  14. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.module.scss.cjs.js +2 -0
  15. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.module.scss.cjs.js.map +1 -0
  16. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.cjs.js +2 -0
  17. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.cjs.js.map +1 -0
  18. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.cjs.js +2 -0
  19. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.cjs.js.map +1 -0
  20. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.cjs.js +2 -0
  21. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.cjs.js.map +1 -0
  22. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/SideMenu.cjs.js +2 -0
  23. package/dist/cjs/DataGrid/DataGridFilters/DateTimePicker/SideMenu.cjs.js.map +1 -0
  24. package/dist/cjs/DatePicker/DatePicker.cjs.js +1 -1
  25. package/dist/cjs/DatePicker/DatePicker.cjs.js.map +1 -1
  26. package/dist/cjs/DatePicker/DatePicker.module.scss.cjs.js +1 -1
  27. package/dist/cjs/Form/FormGroup/FormGroup.cjs.js +1 -1
  28. package/dist/cjs/Form/FormGroup/FormGroup.cjs.js.map +1 -1
  29. package/dist/cjs/Form/FormSelectorWrapper/FormSelectorWrapper.cjs.js +1 -1
  30. package/dist/cjs/Form/FormSelectorWrapper/FormSelectorWrapper.cjs.js.map +1 -1
  31. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js +1 -1
  32. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js.map +1 -1
  33. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js +1 -1
  34. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js.map +1 -1
  35. package/dist/cjs/Form/Select/useSelectPositionList.cjs.js +1 -1
  36. package/dist/cjs/Form/Select/useSelectPositionList.cjs.js.map +1 -1
  37. package/dist/cjs/Form/Wrapper/InputWrapper/InputWrapper.cjs.js +1 -1
  38. package/dist/cjs/Form/Wrapper/InputWrapper/InputWrapper.cjs.js.map +1 -1
  39. package/dist/cjs/Form/Wrapper/Wrapper/Wrapper.cjs.js +1 -1
  40. package/dist/cjs/Form/Wrapper/Wrapper/Wrapper.cjs.js.map +1 -1
  41. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridDateFilter.d.ts +9 -0
  42. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridFilterTag.d.ts +2 -1
  43. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridFilters.interfaces.d.ts +10 -1
  44. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridToolbar.d.ts +5 -3
  45. package/dist/cjs/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.d.ts +31 -0
  46. package/dist/cjs/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.d.ts +15 -0
  47. package/dist/cjs/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.d.ts +18 -0
  48. package/dist/cjs/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.d.ts +10 -0
  49. package/dist/cjs/src/components/DataGrid/DataGridFilters/DateTimePicker/SideMenu.d.ts +10 -0
  50. package/dist/cjs/src/components/DataGrid/testUtils.d.ts +7 -1
  51. package/dist/cjs/src/components/DatePicker/DatePicker.d.ts +4 -1
  52. package/dist/cjs/src/components/Form/FormGroup/FormGroup.d.ts +1 -0
  53. package/dist/cjs/src/components/Form/Wrapper/Wrapper/Wrapper.d.ts +1 -0
  54. package/dist/cjs/src/hooks/useClickOutside.cjs.js +2 -0
  55. package/dist/cjs/src/hooks/useClickOutside.cjs.js.map +1 -0
  56. package/dist/cjs/src/hooks/useClickOutside.d.ts +2 -0
  57. package/dist/cjs/src/index.cjs.js +1 -1
  58. package/dist/cjs/src/index.d.ts +1 -0
  59. package/dist/esm/Button/BaseButton.esm.js +5 -2
  60. package/dist/esm/Button/BaseButton.esm.js.map +1 -1
  61. package/dist/esm/ContextMenu/ContextMenu.esm.js +6 -8
  62. package/dist/esm/ContextMenu/ContextMenu.esm.js.map +1 -1
  63. package/dist/esm/ContextMenu/ContextMenuItem.esm.js +3 -3
  64. package/dist/esm/ContextMenu/ContextMenuItem.esm.js.map +1 -1
  65. package/dist/esm/ContextMenu/ContextMenuItem.module.scss.esm.js +2 -2
  66. package/dist/esm/DataGrid/DataGridFilters/DataGridDateFilter.esm.js +35 -0
  67. package/dist/esm/DataGrid/DataGridFilters/DataGridDateFilter.esm.js.map +1 -0
  68. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterTag.esm.js +16 -7
  69. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterTag.esm.js.map +1 -1
  70. package/dist/esm/DataGrid/DataGridFilters/DataGridFilters.interfaces.esm.js.map +1 -1
  71. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbar.esm.js +15 -12
  72. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbar.esm.js.map +1 -1
  73. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.esm.js +138 -0
  74. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.esm.js.map +1 -0
  75. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.module.scss.esm.js +8 -0
  76. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.module.scss.esm.js.map +1 -0
  77. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.esm.js +54 -0
  78. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.esm.js.map +1 -0
  79. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.esm.js +51 -0
  80. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.esm.js.map +1 -0
  81. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.esm.js +29 -0
  82. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.esm.js.map +1 -0
  83. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/SideMenu.esm.js +26 -0
  84. package/dist/esm/DataGrid/DataGridFilters/DateTimePicker/SideMenu.esm.js.map +1 -0
  85. package/dist/esm/DatePicker/DatePicker.esm.js +3 -1
  86. package/dist/esm/DatePicker/DatePicker.esm.js.map +1 -1
  87. package/dist/esm/DatePicker/DatePicker.module.scss.esm.js +2 -2
  88. package/dist/esm/Form/FormGroup/FormGroup.esm.js +2 -2
  89. package/dist/esm/Form/FormGroup/FormGroup.esm.js.map +1 -1
  90. package/dist/esm/Form/FormSelectorWrapper/FormSelectorWrapper.esm.js +1 -1
  91. package/dist/esm/Form/FormSelectorWrapper/FormSelectorWrapper.esm.js.map +1 -1
  92. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js +9 -5
  93. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js.map +1 -1
  94. package/dist/esm/Form/Select/SingleSelect/Select.esm.js +9 -5
  95. package/dist/esm/Form/Select/SingleSelect/Select.esm.js.map +1 -1
  96. package/dist/esm/Form/Select/useSelectPositionList.esm.js +8 -11
  97. package/dist/esm/Form/Select/useSelectPositionList.esm.js.map +1 -1
  98. package/dist/esm/Form/Wrapper/InputWrapper/InputWrapper.esm.js +2 -2
  99. package/dist/esm/Form/Wrapper/InputWrapper/InputWrapper.esm.js.map +1 -1
  100. package/dist/esm/Form/Wrapper/Wrapper/Wrapper.esm.js +2 -2
  101. package/dist/esm/Form/Wrapper/Wrapper/Wrapper.esm.js.map +1 -1
  102. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridDateFilter.d.ts +9 -0
  103. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridFilterTag.d.ts +2 -1
  104. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridFilters.interfaces.d.ts +10 -1
  105. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridToolbar.d.ts +5 -3
  106. package/dist/esm/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.d.ts +31 -0
  107. package/dist/esm/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.d.ts +15 -0
  108. package/dist/esm/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.d.ts +18 -0
  109. package/dist/esm/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.d.ts +10 -0
  110. package/dist/esm/src/components/DataGrid/DataGridFilters/DateTimePicker/SideMenu.d.ts +10 -0
  111. package/dist/esm/src/components/DataGrid/testUtils.d.ts +7 -1
  112. package/dist/esm/src/components/DatePicker/DatePicker.d.ts +4 -1
  113. package/dist/esm/src/components/Form/FormGroup/FormGroup.d.ts +1 -0
  114. package/dist/esm/src/components/Form/Wrapper/Wrapper/Wrapper.d.ts +1 -0
  115. package/dist/esm/src/hooks/useClickOutside.d.ts +2 -0
  116. package/dist/esm/src/hooks/useClickOutside.esm.js +38 -0
  117. package/dist/esm/src/hooks/useClickOutside.esm.js.map +1 -0
  118. package/dist/esm/src/index.d.ts +1 -0
  119. package/dist/esm/src/index.esm.js +1 -0
  120. package/dist/esm/src/index.esm.js.map +1 -1
  121. package/package.json +7 -3
  122. package/src/components/Button/BaseButton.tsx +7 -4
  123. package/src/components/ContextMenu/ContextMenu.tsx +5 -13
  124. package/src/components/DataGrid/DataGridBody/__snapshots__/DataGridBody.test.tsx.snap +4 -4
  125. package/src/components/DataGrid/DataGridFilters/DataGridDateFilter.tsx +65 -0
  126. package/src/components/DataGrid/DataGridFilters/DataGridFilterTag.tsx +25 -5
  127. package/src/components/DataGrid/DataGridFilters/DataGridFilters.interfaces.ts +18 -1
  128. package/src/components/DataGrid/DataGridFilters/DataGridToolbar.tsx +53 -33
  129. package/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.module.scss +134 -0
  130. package/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePicker.tsx +267 -0
  131. package/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerCalendarSection.tsx +103 -0
  132. package/src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimePickerInputSection.tsx +121 -0
  133. package/{dist/esm/src/hooks/useBodyClick.esm.js → src/components/DataGrid/DataGridFilters/DateTimePicker/DateTimeService.ts} +14 -17
  134. package/src/components/DataGrid/DataGridFilters/DateTimePicker/SideMenu.tsx +50 -0
  135. package/src/components/DataGrid/testUtils.ts +48 -15
  136. package/src/components/DatePicker/DatePicker.module.scss +32 -9
  137. package/src/components/DatePicker/DatePicker.tsx +15 -1
  138. package/src/components/Form/FormGroup/FormGroup.tsx +6 -1
  139. package/src/components/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +2 -2
  140. package/src/components/Form/Select/MultiSelect/MultiSelect.tsx +13 -13
  141. package/src/components/Form/Select/SingleSelect/Select.tsx +13 -13
  142. package/src/components/Form/Select/useSelectPositionList.ts +8 -12
  143. package/src/components/Form/Wrapper/InputWrapper/InputWrapper.tsx +2 -0
  144. package/src/components/Form/Wrapper/Wrapper/Wrapper.tsx +3 -0
  145. package/src/hooks/{useBodyClick.ts → useClickOutside.ts} +17 -11
  146. package/src/index.ts +1 -0
  147. package/dist/cjs/src/hooks/useBodyClick.cjs.js +0 -2
  148. package/dist/cjs/src/hooks/useBodyClick.cjs.js.map +0 -1
  149. package/dist/cjs/src/hooks/useBodyClick.d.ts +0 -1
  150. package/dist/esm/src/hooks/useBodyClick.d.ts +0 -1
  151. package/dist/esm/src/hooks/useBodyClick.esm.js.map +0 -1
  152. /package/dist/cjs/src/hooks/{useBodyClick.test.d.ts → useClickOutside.test.d.ts} +0 -0
  153. /package/dist/esm/src/hooks/{useBodyClick.test.d.ts → useClickOutside.test.d.ts} +0 -0
@@ -0,0 +1,267 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React, { useEffect, useState } from "react";
18
+ import { Popover } from "../../../Popover/Popover";
19
+ import classes from "./DateTimePicker.module.scss";
20
+ import { Button } from "../../../Button/Button";
21
+ import { DateRange } from "react-day-picker";
22
+ import {
23
+ CUSTOM_DATE_RANGE,
24
+ FIVE_MINUTES,
25
+ ONE_HOUR,
26
+ ONE_MINUTE,
27
+ THIRTY_SECONDS,
28
+ TWENTY_FOUR_HOURS,
29
+ formatInputDate
30
+ } from "./DateTimeService";
31
+ import { SideMenu } from "./SideMenu";
32
+ import { addSeconds } from "date-fns";
33
+ import { DateTimePickerInputSection } from "./DateTimePickerInputSection";
34
+ import { DateTimePickerCalendarSection } from "./DateTimePickerCalendarSection";
35
+ import { DateTimeFilter, DateTimeFilterType } from "../DataGridFilters.interfaces";
36
+ import { useRepeatFocus } from "../../../../hooks/useRepeatFocus";
37
+
38
+ export type DateTimePickerTranslations = {
39
+ errors: {
40
+ dateFormatError: string;
41
+ };
42
+ previousMonth: string;
43
+ nextMonth: string;
44
+ from: string;
45
+ to: string;
46
+ cancel: string;
47
+ apply: string;
48
+ dateInputPlaceholder: string;
49
+ };
50
+
51
+ export type Props = {
52
+ popoverRef: React.RefObject<HTMLDivElement>;
53
+ anchorRef?: React.RefObject<HTMLDivElement>;
54
+ isOpen: boolean;
55
+ onTagCaptionChange: (value: string) => void;
56
+ setPickerOpen: (open: boolean) => void;
57
+ translations?: DateTimePickerTranslations;
58
+ dateFilterValue?: DateTimeFilter;
59
+ onDateFilterValueChange?: (dateTimeFilter: DateTimeFilter) => void;
60
+ };
61
+
62
+ export type SideMenuItem = {
63
+ id: DateTimeFilterType;
64
+ name: string;
65
+ rangeSeconds?: number;
66
+ };
67
+
68
+ export const dateFormat = "yyyy-mm-dd hh:mm:ss";
69
+
70
+ const sideMenuItems: SideMenuItem[] = [
71
+ { id: THIRTY_SECONDS, name: "Last 30 seconds", rangeSeconds: 30 },
72
+ { id: ONE_MINUTE, name: "Last 1 minute", rangeSeconds: 60 },
73
+ { id: FIVE_MINUTES, name: "Last 5 minutes", rangeSeconds: 300 },
74
+ { id: ONE_HOUR, name: "Last 1 hour", rangeSeconds: 3600 },
75
+ { id: TWENTY_FOUR_HOURS, name: "Last 24 hours", rangeSeconds: 86400 },
76
+ { id: CUSTOM_DATE_RANGE, name: "Custom" }
77
+ ];
78
+
79
+ export const DateTimePicker = ({
80
+ anchorRef,
81
+ popoverRef,
82
+ isOpen,
83
+ setPickerOpen,
84
+ onTagCaptionChange,
85
+ translations = {
86
+ errors: {
87
+ dateFormatError: `The format must be ${dateFormat}`
88
+ },
89
+ previousMonth: "Previous month",
90
+ nextMonth: "Next month",
91
+ from: "From",
92
+ to: "To",
93
+ cancel: "Cancel",
94
+ apply: "Apply",
95
+ dateInputPlaceholder: dateFormat
96
+ },
97
+ dateFilterValue,
98
+ onDateFilterValueChange
99
+ }: Props) => {
100
+ const {
101
+ errors: { dateFormatError },
102
+ previousMonth,
103
+ nextMonth,
104
+ cancel,
105
+ from,
106
+ to,
107
+ apply,
108
+ dateInputPlaceholder
109
+ } = translations;
110
+ const [selectedDate, setSelectedDate] = useState<DateRange>({
111
+ from: dateFilterValue?.fromDate ? new Date(dateFilterValue?.fromDate) : undefined,
112
+ to: dateFilterValue?.toDate ? new Date(dateFilterValue?.toDate) : undefined
113
+ });
114
+ const [selectedPredefinedRange, setSelectedPredefinedRange] = useState<DateTimeFilterType>(
115
+ sideMenuItems[0].id
116
+ );
117
+ const [fromDateText, setFromDateText] = useState("");
118
+ const [toDateText, setToDateText] = useState("");
119
+ const [fromDateError, setFromDateError] = useState("");
120
+ const [toDateError, setToDateError] = useState("");
121
+ useRepeatFocus(popoverRef);
122
+
123
+ const disableDateRangePickers = selectedPredefinedRange !== CUSTOM_DATE_RANGE;
124
+
125
+ useEffect(() => {
126
+ if (isOpen) {
127
+ popoverRef.current?.focus();
128
+ }
129
+ }, [isOpen]);
130
+
131
+ useEffect(() => {
132
+ if (dateFilterValue) {
133
+ const foundItem = sideMenuItems.find(item => item.id === dateFilterValue.type);
134
+
135
+ foundItem && onTagCaptionChange(foundItem.name);
136
+
137
+ setSelectedPredefinedRange(dateFilterValue.type);
138
+
139
+ if (foundItem?.rangeSeconds && dateFilterValue.type !== CUSTOM_DATE_RANGE) {
140
+ const fromDate = addSeconds(new Date(), -foundItem.rangeSeconds);
141
+ const toDate = new Date();
142
+
143
+ setFromDateText(formatInputDate(fromDate));
144
+ setToDateText(formatInputDate(toDate));
145
+ setSelectedDate({ from: fromDate, to: toDate });
146
+
147
+ return;
148
+ }
149
+
150
+ dateFilterValue.fromDate &&
151
+ setFromDateText(formatInputDate(new Date(dateFilterValue.fromDate)));
152
+
153
+ dateFilterValue.toDate && setToDateText(formatInputDate(new Date(dateFilterValue.toDate)));
154
+
155
+ setSelectedDate({
156
+ from: dateFilterValue?.fromDate ? new Date(dateFilterValue?.fromDate) : undefined,
157
+ to: dateFilterValue?.toDate ? new Date(dateFilterValue?.toDate) : undefined
158
+ });
159
+ }
160
+ }, [dateFilterValue]);
161
+
162
+ useEffect(() => {
163
+ if (!dateFilterValue) {
164
+ isOpen && onSideMenuItemSelect(selectedPredefinedRange);
165
+ }
166
+ }, [isOpen, dateFilterValue]);
167
+
168
+ const onSideMenuItemSelect = (itemId: DateTimeFilterType) => {
169
+ setSelectedPredefinedRange(itemId);
170
+ const foundItem = sideMenuItems.find(item => item.id === itemId);
171
+ foundItem && onTagCaptionChange(foundItem.name);
172
+
173
+ if (itemId !== CUSTOM_DATE_RANGE) {
174
+ if (!foundItem) {
175
+ return;
176
+ }
177
+
178
+ if (foundItem.rangeSeconds) {
179
+ const fromDate = addSeconds(new Date(), -foundItem.rangeSeconds);
180
+ const toDate = new Date();
181
+
182
+ setSelectedDate({ from: fromDate, to: toDate });
183
+ setFromDateText(formatInputDate(fromDate));
184
+ setToDateText(formatInputDate(toDate));
185
+ }
186
+ }
187
+ };
188
+
189
+ const closeDateTimePicker = () => {
190
+ setPickerOpen(false);
191
+ };
192
+
193
+ const saveDateTimePicker = () => {
194
+ onDateFilterValueChange &&
195
+ onDateFilterValueChange({
196
+ toDate: selectedDate.to?.toISOString() ?? "",
197
+ fromDate: selectedDate.from?.toISOString() ?? "",
198
+ type: selectedPredefinedRange
199
+ });
200
+ setPickerOpen(false);
201
+ };
202
+
203
+ return (
204
+ <Popover
205
+ tabIndex={-1}
206
+ anchorEl={anchorRef}
207
+ ref={popoverRef}
208
+ show={isOpen}
209
+ placement={{ horizontal: "left", vertical: "bottom" }}
210
+ transformOrigin={{ horizontal: "left", vertical: "top" }}
211
+ >
212
+ {isOpen && (
213
+ <div className={classes["popover"]}>
214
+ <div className={classes["content-wrapper"]}>
215
+ <div className={classes["aside"]}>
216
+ <SideMenu
217
+ sideMenuItems={sideMenuItems}
218
+ selectedItemId={selectedPredefinedRange}
219
+ onItemSelect={onSideMenuItemSelect}
220
+ />
221
+ </div>
222
+ <div
223
+ className={`${classes["controls"]} ${toDateError || fromDateError ? classes["has-error"] : ""}`}
224
+ >
225
+ <div className={classes["controls-panel"]}>
226
+ <DateTimePickerInputSection
227
+ from={from}
228
+ to={to}
229
+ dateInputPlaceholder={dateInputPlaceholder}
230
+ dateFormatError={dateFormatError}
231
+ fromDateText={fromDateText}
232
+ toDateText={toDateText}
233
+ fromDateError={fromDateError}
234
+ toDateError={toDateError}
235
+ setSelectedDate={setSelectedDate}
236
+ setFromDateText={setFromDateText}
237
+ setToDateText={setToDateText}
238
+ setFromDateError={setFromDateError}
239
+ setToDateError={setToDateError}
240
+ />
241
+ </div>
242
+ <div className={`${classes["controls-panel"]} ${classes["set-height"]}`}>
243
+ <DateTimePickerCalendarSection
244
+ previousMonth={previousMonth}
245
+ nextMonth={nextMonth}
246
+ selectedDate={selectedDate}
247
+ disableDateRangePickers={disableDateRangePickers}
248
+ setSelectedDate={setSelectedDate}
249
+ setFromDateText={setFromDateText}
250
+ setFromDateError={setFromDateError}
251
+ setToDateText={setToDateText}
252
+ setToDateError={setToDateError}
253
+ />
254
+ </div>
255
+ </div>
256
+ </div>
257
+ <div className={classes["actions"]}>
258
+ <Button variant="text" onClick={closeDateTimePicker}>
259
+ {cancel}
260
+ </Button>
261
+ <Button onClick={saveDateTimePicker}>{apply}</Button>
262
+ </div>
263
+ </div>
264
+ )}
265
+ </Popover>
266
+ );
267
+ };
@@ -0,0 +1,103 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React from "react";
18
+ import classes from "./DateTimePicker.module.scss";
19
+ import { DatePicker } from "../../../DatePicker/DatePicker";
20
+ import { IconButton } from "../../../Button/IconButton";
21
+ import { DateRange } from "react-day-picker";
22
+ import { formatInputDate, getMonthName, getYearFromDate } from "./DateTimeService";
23
+ import { Icon, Icons } from "../../../Icon/Icon";
24
+ import { Typography } from "../../../Typography/Typography";
25
+
26
+ type Props = {
27
+ previousMonth: string;
28
+ nextMonth: string;
29
+ selectedDate: DateRange | undefined;
30
+ disableDateRangePickers: boolean;
31
+ setSelectedDate: React.Dispatch<React.SetStateAction<DateRange>>;
32
+ setFromDateText: React.Dispatch<React.SetStateAction<string>>;
33
+ setToDateText: React.Dispatch<React.SetStateAction<string>>;
34
+ setFromDateError: React.Dispatch<React.SetStateAction<string>>;
35
+ setToDateError: React.Dispatch<React.SetStateAction<string>>;
36
+ };
37
+
38
+ export const DateTimePickerCalendarSection = ({
39
+ previousMonth,
40
+ nextMonth,
41
+ selectedDate,
42
+ disableDateRangePickers,
43
+ setSelectedDate,
44
+ setFromDateText,
45
+ setFromDateError,
46
+ setToDateError,
47
+ setToDateText
48
+ }: Props) => {
49
+ const onDatePickerSelect = (date: Date | DateRange | undefined): void => {
50
+ if (date) {
51
+ setSelectedDate(date as DateRange);
52
+
53
+ const fromDate = (date as DateRange).from;
54
+ const toDate = (date as DateRange).to;
55
+
56
+ if (fromDate) {
57
+ setFromDateText(formatInputDate(fromDate));
58
+ setFromDateError("");
59
+ }
60
+
61
+ if (toDate) {
62
+ setToDateText(formatInputDate(toDate));
63
+ setToDateError("");
64
+ }
65
+ }
66
+ };
67
+ return (
68
+ <DatePicker
69
+ onSelect={onDatePickerSelect}
70
+ value={selectedDate}
71
+ disabled={disableDateRangePickers}
72
+ mode={"range"}
73
+ components={{
74
+ Nav: ({ onNextClick, onPreviousClick }) => (
75
+ <div className={classes["nav"]}>
76
+ <IconButton
77
+ title={previousMonth}
78
+ onClick={onPreviousClick}
79
+ className={classes["prev-button"]}
80
+ disabled={disableDateRangePickers}
81
+ >
82
+ <Icon size="0.75rem" icon={Icons.ChevronLeft} />
83
+ </IconButton>
84
+ <IconButton
85
+ title={nextMonth}
86
+ onClick={onNextClick}
87
+ className={classes["next-button"]}
88
+ disabled={disableDateRangePickers}
89
+ >
90
+ <Icon size="0.75rem" icon={Icons.ChevronRight} />
91
+ </IconButton>
92
+ </div>
93
+ ),
94
+ MonthCaption: ({ calendarMonth }) => (
95
+ <Typography className={classes["month-caption"]} variant="body">
96
+ {getMonthName(calendarMonth.date)} {getYearFromDate(calendarMonth.date)}
97
+ </Typography>
98
+ )
99
+ }}
100
+ numberOfMonths={2}
101
+ />
102
+ );
103
+ };
@@ -0,0 +1,121 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React, { Fragment } from "react";
18
+ import { InputWrapper } from "../../../Form/Wrapper/InputWrapper/InputWrapper";
19
+ import classes from "./DateTimePicker.module.scss";
20
+ import { parse } from "date-fns";
21
+ import { DateRange } from "react-day-picker";
22
+
23
+ export type Props = {
24
+ from: string;
25
+ to: string;
26
+ dateInputPlaceholder: string;
27
+ dateFormatError: string;
28
+ fromDateText: string;
29
+ toDateText: string;
30
+ fromDateError: string;
31
+ toDateError: string;
32
+ setSelectedDate: React.Dispatch<React.SetStateAction<DateRange>>;
33
+ setFromDateText: React.Dispatch<React.SetStateAction<string>>;
34
+ setToDateText: React.Dispatch<React.SetStateAction<string>>;
35
+ setFromDateError: React.Dispatch<React.SetStateAction<string>>;
36
+ setToDateError: React.Dispatch<React.SetStateAction<string>>;
37
+ };
38
+
39
+ export const DateTimePickerInputSection = ({
40
+ from,
41
+ to,
42
+ dateInputPlaceholder,
43
+ dateFormatError,
44
+ toDateText,
45
+ fromDateText,
46
+ fromDateError,
47
+ toDateError,
48
+ setSelectedDate,
49
+ setFromDateText,
50
+ setToDateText,
51
+ setFromDateError,
52
+ setToDateError
53
+ }: Props) => {
54
+ const dateParseTemplate = "yyyy-MM-dd HH:mm:ss";
55
+ const parseDate = (date: string) => {
56
+ const dateText = parse(date, dateParseTemplate, new Date());
57
+ return dateText;
58
+ };
59
+
60
+ const validationRegex =
61
+ /^(\d{4})-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01]) ([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)$/;
62
+ const validateInput = (text: string) => validationRegex.test(text);
63
+
64
+ const onInputBlur =
65
+ (setError: (value: React.SetStateAction<string>) => void, setDate: (value: string) => void) =>
66
+ (e: React.FocusEvent<HTMLInputElement, Element>) => {
67
+ if (!validateInput(e.target.value)) {
68
+ setError(dateFormatError);
69
+ return;
70
+ }
71
+
72
+ setDate(e.target.value);
73
+ setError("");
74
+ };
75
+
76
+ const setFromDate = (value: string) =>
77
+ setSelectedDate(prev => ({ ...prev, from: parseDate(value) }));
78
+
79
+ const setToDate = (value: string) =>
80
+ setSelectedDate(prev => ({ from: prev?.from, to: parseDate(value) }));
81
+
82
+ const onFromInputBlur = onInputBlur(setFromDateError, setFromDate);
83
+ const onToInputBlur = onInputBlur(setToDateError, setToDate);
84
+
85
+ return (
86
+ <Fragment>
87
+ <InputWrapper
88
+ label={from}
89
+ name="fromDate"
90
+ error={!!fromDateError}
91
+ errorMessage={fromDateError}
92
+ errorMessageProps={{ className: classes["error-message"] }}
93
+ helperProps={{
94
+ style: { fontSize: "0.625rem" }
95
+ }}
96
+ type="text"
97
+ value={fromDateText}
98
+ onBlur={onFromInputBlur}
99
+ onChange={e => setFromDateText(e.target.value)}
100
+ inputProps={{ style: { height: "2rem" }, placeholder: dateInputPlaceholder }}
101
+ className={classes["input"]}
102
+ />
103
+ <InputWrapper
104
+ className={classes["input"]}
105
+ inputProps={{ style: { height: "2rem" }, placeholder: dateInputPlaceholder }}
106
+ label={to}
107
+ value={toDateText}
108
+ error={!!toDateError}
109
+ errorMessage={toDateError}
110
+ errorMessageProps={{ className: classes["error-message"] }}
111
+ helperProps={{
112
+ style: { fontSize: "0.625rem" }
113
+ }}
114
+ onChange={e => setToDateText(e.target.value)}
115
+ onBlur={onToInputBlur}
116
+ name="toDate"
117
+ type="text"
118
+ />
119
+ </Fragment>
120
+ );
121
+ };
@@ -1,5 +1,3 @@
1
- import { useEffect } from 'react';
2
-
3
1
  /*
4
2
  * Copyright 2022 OneWelcome B.V.
5
3
  *
@@ -15,19 +13,18 @@ import { useEffect } from 'react';
15
13
  * See the License for the specific language governing permissions and
16
14
  * limitations under the License.
17
15
  */
18
- const useBodyClick = (checkFunction, callbackFunction, dependingStateVariable) => {
19
- function bodyClickListener(event) {
20
- if (checkFunction(event)) {
21
- callbackFunction();
22
- }
23
- }
24
- useEffect(() => {
25
- window.addEventListener("click", bodyClickListener);
26
- return () => {
27
- window.removeEventListener("click", bodyClickListener);
28
- };
29
- }, [dependingStateVariable]);
30
- };
31
16
 
32
- export { useBodyClick };
33
- //# sourceMappingURL=useBodyClick.esm.js.map
17
+ import { format, Locale } from "date-fns";
18
+
19
+ export const THIRTY_SECONDS = "THIRTY_SECONDS";
20
+ export const ONE_MINUTE = "ONE_MINUTE";
21
+ export const FIVE_MINUTES = "FIVE_MINUTES";
22
+ export const ONE_HOUR = "ONE_HOUR";
23
+ export const TWENTY_FOUR_HOURS = "TWENTY_FOUR_HOURS";
24
+ export const CUSTOM_DATE_RANGE = "CUSTOM";
25
+
26
+ export const getMonthName = (date: Date, locale?: Locale) => format(date, "MMMM", { locale });
27
+
28
+ export const getYearFromDate = (date: Date) => format(date, "yyyy");
29
+
30
+ export const formatInputDate = (date: Date) => format(date, "yyyy-MM-dd HH:mm:ss");
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright 2022 OneWelcome B.V.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React from "react";
18
+ import classes from "./DateTimePicker.module.scss";
19
+ import contextMenuItemClasses from "../../../ContextMenu/ContextMenuItem.module.scss";
20
+ import { SideMenuItem } from "./DateTimePicker";
21
+ import { DateTimeFilterType } from "../DataGridFilters.interfaces";
22
+
23
+ type Props = {
24
+ sideMenuItems: SideMenuItem[];
25
+ selectedItemId: string;
26
+ onItemSelect: (id: DateTimeFilterType) => void;
27
+ };
28
+
29
+ export const SideMenu = ({ sideMenuItems, selectedItemId, onItemSelect }: Props) => {
30
+ return (
31
+ <ul className={classes["aside-menu"]}>
32
+ {sideMenuItems.map(item => (
33
+ <li
34
+ key={item.id}
35
+ role="none"
36
+ className={`${contextMenuItemClasses["context-menu-item"]} ${classes["aside-menu-item"]}`}
37
+ >
38
+ <button
39
+ role="menuitem"
40
+ style={{ height: "2rem" }}
41
+ className={selectedItemId === item.id ? contextMenuItemClasses["active"] : undefined}
42
+ onClick={() => onItemSelect(item.id)}
43
+ >
44
+ {item.name}
45
+ </button>
46
+ </li>
47
+ ))}
48
+ </ul>
49
+ );
50
+ };
@@ -15,8 +15,9 @@
15
15
  */
16
16
 
17
17
  import { useEffect, useState } from "react";
18
- import { Filter } from "./DataGridFilters/DataGridFilters.interfaces";
18
+ import { DateTimeFilter, Filter } from "./DataGridFilters/DataGridFilters.interfaces";
19
19
  import { useFiltersReducer } from "./DataGridFilters/useFiltersReducer";
20
+ import { isWithinInterval } from "date-fns";
20
21
 
21
22
  type OperatorPredicateMap<TOperator extends string> = {
22
23
  [op in TOperator]: (v1: string, v2: string) => boolean;
@@ -47,10 +48,26 @@ export const useMockFilteringLogic = <T extends { [k: string]: string }>(
47
48
 
48
49
  const [gridData, setGridData] = useState(data);
49
50
 
51
+ const filterRow = (row: T) => {
52
+ let shouldBeDiscarded: boolean[] = [];
53
+ state.filters.forEach(filter => {
54
+ const reduce = filter.operator == "is" ? reduceDisjunction : reduceConjunction;
55
+ const operatorPredicate = operatorPredicateMap[filter.operator];
56
+ shouldBeDiscarded = [
57
+ ...shouldBeDiscarded,
58
+ !reduce(filter.value, val => operatorPredicate(row[filter.column], val))
59
+ ];
60
+ });
61
+
62
+ return shouldBeDiscarded.length > 0 && shouldBeDiscarded.reduce((acc, val) => acc || val, false)
63
+ ? undefined
64
+ : row;
65
+ };
66
+
50
67
  useEffect(() => {
51
68
  const filteredData = data.map(filterRow).filter(val => {
52
69
  return val !== undefined;
53
- });
70
+ }) as T[];
54
71
  setGridData(filteredData);
55
72
  }, [state.filters]);
56
73
 
@@ -63,20 +80,36 @@ export const useMockFilteringLogic = <T extends { [k: string]: string }>(
63
80
  setGridData,
64
81
  filters: state.filters
65
82
  };
83
+ };
66
84
 
67
- function filterRow(row: T) {
68
- let shouldBeDiscarded: boolean[] = [];
69
- state.filters.forEach(filter => {
70
- const reduce = filter.operator == "is" ? reduceDisjunction : reduceConjunction;
71
- const operatorPredicate = operatorPredicateMap[filter.operator];
72
- shouldBeDiscarded = [
73
- ...shouldBeDiscarded,
74
- !reduce(filter.value, val => operatorPredicate(row[filter.column], val))
75
- ];
85
+ export const useMockFilteringByDateLogic = <T extends { [k: string]: string | Date }>(
86
+ data: T[],
87
+ dateFieldKey: string,
88
+ filterValue: DateTimeFilter | undefined
89
+ ) => {
90
+ const [gridData, setGridData] = useState(data);
91
+
92
+ const filterRowByDateRange = (date: string | Date, fromDate: string, toDate: string): boolean => {
93
+ return isWithinInterval(new Date(date), {
94
+ start: new Date(fromDate),
95
+ end: new Date(toDate)
76
96
  });
97
+ };
77
98
 
78
- return shouldBeDiscarded.length > 0 && shouldBeDiscarded.reduce((acc, val) => acc || val, false)
79
- ? undefined
80
- : row;
81
- }
99
+ useEffect(() => {
100
+ if (filterValue) {
101
+ const fromDate = filterValue.fromDate;
102
+ const toDate = filterValue.toDate;
103
+
104
+ const filteredData = data.filter(item =>
105
+ filterRowByDateRange(item[dateFieldKey], fromDate, toDate)
106
+ );
107
+ setGridData(filteredData);
108
+ }
109
+ }, [filterValue, data]);
110
+
111
+ return {
112
+ gridData,
113
+ setGridData
114
+ };
82
115
  };