@dhis2/analytics 21.1.1 → 21.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/build/cjs/components/FileMenu/FileMenu.js +6 -16
  3. package/build/cjs/components/FileMenu/__tests__/FileMenu.spec.js +3 -3
  4. package/build/cjs/components/TranslationDialog/TranslationModal/LocalesSelect.js +69 -0
  5. package/build/cjs/components/TranslationDialog/TranslationModal/TranslationForm.js +152 -0
  6. package/build/cjs/components/TranslationDialog/TranslationModal/TranslationModal.js +76 -0
  7. package/build/cjs/components/TranslationDialog/TranslationModal/TranslationModalActions.js +39 -0
  8. package/build/cjs/components/TranslationDialog/TranslationModal/useTranslationsResults.js +46 -0
  9. package/build/cjs/components/TranslationDialog/index.js +13 -0
  10. package/build/cjs/locales/ar/translations.json +7 -0
  11. package/build/cjs/locales/ar_EG/translations.json +7 -0
  12. package/build/cjs/locales/ar_IQ/translations.json +7 -0
  13. package/build/cjs/locales/ckb/translations.json +7 -0
  14. package/build/cjs/locales/cs/translations.json +7 -0
  15. package/build/cjs/locales/da/translations.json +7 -0
  16. package/build/cjs/locales/en/translations.json +8 -0
  17. package/build/cjs/locales/es/translations.json +7 -0
  18. package/build/cjs/locales/fr/translations.json +7 -0
  19. package/build/cjs/locales/id/translations.json +7 -0
  20. package/build/cjs/locales/km/translations.json +7 -0
  21. package/build/cjs/locales/lo/translations.json +7 -0
  22. package/build/cjs/locales/my/translations.json +7 -0
  23. package/build/cjs/locales/nb/translations.json +7 -0
  24. package/build/cjs/locales/nl/translations.json +7 -0
  25. package/build/cjs/locales/prs/translations.json +7 -0
  26. package/build/cjs/locales/ps/translations.json +7 -0
  27. package/build/cjs/locales/pt/translations.json +7 -0
  28. package/build/cjs/locales/pt_BR/translations.json +7 -0
  29. package/build/cjs/locales/ru/translations.json +7 -0
  30. package/build/cjs/locales/sv/translations.json +7 -0
  31. package/build/cjs/locales/tet/translations.json +7 -0
  32. package/build/cjs/locales/tg/translations.json +7 -0
  33. package/build/cjs/locales/uk/translations.json +7 -0
  34. package/build/cjs/locales/ur/translations.json +7 -0
  35. package/build/cjs/locales/uz/translations.json +7 -0
  36. package/build/cjs/locales/uz_Latn/translations.json +7 -0
  37. package/build/cjs/locales/vi/translations.json +7 -0
  38. package/build/cjs/locales/zh/translations.json +7 -0
  39. package/build/cjs/locales/zh_CN/translations.json +7 -0
  40. package/build/es/components/FileMenu/FileMenu.js +4 -14
  41. package/build/es/components/FileMenu/__tests__/FileMenu.spec.js +1 -1
  42. package/build/es/components/TranslationDialog/TranslationModal/LocalesSelect.js +52 -0
  43. package/build/es/components/TranslationDialog/TranslationModal/TranslationForm.js +129 -0
  44. package/build/es/components/TranslationDialog/TranslationModal/TranslationModal.js +54 -0
  45. package/build/es/components/TranslationDialog/TranslationModal/TranslationModalActions.js +24 -0
  46. package/build/es/components/TranslationDialog/TranslationModal/useTranslationsResults.js +32 -0
  47. package/build/es/components/TranslationDialog/index.js +2 -0
  48. package/build/es/locales/ar/translations.json +7 -0
  49. package/build/es/locales/ar_EG/translations.json +7 -0
  50. package/build/es/locales/ar_IQ/translations.json +7 -0
  51. package/build/es/locales/ckb/translations.json +7 -0
  52. package/build/es/locales/cs/translations.json +7 -0
  53. package/build/es/locales/da/translations.json +7 -0
  54. package/build/es/locales/en/translations.json +8 -0
  55. package/build/es/locales/es/translations.json +7 -0
  56. package/build/es/locales/fr/translations.json +7 -0
  57. package/build/es/locales/id/translations.json +7 -0
  58. package/build/es/locales/km/translations.json +7 -0
  59. package/build/es/locales/lo/translations.json +7 -0
  60. package/build/es/locales/my/translations.json +7 -0
  61. package/build/es/locales/nb/translations.json +7 -0
  62. package/build/es/locales/nl/translations.json +7 -0
  63. package/build/es/locales/prs/translations.json +7 -0
  64. package/build/es/locales/ps/translations.json +7 -0
  65. package/build/es/locales/pt/translations.json +7 -0
  66. package/build/es/locales/pt_BR/translations.json +7 -0
  67. package/build/es/locales/ru/translations.json +7 -0
  68. package/build/es/locales/sv/translations.json +7 -0
  69. package/build/es/locales/tet/translations.json +7 -0
  70. package/build/es/locales/tg/translations.json +7 -0
  71. package/build/es/locales/uk/translations.json +7 -0
  72. package/build/es/locales/ur/translations.json +7 -0
  73. package/build/es/locales/uz/translations.json +7 -0
  74. package/build/es/locales/uz_Latn/translations.json +7 -0
  75. package/build/es/locales/vi/translations.json +7 -0
  76. package/build/es/locales/zh/translations.json +7 -0
  77. package/build/es/locales/zh_CN/translations.json +7 -0
  78. package/package.json +1 -1
