feat: date format on weather widget (#1443)

* feat: date format on weather widget

* fix: type check error

* fix: reviewed changes

* fix: reviewed changes
This commit is contained in:
Yossi Hillali
2024-11-08 11:33:03 +02:00
committed by GitHub
parent aa503992af
commit c51c5db3d7
6 changed files with 45 additions and 2 deletions

View File

@@ -12,5 +12,15 @@ export type OldmarrWeatherDefinition = CommonOldmarrWidgetDefinition<
latitude: number;
longitude: number;
};
dateFormat:
| "hide"
| "dddd, MMMM D"
| "dddd, D MMMM"
| "MMM D"
| "D MMM"
| "DD/MM/YYYY"
| "MM/DD/YYYY"
| "DD/MM"
| "MM/DD";
}
>;

View File

@@ -72,6 +72,7 @@ const optionMapping: OptionMapping = {
isFormatFahrenheit: (oldOptions) => oldOptions.displayInFahrenheit,
location: (oldOptions) => oldOptions.location,
showCity: (oldOptions) => oldOptions.displayCityName,
dateFormat: (oldOptions) => (oldOptions.dateFormat === "hide" ? undefined : oldOptions.dateFormat),
},
iframe: {
embedUrl: (oldOptions) => oldOptions.embedUrl,

View File

@@ -1134,6 +1134,10 @@
"forecastDayCount": {
"label": "Amount of forecast days",
"description": "When the widget is not wide enough, less days are shown"
},
"dateFormat": {
"label": "Date Format",
"description": "How the date should look like"
}
},
"kind": {

View File

@@ -115,6 +115,7 @@ const WeeklyForecast = ({ options, weather }: WeatherProps) => {
};
function Forecast({ weather, options }: WeatherProps) {
const dateFormat = options.dateFormat;
return (
<Group className="weather-forecast-days-group" w="100%" justify="space-evenly" wrap="nowrap" pb="2.5cqmin">
{weather.daily.slice(0, options.forecastDayCount).map((dayWeather, index) => (
@@ -136,6 +137,7 @@ function Forecast({ weather, options }: WeatherProps) {
</HoverCard.Target>
<HoverCard.Dropdown>
<WeatherDescription
dateFormat={dateFormat}
time={dayWeather.time}
weatherCode={dayWeather.weatherCode}
maxTemp={getPreferredUnit(dayWeather.maxTemp, options.isFormatFahrenheit)}

View File

@@ -15,6 +15,8 @@ import type { TranslationObject } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import type { TablerIcon } from "@homarr/ui";
import type { WidgetProps } from "../definition";
interface WeatherIconProps {
code: number;
size?: string | number;
@@ -34,6 +36,7 @@ export const WeatherIcon = ({ code, size = 50 }: WeatherIconProps) => {
interface WeatherDescriptionProps {
weatherOnly?: boolean;
dateFormat?: WidgetProps<"weather">["options"]["dateFormat"];
time?: string;
weatherCode: number;
maxTemp?: string;
@@ -42,13 +45,21 @@ interface WeatherDescriptionProps {
/**
* Description Dropdown for a given set of parameters
* @param dateFormat format of the date that will be displayed on the widget
* @param time date that can be formatted by dayjs
* @param weatherCode weather code from api
* @param maxTemp preformatted string for max temperature
* @param minTemp preformatted string for min temperature
* @returns Content for a HoverCard dropdown presenting weather information
*/
export const WeatherDescription = ({ weatherOnly, time, weatherCode, maxTemp, minTemp }: WeatherDescriptionProps) => {
export const WeatherDescription = ({
weatherOnly,
dateFormat,
time,
weatherCode,
maxTemp,
minTemp,
}: WeatherDescriptionProps) => {
const t = useScopedI18n("widget.weather");
const tCommon = useScopedI18n("common");
@@ -60,7 +71,7 @@ export const WeatherDescription = ({ weatherOnly, time, weatherCode, maxTemp, mi
return (
<Stack align="center" gap="0">
<Text fz="24px">{dayjs(time).format("dddd MMMM D YYYY")}</Text>
<Text fz="24px">{dayjs(time).format(dateFormat)}</Text>
<Text fz="16px">{t(`kind.${name}`)}</Text>
<Text fz="16px">{`${tCommon("information.max")}: ${maxTemp}`}</Text>
<Text fz="16px">{`${tCommon("information.min")}: ${minTemp}`}</Text>

View File

@@ -1,4 +1,5 @@
import { IconCloud } from "@tabler/icons-react";
import dayjs from "dayjs";
import { z } from "@homarr/validation";
@@ -17,6 +18,20 @@ export const { definition, componentLoader } = createWidgetDefinition("weather",
longitude: 2.3488,
},
}),
dateFormat: factory.select({
options: [
{ value: "dddd, MMMM D", label: dayjs().format("dddd, MMMM D") },
{ value: "dddd, D MMMM", label: dayjs().format("dddd, D MMMM") },
{ value: "MMM D", label: dayjs().format("MMM D") },
{ value: "D MMM", label: dayjs().format("D MMM") },
{ value: "DD/MM/YYYY", label: dayjs().format("DD/MM/YYYY") },
{ value: "MM/DD/YYYY", label: dayjs().format("MM/DD/YYYY") },
{ value: "DD/MM", label: dayjs().format("DD/MM") },
{ value: "MM/DD", label: dayjs().format("MM/DD") },
],
defaultValue: "dddd, MMMM D",
withDescription: true,
}),
showCity: factory.switch(),
hasForecast: factory.switch(),
forecastDayCount: factory.slider({