diff --git a/src/qqq/components/widgets/components/WidgetDropdownMenu.tsx b/src/qqq/components/widgets/components/WidgetDropdownMenu.tsx index 0bc0b8d..d64e3e9 100644 --- a/src/qqq/components/widgets/components/WidgetDropdownMenu.tsx +++ b/src/qqq/components/widgets/components/WidgetDropdownMenu.tsx @@ -26,7 +26,7 @@ import Icon from "@mui/material/Icon"; import IconButton from "@mui/material/IconButton"; import TextField from "@mui/material/TextField"; import {SxProps} from "@mui/system"; -import {DatePicker, DateValidationError, LocalizationProvider, PickerChangeHandlerContext} from "@mui/x-date-pickers"; +import {DatePicker, DateValidationError, LocalizationProvider, PickerChangeHandlerContext, PickerValidDate} from "@mui/x-date-pickers"; import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; import dayjs from "dayjs"; import {Field, Form, Formik} from "formik"; @@ -34,7 +34,7 @@ import QContext from "QContext"; import colors from "qqq/assets/theme/base/colors"; import MDInput from "qqq/components/legacy/MDInput"; import ValueUtils from "qqq/utils/qqq/ValueUtils"; -import React, {useContext, useState} from "react"; +import React, {useContext, useEffect, useState} from "react"; export interface DropdownOption @@ -110,6 +110,7 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, const [isOpen, setIsOpen] = useState(false); const [value, setValue] = useState(defaultValue); + const [dateValue, setDateValue] = useState(defaultValue); const [inputValue, setInputValue] = useState(""); const [backDisabled, setBackDisabled] = useState(false); @@ -122,6 +123,14 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, setIsOpen(true); }; + useEffect(() => + { + if (type == "DATE_PICKER") + { + handleOnChange(null, defaultValue, null); + } + }, [defaultValue]); + function getSelectedIndex(value: DropdownOption) { let currentIndex = null; @@ -136,9 +145,19 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, return currentIndex; } - const navigateBackAndForth = (event: React.MouseEvent, direction: -1 | 1) => + + const navigateBackAndForth = (event: React.MouseEvent, direction: -1 | 1, type: string) => { event.stopPropagation(); + + if (type == "DATE_PICKER") + { + let currentDate = new Date(dateValue); + currentDate.setDate(currentDate.getDate() + direction); + handleOnChange(null, currentDate, null); + return; + } + let currentIndex = getSelectedIndex(value); if (currentIndex == null) @@ -163,15 +182,26 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, }; - const handleDatePickerOnChange = (value: any, context: PickerChangeHandlerContext) => + const handleDatePickerOnChange = (value: PickerValidDate, context: PickerChangeHandlerContext) => { - handleOnChange(null, {id: value.$d.toLocaleDateString()}, null); + if (value.isValid()) + { + handleOnChange(null, value.toDate(), null); + } }; const handleOnChange = (event: any, newValue: any, reason: string) => { - setValue(newValue); + if (type == "DATE_PICKER") + { + setDateValue(newValue); + newValue = {"id": new Date(newValue).toLocaleDateString()}; + } + else + { + setValue(newValue); + } const isTimeframeCustom = name == "timeframe" && newValue && newValue.id == "custom"; setCustomTimesVisible(isTimeframeCustom); @@ -276,21 +306,27 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, { return ( - doForceOpen(event)}> - - - - + ...sx, + background: "white", + width: "250px", + borderRadius: "0.75rem !important", + border: `1px solid ${colors.grayLines.main}`, + "& *": {cursor: "pointer"} + }} display="flex" alignItems="center" onClick={(event) => doForceOpen(event)}> + {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? 1 : -1, type)} disabled={backDisabled}>navigate_before} + + + + {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? -1 : 1, type)} disabled={forthDisabled}>navigate_next} ); } @@ -339,14 +375,14 @@ function WidgetDropdownMenu({name, type, defaultValue, label, startIcon, width, renderInput={(params: any) => <> doForceOpen(event)}> - {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? 1 : -1)} disabled={backDisabled}>navigate_before} + {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? 1 : -1, type)} disabled={backDisabled}>navigate_before} - {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? -1 : 1)} disabled={forthDisabled}>navigate_next} + {allowBackAndForth && navigateBackAndForth(event, backAndForthInverted ? -1 : 1, type)} disabled={forthDisabled}>navigate_next} } diff --git a/src/qqq/styles/qqq-override-styles.css b/src/qqq/styles/qqq-override-styles.css index b327e62..2b6d772 100644 --- a/src/qqq/styles/qqq-override-styles.css +++ b/src/qqq/styles/qqq-override-styles.css @@ -158,6 +158,7 @@ but we've turned off the click-to-sort function, so remove hand cursor */ white-space: normal; height: auto; } + .MuiDataGrid-filterForm { align-items: flex-end; @@ -173,10 +174,12 @@ but we've turned off the click-to-sort function, so remove hand cursor */ { width: 200px; } + .MuiDataGrid-filterForm .MuiDataGrid-filterFormValueInput { width: 300px; } + .MuiDataGrid-filterForm .MuiDataGrid-filterFormOperatorInput { width: 150px; @@ -187,13 +190,14 @@ but we've turned off the click-to-sort function, so remove hand cursor */ { padding-top: 4px; } + .MuiDataGrid-filterForm .MuiDataGrid-filterFormValueInput .MuiAutocomplete-root .MuiAutocomplete-endAdornment svg { height: 0.625em; } /* fix strange size bug on filter autocompletes */ -.MuiDataGrid-filterForm .MuiDataGrid-filterFormValueInput>.MuiBox-root>.MuiBox-root:has(>.MuiAutocomplete-root) +.MuiDataGrid-filterForm .MuiDataGrid-filterFormValueInput > .MuiBox-root > .MuiBox-root:has(>.MuiAutocomplete-root) { margin-bottom: 0; width: 100%; @@ -208,16 +212,31 @@ but we've turned off the click-to-sort function, so remove hand cursor */ } /* clears the ‘X’ from Internet Explorer */ -input[type=search]::-ms-clear { display: none; width : 0; height: 0; } -input[type=search]::-ms-reveal { display: none; width : 0; height: 0; } +input[type=search]::-ms-clear +{ + display: none; + width: 0; + height: 0; +} + +input[type=search]::-ms-reveal +{ + display: none; + width: 0; + height: 0; +} + /* clears the ‘X’ from Chrome */ input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-results-button, -input[type="search"]::-webkit-search-results-decoration { display: none; } +input[type="search"]::-webkit-search-results-decoration +{ + display: none; +} /* Shrink the big margin-bottom on modal processes */ -.modalProcess>.MuiBox-root>.MuiBox-root +.modalProcess > .MuiBox-root > .MuiBox-root { margin-bottom: 24px; } @@ -270,6 +289,7 @@ input[type="search"]::-webkit-search-results-decoration { display: none; } color: initial !important; border: 1px solid rgb(206, 212, 218); } + .MuiDataGrid-filterForm .MuiAutocomplete-tag .MuiSvgIcon-root { color: initial !important; @@ -287,7 +307,7 @@ input[type="search"]::-webkit-search-results-decoration { display: none; } right: 0.125rem; } -.devDocumentation ul>li +.devDocumentation ul > li { margin-left: 30px; } @@ -640,6 +660,7 @@ input[type="search"]::-webkit-search-results-decoration { display: none; } border: 1px solid #BDBDBD; border-radius: 0.5rem !important; } + .MuiToggleButtonGroup-root .MuiButtonBase-root { text-transform: none; @@ -650,11 +671,19 @@ input[type="search"]::-webkit-search-results-decoration { display: none; } border: none; flex: 1 1 0px; } + .MuiToggleButtonGroup-root .MuiButtonBase-root.Mui-selected { background: rgba(117, 117, 117, 0.20); } + .MuiToggleButtonGroup-root .MuiButtonBase-root.Mui-disabled { border: none; } + +.MuiPickersDay-root.Mui-selected, .MuiPickersDay-root.MuiPickersDay-dayWithMargin:hover +{ + color: white; + background-color: #0062FF !important; +}