@@ -218,6 +218,13 @@
218
218
  "Six-months": "6 ເດືອນ",
219
219
  "Financial Years": "",
220
220
  "Years": "ປີ",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "ແທ່ງ",
222
229
  "Category": "ລວງນອນ",
223
230
  "Filter": "Filter",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "၆ လ",
219
219
  "Financial Years": "",
220
220
  "Years": "နှစ်များ",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "အစဉ်အတန်းများ",
222
229
  "Category": "category",
223
230
  "Filter": "ရှာဖွေထုတ်သည်",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "Halvår",
223
223
  "Financial Years": "Regnskapsår",
224
224
  "Years": "År",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "Serie",
226
233
  "Category": "Kategori",
227
234
  "Filter": "Filter",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "",
223
223
  "Financial Years": "",
224
224
  "Years": "",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "",
226
233
  "Category": "",
227
234
  "Filter": "",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "شش-ماهه",
223
223
  "Financial Years": "",
224
224
  "Years": "سالانه",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "سلسله (لړۍ)",
226
233
  "Category": "دسته بندی",
227
234
  "Filter": "فلتر",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "شپږ میاشتې",
223
223
  "Financial Years": "",
224
224
  "Years": "کلونه",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "سلسله (لړۍ)",
226
233
  "Category": "کټګوري",
227
234
  "Filter": "فیلټر",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "Seis meses",
223
223
  "Financial Years": "Ano financeiro ",
224
224
  "Years": "Anos",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "Série",
226
233
  "Category": "Categoria",
227
234
  "Filter": "Filtro",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "",
223
223
  "Financial Years": "",
224
224
  "Years": "Anos",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "Série",
226
233
  "Category": "Categoria",
227
234
  "Filter": "Filtro",
@@ -230,6 +230,13 @@
230
230
  "Six-months": "Полугодие",
231
231
  "Financial Years": "Финансовые годы",
232
232
  "Years": "Годы",
233
+ "Translating to": "",
234
+ "Choose a locale": "",
235
+ "Base locale reference": "",
236
+ "Choose a locale to translate from the menu above": "",
237
+ "Translate: {{objectName}}": "",
238
+ "Save translations": "",
239
+ "Retry": "",
233
240
  "Series": "Ряды",
234
241
  "Category": "Категория",
235
242
  "Filter": "Фильтр",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "",
223
223
  "Financial Years": "",
224
224
  "Years": "År",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "",
226
233
  "Category": "",
227
234
  "Filter": "Filtrera",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "Fulan-nén",
219
219
  "Financial Years": "",
