thelightbird opened a new issue #13442:
URL: https://github.com/apache/superset/issues/13442


   ## [SIP] Proposal to extend i18n support to charts
   
   ### Motivation
   We would like to adopt Superset to replace our in-house BI tool. However, it 
turns out that a key feature is partly missing for us: internationalization.
   Indeed, even though it is already partially implemented, we would like to 
push Superset’s internationalization even further.
   
   We see internationalization as follows in Superset:
   
   1. **Superset UI Translation:** text displayed in the frontend that is not 
entered by the user.  
   ✅ Already implemented and it is possible to add languages, after activation 
of the feature in the settings file. Given that translations are packed into 
the frontend, a re-deployment is required for any change.
   
   2. **Translation of the text that the user can fill in the charts** (e.g. 
chart title, axis names, and metric names).  
   ❌ Not implemented.
   
   3. **Localization (l10n):** Format the data according to the selected 
language: number, date, calendar, currency, ...  
   Example: the days of the week and month on the time axes of the charts.  
   ❌ Not implemented.  
   
   In this SIP, we aim to address part 2. about chart text translation.
   
   We would like to be able to register multiple translations (one per 
language) for each text element that a chart may include. This way, when a user 
would switch the language in the frontend, the change would not be limited to 
Superset’s UI only. Instead, the newly selected language would be applied to 
the whole dashboard, then including for each chart: the chart title, the chart 
axis labels, and the metric labels.
   
   ## Proposed Change
   
   In this SIP, the internationalization implementation that we offer relies on 
the language selection feature, which is already available in Superset. The 
proposed change consists of replacing each text with a JSON containing the 
translations, as described in the section New or Changed Public Interfaces 
below.
   When there is one or no language defined, the behavior would remain the same 
as it is right now. But once that 2 or more languages would be defined, the 
multi-language behavior would be enabled.
   
   Specifically, in the frontend, the change involves replacing all text input 
components with a new React component that would let the user input one 
translation per language via an edit button opening a modal (cf screenshot 3). 
When the modal is not opened, this component would only display the text 
matching the currently selected language.
   
   
   ### Screenshot Before - Chart edition page
   ![1 
before](https://user-images.githubusercontent.com/2736098/109843978-f6351f00-7c4b-11eb-9a82-e756aa189a6c.png)
   
   ### Screenshot After - Chart edition page
   ![2 
after](https://user-images.githubusercontent.com/2736098/109843994-fa613c80-7c4b-11eb-869e-a2711eeb601c.png)
   ![3 edit 
translation](https://user-images.githubusercontent.com/2736098/109843996-faf9d300-7c4b-11eb-8354-d6842f102523.png)
   
   
   ### New or Changed Public Interfaces
   
   For each text field on the chart page, another i18n form field containing a 
JSON with all the translations would be added. This way, it would still be 
backward compatible if the user would decide later to deactivate the i18n 
feature from the backend configuration file.
   
   First, we offer changes specifically for the translation of the title of a 
chart, named identically `slice_name` as a field of the Slice database model 
and as a form field validated by a schema.
   
   The entire set of translations would be returned each time a GET request 
would be performed for a chart. To save the new i18n fields, the backend would 
have to be modified. Depending on the number of languages defined in the config 
file, the frontend would have to choose from which field the text would need to 
be displayed (example: il would be `slice_name` if less than 2 languages, else 
`slice_name_i18n` with the key of the currently selected language).
   
   In the frontend, to avoid developing 2 distinct components (one to display, 
and another to edit translations), we can reuse the same component to display 
and optionally edit the translations.
   When less than 2 languages would be defined in the superset config, the 
component would act as a simple text field as it is right now. But when more 
than 1 language would be defined, it would display the text matching the 
currently selected language and have an edit button to change all translations.
   
   
   
   Interface of the frontend React component:
   ```
   TranslatableTextField.propTypes = {
     value: PropTypes.string, // Example: "Title"
     setValue: PropTypes.func,
     i18nValue: PropTypes.string, // Example: { "en": "Title", "fr": "Titre" }
     setI18nValue: PropTypes.func,
     enableEditMode: PropTypes.bool, // Show/hide edit button
   }
   ```
   
   Example of use:
   ```
   <TranslatableTextField
     value={chart.slice_name}
     setValue={updateTitle()}
     i18nValue={chart.slice_name_i18n}
     setI18nValue={updateTitleTranslations()} />
   ```
   
   The parameter `i18nValue` would be used only when more than one language 
would be defined.
   The parameter `value` would be used even if more than one language would be 
defined in case we want to disable multi-language support later.
   
   To display the text, the react component would try to display the text 
associated with the currently selected language. If it is null or undefined, a 
generic message or a dash could be displayed instead.
   
   Example of the changes on the GET chart response with the name of the chart 
if we would have 2 or more languages defined:
   - pre-implementation:
   ```
   slice_name: "Title"
   ```
   - post-implementation:
   ```
   slice_name: "Title",
   slice_name_i18n: "{ "en": "Title", "fr": "Titre" }"
   ```
   
   For the other text parts of a chart, like its axis labels or its metric 
name, which would need to be translated too, and which are currently all stored 
in the `params` field of the Slice object database model, it may require to 
store their matching translated text parts inside this `params` as well.
   We have thought about the required changes for those other text parts, but 
we would like to have the SIP initially reviewed on the idea and feasibility of 
incorporating the proposed changes for the translation of the chart title first 
because it is easier to reason about. We could offer more detailed changes 
about those other chart text fields in this SIP later.
   
   
   ### Migration Plan and Compatibility
   
   #### Required changes
    - frontend: edit all views which display text in chart fields, to wrap the 
displayed text with the new React component that would only display the 
translation associated with the currently selected language
   - backend: add an i18n field for each text field of the chart, add some code 
to transform i18n fields on the fly if they are empty.
   
   #### Compatibility enabling and disabling multi-language
   
   In the backend, when a GET request would be performed while more than one 
language would be defined, the backend would transform the i18n fields to fill 
each empty language with the untranslated key.
   Example:
   In database: 
   ```
   slice_name: "Title",
   slice_name_i18n: null
   ```
   Response of the GET:
   ```
   slice_name: "Title",
   slice_name_i18n: "{ "en": "Title", "es": "Title", "fr": "Title" }"
   ```
   
   In the frontend, if more than one language would be defined in the backend 
configuration file, when creating a chart, the untranslated text field (for eg. 
slice_name) would be filled by the React component with the translation 
matching the selected language.
   
   ### Rejected alternatives
   Currently, the only way we have found to translate charts is by duplicating 
charts but this does not scale.
   
   
   Related issue: i18n: translation of dashboards and charts #13030
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to