Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chart Editor - Impossible to translate Time Grain dropdown contents #29478

Open
goldjee opened this issue Jul 3, 2024 · 1 comment
Open

Chart Editor - Impossible to translate Time Grain dropdown contents #29478

goldjee opened this issue Jul 3, 2024 · 1 comment
Labels
i18n:general Related to translations

Comments

@goldjee
Copy link
Contributor

goldjee commented Jul 3, 2024

Screenshot

image

Description

The editor for many chart types (like Line Chart, Scatter Plot etc) use "Time Grain" dropdown to adjust time granularity as depicted on the attached screenshot. It seems that the contents of this dropdown are not able to be translated as I haven't found corresponding lines in messages.po files.

Design input

@dosubot dosubot bot added i18n:general Related to translations labels Jul 3, 2024
Copy link

dosubot bot commented Jul 3, 2024

To make the contents of the "Time Grain" dropdown menu in the Chart Editor translatable, you need to use the t function from @superset-ui/core for each item in the dropdown. This function marks strings for translation.

Here is an example of how you can modify the code to make the dropdown items translatable:

import { t } from '@superset-ui/core';

// Example of dropdown items
const timeGrainOptions = [
  { value: 'PT1S', label: t('Second') },
  { value: 'PT1M', label: t('Minute') },
  { value: 'PT1H', label: t('Hour') },
  { value: 'P1D', label: t('Day') },
  { value: 'P1W', label: t('Week') },
  { value: 'P1M', label: t('Month') },
  { value: 'P3M', label: t('Quarter') },
  { value: 'P1Y', label: t('Year') },
];

// Use these options in your dropdown component

In this example, each label in the timeGrainOptions array is wrapped with the t function to ensure it is translatable. You would then use this timeGrainOptions array in your dropdown component.

Additionally, you can refer to the PluginFilterTimegrain component in the TimeGrainFilterPlugin.tsx file for a more comprehensive implementation. Here is a snippet from that file showing how translation is handled:

import {
  ensureIsArray,
  ExtraFormData,
  t,
  TimeGranularity,
  tn,
} from '@superset-ui/core';
import React, { useEffect, useMemo, useState } from 'react';
import { Select } from 'src/components';
import { FormItemProps } from 'antd/lib/form';
import { FilterPluginStyle, StyledFormItem, StatusMessage } from '../common';
import { PluginFilterTimeGrainProps } from './types';

export default function PluginFilterTimegrain(
  props: PluginFilterTimeGrainProps,
) {
  const {
    data,
    formData,
    height,
    width,
    setDataMask,
    setHoveredFilter,
    unsetHoveredFilter,
    setFocusedFilter,
    unsetFocusedFilter,
    setFilterActive,
    filterState,
    inputRef,
  } = props;
  const { defaultValue } = formData;

  const [value, setValue] = useState<string[]>(defaultValue ?? []);
  const durationMap = useMemo(
    () =>
      data.reduce(
        (agg, { duration, name }: { duration: string; name: string }) => ({
          ...agg,
          [duration]: name,
        }),
        {} as { [key in string]: string },
      ),
    [JSON.stringify(data)],
  );

  const handleChange = (values: string[] | string | undefined | null) => {
    const resultValue: string[] = ensureIsArray<string>(values);
    const [timeGrain] = resultValue;
    const label = timeGrain ? durationMap[timeGrain] : undefined;

    const extraFormData: ExtraFormData = {};
    if (timeGrain) {
      extraFormData.time_grain_sqla = timeGrain as TimeGranularity;
    }
    setValue(resultValue);
    setDataMask({
      extraFormData,
      filterState: {
        label,
        value: resultValue.length ? resultValue : null,
      },
    });
  };

  useEffect(() => {
    handleChange(defaultValue ?? []);
  }, [JSON.stringify(defaultValue)]);

  useEffect(() => {
    handleChange(filterState.value ?? []);
  }, [JSON.stringify(filterState.value)]);

  const placeholderText =
    (data || []).length === 0
      ? t('No data')
      : tn('%s option', '%s options', data.length, data.length);

  const formItemData: FormItemProps = {};
  if (filterState.validateMessage) {
    formItemData.extra = (
      <StatusMessage status={filterState.validateStatus}>
        {filterState.validateMessage}
      </StatusMessage>
    );
  }

  const options = (data || []).map(
    (row: { name: string; duration: string }) => {
      const { name, duration } = row;
      return {
        label: name,
        value: duration,
      };
    },
  );

  return (
    <FilterPluginStyle height={height} width={width}>
      <StyledFormItem
        validateStatus={filterState.validateStatus}
        {...formItemData}
      >
        <Select
          allowClear
          value={value}
          placeholder={placeholderText}
          onChange={handleChange}
          onBlur={unsetFocusedFilter}
          onFocus={setFocusedFilter}
          onMouseEnter={setHoveredFilter}
          onMouseLeave={unsetHoveredFilter}
          ref={inputRef}
          options={options}
          onDropdownVisibleChange={setFilterActive}
        />
      </StyledFormItem>
    </FilterPluginStyle>
  );
}

In this component, the t function is used to translate the placeholder text and other strings, ensuring that the dropdown menu contents are translatable [1][2].

To continue talking to Dosu, mention @dosu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n:general Related to translations
Projects
None yet
Development

No branches or pull requests

1 participant