220
220
  "Years": "Tinan",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "Séries",
222
229
  "Category": "Kategoria",
223
230
  "Filter": "Filtru",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "Шашмоҳаҳо",
223
223
  "Financial Years": "",
224
224
  "Years": "Солҳо",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "Силсила",
226
233
  "Category": "Категория",
227
234
  "Filter": "Филтр",
@@ -230,6 +230,13 @@
230
230
  "Six-months": "Півріччя",
231
231
  "Financial Years": "",
232
232
  "Years": "Роки",
233
+ "Translating to": "",
234
+ "Choose a locale": "",
235
+ "Base locale reference": "",
236
+ "Choose a locale to translate from the menu above": "",
237
+ "Translate: {{objectName}}": "",
238
+ "Save translations": "",
239
+ "Retry": "",
233
240
  "Series": "",
234
241
  "Category": "Категорія",
235
242
  "Filter": "Фільтр",
@@ -222,6 +222,13 @@
222
222
  "Six-months": "چھ ماہ",
223
223
  "Financial Years": "",
224
224
  "Years": "سال",
225
+ "Translating to": "",
226
+ "Choose a locale": "",
227
+ "Base locale reference": "",
228
+ "Choose a locale to translate from the menu above": "",
229
+ "Translate: {{objectName}}": "",
230
+ "Save translations": "",
231
+ "Retry": "",
225
232
  "Series": "سیریز",
226
233
  "Category": "قسم",
227
234
  "Filter": "فلٹر",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "Ярим йиллик",
219
219
  "Financial Years": "Молиявий йиллар",
220
220
  "Years": "Йиллар",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "Кетма-кетликлар",
222
229
  "Category": "Категория",
223
230
  "Filter": "Фильтр",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "Yarim yillik",
219
219
  "Financial Years": "Moliyaviy yillar",
220
220
  "Years": "Yillar",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "Ketma-ketliklar",
222
229
  "Category": "Kategoriya",
223
230
  "Filter": "Filtr",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "Sáu-tháng",
219
219
  "Financial Years": "Năm tài chính",
220
220
  "Years": "Năm",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "Chuỗi Dữ Liệu",
222
229
  "Category": "Phân loại",
223
230
  "Filter": "Lọc",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "Six-months",
219
219
  "Financial Years": "Financial Years",
220
220
  "Years": "年",
221
+ "Translating to": "翻译成",
222
+ "Choose a locale": "选择语言环境",
223
+ "Base locale reference": "基本语言环境参考",
224
+ "Choose a locale to translate from the menu above": "从上面的菜单中选择要翻译的语言环境",
225
+ "Translate: {{objectName}}": "翻译:{{objectName}}",
226
+ "Save translations": "保存翻译",
227
+ "Retry": "重试",
221
228
  "Series": "系列",
222
229
  "Category": "分类",
223
230
  "Filter": "过滤器",
@@ -218,6 +218,13 @@
218
218
  "Six-months": "",
219
219
  "Financial Years": "",
220
220
  "Years": "年",
221
+ "Translating to": "",
222
+ "Choose a locale": "",
223
+ "Base locale reference": "",
224
+ "Choose a locale to translate from the menu above": "",
225
+ "Translate: {{objectName}}": "",
226
+ "Save translations": "",
227
+ "Retry": "",
221
228
  "Series": "",
222
229
  "Category": "分类",
223
230
  "Filter": "过滤器",
@@ -1,10 +1,10 @@
1
1
  import _JSXStyle from "styled-jsx/style";
2
- import TranslationDialog from '@dhis2/d2-ui-translation-dialog';
3
2
  import { IconAdd24, IconLaunch24, IconSave24, IconEdit24, IconTranslate24, IconShare24, IconLink24, IconDelete24, SharingDialog, colors, FlyoutMenu, Layer, MenuItem, MenuDivider, Popper } from '@dhis2/ui';
4
3
  import PropTypes from 'prop-types';
5
4
  import React, { createRef, useState } from 'react';
6
5
  import i18n from '../../locales/index.js';
7
6
  import { OpenFileDialog } from '../OpenFileDialog/OpenFileDialog.js';
