Skip to content

Commit d5c5464

Browse files
committed
chore: icon added
1 parent 4264851 commit d5c5464

7 files changed

Lines changed: 266 additions & 3 deletions

File tree

Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
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 { useState } from 'react'
18+
import { DayPickerRangeController, isInclusivelyBeforeDay } from 'react-dates'
19+
import CustomizableCalendarDay from 'react-dates/esm/components/CustomizableCalendarDay.js'
20+
import moment, { Moment } from 'moment'
21+
22+
import 'react-dates/initialize'
23+
24+
import { Icon } from '../Icon'
25+
import { customDayStyles, DayPickerCalendarInfoHorizontal, DayPickerRangeControllerPresets, styles } from './constants'
26+
import { DatePickerRangeControllerProps } from './types'
27+
28+
import 'react-dates/lib/css/_datepicker.css'
29+
30+
export const DatePickerRangeController = ({
31+
handlePredefinedRange,
32+
handleApply,
33+
calendar,
34+
calendarInputs,
35+
handleDateInput,
36+
handleDatesChange,
37+
calendarValue,
38+
focusedInput,
39+
handleFocusChange,
40+
}: DatePickerRangeControllerProps) => {
41+
const [showCalendar, setShowCalender] = useState(false)
42+
const onClickApplyTimeChange = () => {
43+
setShowCalender(false)
44+
handleApply()
45+
}
46+
47+
const onClickPredefinedTimeRange = (startDate: Moment, endDate: Moment, endStr: string) => () => {
48+
handlePredefinedRange(startDate, endDate, endStr)
49+
setShowCalender(false)
50+
}
51+
52+
const renderDatePresets = () => (
53+
<div
54+
className="flex left top"
55+
style={{
56+
...styles.PresetDateRangePicker_panel,
57+
...DayPickerCalendarInfoHorizontal,
58+
...{
59+
PresetDateRangePicker_panel: {
60+
padding: '0px',
61+
width: '200px',
62+
height: '100%',
63+
},
64+
...styles.DayPicker__horizontal,
65+
},
66+
}}
67+
>
68+
<div style={{ width: '312px', borderLeft: 'solid 1px var(--N200)', height: '304px', padding: '16px' }}>
69+
<p className="mb-16 fw-6">Pick time range</p>
70+
<div>
71+
<div className="w-100 mb-16">
72+
From
73+
<input
74+
type="text"
75+
className="dc__block w-100 dc__border"
76+
value={calendarInputs.startDate}
77+
onChange={(event) => {
78+
handleDateInput('startDate', event.target.value)
79+
}}
80+
/>
81+
</div>
82+
<div className="w-100 mb-16">
83+
To
84+
<input
85+
type="text"
86+
className="dc__block w-100 dc__border"
87+
value={calendarInputs.endDate}
88+
onChange={(event) => {
89+
handleDateInput('endDate', event.target.value)
90+
}}
91+
/>
92+
</div>
93+
<button type="button" className="cta small" onClick={onClickApplyTimeChange}>
94+
Apply Time Range
95+
</button>
96+
</div>
97+
</div>
98+
<div style={{ width: '220px', padding: '16px', borderLeft: 'solid 1px var(--N200)', height: '304px' }}>
99+
{DayPickerRangeControllerPresets.map(({ text, startDate, endDate, endStr }) => {
100+
const isSelected =
101+
startDate.isSame(calendar.startDate, 'minute') &&
102+
startDate.isSame(calendar.startDate, 'hour') &&
103+
startDate.isSame(calendar.startDate, 'day') &&
104+
endDate.isSame(calendar.endDate, 'day')
105+
let buttonStyles = {
106+
...styles.PresetDateRangePicker_button,
107+
}
108+
if (isSelected) {
109+
buttonStyles = {
110+
...buttonStyles,
111+
...styles.PresetDateRangePicker_button__selected,
112+
}
113+
}
114+
return (
115+
<button
116+
type="button"
117+
key={text}
118+
style={{ ...buttonStyles, textAlign: 'left' }}
119+
onClick={onClickPredefinedTimeRange(startDate, endDate, endStr)}
120+
>
121+
{text}
122+
</button>
123+
)
124+
})}
125+
</div>
126+
</div>
127+
)
128+
129+
return (
130+
<>
131+
<div
132+
data-testid="app-metrics-range-picker-box"
133+
className="flex h-36"
134+
style={{ borderRadius: '4px', border: 'solid 1px var(--N200)' }}
135+
onClick={() => {
136+
setShowCalender(!showCalendar)
137+
}}
138+
>
139+
<p className="cursor" style={{ marginBottom: '0', height: '32px', padding: '5px' }}>
140+
{calendarValue}
141+
</p>
142+
<Icon name="ic-caret-down-small" color="N600" />
143+
</div>
144+
{showCalendar && (
145+
<DayPickerRangeController
146+
startDate={calendar.startDate}
147+
endDate={calendar.endDate}
148+
focusedInput={focusedInput}
149+
onDatesChange={handleDatesChange}
150+
onFocusChange={handleFocusChange}
151+
numberOfMonths={1}
152+
withPortal
153+
renderCalendarInfo={renderDatePresets}
154+
calendarInfoPosition="after"
155+
hideKeyboardShortcutsPanel
156+
isOutsideRange={(day) => !isInclusivelyBeforeDay(day, moment())} // enable past dates
157+
renderCalendarDay={(props) => <CustomizableCalendarDay {...props} {...customDayStyles} />}
158+
onOutsideClick={() => {
159+
setShowCalender(false)
160+
}}
161+
initialVisibleMonth={() => moment().subtract(2, 'd')} //
162+
/>
163+
)}
164+
</>
165+
)
166+
}

