@mwater/visualization 5.4.0 → 5.4.2
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.
- package/lib/ColorComponent.js +2 -1
- package/lib/IdSelection.d.ts +16 -0
- package/lib/IdSelection.js +59 -0
- package/lib/MWaterAddRelatedIndicatorComponent.js +2 -2
- package/lib/MWaterCompleteTableSelectComponent.d.ts +3 -8
- package/lib/MWaterCompleteTableSelectComponent.js +36 -42
- package/lib/MWaterLoaderComponent.d.ts +11 -10
- package/lib/MWaterLoaderComponent.js +1 -1
- package/lib/MWaterResponsesFilterComponent.js +1 -1
- package/lib/MWaterTableSelectComponent.d.ts +0 -1
- package/lib/MWaterTableSelectComponent.js +4 -6
- package/lib/autotranslate.d.ts +20 -0
- package/lib/autotranslate.js +122 -0
- package/lib/axes/AxisBuilder.js +3 -3
- package/lib/axes/AxisColorEditorComponent.js +4 -0
- package/lib/axes/AxisComponent.d.ts +8 -12
- package/lib/axes/AxisComponent.js +32 -80
- package/lib/axes/CategoryMapComponent.js +4 -4
- package/lib/axes/RangesComponent.js +2 -2
- package/lib/dashboards/DashboardComponent.d.ts +6 -0
- package/lib/dashboards/DashboardComponent.js +44 -12
- package/lib/dashboards/DashboardDesign.d.ts +11 -2
- package/lib/dashboards/DashboardUtils.d.ts +5 -0
- package/lib/dashboards/DashboardUtils.js +30 -0
- package/lib/dashboards/DashboardViewComponent.d.ts +2 -0
- package/lib/dashboards/DashboardViewComponent.js +16 -3
- package/lib/dashboards/ServerDashboardDataSource.js +2 -1
- package/lib/dashboards/SettingsModalComponent.d.ts +1 -1
- package/lib/dashboards/SettingsModalComponent.js +256 -19
- package/lib/dashboards/WidgetComponent.d.ts +6 -3
- package/lib/dashboards/WidgetComponent.js +3 -1
- package/lib/datagrids/CellEditor.d.ts +19 -0
- package/lib/datagrids/CellEditor.js +223 -0
- package/lib/datagrids/DatagridComponent.d.ts +18 -87
- package/lib/datagrids/DatagridComponent.js +304 -222
- package/lib/datagrids/DatagridViewComponent.d.ts +15 -53
- package/lib/datagrids/DatagridViewComponent.js +256 -257
- package/lib/datagrids/DirectDatagridDataSource.js +2 -3
- package/lib/datagrids/ExprCellComponent.d.ts +8 -15
- package/lib/datagrids/ExprCellComponent.js +11 -15
- package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -6
- package/lib/datagrids/FindReplaceModalComponent.js +38 -75
- package/lib/index.css +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
- package/lib/mWaterLoader.d.ts +1 -1
- package/lib/maps/BufferLayer.d.ts +7 -5
- package/lib/maps/BufferLayer.js +69 -48
- package/lib/maps/BufferLayerDesign.d.ts +21 -14
- package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
- package/lib/maps/BufferLayerDesignerComponent.js +68 -102
- package/lib/maps/ChoroplethLayer.d.ts +5 -4
- package/lib/maps/ChoroplethLayer.js +32 -9
- package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
- package/lib/maps/ChoroplethLayerDesigner.js +4 -2
- package/lib/maps/ClusterLayer.d.ts +3 -4
- package/lib/maps/ClusterLayer.js +2 -1
- package/lib/maps/DetailLevelSelectComponent.js +1 -1
- package/lib/maps/DirectMapDataSource.js +2 -1
- package/lib/maps/EditPopupComponent.js +5 -3
- package/lib/maps/GridLayer.d.ts +3 -4
- package/lib/maps/GridLayer.js +2 -1
- package/lib/maps/GridLayerDesigner.js +5 -3
- package/lib/maps/HoverContent.d.ts +11 -3
- package/lib/maps/HoverContent.js +25 -9
- package/lib/maps/Layer.d.ts +24 -3
- package/lib/maps/Layer.js +5 -1
- package/lib/maps/LayerFactory.js +0 -8
- package/lib/maps/LayerLegendComponent.js +0 -1
- package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
- package/lib/maps/LayerSwitcherComponent.js +1 -1
- package/lib/maps/LeafletMapComponent.js +3 -1
- package/lib/maps/LegendComponent.d.ts +1 -0
- package/lib/maps/LegendComponent.js +9 -1
- package/lib/maps/MWaterServerLayer.d.ts +2 -2
- package/lib/maps/MWaterServerLayer.js +2 -2
- package/lib/maps/MapComponent.js +3 -3
- package/lib/maps/MapDesign.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.d.ts +4 -3
- package/lib/maps/MapDesignerComponent.js +68 -74
- package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
- package/lib/maps/MapUtils.d.ts +4 -0
- package/lib/maps/MapUtils.js +19 -0
- package/lib/maps/MapViewComponent.d.ts +8 -3
- package/lib/maps/MarkersLayer.d.ts +5 -4
- package/lib/maps/MarkersLayer.js +33 -7
- package/lib/maps/MarkersLayerDesign.d.ts +19 -16
- package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
- package/lib/maps/PopupFilterJoinsUtils.js +0 -6
- package/lib/maps/RasterMapViewComponent.d.ts +3 -31
- package/lib/maps/RasterMapViewComponent.js +7 -2
- package/lib/maps/ServerMapDataSource.js +2 -1
- package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
- package/lib/maps/SwitchableTileUrlLayer.js +2 -1
- package/lib/maps/TileUrlLayer.d.ts +4 -5
- package/lib/maps/TileUrlLayer.js +2 -1
- package/lib/maps/VectorMapViewComponent.d.ts +5 -37
- package/lib/maps/VectorMapViewComponent.js +19 -8
- package/lib/maps/maps.d.ts +3 -0
- package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
- package/lib/quickfilter/QuickfiltersComponent.js +9 -7
- package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +1 -1
- package/lib/quickfilter/QuickfiltersDesignComponent.js +19 -35
- package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
- package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
- package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
- package/lib/richtext/ExprItemsTranslator.js +149 -0
- package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
- package/lib/richtext/ItemsHtmlConverter.js +31 -15
- package/lib/wellknown.js +12 -9
- package/lib/widgets/IFrameWidget.d.ts +4 -4
- package/lib/widgets/ImageWidget.d.ts +7 -4
- package/lib/widgets/ImageWidget.js +9 -1
- package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
- package/lib/widgets/ImageWidgetComponent.js +1 -1
- package/lib/widgets/MapWidget.d.ts +5 -48
- package/lib/widgets/MapWidget.js +26 -63
- package/lib/widgets/MarkdownWidget.d.ts +3 -0
- package/lib/widgets/MarkdownWidget.js +3 -0
- package/lib/widgets/TOCWidget.d.ts +15 -27
- package/lib/widgets/TOCWidget.js +107 -183
- package/lib/widgets/Widget.d.ts +18 -7
- package/lib/widgets/Widget.js +4 -0
- package/lib/widgets/WidgetScopesViewComponent.js +1 -1
- package/lib/widgets/charts/Chart.d.ts +10 -1
- package/lib/widgets/charts/Chart.js +22 -11
- package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartViewComponent.js +6 -3
- package/lib/widgets/charts/ChartWidget.d.ts +2 -0
- package/lib/widgets/charts/ChartWidget.js +9 -1
- package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
- package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
- package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
- package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
- package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
- package/lib/widgets/charts/layered/LayeredChart.js +63 -3
- package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
- package/lib/widgets/charts/layered/LayeredChartCompiler.js +3 -3
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
- package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
- package/lib/widgets/charts/pivot/PivotChart.js +63 -0
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +1 -0
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +6 -0
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
- package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
- package/lib/widgets/charts/table/TableChart.d.ts +1 -0
- package/lib/widgets/charts/table/TableChart.js +15 -0
- package/lib/widgets/text/TextComponent.d.ts +11 -4
- package/lib/widgets/text/TextComponent.js +11 -8
- package/lib/widgets/text/TextWidget.d.ts +6 -3
- package/lib/widgets/text/TextWidget.js +7 -1
- package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
- package/lib/widgets/text/TextWidgetComponent.js +7 -1
- package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
- package/lib/widgets/text/TextWidgetDesign.js +1 -1
- package/package.json +7 -8
- package/src/ColorComponent.tsx +1 -2
- package/src/IdSelection.ts +62 -0
- package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
- package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
- package/src/MWaterLoaderComponent.ts +28 -26
- package/src/MWaterResponsesFilterComponent.ts +5 -2
- package/src/MWaterTableSelectComponent.tsx +5 -9
- package/src/autotranslate.ts +141 -0
- package/src/axes/AxisBuilder.ts +3 -3
- package/src/axes/AxisColorEditorComponent.tsx +5 -0
- package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
- package/src/axes/CategoryMapComponent.ts +4 -4
- package/src/axes/RangesComponent.ts +3 -2
- package/src/dashboards/DashboardComponent.tsx +79 -14
- package/src/dashboards/DashboardDesign.ts +9 -2
- package/src/dashboards/DashboardUtils.ts +39 -0
- package/src/dashboards/DashboardViewComponent.tsx +22 -3
- package/src/dashboards/ServerDashboardDataSource.ts +2 -1
- package/src/dashboards/SettingsModalComponent.tsx +450 -35
- package/src/dashboards/WidgetComponent.tsx +12 -6
- package/src/datagrids/CellEditor.tsx +354 -0
- package/src/datagrids/DatagridComponent.tsx +646 -0
- package/src/datagrids/DatagridViewComponent.tsx +539 -0
- package/src/datagrids/DirectDatagridDataSource.ts +2 -3
- package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
- package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
- package/src/index.css +1 -1
- package/src/index.ts +0 -1
- package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
- package/src/mWaterLoader.ts +1 -1
- package/src/maps/BufferLayer.ts +83 -60
- package/src/maps/BufferLayerDesign.ts +20 -14
- package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
- package/src/maps/ChoroplethLayer.ts +40 -19
- package/src/maps/ChoroplethLayerDesign.ts +4 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
- package/src/maps/ClusterLayer.ts +4 -10
- package/src/maps/DetailLevelSelectComponent.ts +1 -1
- package/src/maps/DirectMapDataSource.ts +2 -1
- package/src/maps/EditPopupComponent.ts +7 -3
- package/src/maps/GridLayer.ts +4 -10
- package/src/maps/GridLayerDesigner.tsx +5 -3
- package/src/maps/HoverContent.tsx +40 -16
- package/src/maps/Layer.ts +28 -10
- package/src/maps/LayerFactory.ts +0 -8
- package/src/maps/LayerLegendComponent.ts +2 -4
- package/src/maps/LayerSwitcherComponent.tsx +6 -2
- package/src/maps/LeafletMapComponent.tsx +3 -1
- package/src/maps/LegendComponent.tsx +10 -1
- package/src/maps/MWaterServerLayer.ts +3 -3
- package/src/maps/MapComponent.ts +3 -3
- package/src/maps/MapDesign.ts +3 -0
- package/src/maps/MapDesignerComponent.tsx +165 -162
- package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
- package/src/maps/MapUtils.ts +24 -0
- package/src/maps/MapViewComponent.tsx +11 -3
- package/src/maps/MarkersLayer.ts +44 -18
- package/src/maps/MarkersLayerDesign.ts +19 -16
- package/src/maps/PopupFilterJoinsUtils.ts +6 -2
- package/src/maps/RasterMapViewComponent.ts +9 -45
- package/src/maps/ServerMapDataSource.ts +2 -2
- package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
- package/src/maps/TileUrlLayer.tsx +4 -10
- package/src/maps/VectorMapViewComponent.tsx +28 -55
- package/src/maps/maps.ts +3 -0
- package/src/quickfilter/QuickfiltersComponent.ts +13 -7
- package/src/quickfilter/QuickfiltersDesignComponent.tsx +56 -74
- package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
- package/src/richtext/ExprItemsTranslator.ts +176 -0
- package/src/richtext/ItemsHtmlConverter.ts +33 -18
- package/src/wellknown.ts +33 -30
- package/src/widgets/ImageWidget.ts +10 -1
- package/src/widgets/ImageWidgetComponent.ts +3 -2
- package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
- package/src/widgets/MarkdownWidget.ts +3 -0
- package/src/widgets/TOCWidget.tsx +281 -0
- package/src/widgets/Widget.ts +25 -5
- package/src/widgets/WidgetScopesViewComponent.ts +2 -1
- package/src/widgets/charts/Chart.ts +31 -12
- package/src/widgets/charts/ChartViewComponent.ts +13 -3
- package/src/widgets/charts/ChartWidget.ts +11 -1
- package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
- package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
- package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
- package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
- package/src/widgets/charts/layered/LayeredChart.ts +71 -3
- package/src/widgets/charts/layered/LayeredChartCompiler.ts +4 -4
- package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
- package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
- package/src/widgets/charts/pivot/PivotChart.ts +73 -0
- package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
- package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
- package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
- package/src/widgets/charts/table/TableChart.ts +17 -0
- package/src/widgets/text/TextComponent.tsx +22 -12
- package/src/widgets/text/TextWidget.ts +9 -2
- package/src/widgets/text/TextWidgetComponent.tsx +16 -1
- package/src/widgets/text/TextWidgetDesign.ts +4 -7
- package/test/IdSelectionTests.ts +54 -0
- package/test/LayeredChartCompilerTests.ts +0 -2
- package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
- package/test/wellknownTests.ts +144 -0
- package/src/datagrids/DatagridComponent.ts +0 -478
- package/src/datagrids/DatagridViewComponent.ts +0 -464
- package/src/datagrids/EditExprCellComponent.tsx +0 -305
- package/src/datagrids/README.md +0 -3
- package/src/maps/BufferLayerDesignerComponent.ts +0 -311
- package/src/widgets/TOCWidget.ts +0 -326
- package/test/LegoLayoutEngineTests.ts +0 -69
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.translateStrings = translateStrings;
|
|
4
|
+
exports.translateLocalizedStrings = translateLocalizedStrings;
|
|
5
|
+
exports.canAutoTranslate = canAutoTranslate;
|
|
6
|
+
/** Translates an array of strings from a source language to a target language using the mWater translation API.
|
|
7
|
+
* @param strings Array of strings to translate
|
|
8
|
+
* @param sourceLanguage Source language code (e.g. "en")
|
|
9
|
+
* @param targetLanguage Target language code to translate to
|
|
10
|
+
* @returns Promise that resolves to array of translated strings in same order as input
|
|
11
|
+
* @throws Error if translation fails
|
|
12
|
+
*/
|
|
13
|
+
async function translateStrings(strings, sourceLanguage, targetLanguage) {
|
|
14
|
+
// Call translation API
|
|
15
|
+
const response = await fetch(`https://api.mwater.co/v3/translate?source_language=${sourceLanguage}&target_language=${targetLanguage}`, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: {
|
|
18
|
+
"Content-Type": "application/json"
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({
|
|
21
|
+
phrases: strings
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error("Translation failed");
|
|
26
|
+
}
|
|
27
|
+
const result = await response.json();
|
|
28
|
+
return result.phrases;
|
|
29
|
+
}
|
|
30
|
+
/** Ensures that all LocalizedString objects have translations for all specified locales.
|
|
31
|
+
* Only translates missing translations, preserving existing ones and base strings.
|
|
32
|
+
* Each string's _base property is used as the source language for translations.
|
|
33
|
+
* @param strings Array of LocalizedString objects to ensure are fully translated
|
|
34
|
+
* @param locales Array of language codes specifying which languages to ensure exist
|
|
35
|
+
* @param baseLanguage Language code of the _base strings (e.g. "en", "fr", etc)
|
|
36
|
+
* @returns Promise that resolves to array of fully translated LocalizedString objects
|
|
37
|
+
*/
|
|
38
|
+
async function translateLocalizedStrings(strings, locales, baseLanguage) {
|
|
39
|
+
// Create copy of strings to modify
|
|
40
|
+
const translatedStrings = strings.map(str => ({ ...str }));
|
|
41
|
+
// For each locale
|
|
42
|
+
for (const locale of locales) {
|
|
43
|
+
// Skip if it's the base language
|
|
44
|
+
if (locale === baseLanguage) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Group strings by their current source language
|
|
48
|
+
// Start with base language strings
|
|
49
|
+
const stringsBySourceLang = new Map();
|
|
50
|
+
translatedStrings.forEach((str, index) => {
|
|
51
|
+
// Skip if translation already exists
|
|
52
|
+
if (str[locale]) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Add to list to translate from base language
|
|
56
|
+
if (!stringsBySourceLang.has(baseLanguage)) {
|
|
57
|
+
stringsBySourceLang.set(baseLanguage, []);
|
|
58
|
+
}
|
|
59
|
+
stringsBySourceLang.get(baseLanguage).push({ str, index });
|
|
60
|
+
});
|
|
61
|
+
// Translate each group
|
|
62
|
+
for (const [sourceLang, stringsToTranslate] of stringsBySourceLang.entries()) {
|
|
63
|
+
try {
|
|
64
|
+
// Get source strings
|
|
65
|
+
const sourceStrings = stringsToTranslate.map(item => item.str[item.str._base]);
|
|
66
|
+
// Translate all strings at once
|
|
67
|
+
const translations = await translateStrings(sourceStrings, sourceLang, locale);
|
|
68
|
+
// Add translations back to strings
|
|
69
|
+
translations.forEach((translation, i) => {
|
|
70
|
+
translatedStrings[stringsToTranslate[i].index][locale] = translation;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error(`Failed to translate from ${sourceLang} to ${locale}:`, error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return translatedStrings;
|
|
80
|
+
}
|
|
81
|
+
/** Returns true if the given language code can be automatically translated. */
|
|
82
|
+
function canAutoTranslate(languageCode) {
|
|
83
|
+
const languageCodes = [
|
|
84
|
+
"en", // English
|
|
85
|
+
"fr", // French
|
|
86
|
+
"es", // Spanish
|
|
87
|
+
"pt", // Portuguese
|
|
88
|
+
"sw", // Swahili
|
|
89
|
+
"id", // Indonesian
|
|
90
|
+
"hi", // Hindi
|
|
91
|
+
"ne", // Nepali
|
|
92
|
+
"rw", // Kinyarwanda
|
|
93
|
+
"sd", // Sindhi
|
|
94
|
+
"tet", // Tetum
|
|
95
|
+
"ur", // Urdu
|
|
96
|
+
"ja", // Japanese
|
|
97
|
+
"de", // German
|
|
98
|
+
"it", // Italian
|
|
99
|
+
"su", // Sundanese
|
|
100
|
+
"ar", // Arabic
|
|
101
|
+
"vi", // Vietnamese
|
|
102
|
+
"mg", // Malagasy
|
|
103
|
+
"tl", // Tagalog/Filipino
|
|
104
|
+
"ht", // Haitian Creole
|
|
105
|
+
"fi", // Finnish
|
|
106
|
+
"bn", // Bangla
|
|
107
|
+
"my", // Burmese
|
|
108
|
+
"km", // Khmer
|
|
109
|
+
"so", // Somali
|
|
110
|
+
"jv", // Javanese
|
|
111
|
+
"ko", // Korean
|
|
112
|
+
"zh", // Chinese
|
|
113
|
+
"ru", // Russian
|
|
114
|
+
"tr", // Turkish
|
|
115
|
+
"nl", // Dutch
|
|
116
|
+
"pl", // Polish
|
|
117
|
+
"hu", // Hungarian
|
|
118
|
+
"cs", // Czech
|
|
119
|
+
"sk" // Slovak
|
|
120
|
+
];
|
|
121
|
+
return languageCodes.includes(languageCode);
|
|
122
|
+
}
|
package/lib/axes/AxisBuilder.js
CHANGED
|
@@ -495,7 +495,7 @@ class AxisBuilder {
|
|
|
495
495
|
}
|
|
496
496
|
if (range.maxValue != null) {
|
|
497
497
|
if (label) {
|
|
498
|
-
label += T `
|
|
498
|
+
label += ` ${T `and`} `;
|
|
499
499
|
}
|
|
500
500
|
if (range.maxOpen) {
|
|
501
501
|
label += `< ${range.maxValue}`;
|
|
@@ -920,7 +920,7 @@ class AxisBuilder {
|
|
|
920
920
|
return this.formatCategory(axis, category);
|
|
921
921
|
}
|
|
922
922
|
else {
|
|
923
|
-
return
|
|
923
|
+
return `???`;
|
|
924
924
|
}
|
|
925
925
|
}).join(", ");
|
|
926
926
|
}
|
|
@@ -930,7 +930,7 @@ class AxisBuilder {
|
|
|
930
930
|
return this.formatCategory(axis, category);
|
|
931
931
|
}
|
|
932
932
|
else {
|
|
933
|
-
return
|
|
933
|
+
return `???`;
|
|
934
934
|
}
|
|
935
935
|
}
|
|
936
936
|
}
|
|
@@ -48,6 +48,10 @@ class AxisColorEditorComponent extends react_1.default.Component {
|
|
|
48
48
|
}
|
|
49
49
|
const missingColorMap = ColorSchemeFactory_1.default.createColorMapForCategories(missingCategories, axisBuilder.isCategorical(this.props.axis));
|
|
50
50
|
colorMap = (this.props.axis.colorMap || []).concat(missingColorMap);
|
|
51
|
+
// If there are categories present, remove any color map values that are not in the categories
|
|
52
|
+
if (this.props.categories.length > 0) {
|
|
53
|
+
colorMap = lodash_1.default.filter(colorMap, (cm) => this.props.categories.find((c) => c.value === cm.value));
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
else {
|
|
53
57
|
// Keep existing
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent";
|
|
3
3
|
import { DataSource, LiteralType, Schema } from "@mwater/expressions";
|
|
4
|
-
import * as ui from "../UIComponents";
|
|
5
|
-
import CategoryMapComponent from "./CategoryMapComponent";
|
|
6
4
|
import { JsonQLFilter } from "../JsonQLFilter";
|
|
7
|
-
import { Axis } from "./Axis";
|
|
5
|
+
import { Axis, AxisCategory } from "./Axis";
|
|
8
6
|
export interface AxisComponentProps {
|
|
9
7
|
schema: Schema;
|
|
10
8
|
dataSource: DataSource;
|
|
@@ -34,7 +32,7 @@ export interface AxisComponentProps {
|
|
|
34
32
|
collapseCategories?: boolean;
|
|
35
33
|
}
|
|
36
34
|
export default class AxisComponent extends AsyncLoadComponent<AxisComponentProps, {
|
|
37
|
-
categories:
|
|
35
|
+
categories: AxisCategory[] | null;
|
|
38
36
|
loading: boolean;
|
|
39
37
|
}> {
|
|
40
38
|
static defaultProps: {
|
|
@@ -45,17 +43,15 @@ export default class AxisComponent extends AsyncLoadComponent<AxisComponentProps
|
|
|
45
43
|
static contextType: React.Context<string>;
|
|
46
44
|
constructor(props: any);
|
|
47
45
|
isLoadNeeded(newProps: any, oldProps: any): boolean;
|
|
48
|
-
load(props: any, prevProps: any, callback: any):
|
|
46
|
+
load(props: any, prevProps: any, callback: any): void;
|
|
49
47
|
handleExprChange: (expr: any) => void;
|
|
50
48
|
handleFormatChange: (ev: any) => void;
|
|
51
49
|
handleXformTypeChange: (type: any) => void;
|
|
52
50
|
handleXformChange: (xform: any) => void;
|
|
53
51
|
cleanAxis(axis: any): Axis | null;
|
|
54
|
-
renderXform(axis: any): React.
|
|
55
|
-
renderColorMap(axis: any): React.
|
|
56
|
-
renderExcludedValues(axis: any):
|
|
57
|
-
renderFormat(axis: any): React.
|
|
58
|
-
|
|
59
|
-
}, HTMLElement> | null;
|
|
60
|
-
render(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
52
|
+
renderXform(axis: any): React.JSX.Element | null;
|
|
53
|
+
renderColorMap(axis: any): React.JSX.Element | null;
|
|
54
|
+
renderExcludedValues(axis: any): React.JSX.Element | null;
|
|
55
|
+
renderFormat(axis: any): React.JSX.Element | null;
|
|
56
|
+
render(): React.JSX.Element;
|
|
61
57
|
}
|
|
@@ -28,7 +28,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const lodash_1 = __importDefault(require("lodash"));
|
|
30
30
|
const react_1 = __importDefault(require("react"));
|
|
31
|
-
const R = react_1.default.createElement;
|
|
32
31
|
const uuid_1 = __importDefault(require("uuid"));
|
|
33
32
|
const AsyncLoadComponent_1 = __importDefault(require("@mwater/react-library/lib/AsyncLoadComponent"));
|
|
34
33
|
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
@@ -118,13 +117,13 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
118
117
|
else {
|
|
119
118
|
valuesQuery.where = whereClauses[0];
|
|
120
119
|
}
|
|
121
|
-
|
|
120
|
+
props.dataSource.performQuery(valuesQuery, (error, rows) => {
|
|
122
121
|
if (error) {
|
|
123
122
|
return; // Ignore errors
|
|
124
123
|
}
|
|
125
124
|
// Get categories (value + label)
|
|
126
125
|
categories = axisBuilder.getCategories(axis, lodash_1.default.pluck(rows, "val"));
|
|
127
|
-
|
|
126
|
+
callback({ categories });
|
|
128
127
|
});
|
|
129
128
|
}
|
|
130
129
|
handleExprChange = (expr) => {
|
|
@@ -204,42 +203,27 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
204
203
|
if (axis.xform && ["bin", "ranges", "floor"].includes(axis.xform.type)) {
|
|
205
204
|
let comp;
|
|
206
205
|
if (axis.xform.type === "ranges") {
|
|
207
|
-
comp =
|
|
208
|
-
schema: this.props.schema,
|
|
209
|
-
expr: axis.expr,
|
|
210
|
-
xform: axis.xform,
|
|
211
|
-
onChange: this.handleXformChange
|
|
212
|
-
});
|
|
206
|
+
comp = react_1.default.createElement(RangesComponent_1.default, { schema: this.props.schema, expr: axis.expr, xform: axis.xform, onChange: this.handleXformChange });
|
|
213
207
|
}
|
|
214
208
|
else if (axis.xform.type === "bin") {
|
|
215
|
-
comp =
|
|
216
|
-
schema: this.props.schema,
|
|
217
|
-
dataSource: this.props.dataSource,
|
|
218
|
-
expr: axis.expr,
|
|
219
|
-
xform: axis.xform,
|
|
220
|
-
onChange: this.handleXformChange
|
|
221
|
-
});
|
|
209
|
+
comp = react_1.default.createElement(BinsComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, expr: axis.expr, xform: axis.xform, onChange: this.handleXformChange });
|
|
222
210
|
}
|
|
223
211
|
else {
|
|
224
212
|
comp = null;
|
|
225
213
|
}
|
|
226
|
-
return
|
|
227
|
-
value: axis.xform ? axis.xform.type : null,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
onChange: this.handleXformTypeChange
|
|
234
|
-
}), comp);
|
|
214
|
+
return (react_1.default.createElement("div", null,
|
|
215
|
+
react_1.default.createElement(ui.RadioToggleComponent, { value: axis.xform ? axis.xform.type : null, options: [
|
|
216
|
+
{ value: "bin", label: T `Equal Bins` },
|
|
217
|
+
{ value: "ranges", label: T `Custom Ranges` },
|
|
218
|
+
{ value: "floor", label: T `Whole Numbers` }
|
|
219
|
+
], onChange: this.handleXformTypeChange }),
|
|
220
|
+
comp));
|
|
235
221
|
}
|
|
236
222
|
const exprUtils = new expressions_1.ExprUtils(this.props.schema);
|
|
237
223
|
const exprType = exprUtils.getExprType(axis.expr);
|
|
238
224
|
switch (exprType) {
|
|
239
225
|
case "date":
|
|
240
|
-
return
|
|
241
|
-
value: axis.xform ? axis.xform.type : null,
|
|
242
|
-
options: [
|
|
226
|
+
return react_1.default.createElement(ui.RadioToggleComponent, { value: axis.xform ? axis.xform.type : null, options: [
|
|
243
227
|
{ value: null, label: T `Exact Date` },
|
|
244
228
|
{ value: "year", label: T `Year` },
|
|
245
229
|
{ value: "yearmonth", label: T `Year/Month` },
|
|
@@ -247,13 +231,9 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
247
231
|
{ value: "week", label: T `Week` },
|
|
248
232
|
{ value: "yearweek", label: T `Year/Week` },
|
|
249
233
|
{ value: "yearquarter", label: T `Year/Quarter` }
|
|
250
|
-
],
|
|
251
|
-
onChange: this.handleXformTypeChange
|
|
252
|
-
});
|
|
234
|
+
], onChange: this.handleXformTypeChange });
|
|
253
235
|
case "datetime":
|
|
254
|
-
return
|
|
255
|
-
value: axis.xform ? axis.xform.type : null,
|
|
256
|
-
options: [
|
|
236
|
+
return react_1.default.createElement(ui.RadioToggleComponent, { value: axis.xform ? axis.xform.type : null, options: [
|
|
257
237
|
{ value: "date", label: T `Date` },
|
|
258
238
|
{ value: "year", label: T `Year` },
|
|
259
239
|
{ value: "yearmonth", label: T `Year/Month` },
|
|
@@ -261,9 +241,7 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
261
241
|
{ value: "week", label: T `Week` },
|
|
262
242
|
{ value: "yearweek", label: T `Year/Week` },
|
|
263
243
|
{ value: "yearquarter", label: T `Year/Quarter` }
|
|
264
|
-
],
|
|
265
|
-
onChange: this.handleXformTypeChange
|
|
266
|
-
});
|
|
244
|
+
], onChange: this.handleXformTypeChange });
|
|
267
245
|
}
|
|
268
246
|
return null;
|
|
269
247
|
}
|
|
@@ -271,20 +249,9 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
271
249
|
if (!this.props.showColorMap || !axis || !axis.expr) {
|
|
272
250
|
return null;
|
|
273
251
|
}
|
|
274
|
-
return
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
schema: this.props.schema,
|
|
278
|
-
axis,
|
|
279
|
-
categories: this.state.categories,
|
|
280
|
-
onChange: this.props.onChange,
|
|
281
|
-
reorderable: this.props.reorderable,
|
|
282
|
-
defaultColor: this.props.defaultColor,
|
|
283
|
-
allowExcludedValues: this.props.allowExcludedValues,
|
|
284
|
-
autosetColors: this.props.autosetColors,
|
|
285
|
-
initiallyExpanded: this.props.collapseCategories !== true
|
|
286
|
-
})
|
|
287
|
-
];
|
|
252
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
253
|
+
react_1.default.createElement("br", null),
|
|
254
|
+
react_1.default.createElement(AxisColorEditorComponent_1.default, { schema: this.props.schema, axis: axis, categories: this.state.categories ?? undefined, onChange: this.props.onChange, reorderable: this.props.reorderable, defaultColor: this.props.defaultColor ?? undefined, allowExcludedValues: this.props.allowExcludedValues, autosetColors: this.props.autosetColors, initiallyExpanded: this.props.collapseCategories !== true })));
|
|
288
255
|
}
|
|
289
256
|
renderExcludedValues(axis) {
|
|
290
257
|
// Only if no color map and allows excluded values
|
|
@@ -295,19 +262,9 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
295
262
|
if (!this.state.categories || this.state.categories.length < 1) {
|
|
296
263
|
return null;
|
|
297
264
|
}
|
|
298
|
-
return
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
schema: this.props.schema,
|
|
302
|
-
axis,
|
|
303
|
-
onChange: this.props.onChange,
|
|
304
|
-
categories: this.state.categories,
|
|
305
|
-
reorderable: false,
|
|
306
|
-
showColorMap: false,
|
|
307
|
-
allowExcludedValues: true,
|
|
308
|
-
initiallyExpanded: this.props.collapseCategories !== true
|
|
309
|
-
})
|
|
310
|
-
];
|
|
265
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
266
|
+
react_1.default.createElement("br", null),
|
|
267
|
+
react_1.default.createElement(CategoryMapComponent_1.default, { schema: this.props.schema, axis: axis, onChange: this.props.onChange, categories: this.state.categories, reorderable: false, showColorMap: false, allowExcludedValues: true, initiallyExpanded: this.props.collapseCategories !== true })));
|
|
311
268
|
}
|
|
312
269
|
renderFormat(axis) {
|
|
313
270
|
const axisBuilder = new AxisBuilder_1.default({ schema: this.props.schema });
|
|
@@ -319,12 +276,10 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
319
276
|
if (!formats) {
|
|
320
277
|
return null;
|
|
321
278
|
}
|
|
322
|
-
return
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
style: { width: "auto", display: "inline-block" },
|
|
326
|
-
onChange: this.handleFormatChange
|
|
327
|
-
}, lodash_1.default.map(formats, (format) => R("option", { key: format.value, value: format.value }, format.label))));
|
|
279
|
+
return (react_1.default.createElement("div", { className: "mb-3" },
|
|
280
|
+
react_1.default.createElement("label", { className: "text-muted" }, T `Format`),
|
|
281
|
+
": ",
|
|
282
|
+
react_1.default.createElement("select", { value: axis.format != null ? axis.format : (0, valueFormatter_2.getDefaultFormat)(valueType), className: "form-select", style: { width: "auto", display: "inline-block" }, onChange: this.handleFormatChange }, lodash_1.default.map(formats, (format) => (react_1.default.createElement("option", { key: format.value, value: format.value }, format.label))))));
|
|
328
283
|
}
|
|
329
284
|
render() {
|
|
330
285
|
let aggrStatuses;
|
|
@@ -343,16 +298,13 @@ class AxisComponent extends AsyncLoadComponent_1.default {
|
|
|
343
298
|
aggrStatuses = ["literal", "aggregate"];
|
|
344
299
|
break;
|
|
345
300
|
}
|
|
346
|
-
return
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
value: this.props.value ? this.props.value.expr : null,
|
|
354
|
-
aggrStatuses
|
|
355
|
-
})), this.renderXform(axis), this.props.showFormat ? this.renderFormat(axis) : undefined, this.renderColorMap(axis), this.renderExcludedValues(axis));
|
|
301
|
+
return (react_1.default.createElement("div", null,
|
|
302
|
+
react_1.default.createElement("div", null,
|
|
303
|
+
react_1.default.createElement(expressions_ui_1.ExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, table: this.props.table, types: axisBuilder.getExprTypes(this.props.types), onChange: this.handleExprChange, value: this.props.value ? this.props.value.expr : null, aggrStatuses: aggrStatuses })),
|
|
304
|
+
this.renderXform(axis),
|
|
305
|
+
this.props.showFormat ? this.renderFormat(axis) : undefined,
|
|
306
|
+
this.renderColorMap(axis),
|
|
307
|
+
this.renderExcludedValues(axis)));
|
|
356
308
|
}
|
|
357
309
|
}
|
|
358
310
|
exports.default = AxisComponent;
|
|
@@ -23,7 +23,7 @@ class CategoryMapComponent extends react_1.default.Component {
|
|
|
23
23
|
}
|
|
24
24
|
handleReorder = (map) => {
|
|
25
25
|
const order = lodash_1.default.pluck(map, "value");
|
|
26
|
-
|
|
26
|
+
this.props.onChange((0, update_object_1.default)(this.props.axis, { drawOrder: { $set: order } }));
|
|
27
27
|
};
|
|
28
28
|
handleColorChange = (value, color) => {
|
|
29
29
|
// Delete if present for value
|
|
@@ -32,7 +32,7 @@ class CategoryMapComponent extends react_1.default.Component {
|
|
|
32
32
|
if (color) {
|
|
33
33
|
colorMap.push({ value, color });
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
this.props.onChange((0, update_object_1.default)(this.props.axis, { colorMap: { $set: colorMap } }));
|
|
36
36
|
};
|
|
37
37
|
handleExcludeChange = (value, ev) => {
|
|
38
38
|
let excludedValues;
|
|
@@ -42,7 +42,7 @@ class CategoryMapComponent extends react_1.default.Component {
|
|
|
42
42
|
else {
|
|
43
43
|
excludedValues = lodash_1.default.union(this.props.axis.excludedValues || [], [value]);
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
this.props.onChange((0, update_object_1.default)(this.props.axis, { excludedValues: { $set: excludedValues } }));
|
|
46
46
|
};
|
|
47
47
|
// Gets the current color value if known
|
|
48
48
|
lookupColor(value) {
|
|
@@ -55,7 +55,7 @@ class CategoryMapComponent extends react_1.default.Component {
|
|
|
55
55
|
handleNullLabelChange = (e) => {
|
|
56
56
|
const name = prompt(T `Enter label for none value`, this.props.axis.nullLabel || T `None`);
|
|
57
57
|
if (name) {
|
|
58
|
-
|
|
58
|
+
this.props.onChange((0, update_object_1.default)(this.props.axis, { nullLabel: { $set: name } }));
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
handleCategoryLabelChange = (category, e) => {
|
|
@@ -54,7 +54,7 @@ class RangesComponent extends react_1.default.Component {
|
|
|
54
54
|
})),
|
|
55
55
|
// _.map @props.xform.ranges, (range, i) =>
|
|
56
56
|
// R RangeComponent, key: range.id, range: range, onChange: @handleRangeChange.bind(null, i), onRemove: @handleRemoveRange.bind(null, i)
|
|
57
|
-
R("button", { className: "btn btn-link btn-sm", type: "button", onClick: this.handleAddRange }, R("span", { className: "fas fa-plus" }), T `
|
|
57
|
+
R("button", { className: "btn btn-link btn-sm", type: "button", onClick: this.handleAddRange }, R("span", { className: "fas fa-plus" }), " ", T `Add Range`));
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
exports.default = RangesComponent;
|
|
@@ -88,7 +88,7 @@ class RangeComponent extends react_1.default.Component {
|
|
|
88
88
|
}
|
|
89
89
|
if (this.props.range.maxValue != null) {
|
|
90
90
|
if (placeholder) {
|
|
91
|
-
placeholder += T `
|
|
91
|
+
placeholder += ` ${T `and`} `;
|
|
92
92
|
}
|
|
93
93
|
if (this.props.range.maxOpen) {
|
|
94
94
|
placeholder += `< ${this.props.range.maxValue}`;
|
|
@@ -39,6 +39,8 @@ export interface DashboardComponentProps {
|
|
|
39
39
|
hideTitleBar?: boolean;
|
|
40
40
|
/** Called when the edit mode changes */
|
|
41
41
|
onEditModeChange?: (editing: boolean) => void;
|
|
42
|
+
/** Locale to prefer if available */
|
|
43
|
+
preferredLocale?: string;
|
|
42
44
|
}
|
|
43
45
|
export interface DashboardComponentState {
|
|
44
46
|
undoStack: UndoStack;
|
|
@@ -47,6 +49,8 @@ export interface DashboardComponentState {
|
|
|
47
49
|
layoutOptionsOpen: boolean;
|
|
48
50
|
hideQuickfilters: boolean;
|
|
49
51
|
refreshKey: number;
|
|
52
|
+
/** Locale to use for display. Ignored if in edit mode */
|
|
53
|
+
locale: string;
|
|
50
54
|
}
|
|
51
55
|
/** Dashboard component that includes an action bar at the top
|
|
52
56
|
* Manages undo stack and quickfilter value
|
|
@@ -72,6 +76,8 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
72
76
|
handleDesignChange: (design: any) => void;
|
|
73
77
|
handleShowQuickfilters: () => void;
|
|
74
78
|
getCompiledFilters(): JsonQLFilter[];
|
|
79
|
+
/** Translate function to use for display. Do not use when editing. */
|
|
80
|
+
translate: (input: string) => string;
|
|
75
81
|
renderEditingSwitch(): React.DetailedReactHTMLElement<{
|
|
76
82
|
key: string;
|
|
77
83
|
className: string;
|
|
@@ -39,6 +39,7 @@ const LayoutManager_1 = __importDefault(require("../layouts/LayoutManager"));
|
|
|
39
39
|
const LayoutOptionsComponent_1 = require("./LayoutOptionsComponent");
|
|
40
40
|
const ModalWindowComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalWindowComponent"));
|
|
41
41
|
const layoutOptions_1 = require("./layoutOptions");
|
|
42
|
+
const __1 = require("..");
|
|
42
43
|
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
43
44
|
/** Dashboard component that includes an action bar at the top
|
|
44
45
|
* Manages undo stack and quickfilter value
|
|
@@ -50,6 +51,15 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
50
51
|
constructor(props) {
|
|
51
52
|
super(props);
|
|
52
53
|
const layoutOptions = (0, layoutOptions_1.getLayoutOptions)(props.design);
|
|
54
|
+
// Prefer the T.en locale if available when loading the dashboard
|
|
55
|
+
let initialLocale = props.design.locale || "en";
|
|
56
|
+
const otherLocales = props.design.otherLocales || [];
|
|
57
|
+
if (props.preferredLocale && otherLocales.includes(props.preferredLocale)) {
|
|
58
|
+
initialLocale = props.preferredLocale;
|
|
59
|
+
}
|
|
60
|
+
else if (otherLocales.includes(T.locale)) {
|
|
61
|
+
initialLocale = T.locale;
|
|
62
|
+
}
|
|
53
63
|
this.state = {
|
|
54
64
|
undoStack: new UndoStack_1.default().push(props.design),
|
|
55
65
|
quickfiltersValues: props.quickfiltersValues || null,
|
|
@@ -57,7 +67,8 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
57
67
|
props.onDesignChange != null,
|
|
58
68
|
layoutOptionsOpen: false,
|
|
59
69
|
hideQuickfilters: layoutOptions.hideQuickfiltersWidth != null && layoutOptions.hideQuickfiltersWidth > document.body.clientWidth,
|
|
60
|
-
refreshKey: 1
|
|
70
|
+
refreshKey: 1,
|
|
71
|
+
locale: initialLocale
|
|
61
72
|
};
|
|
62
73
|
if (props.onEditModeChange) {
|
|
63
74
|
props.onEditModeChange(this.state.editing);
|
|
@@ -141,15 +152,24 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
141
152
|
compiledFilters = compiledFilters.concat(this.props.filters || []);
|
|
142
153
|
return compiledFilters;
|
|
143
154
|
}
|
|
155
|
+
/** Translate function to use for display. Do not use when editing. */
|
|
156
|
+
translate = (input) => {
|
|
157
|
+
const designLocale = this.props.design.locale ?? "en";
|
|
158
|
+
const displayLocale = this.state.editing ? designLocale : (this.state.locale ?? designLocale ?? "en");
|
|
159
|
+
if (designLocale === displayLocale) {
|
|
160
|
+
return input;
|
|
161
|
+
}
|
|
162
|
+
return this.props.design.translations?.[displayLocale]?.[input] ?? input;
|
|
163
|
+
};
|
|
144
164
|
renderEditingSwitch() {
|
|
145
165
|
return R("a", {
|
|
146
166
|
key: "edit",
|
|
147
167
|
className: `btn btn-primary btn-sm ${this.state.editing ? "active" : ""}`,
|
|
148
168
|
onClick: this.handleToggleEditing
|
|
149
|
-
}, R("span", { className: "fas fa-pencil-alt" }), this.state.editing ? T `
|
|
169
|
+
}, R("span", { className: "fas fa-pencil-alt" }), " ", this.state.editing ? T `Editing` : T `Edit`);
|
|
150
170
|
}
|
|
151
171
|
renderStyle() {
|
|
152
|
-
return R("button", { type: "button", key: "style", className: "btn btn-link btn-sm", onClick: this.handleOpenLayoutOptions }, R("span", { className: "fa fa-mobile" }), R("span", { className: "hide-600px" }, T `
|
|
172
|
+
return R("button", { type: "button", key: "style", className: "btn btn-link btn-sm", onClick: this.handleOpenLayoutOptions }, R("span", { className: "fa fa-mobile" }), R("span", { className: "hide-600px" }, " ", T `Layout`));
|
|
153
173
|
}
|
|
154
174
|
renderActionLinks() {
|
|
155
175
|
return R("div", null, this.state.editing
|
|
@@ -158,22 +178,30 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
158
178
|
key: "undo",
|
|
159
179
|
className: `btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`,
|
|
160
180
|
onClick: this.handleUndo
|
|
161
|
-
}, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, T `
|
|
181
|
+
}, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, " ", T `Undo`)),
|
|
162
182
|
" ",
|
|
163
183
|
R("a", {
|
|
164
184
|
key: "redo",
|
|
165
185
|
className: `btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`,
|
|
166
186
|
onClick: this.handleRedo
|
|
167
|
-
}, R("span", { className: "fas fa-caret-right" }), R("span", { className: "hide-600px" }, T `
|
|
187
|
+
}, R("span", { className: "fas fa-caret-right" }), R("span", { className: "hide-600px" }, " ", T `Redo`))
|
|
168
188
|
]
|
|
169
|
-
: undefined,
|
|
170
|
-
? R("
|
|
189
|
+
: undefined, !this.state.editing && this.props.design.otherLocales && this.props.design.otherLocales.length > 0
|
|
190
|
+
? R("div", { key: "translations", className: "dropdown d-inline-block" }, R("a", {
|
|
191
|
+
className: "btn btn-link btn-sm dropdown-toggle",
|
|
192
|
+
"data-bs-toggle": "dropdown"
|
|
193
|
+
}, R("span", { className: "fal fa-globe" }), " ", this.state.locale), R("ul", { className: "dropdown-menu dropdown-menu-end" }, [this.props.design.locale || "en", ...this.props.design.otherLocales].map(locale => R("li", { key: locale }, R("a", {
|
|
194
|
+
className: "dropdown-item",
|
|
195
|
+
onClick: () => this.setState({ locale: locale })
|
|
196
|
+
}, __1.languages.find(l => l.code === locale)?.name || locale)))))
|
|
197
|
+
: undefined, R("a", { key: "print", className: "btn btn-link btn-sm", onClick: this.handlePrint }, R("span", { className: "fas fa-print" }), R("span", { className: "hide-600px" }, " ", T `Print`)), R("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData }, R("span", { className: "fas fa-sync" }), R("span", { className: "hide-600px" }, " ", T `Refresh`)), this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
|
|
198
|
+
? R("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters }, R("span", { className: "fa fa-filter" }), R("span", { className: "hide-600px" }, " ", T `Show Quickfilters`))
|
|
171
199
|
: undefined,
|
|
172
200
|
// R 'a', key: "export", className: "btn btn-link btn-sm", onClick: @handleSaveDesignFile,
|
|
173
201
|
// R('span', className: "glyphicon glyphicon-download-alt")
|
|
174
202
|
// " Export"
|
|
175
203
|
this.state.editing
|
|
176
|
-
? R("a", { key: "settings", className: "btn btn-link btn-sm", onClick: this.handleSettings }, R("span", { className: "fas fa-cog" }), R("span", { className: "hide-600px" }, T `
|
|
204
|
+
? R("a", { key: "settings", className: "btn btn-link btn-sm", onClick: this.handleSettings }, R("span", { className: "fas fa-cog" }), R("span", { className: "hide-600px" }, " ", T `Settings`))
|
|
177
205
|
: undefined, this.state.editing ? this.renderStyle() : undefined, this.props.extraTitleButtonsElem, this.props.onDesignChange != null ? this.renderEditingSwitch() : undefined);
|
|
178
206
|
}
|
|
179
207
|
renderTitleBar() {
|
|
@@ -191,7 +219,8 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
191
219
|
filters: this.getCompiledFilters(),
|
|
192
220
|
hideTopBorder: this.props.hideTitleBar,
|
|
193
221
|
// Don't hide if title bar is hidden as it can't be shown again
|
|
194
|
-
onHide: () => !this.props.hideTitleBar ? this.setState({ hideQuickfilters: true }) : undefined
|
|
222
|
+
onHide: () => !this.props.hideTitleBar ? this.setState({ hideQuickfilters: true }) : undefined,
|
|
223
|
+
translate: this.translate
|
|
195
224
|
});
|
|
196
225
|
}
|
|
197
226
|
refDashboardView = (el) => {
|
|
@@ -201,6 +230,7 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
201
230
|
let filters = this.props.filters || [];
|
|
202
231
|
// Compile quickfilters
|
|
203
232
|
filters = filters.concat(new QuickfilterCompiler_1.default(this.props.schema).compile(this.props.design.quickfilters || [], this.state.quickfiltersValues, this.props.quickfilterLocks));
|
|
233
|
+
const displayLocale = this.state.editing ? this.props.design.locale || "en" : this.state.locale;
|
|
204
234
|
const dashboardView = R(DashboardViewComponent_1.default, {
|
|
205
235
|
schema: this.props.schema,
|
|
206
236
|
dataSource: this.props.dataSource,
|
|
@@ -212,7 +242,8 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
212
242
|
onRowClick: this.props.onRowClick,
|
|
213
243
|
namedStrings: this.props.namedStrings,
|
|
214
244
|
hideScopes: this.state.hideQuickfilters,
|
|
215
|
-
refreshKey: this.state.refreshKey
|
|
245
|
+
refreshKey: this.state.refreshKey,
|
|
246
|
+
locale: displayLocale
|
|
216
247
|
});
|
|
217
248
|
const readonlyDashboardView = R(DashboardViewComponent_1.default, {
|
|
218
249
|
schema: this.props.schema,
|
|
@@ -223,11 +254,12 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
223
254
|
filters,
|
|
224
255
|
onRowClick: this.props.onRowClick,
|
|
225
256
|
namedStrings: this.props.namedStrings,
|
|
226
|
-
hideScopes: this.state.hideQuickfilters
|
|
257
|
+
hideScopes: this.state.hideQuickfilters,
|
|
258
|
+
locale: displayLocale
|
|
227
259
|
});
|
|
228
260
|
// Pass active tables down to table select components so they can present a shorter list
|
|
229
261
|
return react_1.default.createElement(expressions_ui_1.ActiveTablesContext.Provider, { value: DashboardUtils.getFilterableTables(this.props.design, this.props.schema) },
|
|
230
|
-
react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value:
|
|
262
|
+
react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: displayLocale },
|
|
231
263
|
react_1.default.createElement("div", { style: {
|
|
232
264
|
display: "grid",
|
|
233
265
|
gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
|