7
+ import { TranslationDialog } from '../TranslationDialog/index.js';
8
8
  import { DeleteDialog } from './DeleteDialog.js';
9
9
  import { fileMenuStyles } from './FileMenu.styles.js';
10
10
  import { GetLinkDialog } from './GetLinkDialog.js';
@@ -70,20 +70,10 @@ export const FileMenu = ({
70
70
 
71
71
  case 'translate':
72
72
  return /*#__PURE__*/React.createElement(TranslationDialog, {
73
- open: true,
74
- d2: d2,
75
- objectToTranslate: { ...fileObject,
76
- // mock modelDefinition to avoid an error
77
- // in the TranslationDialog component
78
- modelDefinition: {
79
- name: fileType
80
- }
81
- },
73
+ objectToTranslate: fileObject,
82
74
  fieldsToTranslate: ['name', 'description'],
83
- onRequestClose: onDialogClose,
84
- onTranslationSaved: onTranslate,
85
- onTranslationError: onError,
86
- insertTheme: true
75
+ onClose: onDialogClose,
76
+ onTranslationSaved: onTranslate
87
77
  });
88
78
 
89
79
  case 'sharing':
@@ -1,8 +1,8 @@
1
- import TranslationDialog from '@dhis2/d2-ui-translation-dialog';
2
1
  import { SharingDialog } from '@dhis2/ui';
3
2
  import { shallow } from 'enzyme';
4
3
  import React from 'react';
5
4
  import { OpenFileDialog } from '../../OpenFileDialog/OpenFileDialog.js';
5
+ import { TranslationDialog } from '../../TranslationDialog/index.js';
6
6
  import { DeleteDialog } from '../DeleteDialog.js';
7
7
  import { FileMenu } from '../FileMenu.js';
8
8
  import { GetLinkDialog } from '../GetLinkDialog.js';
@@ -0,0 +1,52 @@
1
+ import { useDataQuery } from '@dhis2/app-runtime';
2
+ import i18n from '@dhis2/d2-i18n';
3
+ import { SingleSelect, SingleSelectOption } from '@dhis2/ui';
4
+ import PropTypes from 'prop-types';
5
+ import React from 'react';
6
+ const query = {
7
+ locales: {
8
+ resource: 'locales/db'
9
+ }
10
+ };
11
+ export const LocalesSelect = ({
12
+ onChange,
13
+ selected
14
+ }) => {
15
+ const {
16
+ data,
17
+ fetching
18
+ } = useDataQuery(query);
19
+ return /*#__PURE__*/React.createElement(SingleSelect, {
20
+ prefix: selected ? i18n.t('Translating to') : i18n.t('Choose a locale'),
21
+ onChange: ({
22
+ selected
23
+ }) => onChange(selected),
24
+ loading: fetching,
25
+ selected: data ? selected : undefined,
26
+ dense: true
27
+ }, data && data.locales // XXX remove duplicates ?! fr_SN - French (Senegal)
28
+ .reduce((locales, {
29
+ locale,
30
+ name
31
+ }) => {
32
+ if (!locales.find(entry => entry.locale === locale)) {
33
+ locales.push({
34
+ locale,
35
+ name
36
+ });
37
+ }
38
+
39
+ return locales;
40
+ }, []).map(({
41
+ locale,
42
+ name
43
+ }) => /*#__PURE__*/React.createElement(SingleSelectOption, {
44
+ key: locale,
45
+ value: locale,
46
+ label: name
47
+ })));
48
+ };
49
+ LocalesSelect.propTypes = {
50
+ onChange: PropTypes.func.isRequired,
51
+ selected: PropTypes.string
52
+ };
@@ -0,0 +1,129 @@
1
+ import { useAlert, useDataMutation } from '@dhis2/app-runtime';
2
+ import i18n from '@dhis2/d2-i18n';
3
+ import { CenteredContent, DataTable, DataTableBody, DataTableCell, DataTableColumnHeader, DataTableHead, DataTableRow, InputField, ModalContent } from '@dhis2/ui';
4
+ import PropTypes from 'prop-types';
5
+ import React, { useEffect, useRef, useState } from 'react';
6
+ import { LocalesSelect } from './LocalesSelect.js';
7
+ import { TranslationModalActions } from './TranslationModalActions.js';
8
+ const SESSION_STORAGE_TRANSLATION_LOCALE_KEY = 'translation-dialog-selected-locale';
9
+ export const TranslationForm = ({
10
+ fieldsToTranslate,
11
+ objectToTranslate,
12
+ translations,
13
+ resource,
14
+ onTranslationSaved,
15
+ onClose
16
+ }) => {
17
+ const [newTranslations, setNewTranslations] = useState();
18
+ const [translationLocale, setTranslationLocale] = useState();
19
+ const [fieldsTranslations, setFieldsTranslations] = useState({});
20
+ const {
21
+ show: showError
22
+ } = useAlert(error => error, {
23
+ critical: true
24
+ });
25
+
26
+ const camelCaseToUnderscores = field => field.replace(/[a-z][A-Z]/g, match => [match.charAt(0), match.charAt(1)].join('_')).toLowerCase();
27
+
28
+ const getTranslationIndexForField = field => newTranslations.findIndex(element => element.locale === translationLocale && element.property.toLowerCase() === camelCaseToUnderscores(field));
29
+
30
+ const getTranslationForField = field => {
31
+ var _newTranslations$tran;
32
+
33
+ const translationIndex = getTranslationIndexForField(field);
34
+ return translationIndex !== -1 ? ((_newTranslations$tran = newTranslations[translationIndex]) === null || _newTranslations$tran === void 0 ? void 0 : _newTranslations$tran.value) || '' : '';
35
+ };
36
+
37
+ const setTranslationForField = (field, translation) => {
38
+ const newTranslation = {
39
+ locale: translationLocale,
40
+ property: camelCaseToUnderscores(field).toUpperCase(),
41
+ value: translation
42
+ };
43
+ const translationIndex = getTranslationIndexForField(field);
44
+ setNewTranslations(translationIndex === -1 ? [...newTranslations, newTranslation] : newTranslations.map((translation, index) => index === translationIndex ? newTranslation : translation));
45
+ };
46
+
47
+ const [fetchFieldsTranslations] = useDataMutation({
48
+ resource: 'i18n',
49
+ type: 'create',
50
+ data: fieldsToTranslate.map(camelCaseToUnderscores)
51
+ }, {
52
+ onComplete: res => setFieldsTranslations(res),
53
+ onError: error => showError(error)
54
+ });
55
+ const translationsMutationRef = useRef({
56
+ resource: "".concat(resource, "/translations"),
57
+ type: 'update',
58
+ data: ({
59
+ translations
60
+ }) => ({
61
+ translations
62
+ })
63
+ });
64
+ const [saveTranslations, {
65
+ loading: saveInProgress
66
+ }] = useDataMutation(translationsMutationRef.current, {
67
+ onComplete: () => {
68
+ onTranslationSaved();
69
+ onClose();
70
+ },
71
+ onError: error => showError(error)
72
+ });
73
+
74
+ const onLocaleChange = locale => {
75
+ setTranslationLocale(locale);
76
+ window.sessionStorage.setItem(SESSION_STORAGE_TRANSLATION_LOCALE_KEY, locale);
77
+ };
78
+
79
+ const save = () => saveTranslations({
80
+ translations: newTranslations
81
+ });
82
+
83
+ useEffect(() => setTranslationLocale(window.sessionStorage.getItem(SESSION_STORAGE_TRANSLATION_LOCALE_KEY)), []);
84
+ useEffect(() => {
85
+ const fetchTranslations = () => fetchFieldsTranslations(fieldsToTranslate);
86
+
87
+ fetchTranslations();
88
+ }, [fieldsToTranslate]);
89
+ useEffect(() => setNewTranslations(translations), [translations]);
90
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ModalContent, null, /*#__PURE__*/React.createElement(DataTable, {
91
+ layout: "fixed"
92
+ }, /*#__PURE__*/React.createElement(DataTableHead, null, /*#__PURE__*/React.createElement(DataTableRow, null, /*#__PURE__*/React.createElement(DataTableColumnHeader, {
93
+ fixed: true,
94
+ top: "0"
95
+ }, i18n.t('Base locale reference')), /*#__PURE__*/React.createElement(DataTableColumnHeader, {
96
+ fixed: true,
97
+ top: "0"
98
+ }, /*#__PURE__*/React.createElement(LocalesSelect, {
99
+ selected: translationLocale,
100
+ onChange: onLocaleChange
101
+ })))), /*#__PURE__*/React.createElement(DataTableBody, null, fieldsToTranslate.map((field, index) => /*#__PURE__*/React.createElement(DataTableRow, {
102
+ key: field
103
+ }, /*#__PURE__*/React.createElement(DataTableCell, null, /*#__PURE__*/React.createElement(InputField, {
104
+ label: fieldsTranslations[field],
105
+ value: objectToTranslate[field],
106
+ readOnly: true
107
+ })), translationLocale && /*#__PURE__*/React.createElement(DataTableCell, null, /*#__PURE__*/React.createElement(InputField, {
108
+ label: fieldsTranslations[field],
109
+ value: getTranslationForField(field),
110
+ onChange: ({
111
+ value
112
+ }) => setTranslationForField(field, value)
113
+ })), !translationLocale && index === 0 && /*#__PURE__*/React.createElement(DataTableCell, {
114
+ rowSpan: String(fieldsToTranslate.length)
115
+ }, /*#__PURE__*/React.createElement(CenteredContent, null, i18n.t('Choose a locale to translate from the menu above')))))))), /*#__PURE__*/React.createElement(TranslationModalActions, {
116
+ onClose: onClose,
117
+ onSave: save,
118
+ saveInProgress: saveInProgress,
119
+ saveButtonDisabled: !translationLocale
120
+ }));
121
+ };
122
+ TranslationForm.propTypes = {
123
+ fieldsToTranslate: PropTypes.array.isRequired,
124
+ objectToTranslate: PropTypes.object.isRequired,
125
+ resource: PropTypes.string.isRequired,
126
+ translations: PropTypes.array.isRequired,
127
+ onClose: PropTypes.func.isRequired,
128
+ onTranslationSaved: PropTypes.func.isRequired
129
+ };
@@ -0,0 +1,54 @@
1
+ import i18n from '@dhis2/d2-i18n';
2
+ import { CenteredContent, CircularLoader, Modal, ModalContent, ModalTitle } from '@dhis2/ui';
3
+ import PropTypes from 'prop-types';
4
+ import React, { useEffect, useState } from 'react';
5
+ import { TranslationForm } from './TranslationForm.js';
6
+ import { TranslationModalActions } from './TranslationModalActions.js';
7
+ import { useTranslationsResults } from './useTranslationsResults.js';
8
+ export const TranslationModal = ({
9
+ objectToTranslate,
10
+ fieldsToTranslate,
11
+ onClose,
12
+ onTranslationSaved
13
+ }) => {
14
+ const [translations, setTranslations] = useState([]);
15
+ const endpointPath = new URL(objectToTranslate.href).pathname;
16
+ const endpointPathMatch = endpointPath.match(/api\/\d+\/(?<resource>.+)/);
17
+ const resource = endpointPathMatch !== null && endpointPathMatch !== void 0 && endpointPathMatch.groups ? endpointPathMatch.groups.resource : null;
18
+ const {
19
+ translationsData,
20
+ fetching
21
+ } = useTranslationsResults({
22
+ resource
23
+ });
24
+ useEffect(() => {
25
+ if (translationsData) {
26
+ setTranslations(translationsData);
27
+ }
28
+ }, [translationsData]);
29
+ return /*#__PURE__*/React.createElement(Modal, {
30
+ large: true,
31
+ position: "middle",
32
+ onClose: onClose
33
+ }, /*#__PURE__*/React.createElement(ModalTitle, null, i18n.t('Translate: {{objectName}}', {
34
+ objectName: objectToTranslate.name || 'TEXT',
35
+ // XXX
36
+ nsSeparator: '^^'
37
+ })), fetching ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ModalContent, null, /*#__PURE__*/React.createElement(CenteredContent, null, /*#__PURE__*/React.createElement(CircularLoader, null))), /*#__PURE__*/React.createElement(TranslationModalActions, {
38
+ onClose: onClose,
39
+ saveButtonDisabled: true
40
+ })) : /*#__PURE__*/React.createElement(TranslationForm, {
41
+ fieldsToTranslate: fieldsToTranslate,
42
+ objectToTranslate: objectToTranslate,
43
+ translations: translations,
44
+ onTranslationSaved: onTranslationSaved,
45
+ resource: resource,
46
+ onClose: onClose
47
+ }));
48
+ };
49
+ TranslationModal.propTypes = {
50
+ fieldsToTranslate: PropTypes.array.isRequired,
51
+ objectToTranslate: PropTypes.object.isRequired,
52
+ onClose: PropTypes.func.isRequired,
53
+ onTranslationSaved: PropTypes.func.isRequired
54
+ };
@@ -0,0 +1,24 @@
1
+ import i18n from '@dhis2/d2-i18n';
2
+ import { Button, ButtonStrip, ModalActions } from '@dhis2/ui';
3
+ import PropTypes from 'prop-types';
4
+ import React from 'react';
5
+ export const TranslationModalActions = ({
6
+ onClose,
7
+ onSave,
8
+ saveInProgress,
9
+ saveButtonDisabled
10
+ }) => /*#__PURE__*/React.createElement(ModalActions, null, /*#__PURE__*/React.createElement(ButtonStrip, null, /*#__PURE__*/React.createElement(Button, {
11
+ secondary: true,
12
+ onClick: onClose
13
+ }, i18n.t('Cancel')), /*#__PURE__*/React.createElement(Button, {
14
+ primary: true,
15
+ onClick: onSave,
16
+ loading: saveInProgress,
17
+ disabled: saveButtonDisabled
18
+ }, i18n.t('Save translations'))));
19
+ TranslationModalActions.propTypes = {
20
+ onClose: PropTypes.func.isRequired,
21
+ saveButtonDisabled: PropTypes.bool,
22
+ saveInProgress: PropTypes.bool,
23
+ onSave: PropTypes.func
24
+ };
@@ -0,0 +1,32 @@
1
+ import { useAlert, useDataQuery } from '@dhis2/app-runtime';
2
+ import i18n from '@dhis2/d2-i18n';
3
+ import { useRef } from 'react';
4
+ export const useTranslationsResults = ({
5
+ resource
6
+ }) => {
7
+ const translationsQueryRef = useRef({
8
+ translations: {
9
+ resource: "".concat(resource, "/translations")
10
+ }
11
+ });
12
+ const {
13
+ data,
14
+ fetching,
15
+ refetch
16
+ } = useDataQuery(translationsQueryRef.current, {
17
+ onError: error => showError(error)
18
+ });
19
+ const {
20
+ show: showError
21
+ } = useAlert(error => error.message || i18n.t('Could not load translations'), {
22
+ critical: true,
23
+ actions: [{
24
+ label: i18n.t('Retry'),
25
+ onClick: refetch
26
+ }]
27
+ });
28
+ return {
29
+ translationsData: fetching ? undefined : data.translations.translations,
30
+ fetching
31
+ };
32
+ };
@@ -0,0 +1,2 @@
1
+ import { TranslationModal as TranslationDialog } from './TranslationModal/TranslationModal.js';
2
+ export { TranslationDialog };
@@ -238,6 +238,13 @@
238
238
  "Six-months": "ستة-أشهر",
239
239
  "Financial Years": "السنوات المالية",
240
240
  "Years": "السنوات",
241
+ "Translating to": "",
242
+ "Choose a locale": "",
243
+ "Base locale reference": "",
244
+ "Choose a locale to translate from the menu above": "",
245
+ "Translate: {{objectName}}": "",
246
+ "Save translations": "",
247
+ "Retry": "",
241
248
  "Series": "سلسلة",
242
249
  "Category": "الفئة",
243
250
  "Filter": "عامل التصفية",