src/Shared/Components/DatePicker/constants.ts

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
const selectedStyles = {
17+
import moment from 'moment'
18+
19+
export const selectedStyles = {
1820
background: 'var(--B100)',
1921
color: 'var(--B500)',
2022

@@ -24,7 +26,7 @@ const selectedStyles = {
2426
},
2527
}
2628

27-
const selectedSpanStyles = {
29+
export const selectedSpanStyles = {
2830
background: 'var(--B100)',
2931
color: 'var(--B500)',
3032
hover: {
@@ -33,7 +35,7 @@ const selectedSpanStyles = {
3335
},
3436
}
3537

36-
const hoveredSpanStyles = {
38+
export const hoveredSpanStyles = {
3739
background: 'var(--B100)',
3840
color: 'var(--B500)',
3941
}
@@ -145,3 +147,74 @@ export const DATE_PICKER_IDS = {
145147
MONTH: 'month_picker',
146148
TIME: 'time_picker',
147149
}
150+
151+
export const styles = {
152+
PresetDateRangePicker_panel: {
153+
padding: '0px',
154+
width: '200px',
155+
height: '100%',
156+
},
157+
PresetDateRangePicker_button: {
158+
width: '188px',
159+
background: 'var(--transparent)',
160+
border: 'none',
161+
color: 'var(--N900)',
162+
padding: '8px',
163+
font: 'inherit',
164+
fontWeight: 500,
165+
lineHeight: 'normal',
166+
overflow: 'visible',
167+
cursor: 'pointer',
168+
':active': {
169+
outline: 0,
170+
},
171+
},
172+
DayPicker__horizontal: {
173+
borderRadius: '4px',
174+
},
175+
PresetDateRangePicker_button__selected: {
176+
color: 'var(--B500)',
177+
fontWeight: 600,
178+
background: 'var(--B100)',
179+
outline: 'none',
180+
},
181+
}
182+
183+
export const DayPickerCalendarInfoHorizontal = {
184+
width: '532px',
185+
boxShadow: 'none',
186+
}
187+
188+
export const DayPickerRangeControllerPresets = [
189+
{ text: 'Last 5 minutes', endDate: moment(), startDate: moment().subtract(5, 'minutes'), endStr: 'now-5m' },
190+
{ text: 'Last 30 minutes', endDate: moment(), startDate: moment().subtract(30, 'minutes'), endStr: 'now-30m' },
191+
{ text: 'Last 1 hour', endDate: moment(), startDate: moment().subtract(1, 'hours'), endStr: 'now-1h' },
192+
{ text: 'Last 24 hours', endDate: moment(), startDate: moment().subtract(24, 'hours'), endStr: 'now-24h' },
193+
{ text: 'Last 7 days', endDate: moment(), startDate: moment().subtract(7, 'days'), endStr: 'now-7d' },
194+
{ text: 'Last 1 month', endDate: moment(), startDate: moment().subtract(1, 'months'), endStr: 'now-1M' },
195+
{ text: 'Last 6 months', endDate: moment(), startDate: moment().subtract(6, 'months'), endStr: 'now-6M' },
196+
]
197+
198+
/**
199+
* Returns a string representing the range of dates
200+
* given by the start and end dates. If the end date
201+
* is 'now' and the start date includes 'now',
202+
* it will return the corresponding range from the
203+
* DayPickerRangeControllerPresets array.
204+
* @param startDateStr - the start date string
205+
* @param endDateStr - the end date string
206+
* @returns - a string representing the range of dates
207+
*/
208+
209+
export function getCalendarValue(startDateStr: string, endDateStr: string): string {
210+
let str: string = `${startDateStr} - ${endDateStr}`
211+
if (endDateStr === 'now' && startDateStr.includes('now')) {
212+
const range = DayPickerRangeControllerPresets.find((d) => d.endStr === startDateStr)
213+
if (range) {
214+
str = range.text
215+
} else {
216+
str = `${startDateStr} - ${endDateStr}`
217+
}
218+
}
219+
return str
220+
}

src/Shared/Components/DatePicker/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
export * from './constants'
1818
export { default as DateTimePicker } from './DateTimePicker'
19+
export { DatePickerRangeController } from './DayPickerRangeController'
1920
export * from './MonthlySelect'
2021
export { default as SingleDatePickerComponent } from './SingleDatePickerComponent'
2122
export * from './TimeSelect'

src/Shared/Components/DatePicker/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,16 @@ export interface DateTimePickerProps
143143
*/
144144
onChange: (date: Date) => void
145145
}
146+
147+
export interface DatePickerRangeControllerProps {
148+
calendar
149+
calendarInputs
150+
focusedInput
151+
handleFocusChange
152+
handleDatesChange
153+
handleCalendarInputs?
154+
calendarValue: string
155+
handlePredefinedRange: (start: Moment, end: Moment, endStr: string) => void
156+
handleDateInput: (key: 'startDate' | 'endDate', value: string) => void
157+
handleApply: (...args) => void
158+
}

src/Shared/Components/Icon/Icon.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@ import { ReactComponent as ICDownload } from '@IconsV2/ic-download.svg'
7878
import { ReactComponent as ICEcr } from '@IconsV2/ic-ecr.svg'
7979
import { ReactComponent as ICEdit } from '@IconsV2/ic-edit.svg'
8080
import { ReactComponent as ICEmail } from '@IconsV2/ic-email.svg'
81+
import { ReactComponent as ICEnterFullscreen } from '@IconsV2/ic-enter-fullscreen.svg'
8182
import { ReactComponent as ICEnterpriseFeat } from '@IconsV2/ic-enterprise-feat.svg'
8283
import { ReactComponent as ICEnterpriseTag } from '@IconsV2/ic-enterprise-tag.svg'
8384
import { ReactComponent as ICEnv } from '@IconsV2/ic-env.svg'
8485
import { ReactComponent as ICEnvironment } from '@IconsV2/ic-environment.svg'
8586
import { ReactComponent as ICEnvironmentIsolated } from '@IconsV2/ic-environment-isolated.svg'
8687
import { ReactComponent as ICError } from '@IconsV2/ic-error.svg'
88+
import { ReactComponent as ICExitFullscreen } from '@IconsV2/ic-exit-fullscreen.svg'
8789
import { ReactComponent as ICExpandRightSm } from '@IconsV2/ic-expand-right-sm.svg'
8890
import { ReactComponent as ICExpandSm } from '@IconsV2/ic-expand-sm.svg'
8991
import { ReactComponent as ICFailure } from '@IconsV2/ic-failure.svg'
@@ -321,12 +323,14 @@ export const iconMap = {
321323
'ic-ecr': ICEcr,
322324
'ic-edit': ICEdit,
323325
'ic-email': ICEmail,
326+
'ic-enter-fullscreen': ICEnterFullscreen,
324327
'ic-enterprise-feat': ICEnterpriseFeat,
325328
'ic-enterprise-tag': ICEnterpriseTag,
326329
'ic-env': ICEnv,
327330
'ic-environment-isolated': ICEnvironmentIsolated,
328331
'ic-environment': ICEnvironment,
329332
'ic-error': ICError,
333+
'ic-exit-fullscreen': ICExitFullscreen,
330334
'ic-expand-right-sm': ICExpandRightSm,
331335
'ic-expand-sm': ICExpandSm,
332336
'ic-failure': ICFailure,

0 commit comments

Comments
 (0)