mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-02 03:50:35 +08:00
Merge branch 'develop' into GH-4325
This commit is contained in:
commit
6f43b085b0
@ -1,3 +1,8 @@
|
|||||||
|
.custom-time-picker {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.time-options-container {
|
.time-options-container {
|
||||||
.time-options-item {
|
.time-options-item {
|
||||||
margin: 2px 0;
|
margin: 2px 0;
|
||||||
@ -43,7 +48,9 @@
|
|||||||
|
|
||||||
.valid-format-error {
|
.valid-format-error {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
color: var(--bg-cherry-400, #ea6d71);
|
color: var(--bg-cherry-400) !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lightMode {
|
.lightMode {
|
||||||
@ -80,9 +87,4 @@
|
|||||||
color: rgba($color: #000000, $alpha: 0.4);
|
color: rgba($color: #000000, $alpha: 0.4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.valid-format-error {
|
|
||||||
margin-top: 4px;
|
|
||||||
color: var(--bg-cherry-400, #ea6d71);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
import './CustomTimePicker.styles.scss';
|
import './CustomTimePicker.styles.scss';
|
||||||
|
|
||||||
import { Input, Popover, Tooltip } from 'antd';
|
import { Input, Popover, Tooltip, Typography } from 'antd';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { Options } from 'container/TopNav/DateTimeSelection/config';
|
import { Options } from 'container/TopNav/DateTimeSelection/config';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@ -11,8 +11,11 @@ import { CheckCircle, ChevronDown, Clock } from 'lucide-react';
|
|||||||
import { ChangeEvent, useEffect, useState } from 'react';
|
import { ChangeEvent, useEffect, useState } from 'react';
|
||||||
import { popupContainer } from 'utils/selectPopupContainer';
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
|
const maxAllowedMinTimeInMonths = 6;
|
||||||
|
|
||||||
interface CustomTimePickerProps {
|
interface CustomTimePickerProps {
|
||||||
onSelect: (value: string) => void;
|
onSelect: (value: string) => void;
|
||||||
|
onError: (value: boolean) => void;
|
||||||
items: any[];
|
items: any[];
|
||||||
selectedValue: string;
|
selectedValue: string;
|
||||||
selectedTime: string;
|
selectedTime: string;
|
||||||
@ -21,6 +24,7 @@ interface CustomTimePickerProps {
|
|||||||
|
|
||||||
function CustomTimePicker({
|
function CustomTimePicker({
|
||||||
onSelect,
|
onSelect,
|
||||||
|
onError,
|
||||||
items,
|
items,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
selectedTime,
|
selectedTime,
|
||||||
@ -34,6 +38,9 @@ function CustomTimePicker({
|
|||||||
|
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const [inputStatus, setInputStatus] = useState<'' | 'error' | 'success'>('');
|
const [inputStatus, setInputStatus] = useState<'' | 'error' | 'success'>('');
|
||||||
|
const [inputErrorMessage, setInputErrorMessage] = useState<string | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
const [isInputFocused, setIsInputFocused] = useState(false);
|
const [isInputFocused, setIsInputFocused] = useState(false);
|
||||||
|
|
||||||
const getSelectedTimeRangeLabel = (
|
const getSelectedTimeRangeLabel = (
|
||||||
@ -71,6 +78,8 @@ function CustomTimePicker({
|
|||||||
const isValidFormat = /^(\d+)([mhdw])$/.test(inputValue);
|
const isValidFormat = /^(\d+)([mhdw])$/.test(inputValue);
|
||||||
if (isValidFormat) {
|
if (isValidFormat) {
|
||||||
setInputStatus('success');
|
setInputStatus('success');
|
||||||
|
onError(false);
|
||||||
|
setInputErrorMessage(null);
|
||||||
|
|
||||||
const match = inputValue.match(/^(\d+)([mhdw])$/);
|
const match = inputValue.match(/^(\d+)([mhdw])$/);
|
||||||
|
|
||||||
@ -78,6 +87,10 @@ function CustomTimePicker({
|
|||||||
const unit = match[2];
|
const unit = match[2];
|
||||||
|
|
||||||
const currentTime = dayjs();
|
const currentTime = dayjs();
|
||||||
|
const maxAllowedMinTime = currentTime.subtract(
|
||||||
|
maxAllowedMinTimeInMonths,
|
||||||
|
'month',
|
||||||
|
);
|
||||||
let minTime = null;
|
let minTime = null;
|
||||||
|
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
@ -98,9 +111,17 @@ function CustomTimePicker({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
onValidCustomDateChange([minTime, currentTime]);
|
if (minTime && minTime < maxAllowedMinTime) {
|
||||||
|
setInputStatus('error');
|
||||||
|
onError(true);
|
||||||
|
setInputErrorMessage('Please enter time less than 6 months');
|
||||||
|
} else {
|
||||||
|
onValidCustomDateChange([minTime, currentTime]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setInputStatus('error');
|
setInputStatus('error');
|
||||||
|
onError(true);
|
||||||
|
setInputErrorMessage(null);
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
@ -128,6 +149,8 @@ function CustomTimePicker({
|
|||||||
onSelect(value);
|
onSelect(value);
|
||||||
setSelectedTimePlaceholderValue(label);
|
setSelectedTimePlaceholderValue(label);
|
||||||
setInputStatus('');
|
setInputStatus('');
|
||||||
|
onError(false);
|
||||||
|
setInputErrorMessage(null);
|
||||||
setInputValue('');
|
setInputValue('');
|
||||||
hide();
|
hide();
|
||||||
}}
|
}}
|
||||||
@ -153,55 +176,64 @@ function CustomTimePicker({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<div className="custom-time-picker">
|
||||||
placement="bottomRight"
|
<Popover
|
||||||
getPopupContainer={popupContainer}
|
className="timeSelection-input-container"
|
||||||
content={content}
|
placement="bottomRight"
|
||||||
arrow={false}
|
getPopupContainer={popupContainer}
|
||||||
open={open}
|
content={content}
|
||||||
onOpenChange={handleOpenChange}
|
arrow={false}
|
||||||
trigger={['click']}
|
open={open}
|
||||||
style={{
|
onOpenChange={handleOpenChange}
|
||||||
padding: 0,
|
trigger={['click']}
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
className="timeSelection-input"
|
|
||||||
type="text"
|
|
||||||
style={{
|
style={{
|
||||||
minWidth: '120px',
|
padding: 0,
|
||||||
width: '100%',
|
|
||||||
}}
|
}}
|
||||||
status={inputValue && inputStatus === 'error' ? 'error' : ''}
|
>
|
||||||
allowClear={!isInputFocused && selectedTime === 'custom'}
|
<Input
|
||||||
placeholder={
|
className="timeSelection-input"
|
||||||
isInputFocused
|
type="text"
|
||||||
? 'Time Format (1m or 2h or 3d or 4w)'
|
style={{
|
||||||
: selectedTimePlaceholderValue
|
minWidth: '120px',
|
||||||
}
|
width: '100%',
|
||||||
value={inputValue}
|
}}
|
||||||
onFocus={handleFocus}
|
status={inputValue && inputStatus === 'error' ? 'error' : ''}
|
||||||
onBlur={handleBlur}
|
allowClear={!isInputFocused && selectedTime === 'custom'}
|
||||||
onChange={handleInputChange}
|
placeholder={
|
||||||
prefix={
|
isInputFocused
|
||||||
inputValue && inputStatus === 'success' ? (
|
? 'Time Format (1m or 2h or 3d or 4w)'
|
||||||
<CheckCircle size={14} color="#51E7A8" />
|
: selectedTimePlaceholderValue
|
||||||
) : (
|
}
|
||||||
<Tooltip title="Enter time in format (e.g., 1m, 2h, 2d, 4w)">
|
value={inputValue}
|
||||||
<Clock size={14} />
|
onFocus={handleFocus}
|
||||||
</Tooltip>
|
onBlur={handleBlur}
|
||||||
)
|
onChange={handleInputChange}
|
||||||
}
|
prefix={
|
||||||
suffix={
|
inputValue && inputStatus === 'success' ? (
|
||||||
<ChevronDown
|
<CheckCircle size={14} color="#51E7A8" />
|
||||||
size={14}
|
) : (
|
||||||
onClick={(): void => {
|
<Tooltip title="Enter time in format (e.g., 1m, 2h, 3d, 4w)">
|
||||||
setOpen(!open);
|
<Clock size={14} />
|
||||||
}}
|
</Tooltip>
|
||||||
/>
|
)
|
||||||
}
|
}
|
||||||
/>
|
suffix={
|
||||||
</Popover>
|
<ChevronDown
|
||||||
|
size={14}
|
||||||
|
onClick={(): void => {
|
||||||
|
setOpen(!open);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{inputStatus === 'error' && inputErrorMessage && (
|
||||||
|
<Typography.Title level={5} className="valid-format-error">
|
||||||
|
{inputErrorMessage}
|
||||||
|
</Typography.Title>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ function DateTimeSelection({
|
|||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const [formSelector] = Form.useForm();
|
const [formSelector] = Form.useForm();
|
||||||
|
|
||||||
|
const [hasSelectedTimeError, setHasSelectedTimeError] = useState(false);
|
||||||
|
|
||||||
const urlQuery = useUrlQuery();
|
const urlQuery = useUrlQuery();
|
||||||
const searchStartTime = urlQuery.get('startTime');
|
const searchStartTime = urlQuery.get('startTime');
|
||||||
const searchEndTime = urlQuery.get('endTime');
|
const searchEndTime = urlQuery.get('endTime');
|
||||||
@ -292,6 +294,9 @@ function DateTimeSelection({
|
|||||||
onSelect={(value: unknown): void => {
|
onSelect={(value: unknown): void => {
|
||||||
onSelectHandler(value as Time);
|
onSelectHandler(value as Time);
|
||||||
}}
|
}}
|
||||||
|
onError={(hasError: boolean): void => {
|
||||||
|
setHasSelectedTimeError(hasError);
|
||||||
|
}}
|
||||||
selectedTime={selectedTime}
|
selectedTime={selectedTime}
|
||||||
onValidCustomDateChange={(dateTime): void =>
|
onValidCustomDateChange={(dateTime): void =>
|
||||||
onCustomDateHandler(dateTime as DateTimeRangeType)
|
onCustomDateHandler(dateTime as DateTimeRangeType)
|
||||||
@ -319,12 +324,14 @@ function DateTimeSelection({
|
|||||||
</FormContainer>
|
</FormContainer>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<RefreshText
|
{!hasSelectedTimeError && (
|
||||||
{...{
|
<RefreshText
|
||||||
onLastRefreshHandler,
|
{...{
|
||||||
}}
|
onLastRefreshHandler,
|
||||||
refreshButtonHidden={refreshButtonHidden}
|
}}
|
||||||
/>
|
refreshButtonHidden={refreshButtonHidden}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<CustomDateTimeModal
|
<CustomDateTimeModal
|
||||||
visible={customDateTimeVisible}
|
visible={customDateTimeVisible}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user