You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2023/09/26 02:40:43 UTC
[superset] 01/04: fix: smarter date formatter
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch sc_74037
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 2ee72fb65effe9cb9b150e480295c9d8738f5595
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Mon Sep 25 14:10:28 2023 -0700
fix: smarter date formatter
---
.../time-format/formatters/finestTemporalGrain.ts | 77 ++++++++++++++++++++++
.../superset-ui-core/src/time-format/index.ts | 1 +
.../components/Select/SelectFilterPlugin.tsx | 8 ++-
3 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts
new file mode 100644
index 0000000000..1400a8eb5b
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+import { utcFormat, timeFormat } from 'd3-time-format';
+import { utcUtils, localTimeUtils } from '../utils/d3Time';
+import TimeFormatter from '../TimeFormatter';
+
+export default function finestTemporalGrain(
+ values: any[],
+ useLocalTime = false,
+) {
+ const format = useLocalTime ? timeFormat : utcFormat;
+
+ const formatMillisecond = format('%Y-%m-%d %H:%M:%S.%L');
+ const formatSecond = format('%Y-%m-%d %H:%M:%S');
+ const formatMinute = format('%Y-%m-%d %H:%M');
+ const formatHour = format('%Y-%m-%d %H:%M');
+ const formatDay = format('%Y-%m-%d');
+ const formatMonth = format('%Y-%m-%d');
+ const formatYear = format('%Y');
+
+ const {
+ hasMillisecond,
+ hasSecond,
+ hasMinute,
+ hasHour,
+ isNotFirstDayOfMonth,
+ isNotFirstMonth,
+ } = useLocalTime ? localTimeUtils : utcUtils;
+
+ let formatFunc = formatYear;
+ values.forEach((value: any) => {
+ if (formatFunc === formatYear && isNotFirstMonth(value)) {
+ formatFunc = formatMonth;
+ }
+ if (formatFunc === formatMonth && isNotFirstDayOfMonth(value)) {
+ formatFunc = formatDay;
+ }
+ if (formatFunc === formatDay && hasHour(value)) {
+ formatFunc = formatHour;
+ }
+ if (formatFunc === formatHour && hasMinute(value)) {
+ formatFunc = formatMinute;
+ }
+ if (formatFunc === formatMinute && hasSecond(value)) {
+ formatFunc = formatSecond;
+ }
+ if (formatFunc === formatSecond && hasMillisecond(value)) {
+ formatFunc = formatMillisecond;
+ }
+ });
+
+ return new TimeFormatter({
+ description:
+ 'Use the finest grain in an array of dates to format all dates in the array',
+ formatFunc,
+ id: 'finest_temporal_grain',
+ label: 'Format temporal columns with the finest grain',
+ useLocalTime,
+ });
+}
diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/index.ts b/superset-frontend/packages/superset-ui-core/src/time-format/index.ts
index 53f23f3643..b0d95c1433 100644
--- a/superset-frontend/packages/superset-ui-core/src/time-format/index.ts
+++ b/superset-frontend/packages/superset-ui-core/src/time-format/index.ts
@@ -35,6 +35,7 @@ export { default as createMultiFormatter } from './factories/createMultiFormatte
export { default as smartDateFormatter } from './formatters/smartDate';
export { default as smartDateDetailedFormatter } from './formatters/smartDateDetailed';
export { default as smartDateVerboseFormatter } from './formatters/smartDateVerbose';
+export { default as finestTemporalGrainFormatter } from './formatters/finestTemporalGrain';
export { default as normalizeTimestamp } from './utils/normalizeTimestamp';
export { default as denormalizeTimestamp } from './utils/denormalizeTimestamp';
diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
index 2c5d919188..87b39e6f1e 100644
--- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
@@ -27,6 +27,7 @@ import {
getColumnLabel,
JsonObject,
smartDateDetailedFormatter,
+ finestTemporalGrainFormatter,
t,
tn,
} from '@superset-ui/core';
@@ -117,9 +118,12 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
const labelFormatter = useMemo(
() =>
getDataRecordFormatter({
- timeFormatter: smartDateDetailedFormatter,
+ timeFormatter:
+ datatype === GenericDataType.TEMPORAL
+ ? finestTemporalGrainFormatter(data.map(el => el.col))
+ : smartDateDetailedFormatter,
}),
- [],
+ [data, datatype],
);
const updateDataMask = useCallback(