From 79dca8bf1f938f3fe7fe05f3e679e8f65ff74a23 Mon Sep 17 00:00:00 2001 From: MenamAfzal Date: Fri, 6 Sep 2024 14:50:58 +0500 Subject: [PATCH 1/4] function calculation reverted --- .../src/comps/comps/dateComp/dateComp.tsx | 274 +++--------------- .../src/comps/comps/dateComp/timeComp.tsx | 163 ++--------- 2 files changed, 71 insertions(+), 366 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx index 3b3e637c5..41aad24fa 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx @@ -1,8 +1,6 @@ import _, { noop } from "lodash"; import dayjs from "dayjs"; import utc from 'dayjs/plugin/utc'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import timezone from 'dayjs/plugin/timezone'; import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core"; import { BoolCodeControl, @@ -56,8 +54,6 @@ import { timeZoneOptions } from "./timeZone"; dayjs.extend(utc); -dayjs.extend(timezone); -dayjs.extend(customParseFormat); const EventOptions = [changeEvent, focusEvent, blurEvent] as const; @@ -473,57 +469,21 @@ export const DatePickerComp = withExposingConfigs(datePickerControl, [ depsConfig({ name: "value", desc: trans("export.datePickerValueDesc"), - depKeys: ["value", "showTime", "timeZone", "userTimeZone"], + depKeys: ["value", "showTime"], func: (input) => { - - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.value, format).isValid()) { - mom = dayjs.utc(input.value, format); - break; - } - } - - if (!input.showTime && mom?.hour() === 0 && mom?.minute() === 0 && mom?.second() === 0) { - mom = mom?.hour(12); // Default to noon to avoid day shift - } - - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; - const formattedDate = mom.tz(tz).format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT); - return formattedDate; - } - - return null; + const mom = Boolean(input.value) ? dayjs(input.value, DateParser) : null; + return mom?.isValid() ? mom.format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT) : null; }, }), - depsConfig({ name: "formattedValue", desc: trans("export.datePickerFormattedValueDesc"), - depKeys: ["value", "format", "timeZone", "userTimeZone"], - + depKeys: ["value", "format"], func: (input) => { - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.value, format).isValid()) { - mom = dayjs.utc(input.value, format); - break; - } - } - if (!input.showTime && mom?.hour() === 0 && mom?.minute() === 0 && mom?.second() === 0) { - mom = mom?.hour(12); // Default to noon to avoid timezone-related day shifts - } - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; - const formattedTime = mom.tz(tz).format(input.format); - return formattedTime; - } - return ''; + const mom = Boolean(input.value) ? dayjs(input.value, DateParser) : null; + return mom?.isValid() ? mom.format(input.format) : ""; }, }), - - depsConfig({ name: "timestamp", desc: trans("export.datePickerTimestampDesc"), @@ -560,235 +520,89 @@ export let DateRangeComp = withExposingConfigs(dateRangeControl, [ depsConfig({ name: "start", desc: trans("export.dateRangeStartDesc"), - depKeys: ["start", "showTime", "timeZone", "userRangeTimeZone"], + depKeys: ["start", "showTime"], func: (input) => { - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.start, format).isValid()) { - mom = dayjs.utc(input.start, format); - break; - } - } - if (!input.showTime && mom?.hour() === 0 && mom?.minute() === 0 && mom?.second() === 0) { - mom = mom?.hour(12); - } - - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - const formattedStart = mom.tz(tz).format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT); - return formattedStart; - } - return null; + const mom = Boolean(input.start) ? dayjs(input.start, DateParser): null; + return mom?.isValid() ? mom.format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT) : null; }, }), - depsConfig({ name: "end", desc: trans("export.dateRangeEndDesc"), - depKeys: ["end", "showTime", "timeZone", "userRangeTimeZone"], - + depKeys: ["end", "showTime"], func: (input) => { - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.end, format).isValid()) { - mom = dayjs.utc(input.end, format); - break; - } - } - if (!input.showTime && mom?.hour() === 0 && mom?.minute() === 0 && mom?.second() === 0) { - mom = mom?.hour(12); - } - - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - const formattedEnd = mom.tz(tz).format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT); - return formattedEnd; - } - return null; + const mom = Boolean(input.end) ? dayjs(input.end, DateParser): null; + return mom?.isValid() ? mom.format(input.showTime ? DATE_TIME_FORMAT : DATE_FORMAT) : null; }, }), - depsConfig({ name: "startTimestamp", desc: trans("export.dateRangeStartTimestampDesc"), - depKeys: ["start", "timeZone", "userRangeTimeZone"], + depKeys: ["start"], func: (input) => { - - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.start, format).isValid()) { - mom = dayjs.utc(input.start, format); - break; - } - } - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return mom.tz(tz).unix(); - } - return ""; + const mom = Boolean(input.start) ? dayjs(input.start, DateParser) : null; + return mom?.isValid() ? mom.unix() : ""; }, }), - depsConfig({ name: "endTimestamp", desc: trans("export.dateRangeEndTimestampDesc"), - depKeys: ["end", "timeZone", "userRangeTimeZone"], + depKeys: ["end"], func: (input) => { - - let mom = null; - for (const format of DateParser) { - if (dayjs.utc(input.end, format).isValid()) { - mom = dayjs.utc(input.end, format); - break; - } - } - if (mom?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return mom.tz(tz).unix(); - } - return ""; + const mom = Boolean(input.end) ? dayjs(input.end, DateParser) : null; + return mom?.isValid() ? mom.unix() : ""; }, }), - depsConfig({ name: "formattedValue", desc: trans("export.dateRangeFormattedValueDesc"), - depKeys: ["start", "end", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["start", "end", "format"], func: (input) => { - let start = null; - let end = null; - - for (const format of DateParser) { - if (dayjs.utc(input.start, format).isValid()) { - start = dayjs.utc(input.start, format); - break; - } - } - for (const format of DateParser) { - if (dayjs.utc(input.end, format).isValid()) { - end = dayjs.utc(input.end, format); - break; - } - } - - //When the time is 00:00:00 and you convert it to a timezone behind UTC (e.g., UTC-5), the date can shift to the previous day - if (!input.showTime && start?.hour() === 0 && start?.minute() === 0 && start?.second() === 0) { - start = start?.hour(12); - } - - if (!input.showTime && end?.hour() === 0 && end?.minute() === 0 && end?.second() === 0) { - end = end?.hour(12); - } - - if (start?.isValid() || end?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - - const formattedStart = start?.isValid() ? start.tz(tz).format(input.format) : ''; - const formattedEnd = end?.isValid() ? end.tz(tz).format(input.format) : ''; - const formattedValue = [formattedStart, formattedEnd].filter(Boolean).join(" - "); - return formattedValue; - } - return ''; + const start = Boolean(input.start) ? dayjs(input.start, DateParser): null; + const end = Boolean(input.end) ? dayjs(input.end, DateParser): null; + return [ + start?.isValid() && start.format(input.format), + end?.isValid() && end.format(input.format), + ] + .filter((item) => item) + .join(" - "); }, }), - - depsConfig({ name: "formattedStartValue", desc: trans("export.dateRangeFormattedStartValueDesc"), - depKeys: ["start", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["start", "format"], func: (input) => { - let start = null; - // Loop through DateParser to find a valid format - for (const format of DateParser) { - if (dayjs.utc(input.start, format).isValid()) { - start = dayjs.utc(input.start, format); - break; - } - } - - if (!input.showTime && start?.hour() === 0 && start?.minute() === 0 && start?.second() === 0) { - start = start?.hour(12); - } - - if (start?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - const formattedStart = start.tz(tz).format(input.format); - return formattedStart; - } - return ''; + const start = Boolean(input.start) ? dayjs(input.start, DateParser): null; + return start?.isValid() && start.format(input.format); }, }), - depsConfig({ name: "formattedEndValue", desc: trans("export.dateRangeFormattedEndValueDesc"), - depKeys: ["end", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["end", "format"], func: (input) => { - let end = null; - // Loop through DateParser to find a valid format - for (const format of DateParser) { - if (dayjs.utc(input.end, format).isValid()) { - end = dayjs.utc(input.end, format); - break; - } - } - - if (!input.showTime && end?.hour() === 0 && end?.minute() === 0 && end?.second() === 0) { - end = end?.hour(12); - } - - if (end?.isValid()) { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - const formattedEnd = end.tz(tz).format(input.format); - return formattedEnd; - } - return ''; + const end = Boolean(input.end) ? dayjs(input.end, DateParser): null; + return end?.isValid() && end.format(input.format); }, }), - - depsConfig({ name: "invalid", desc: trans("export.invalidDesc"), - depKeys: ["start", "end", "required", "minTime", "maxTime", "minDate", "maxDate", "customRule", "timeZone", "userRangeTimeZone"], - func: (input) => { - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - let startDate = null; - let endDate = null; - - for (const format of DateParser) { - if (dayjs.utc(input.start, format).isValid()) { - startDate = dayjs.utc(input.start, format).tz(tz); - break; - } - } - for (const format of DateParser) { - if (dayjs.utc(input.end, format).isValid()) { - endDate = dayjs.utc(input.end, format).tz(tz); - break; - } - } - - const startInvalid = startDate && (!startDate.isValid() || (input.minDate && startDate.isBefore(dayjs(input.minDate).tz(tz))) || (input.maxDate && startDate.isAfter(dayjs(input.maxDate).tz(tz)))); - const endInvalid = endDate && (!endDate.isValid() || (input.minDate && endDate.isBefore(dayjs(input.minDate).tz(tz))) || (input.maxDate && endDate.isAfter(dayjs(input.maxDate).tz(tz)))); - - return startInvalid || endInvalid; - }, - }), - - depsConfig({ - name: "timeZone", - desc: trans("export.timeZoneDesc"), - depKeys: ["timeZone", "userRangeTimeZone"], - func: (input) => { - return input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - }, + depKeys: ["start", "end", "required", "minTime", "maxTime", "minDate", "maxDate", "customRule"], + func: (input) => + validate({ + ...input, + value: { value: input.start }, + }).validateStatus !== "success" || + validate({ + ...input, + value: { value: input.end }, + }).validateStatus !== "success", }), ...CommonNameConfig, ]); - DateRangeComp = withMethodExposing(DateRangeComp, [ ...dateRefMethods, { @@ -830,4 +644,4 @@ DateRangeComp = withMethodExposing(DateRangeComp, [ comp.children.end.getView().onChange(data.end); }, }, -]); +]); \ No newline at end of file diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx index 5b8809e9a..90a6cc879 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx @@ -1,8 +1,6 @@ import _ from "lodash"; import dayjs from "dayjs"; import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core"; import { BoolCodeControl, @@ -59,8 +57,6 @@ import { dropdownControl } from "comps/controls/dropdownControl"; import { timeZoneOptions } from "./timeZone"; dayjs.extend(utc); -dayjs.extend(timezone); -dayjs.extend(customParseFormat); const EventOptions = [changeEvent, focusEvent, blurEvent] as const; @@ -426,20 +422,10 @@ export const TimePickerComp = withExposingConfigs(timePickerControl, [ depsConfig({ name: "formattedValue", desc: trans("export.timePickerFormattedValueDesc"), - depKeys: ["value", "format", "timeZone", "userTimeZone"], + depKeys: ["value", "format"], func: (input) => { - let mom = null; - - // Loop through TimeParser to find a valid format - for (const format of TimeParser) { - if (dayjs.utc(input.value, format).isValid()) { - mom = dayjs.utc(input.value, format); - break; - } - } - - const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; - return mom?.isValid() ? mom.tz(tz).format(input.format) : ''; + const mom = Boolean(input.value) ? dayjs(input.value, TimeParser) : null; + return mom?.isValid() ? mom.format(input.format) : ''; }, }), @@ -451,7 +437,6 @@ export const TimePickerComp = withExposingConfigs(timePickerControl, [ return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; }, }), - depsConfig({ name: "invalid", desc: trans("export.invalidDesc"), @@ -460,158 +445,64 @@ export const TimePickerComp = withExposingConfigs(timePickerControl, [ validate({ ...input, value: { value: input.value }, - }).validateStatus !== "success", + } as any).validateStatus !== "success", }), - ...CommonNameConfig, ]); - export let TimeRangeComp = withExposingConfigs(timeRangeControl, [ - // new NameConfig("start", trans("export.timeRangeStartDesc")), - // new NameConfig("end", trans("export.timeRangeEndDesc")), - depsConfig({ - name: "start", - desc: trans("export.timeRangeStartDesc"), - depKeys: ["start", "timeZone", "userRangeTimeZone"], - func: (input) => { - let start = null; - - // Loop through TimeParser to find a valid format for start - for (const format of TimeParser) { - if (dayjs.utc(input.start, format).isValid()) { - start = dayjs.utc(input.start, format); - break; - } - } - - if (start?.hour() === 0 && start?.minute() === 0 && start?.second() === 0) { - start = start?.hour(12); - } - - // Apply timezone conversion if valid - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return start?.isValid() ? start.tz(tz).format(input.format || "HH:mm:ss") : null; - }, - }), - - depsConfig({ - name: "end", - desc: trans("export.timeRangeEndDesc"), - depKeys: ["end", "timeZone", "userRangeTimeZone"], - func: (input) => { - let end = null; - - // Loop through TimeParser to find a valid format for end - for (const format of TimeParser) { - if (dayjs.utc(input.end, format).isValid()) { - end = dayjs.utc(input.end, format); - break; - } - } - - // Apply timezone conversion if valid - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return end?.isValid() ? end.tz(tz).format(input.format || "HH:mm:ss") : null; - }, - }), - + new NameConfig("start", trans("export.timeRangeStartDesc")), + new NameConfig("end", trans("export.timeRangeEndDesc")), depsConfig({ name: "formattedValue", desc: trans("export.timeRangeFormattedValueDesc"), - depKeys: ["start", "end", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["start", "end", "format"], func: (input) => { - let start = null; - let end = null; - for (const format of TimeParser) { - if (dayjs.utc(input.start, format).isValid()) { - start = dayjs.utc(input.start, format); - break; - } - } - for (const format of TimeParser) { - if (dayjs.utc(input.end, format).isValid()) { - end = dayjs.utc(input.end, format); - break; - } - } - - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - const formattedStart = start?.isValid() ? start.tz(tz).format(input.format) : ''; - const formattedEnd = end?.isValid() ? end.tz(tz).format(input.format) : ''; - - return [formattedStart, formattedEnd].filter(Boolean).join(" - "); + const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null; + const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null; + return [ + start?.isValid() && start.format(input.format), + end?.isValid() && end.format(input.format), + ] + .filter((item) => item) + .join(" - "); }, }), - depsConfig({ name: "formattedStartValue", desc: trans("export.timeRangeFormattedStartValueDesc"), - depKeys: ["start", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["start", "format"], func: (input) => { - let start = null; - for (const format of TimeParser) { - if (dayjs.utc(input.start, format).isValid()) { - start = dayjs.utc(input.start, format); - break; - } - } - - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return start?.isValid() ? start.tz(tz).format(input.format) : ''; + const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null; + return start?.isValid() && start.format(input.format); }, }), - depsConfig({ name: "formattedEndValue", desc: trans("export.timeRangeFormattedEndValueDesc"), - depKeys: ["end", "format", "timeZone", "userRangeTimeZone"], + depKeys: ["end", "format"], func: (input) => { - let end = null; - for (const format of TimeParser) { - if (dayjs.utc(input.end, format).isValid()) { - end = dayjs.utc(input.end, format); - break; - } - } - - const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - return end?.isValid() ? end.tz(tz).format(input.format) : ''; + const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null; + return end?.isValid() && end.format(input.format); }, }), - - depsConfig({ - name: "timeZone", - desc: trans("export.timeZoneDesc"), - depKeys: ["timeZone", "userRangeTimeZone"], - func: (input) => { - return input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC'; - }, - }), - depsConfig({ name: "invalid", desc: trans("export.invalidDesc"), depKeys: ["start", "end", "required", "minTime", "maxTime", "customRule"], - func: (input) => { - const startInvalid = validate({ + func: (input) => + validate({ ...input, value: { value: input.start }, - }).validateStatus !== "success"; - - const endInvalid = validate({ + }).validateStatus !== "success" || + validate({ ...input, value: { value: input.end }, - }).validateStatus !== "success"; - - return startInvalid || endInvalid; - }, + }).validateStatus !== "success", }), - ...CommonNameConfig, ]); - TimeRangeComp = withMethodExposing(TimeRangeComp, [ ...dateRefMethods, { @@ -653,4 +544,4 @@ TimeRangeComp = withMethodExposing(TimeRangeComp, [ comp.children.end.getView().onChange(data.end); }, }, -]); +]); \ No newline at end of file From 56ebeae7d4293b22484f638e7514cb815eed210d Mon Sep 17 00:00:00 2001 From: MenamAfzal Date: Fri, 6 Sep 2024 15:32:16 +0500 Subject: [PATCH 2/4] missing timeZones added --- .../lowcoder/src/comps/comps/dateComp/timeUIView.tsx | 2 +- .../lowcoder/src/comps/comps/dateComp/timeZone.ts | 8 +++++++- client/packages/lowcoder/src/i18n/locales/en.ts | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx index 942061e68..4a84c51c3 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx @@ -21,7 +21,7 @@ const TimeMobileUIView = React.lazy(() => ); const StyledAntdSelect = styled(AntdSelect)` - width: 100%; + width: 350px; margin: 10px 0; .ant-select-selector { font-size: 14px; diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts index 33108bcad..ca4c1e69e 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts @@ -20,10 +20,16 @@ export const timeZoneOptions = [ { label: trans("timeZone.UTC+04:00"), value: "Asia/Dubai" }, { label: trans("timeZone.UTC+05:00"), value: "Asia/Karachi" }, { label: trans("timeZone.UTC+05:30"), value: "Asia/Kolkata" }, + { label: trans("timeZone.UTC+05:45"), value: "Asia/Kathmandu" }, { label: trans("timeZone.UTC+06:00"), value: "Asia/Dhaka" }, + { label: trans("timeZone.UTC+06:30"), value: "Asia/Rangoon" }, { label: trans("timeZone.UTC+07:00"), value: "Asia/Bangkok" }, { label: trans("timeZone.UTC+08:00"), value: "Asia/Shanghai" }, { label: trans("timeZone.UTC+09:00"), value: "Asia/Tokyo" }, + { label: trans("timeZone.UTC+09:30"), value: "Australia/Darwin" }, { label: trans("timeZone.UTC+10:00"), value: "Australia/Sydney" }, - { label: trans("timeZone.UserChoice"), value: "UserChoice" }, + { label: trans("timeZone.UTC+11:00"), value: "Pacific/Guadalcanal" }, + { label: trans("timeZone.UTC+12:00"), value: "Pacific/Auckland" }, + { label: trans("timeZone.UTC+13:00"), value: "Pacific/Tongatapu" }, + { label: trans("timeZone.UserChoice"), value: "UserChoice" } ]; diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 61d0ae8a6..4b0b21488 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -3633,14 +3633,19 @@ export const en = { "UTC+04:00": "(UTC+04:00) Dubai, Muscat", "UTC+05:00": "(UTC+05:00) Karachi", "UTC+05:30": "(UTC+05:30) New Delhi", + "UTC+05:45": "(UTC+05:45) Kathmandu", "UTC+06:00": "(UTC+06:00) Dhaka", + "UTC+06:30": "(UTC+06:30) Yangon", "UTC+07:00": "(UTC+07:00) Bangkok", "UTC+08:00": "(UTC+08:00) Beijing, HK", "UTC+09:00": "(UTC+09:00) Tokyo, Seoul", + "UTC+09:30": "(UTC+09:30) Adelaide, Darwin", "UTC+10:00": "(UTC+10:00) Sydney", + "UTC+11:00": "(UTC+11:00) Solomon Islands, New Caledonia", + "UTC+12:00": "(UTC+12:00) Auckland, Fiji", + "UTC+13:00": "(UTC+13:00) Nuku'alofa, Samoa", "UserChoice": "User Choice" }, - tour: { section1Title: "Steps", section1Subtitle: "Steps", From fd6ad1d6039c6a18ee474e1c41db6b79ed13b29e Mon Sep 17 00:00:00 2001 From: MenamAfzal Date: Fri, 6 Sep 2024 15:48:18 +0500 Subject: [PATCH 3/4] default values added --- .../comps/comps/dateComp/dateRangeUIView.tsx | 2 +- .../src/comps/comps/dateComp/dateUIView.tsx | 2 +- .../comps/comps/dateComp/timeRangeUIView.tsx | 4 +- .../src/comps/comps/dateComp/timeUIView.tsx | 4 +- .../src/comps/comps/dateComp/timeZone.ts | 62 +++++++++---------- .../packages/lowcoder/src/i18n/locales/en.ts | 2 +- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx index 1c925fa95..a5ca43700 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx @@ -82,7 +82,7 @@ export const DateRangeUIView = (props: DateRangeUIViewProps) => { option.value !== 'UserChoice')} placeholder="Select Time Zone" - defaultValue={'Etc/UTC'} + defaultValue={'(UTC 00:00) UTC'} onChange={props?.onClickDateRangeTimeZone} /> diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx index 80ab630f6..db32501d6 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx @@ -70,7 +70,7 @@ export const DateUIView = (props: DataUIViewProps) => { option.value !== 'UserChoice')} placeholder="Select Time Zone" - defaultValue={'Etc/UTC'} + defaultValue={'(UTC 00:00) UTC'} onChange={props.onClickDateTimeZone} /> diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx index 4d837b94a..2a1f8c8c2 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx @@ -21,7 +21,7 @@ const RangePickerStyled = styled((props: any) => )<{ $ `; const StyledAntdSelect = styled(AntdSelect)` - width: 100%; + width: 300px; margin: 10px 0px; .ant-select-selector { font-size: 14px; @@ -71,7 +71,7 @@ export const TimeRangeUIView = (props: TimeRangeUIViewProps) => { option.value !== 'UserChoice')} // Filter out 'userChoice' - defaultValue={'Etc/UTC'} + defaultValue={'(UTC 00:00) UTC'} onChange={props.handleTimeRangeZoneChange} /> ) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx index 4a84c51c3..9e6f0ebbb 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx @@ -21,7 +21,7 @@ const TimeMobileUIView = React.lazy(() => ); const StyledAntdSelect = styled(AntdSelect)` - width: 350px; + width: 300px; margin: 10px 0; .ant-select-selector { font-size: 14px; @@ -54,7 +54,7 @@ export const TimeUIView = (props: TimeUIViewProps) => { placeholder="Select Time Zone" options={timeZoneOptions.filter(option => option.value !== 'UserChoice')} // Filter out 'userChoice' onChange={props?.handleTimeZoneChange} - defaultValue={'Etc/UTC'} + defaultValue={'(UTC 00:00) UTC'} /> ) )} diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts index ca4c1e69e..6e6dfbeb3 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts @@ -1,35 +1,35 @@ import { trans } from "i18n"; export const timeZoneOptions = [ - { label: trans("timeZone.UTC-12:00"), value: "Etc/GMT+12" }, - { label: trans("timeZone.UTC-11:00"), value: "Etc/GMT+11" }, - { label: trans("timeZone.UTC-10:00"), value: "Pacific/Honolulu" }, - { label: trans("timeZone.UTC-09:00"), value: "America/Anchorage" }, - { label: trans("timeZone.UTC-08:00"), value: "America/Tijuana" }, - { label: trans("timeZone.UTC-07:00"), value: "America/Los_Angeles" }, - { label: trans("timeZone.UTC-06:00"), value: "America/Chicago" }, - { label: trans("timeZone.UTC-05:00"), value: "America/New_York" }, - { label: trans("timeZone.UTC-04:00"), value: "America/Halifax" }, - { label: trans("timeZone.UTC-03:00"), value: "America/Argentina/Buenos_Aires" }, - { label: trans("timeZone.UTC-02:00"), value: "Etc/GMT+2" }, - { label: trans("timeZone.UTC-01:00"), value: "Atlantic/Cape_Verde" }, - { label: trans("timeZone.UTC+00:00"), value: "Etc/UTC" }, - { label: trans("timeZone.UTC+01:00"), value: "Europe/Berlin" }, - { label: trans("timeZone.UTC+02:00"), value: "Europe/Bucharest" }, - { label: trans("timeZone.UTC+03:00"), value: "Europe/Moscow" }, - { label: trans("timeZone.UTC+04:00"), value: "Asia/Dubai" }, - { label: trans("timeZone.UTC+05:00"), value: "Asia/Karachi" }, - { label: trans("timeZone.UTC+05:30"), value: "Asia/Kolkata" }, - { label: trans("timeZone.UTC+05:45"), value: "Asia/Kathmandu" }, - { label: trans("timeZone.UTC+06:00"), value: "Asia/Dhaka" }, - { label: trans("timeZone.UTC+06:30"), value: "Asia/Rangoon" }, - { label: trans("timeZone.UTC+07:00"), value: "Asia/Bangkok" }, - { label: trans("timeZone.UTC+08:00"), value: "Asia/Shanghai" }, - { label: trans("timeZone.UTC+09:00"), value: "Asia/Tokyo" }, - { label: trans("timeZone.UTC+09:30"), value: "Australia/Darwin" }, - { label: trans("timeZone.UTC+10:00"), value: "Australia/Sydney" }, - { label: trans("timeZone.UTC+11:00"), value: "Pacific/Guadalcanal" }, - { label: trans("timeZone.UTC+12:00"), value: "Pacific/Auckland" }, - { label: trans("timeZone.UTC+13:00"), value: "Pacific/Tongatapu" }, - { label: trans("timeZone.UserChoice"), value: "UserChoice" } + { label: trans("timeZone.UTC-12:00"), value: trans("timeZone.UTC-12:00") }, + { label: trans("timeZone.UTC-11:00"), value: trans("timeZone.UTC-11:00") }, + { label: trans("timeZone.UTC-10:00"), value: trans("timeZone.UTC-10:00") }, + { label: trans("timeZone.UTC-09:00"), value: trans("timeZone.UTC-09:00") }, + { label: trans("timeZone.UTC-08:00"), value: trans("timeZone.UTC-08:00") }, + { label: trans("timeZone.UTC-07:00"), value: trans("timeZone.UTC-07:00") }, + { label: trans("timeZone.UTC-06:00"), value: trans("timeZone.UTC-06:00") }, + { label: trans("timeZone.UTC-05:00"), value: trans("timeZone.UTC-05:00") }, + { label: trans("timeZone.UTC-04:00"), value: trans("timeZone.UTC-04:00") }, + { label: trans("timeZone.UTC-03:00"), value: trans("timeZone.UTC-03:00") }, + { label: trans("timeZone.UTC-02:00"), value: trans("timeZone.UTC-02:00") }, + { label: trans("timeZone.UTC-01:00"), value: trans("timeZone.UTC-01:00") }, + { label: trans("timeZone.UTC+00:00"), value: trans("timeZone.UTC+00:00") }, + { label: trans("timeZone.UTC+01:00"), value: trans("timeZone.UTC+01:00") }, + { label: trans("timeZone.UTC+02:00"), value: trans("timeZone.UTC+02:00") }, + { label: trans("timeZone.UTC+03:00"), value: trans("timeZone.UTC+03:00") }, + { label: trans("timeZone.UTC+04:00"), value: trans("timeZone.UTC+04:00") }, + { label: trans("timeZone.UTC+05:00"), value: trans("timeZone.UTC+05:00") }, + { label: trans("timeZone.UTC+05:30"), value: trans("timeZone.UTC+05:30") }, + { label: trans("timeZone.UTC+05:45"), value: trans("timeZone.UTC+05:45") }, + { label: trans("timeZone.UTC+06:00"), value: trans("timeZone.UTC+06:00") }, + { label: trans("timeZone.UTC+06:30"), value: trans("timeZone.UTC+06:30") }, + { label: trans("timeZone.UTC+07:00"), value: trans("timeZone.UTC+07:00") }, + { label: trans("timeZone.UTC+08:00"), value: trans("timeZone.UTC+08:00") }, + { label: trans("timeZone.UTC+09:00"), value: trans("timeZone.UTC+09:00") }, + { label: trans("timeZone.UTC+09:30"), value: trans("timeZone.UTC+09:30") }, + { label: trans("timeZone.UTC+10:00"), value: trans("timeZone.UTC+10:00") }, + { label: trans("timeZone.UTC+11:00"), value: trans("timeZone.UTC+11:00") }, + { label: trans("timeZone.UTC+12:00"), value: trans("timeZone.UTC+12:00") }, + { label: trans("timeZone.UTC+13:00"), value: trans("timeZone.UTC+13:00") }, + { label: trans("timeZone.UserChoice"), value: trans("timeZone.UserChoice") } ]; diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 4b0b21488..26c04b630 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -3644,7 +3644,7 @@ export const en = { "UTC+11:00": "(UTC+11:00) Solomon Islands, New Caledonia", "UTC+12:00": "(UTC+12:00) Auckland, Fiji", "UTC+13:00": "(UTC+13:00) Nuku'alofa, Samoa", - "UserChoice": "User Choice" + "UserChoice": "UserChoice" }, tour: { section1Title: "Steps", From 6de6379139b385ad864e11597b70ac9c4b28b688 Mon Sep 17 00:00:00 2001 From: MenamAfzal Date: Tue, 10 Sep 2024 21:48:49 +0500 Subject: [PATCH 4/4] formatted values with respect to selective timeZone --- .../src/comps/comps/dateComp/dateComp.tsx | 80 +++++++++++++------ .../comps/comps/dateComp/dateRangeUIView.tsx | 2 +- .../src/comps/comps/dateComp/dateUIView.tsx | 2 +- .../src/comps/comps/dateComp/timeComp.tsx | 67 ++++++++++++---- .../comps/comps/dateComp/timeRangeUIView.tsx | 2 +- .../src/comps/comps/dateComp/timeUIView.tsx | 2 +- .../src/comps/comps/dateComp/timeZone.ts | 62 +++++++------- 7 files changed, 140 insertions(+), 77 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx index 41aad24fa..c180ad917 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx @@ -1,6 +1,5 @@ import _, { noop } from "lodash"; import dayjs from "dayjs"; -import utc from 'dayjs/plugin/utc'; import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core"; import { BoolCodeControl, @@ -53,8 +52,6 @@ import { dropdownControl } from "comps/controls/dropdownControl"; import { timeZoneOptions } from "./timeZone"; -dayjs.extend(utc); - const EventOptions = [changeEvent, focusEvent, blurEvent] as const; @@ -87,7 +84,7 @@ const commonChildren = { ...validationChildren, viewRef: RefControl, inputFieldStyle: styleControl(DateTimeStyle, 'inputFieldStyle'), - timeZone: dropdownControl(timeZoneOptions, "Etc/UTC"), + timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone), }; type CommonChildrenType = RecordConstructorToComp; @@ -145,7 +142,7 @@ function validate( const childrenMap = { value: stringExposingStateControl("value"), - userTimeZone: stringExposingStateControl("userTimeZone", 'Etc/UTC'), + userTimeZone: stringExposingStateControl("userTimeZone", Intl.DateTimeFormat().resolvedOptions().timeZone), ...commonChildren, ...formDataChildren, }; @@ -306,7 +303,7 @@ export const dateRangeControl = (function () { const childrenMap = { start: stringExposingStateControl("start"), end: stringExposingStateControl("end"), - userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , 'Etc/UTC'), + userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , Intl.DateTimeFormat().resolvedOptions().timeZone), ...formDataChildren, ...commonChildren, }; @@ -465,6 +462,14 @@ export const dateRangeControl = (function () { .build(); })(); +const getTimeZoneInfo = (timeZone: any, othereTimeZone: any) => { + const tz = timeZone === 'UserChoice' ? othereTimeZone : timeZone ; + return { + TimeZone: tz, + Offset: dayjs().tz(tz).format('Z') // Get the UTC offset for the selected timezone + }; +}; + export const DatePickerComp = withExposingConfigs(datePickerControl, [ depsConfig({ name: "value", @@ -478,10 +483,16 @@ export const DatePickerComp = withExposingConfigs(datePickerControl, [ depsConfig({ name: "formattedValue", desc: trans("export.datePickerFormattedValueDesc"), - depKeys: ["value", "format"], + depKeys: ["value", "format", "timeZone", "userTimeZone"], func: (input) => { const mom = Boolean(input.value) ? dayjs(input.value, DateParser) : null; - return mom?.isValid() ? mom.format(input.format) : ""; + const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone; // Get the selected timezone + const timeInTz = mom?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time) + return mom?.isValid() + ? (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z' + ? timeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available + : mom.format(input.format) // Otherwise, return mom.format(input.format) + : ""; }, }), depsConfig({ @@ -507,11 +518,8 @@ export const DatePickerComp = withExposingConfigs(datePickerControl, [ name: "timeZone", desc: trans("export.timeZoneDesc"), depKeys: ["timeZone", "userTimeZone"], - func: (input) => { - console.log("input.timeZone", input.timeZone) - return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; + func: (input: { timeZone: any; userTimeZone: any; }) => getTimeZoneInfo(input.timeZone, input.userTimeZone) - }, }), ...CommonNameConfig, ]); @@ -556,36 +564,58 @@ export let DateRangeComp = withExposingConfigs(dateRangeControl, [ depsConfig({ name: "formattedValue", desc: trans("export.dateRangeFormattedValueDesc"), - depKeys: ["start", "end", "format"], + depKeys: ["start", "end", "format" , "timeZone", "userRangeTimeZone"], func: (input) => { const start = Boolean(input.start) ? dayjs(input.start, DateParser): null; const end = Boolean(input.end) ? dayjs(input.end, DateParser): null; + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; // Get the selected timezone + const startTimeInTz = start?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time) + const endTimeInTz = end?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time) + return [ - start?.isValid() && start.format(input.format), - end?.isValid() && end.format(input.format), + start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z' + ? startTimeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available + : start?.format(input.format), + end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z' + ? endTimeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available + : end?.format(input.format) , ] .filter((item) => item) .join(" - "); }, }), depsConfig({ - name: "formattedStartValue", - desc: trans("export.dateRangeFormattedStartValueDesc"), - depKeys: ["start", "format"], - func: (input) => { - const start = Boolean(input.start) ? dayjs(input.start, DateParser): null; - return start?.isValid() && start.format(input.format); - }, - }), + name: "formattedStartValue", + desc: trans("export.dateRangeFormattedStartValueDesc"), + depKeys: ["start", "format", "timeZone", "userRangeTimeZone"], + func: (input) => { + const start = Boolean(input.start) ? dayjs(input.start, DateParser): null; + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; + const startTimeInTz = start?.clone().tz(tz, true); + return start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) + ? startTimeInTz?.format(input?.format) + : start?.format(input.format); + }, +}), depsConfig({ name: "formattedEndValue", desc: trans("export.dateRangeFormattedEndValueDesc"), - depKeys: ["end", "format"], + depKeys: ["end", "format" , "timeZone", "userRangeTimeZone"], func: (input) => { const end = Boolean(input.end) ? dayjs(input.end, DateParser): null; - return end?.isValid() && end.format(input.format); + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; + const endTimeInTz = end?.clone().tz(tz, true); + return end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) + ? endTimeInTz?.format(input?.format) + : end?.format(input.format); }, }), + depsConfig({ + name: "timeZone", + desc: trans("export.timeZoneDesc"), + depKeys: ["timeZone", "userRangeTimeZone"], + func: (input:any) => getTimeZoneInfo(input.timeZone, input.userRangeTimeZone) + }), depsConfig({ name: "invalid", desc: trans("export.invalidDesc"), diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx index a5ca43700..678bbced5 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx @@ -82,7 +82,7 @@ export const DateRangeUIView = (props: DateRangeUIViewProps) => { option.value !== 'UserChoice')} placeholder="Select Time Zone" - defaultValue={'(UTC 00:00) UTC'} + defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone} onChange={props?.onClickDateRangeTimeZone} /> diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx index db32501d6..2d55bfd1c 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx @@ -70,7 +70,7 @@ export const DateUIView = (props: DataUIViewProps) => { option.value !== 'UserChoice')} placeholder="Select Time Zone" - defaultValue={'(UTC 00:00) UTC'} + defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone} onChange={props.onClickDateTimeZone} /> diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx index 90a6cc879..9e74e3d3f 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx @@ -1,6 +1,5 @@ import _ from "lodash"; import dayjs from "dayjs"; -import utc from 'dayjs/plugin/utc'; import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core"; import { BoolCodeControl, @@ -56,7 +55,6 @@ import { EditorContext } from "comps/editorState"; import { dropdownControl } from "comps/controls/dropdownControl"; import { timeZoneOptions } from "./timeZone"; -dayjs.extend(utc); const EventOptions = [changeEvent, focusEvent, blurEvent] as const; @@ -86,7 +84,7 @@ const commonChildren = { ), inputFieldStyle: styleControl(DateTimeStyle, 'inputFieldStyle'), suffixIcon: withDefault(IconControl, "/icon:regular/clock"), - timeZone: dropdownControl(timeZoneOptions, "Etc/UTC"), + timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone), viewRef: RefControl, ...validationChildren, }; @@ -126,7 +124,7 @@ function validate( const childrenMap = { value: stringExposingStateControl("value"), - userTimeZone: stringExposingStateControl("userTimeZone" , 'Etc/UTC'), + userTimeZone: stringExposingStateControl("userTimeZone", Intl.DateTimeFormat().resolvedOptions().timeZone), ...commonChildren, ...formDataChildren, }; @@ -271,7 +269,7 @@ export const timeRangeControl = (function () { const childrenMap = { start: stringExposingStateControl("start"), end: stringExposingStateControl("end"), - userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , 'Etc/UTC'), + userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , Intl.DateTimeFormat().resolvedOptions().timeZone), ...formDataChildren, ...commonChildren, }; @@ -416,16 +414,30 @@ export const timeRangeControl = (function () { .build(); })(); +const getTimeZoneInfo = (timeZone: any, othereTimeZone: any) => { + const tz = timeZone === 'UserChoice' ? othereTimeZone : timeZone ; + return { + TimeZone: tz, + Offset: dayjs().tz(tz).format('Z') // Get the UTC offset for the selected timezone + }; +}; + export const TimePickerComp = withExposingConfigs(timePickerControl, [ new NameConfig("value", trans("export.timePickerValueDesc")), depsConfig({ name: "formattedValue", desc: trans("export.timePickerFormattedValueDesc"), - depKeys: ["value", "format"], + depKeys: ["value", "format", "timeZone", "userTimeZone"], func: (input) => { const mom = Boolean(input.value) ? dayjs(input.value, TimeParser) : null; - return mom?.isValid() ? mom.format(input.format) : ''; + const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone; // Get the selected timezone + const timeInTz = mom?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time) + const formattedTimeWithoffset = timeInTz?.format(input?.format); + return mom?.isValid() ? (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z' + ? formattedTimeWithoffset // Return formattedDateWithoffset if format includes 'Z' or is not available + : mom.format(input.format) // Otherwise, return mom.format(input.format) + : ""; }, }), @@ -433,9 +445,7 @@ export const TimePickerComp = withExposingConfigs(timePickerControl, [ name: "timeZone", desc: trans("export.timeZoneDesc"), depKeys: ["timeZone", "userTimeZone"], - func: (input) => { - return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC'; - }, + func: (input: { timeZone: any; userTimeZone: any; }) => getTimeZoneInfo(input.timeZone, input.userTimeZone) }), depsConfig({ name: "invalid", @@ -456,13 +466,20 @@ export let TimeRangeComp = withExposingConfigs(timeRangeControl, [ depsConfig({ name: "formattedValue", desc: trans("export.timeRangeFormattedValueDesc"), - depKeys: ["start", "end", "format"], + depKeys: ["start", "end", "format", "timeZone", "userRangeTimeZone"], func: (input) => { const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null; const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null; + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; // Get the selected timezone + const startTimeInTz = start?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time) + const endTimeInTz = end?.clone().tz(tz, true); return [ - start?.isValid() && start.format(input.format), - end?.isValid() && end.format(input.format), + start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z' + ? startTimeInTz?.format(input?.format) // Return formattedTimeWithoffset if format includes 'Z' or is not available + : start?.format(input.format), + end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) + ? endTimeInTz?.format(input?.format) + : end?.format(input.format) , ] .filter((item) => item) .join(" - "); @@ -471,21 +488,37 @@ export let TimeRangeComp = withExposingConfigs(timeRangeControl, [ depsConfig({ name: "formattedStartValue", desc: trans("export.timeRangeFormattedStartValueDesc"), - depKeys: ["start", "format"], + depKeys: ["start", "format" , "timeZone", "userRangeTimeZone"], func: (input) => { const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null; - return start?.isValid() && start.format(input.format); + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; + const startTimeInTz = start?.clone().tz(tz, true); + const formattedDate = startTimeInTz?.format(input?.format); + return start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) + ? formattedDate + : start?.format(input.format); }, }), depsConfig({ name: "formattedEndValue", desc: trans("export.timeRangeFormattedEndValueDesc"), - depKeys: ["end", "format"], + depKeys: ["end", "format", "timeZone", "userRangeTimeZone"], func: (input) => { const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null; - return end?.isValid() && end.format(input.format); + const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; + const endTimeInTz = end?.clone().tz(tz, true); + return end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) + ? endTimeInTz?.format(input?.format) + : end?.format(input.format); }, }), + depsConfig({ + name: "timeZone", + desc: trans("export.timeZoneDesc"), + depKeys: ["timeZone", "userRangeTimeZone"], + func: (input:any) => getTimeZoneInfo(input.timeZone, input.userRangeTimeZone) + + }), depsConfig({ name: "invalid", desc: trans("export.invalidDesc"), diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx index 2a1f8c8c2..fd8ce4d69 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx @@ -71,7 +71,7 @@ export const TimeRangeUIView = (props: TimeRangeUIViewProps) => { option.value !== 'UserChoice')} // Filter out 'userChoice' - defaultValue={'(UTC 00:00) UTC'} + defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone} onChange={props.handleTimeRangeZoneChange} /> ) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx index 9e6f0ebbb..9e4d414c7 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx @@ -54,7 +54,7 @@ export const TimeUIView = (props: TimeUIViewProps) => { placeholder="Select Time Zone" options={timeZoneOptions.filter(option => option.value !== 'UserChoice')} // Filter out 'userChoice' onChange={props?.handleTimeZoneChange} - defaultValue={'(UTC 00:00) UTC'} + defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone} /> ) )} diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts index 6e6dfbeb3..72e0206a6 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeZone.ts @@ -1,35 +1,35 @@ import { trans } from "i18n"; export const timeZoneOptions = [ - { label: trans("timeZone.UTC-12:00"), value: trans("timeZone.UTC-12:00") }, - { label: trans("timeZone.UTC-11:00"), value: trans("timeZone.UTC-11:00") }, - { label: trans("timeZone.UTC-10:00"), value: trans("timeZone.UTC-10:00") }, - { label: trans("timeZone.UTC-09:00"), value: trans("timeZone.UTC-09:00") }, - { label: trans("timeZone.UTC-08:00"), value: trans("timeZone.UTC-08:00") }, - { label: trans("timeZone.UTC-07:00"), value: trans("timeZone.UTC-07:00") }, - { label: trans("timeZone.UTC-06:00"), value: trans("timeZone.UTC-06:00") }, - { label: trans("timeZone.UTC-05:00"), value: trans("timeZone.UTC-05:00") }, - { label: trans("timeZone.UTC-04:00"), value: trans("timeZone.UTC-04:00") }, - { label: trans("timeZone.UTC-03:00"), value: trans("timeZone.UTC-03:00") }, - { label: trans("timeZone.UTC-02:00"), value: trans("timeZone.UTC-02:00") }, - { label: trans("timeZone.UTC-01:00"), value: trans("timeZone.UTC-01:00") }, - { label: trans("timeZone.UTC+00:00"), value: trans("timeZone.UTC+00:00") }, - { label: trans("timeZone.UTC+01:00"), value: trans("timeZone.UTC+01:00") }, - { label: trans("timeZone.UTC+02:00"), value: trans("timeZone.UTC+02:00") }, - { label: trans("timeZone.UTC+03:00"), value: trans("timeZone.UTC+03:00") }, - { label: trans("timeZone.UTC+04:00"), value: trans("timeZone.UTC+04:00") }, - { label: trans("timeZone.UTC+05:00"), value: trans("timeZone.UTC+05:00") }, - { label: trans("timeZone.UTC+05:30"), value: trans("timeZone.UTC+05:30") }, - { label: trans("timeZone.UTC+05:45"), value: trans("timeZone.UTC+05:45") }, - { label: trans("timeZone.UTC+06:00"), value: trans("timeZone.UTC+06:00") }, - { label: trans("timeZone.UTC+06:30"), value: trans("timeZone.UTC+06:30") }, - { label: trans("timeZone.UTC+07:00"), value: trans("timeZone.UTC+07:00") }, - { label: trans("timeZone.UTC+08:00"), value: trans("timeZone.UTC+08:00") }, - { label: trans("timeZone.UTC+09:00"), value: trans("timeZone.UTC+09:00") }, - { label: trans("timeZone.UTC+09:30"), value: trans("timeZone.UTC+09:30") }, - { label: trans("timeZone.UTC+10:00"), value: trans("timeZone.UTC+10:00") }, - { label: trans("timeZone.UTC+11:00"), value: trans("timeZone.UTC+11:00") }, - { label: trans("timeZone.UTC+12:00"), value: trans("timeZone.UTC+12:00") }, - { label: trans("timeZone.UTC+13:00"), value: trans("timeZone.UTC+13:00") }, - { label: trans("timeZone.UserChoice"), value: trans("timeZone.UserChoice") } + { label: trans("timeZone.UserChoice"), value: "UserChoice" }, + { label: trans("timeZone.UTC-12:00"), value: "Pacific/Baker" }, + { label: trans("timeZone.UTC-11:00"), value: "Pacific/Niue" }, + { label: trans("timeZone.UTC-10:00"), value: "Pacific/Honolulu" }, + { label: trans("timeZone.UTC-09:00"), value: "America/Anchorage" }, + { label: trans("timeZone.UTC-08:00"), value: "America/Tijuana" }, + { label: trans("timeZone.UTC-07:00"), value: "America/Los_Angeles" }, + { label: trans("timeZone.UTC-06:00"), value: "America/Chicago" }, + { label: trans("timeZone.UTC-05:00"), value: "America/New_York" }, + { label: trans("timeZone.UTC-04:00"), value: "America/Halifax" }, + { label: trans("timeZone.UTC-03:00"), value: "America/Argentina/Buenos_Aires" }, + { label: trans("timeZone.UTC-02:00"), value: "Atlantic/South_Georgia" }, + { label: trans("timeZone.UTC-01:00"), value: "Atlantic/Cape_Verde" }, + { label: trans("timeZone.UTC+00:00"), value: "Etc/UTC" }, + { label: trans("timeZone.UTC+01:00"), value: "Europe/Berlin" }, + { label: trans("timeZone.UTC+02:00"), value: "Europe/Bucharest" }, + { label: trans("timeZone.UTC+03:00"), value: "Europe/Moscow" }, + { label: trans("timeZone.UTC+04:00"), value: "Asia/Dubai" }, + { label: trans("timeZone.UTC+05:00"), value: "Asia/Karachi" }, + { label: trans("timeZone.UTC+05:30"), value: "Asia/Kolkata" }, + { label: trans("timeZone.UTC+05:45"), value: "Asia/Kathmandu" }, + { label: trans("timeZone.UTC+06:00"), value: "Asia/Dhaka" }, + { label: trans("timeZone.UTC+06:30"), value: "Asia/Rangoon" }, + { label: trans("timeZone.UTC+07:00"), value: "Asia/Bangkok" }, + { label: trans("timeZone.UTC+08:00"), value: "Asia/Shanghai" }, + { label: trans("timeZone.UTC+09:00"), value: "Asia/Tokyo" }, + { label: trans("timeZone.UTC+09:30"), value: "Australia/Darwin" }, + { label: trans("timeZone.UTC+10:00"), value: "Australia/Sydney" }, + { label: trans("timeZone.UTC+11:00"), value: "Pacific/Guadalcanal" }, + { label: trans("timeZone.UTC+12:00"), value: "Pacific/Auckland" }, + { label: trans("timeZone.UTC+13:00"), value: "Pacific/Tongatapu" }, ];