This is an automated email from the ASF dual-hosted git repository. jedcunningham pushed a commit to branch v2-9-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit d5d8b588f72fc8b91a7a5a7a16bcbe4cf82b1fe8 Author: Brent Bovenzi <br...@astronomer.io> AuthorDate: Thu Apr 25 13:21:17 2024 -0400 Add workaround for datetime-local input in firefox (#39261) (cherry picked from commit 5638bc3f502e656b1b3c8b765ad1c84434017b41) --- .../static/js/cluster-activity/nav/FilterBar.tsx | 9 ++- airflow/www/static/js/components/DateTimeInput.tsx | 84 ++++++++++++++++++++++ airflow/www/static/js/dag/nav/FilterBar.tsx | 6 +- 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx b/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx index b4f840cb5f..7e458ab5ab 100644 --- a/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx +++ b/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx @@ -19,7 +19,7 @@ /* global moment */ -import { Box, Button, Flex, Input, Text } from "@chakra-ui/react"; +import { Box, Button, Flex, Text } from "@chakra-ui/react"; import React from "react"; import { useTimezone } from "src/context/timezone"; @@ -29,6 +29,7 @@ import { getDuration, } from "src/datetime_utils"; import useFilters from "src/cluster-activity/useFilters"; +import DateTimeInput from "src/components/DateTimeInput"; const FilterBar = () => { const { filters, onStartDateChange, onEndDateChange, clearFilters } = @@ -61,9 +62,8 @@ const FilterBar = () => { <Text fontSize="sm" as="b" position="absolute" mt="-14px" ml={1}> Start Date </Text> - <Input + <DateTimeInput {...inputStyles} - type="datetime-local" value={formattedStartDate || ""} onChange={(e) => onStartDateChange(e.target.value)} /> @@ -72,9 +72,8 @@ const FilterBar = () => { <Text fontSize="sm" as="b" position="absolute" mt="-14px" ml={1}> End Date </Text> - <Input + <DateTimeInput {...inputStyles} - type="datetime-local" value={formattedEndDate || ""} onChange={(e) => onEndDateChange(e.target.value)} /> diff --git a/airflow/www/static/js/components/DateTimeInput.tsx b/airflow/www/static/js/components/DateTimeInput.tsx new file mode 100644 index 0000000000..1d6b32ef1c --- /dev/null +++ b/airflow/www/static/js/components/DateTimeInput.tsx @@ -0,0 +1,84 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* global moment */ + +import React from "react"; +import { Flex, Input, InputProps } from "@chakra-ui/react"; + +const DateTimeInput = (props: InputProps) => { + // Firefox and safari do not support datetime-local so we need to put a date and time input next to each other + const userAgent = navigator.userAgent.toLowerCase(); + const unsupportedBrowser = + userAgent.includes("firefox") || userAgent.includes("safari"); + + if (!unsupportedBrowser) return <Input type="datetime-local" {...props} />; + + const { value, onChange, ...rest } = props; + // @ts-ignore + let datetime = moment(value as string); + // @ts-ignore + datetime = datetime.isValid() ? datetime : moment(); + // @ts-ignore + const date = moment(datetime).format("YYYY-MM-DD"); + // @ts-ignore + const time = moment(datetime).format("HH:mm:ss"); + return ( + <Flex> + <Input + type="date" + value={date} + onChange={(e) => { + if (onChange) + onChange({ + ...e, + target: { + ...e.target, + value: `${e.target.value}T${time}`, + }, + }); + }} + {...rest} + borderRightWidth={0} + borderRightRadius={0} + paddingInlineEnd={0} + /> + <Input + type="time" + value={time} + onChange={(e) => { + if (onChange) + onChange({ + ...e, + target: { + ...e.target, + value: `${date}T${e.target.value}`, + }, + }); + }} + {...rest} + borderLeftWidth={0} + borderLeftRadius={0} + paddingInlineStart={0} + /> + </Flex> + ); +}; + +export default DateTimeInput; diff --git a/airflow/www/static/js/dag/nav/FilterBar.tsx b/airflow/www/static/js/dag/nav/FilterBar.tsx index f03ea734b8..2a0b356893 100644 --- a/airflow/www/static/js/dag/nav/FilterBar.tsx +++ b/airflow/www/static/js/dag/nav/FilterBar.tsx @@ -19,7 +19,7 @@ /* global moment */ -import { Box, Button, Flex, Input, Select } from "@chakra-ui/react"; +import { Box, Button, Flex, Select } from "@chakra-ui/react"; import MultiSelect from "src/components/MultiSelect"; import React from "react"; import type { DagRun, RunState, TaskState } from "src/types"; @@ -30,6 +30,7 @@ import { useChakraSelectProps } from "chakra-react-select"; import { useTimezone } from "src/context/timezone"; import { isoFormatWithoutTZ } from "src/datetime_utils"; import useFilters from "src/dag/useFilters"; +import DateTimeInput from "src/components/DateTimeInput"; declare const filtersOptions: { dagStates: RunState[]; @@ -124,9 +125,8 @@ const FilterBar = () => { <Flex backgroundColor="blackAlpha.200" p={4} justifyContent="space-between"> <Flex ml={10}> <Box px={2}> - <Input + <DateTimeInput {...inputStyles} - type="datetime-local" value={formattedTime || ""} onChange={(e) => onBaseDateChange(e.target.value)} {...(isBaseDateDefault ? {} : filteredStyles)}