From 16d54fe99684007163d22a2a7712ac18fb050dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bl=C3=A4sta?= <48793206+johnnyblasta@users.noreply.github.com> Date: Wed, 15 Jan 2025 11:53:52 +0100 Subject: [PATCH] feature: localize legend control (#2123) * feature: localize legend control * Fixed tranlations and bugs * Language correction --- src/controls/legend.js | 34 ++++++++++++--------- src/controls/legend/group.js | 8 ++--- src/controls/legend/moreinfobutton.js | 23 ++++++++------ src/controls/legend/overlay.js | 15 ++++++---- src/controls/legend/overlayproperties.js | 11 +++++-- src/controls/legend/overlays.js | 16 ++++++---- src/controls/legend/visibleOverlays.js | 8 +++-- src/loc/en_US.json | 38 ++++++++++++++++++++---- src/loc/sv_SE.json | 38 ++++++++++++++++++++---- 9 files changed, 137 insertions(+), 54 deletions(-) diff --git a/src/controls/legend.js b/src/controls/legend.js index 2d0c48732..880bf8af9 100644 --- a/src/controls/legend.js +++ b/src/controls/legend.js @@ -9,6 +9,12 @@ import LayerProperties from './legend/overlayproperties'; import PopupMenu from '../ui/popupmenu'; const Legend = function Legend(options = {}) { + const localization = options.localization; + + function localize(key) { + return localization.getStringByKeys({ targetParentKey: 'legend', targetKey: key }); + } + const { cls: clsSettings = '', style: styleSettings = {}, @@ -26,7 +32,7 @@ const Legend = function Legend(options = {}) { searchLayersMinLength = 2, searchLayersLimit = 10, searchLayersParameters = ['name', 'title'], - searchLayersPlaceholderText = 'Sök lager' + searchLayersPlaceholderText = localize('placeholderText') } = options; let { @@ -174,7 +180,7 @@ const Legend = function Legend(options = {}) { const turnOffLayersButton = Button({ cls: 'round compact icon-small margin-x-smaller', - title: 'Släck alla lager', + title: localize('turnOffLayersTitle'), click() { viewer.dispatch('active:turnofflayers'); }, @@ -190,7 +196,7 @@ const Legend = function Legend(options = {}) { const showVisibleLayersButton = Button({ cls: 'compact icon-smaller margin-x-small hidden', - title: 'Visa endast tända lager', + title: localize('showVisibleTitle'), click() { viewer.dispatch('active:togglevisibleLayers'); }, @@ -206,7 +212,7 @@ const Legend = function Legend(options = {}) { const showAllVisibleLayersButton = Button({ cls: 'compact icon-smaller margin-x-small hidden', - title: 'Visa alla lager', + title: localize('showAllVisibleTitle'), click() { viewer.dispatch('active:togglevisibleLayers'); }, @@ -247,7 +253,7 @@ const Legend = function Legend(options = {}) { const turnOnLayersButton = Button({ cls: 'round compact icon-small margin-x-smaller', - title: 'Tänd alla lager utom bakgrundslager', + title: localize('turnOnLayersTitle'), click() { viewer.dispatch('active:turnonlayers'); }, @@ -328,8 +334,8 @@ const Legend = function Legend(options = {}) { 'align-self': 'center' }, icon: '#o_add_24px', - ariaLabel: 'Lägg till lager', - title: 'Lägg till lager', + ariaLabel: localize('addLayerTitle'), + title: localize('addLayerTitle'), tabIndex: -1, validStates: ['initial', 'hidden'], state: 'hidden' @@ -390,7 +396,7 @@ const Legend = function Legend(options = {}) { layer.setVisible(true); document.getElementsByClassName('o-search-layer-field')[0].value = ''; } else { - console.error('Search options are missing'); + console.error(localize('selectHandlerError')); } } @@ -478,7 +484,7 @@ const Legend = function Legend(options = {}) { found = true; } if (typeof layer.get('title') === 'undefined') { - value = `Titel saknas (${shorten(value, obj.value)})`; + value = `${localize('titleMissing')} (${shorten(value, obj.value)})`; } else { value = `${layer.get('title')} (${shorten(value, obj.value)})`; } @@ -642,16 +648,16 @@ const Legend = function Legend(options = {}) { target = document.getElementById(viewer.getMain().getId()); const maxHeight = calcMaxHeight(getTargetHeight()); overlaysCmp = Overlays({ - viewer, cls: contentCls, style: contentStyle, labelOpacitySlider + viewer, cls: contentCls, style: contentStyle, labelOpacitySlider, localization }); visibleOverlaysCmp = VisibleOverlays({ - viewer, cls: `${contentCls} hidden`, style: contentStyle, labelOpacitySlider + viewer, cls: `${contentCls} hidden`, style: contentStyle, labelOpacitySlider, localization }); const baselayerCmps = [toggleGroup]; toolsCmp = El({ cls: 'flex padding-small no-shrink hidden', - tooltipText: 'Lagerbytare', + tooltipText: localize('layerSwitcher'), style: { 'background-color': '#fff', 'justify-content': 'flex-end', @@ -669,7 +675,7 @@ const Legend = function Legend(options = {}) { icon: '#ic_close_24px', state: closeButtonState, validStates: ['initial', 'hidden'], - ariaLabel: 'Stäng', + ariaLabel: localize('close'), click() { toggleVisibility(); } @@ -739,7 +745,7 @@ const Legend = function Legend(options = {}) { const layerButtonCls = isExpanded ? ' faded' : ''; layerButton = Button({ icon: '#ic_layers_24px', - tooltipText: 'Lager', + tooltipText: localize('layer'), tooltipPlacement: 'west', cls: `control icon-small medium round absolute light bottom-right${layerButtonCls}`, click() { diff --git a/src/controls/legend/group.js b/src/controls/legend/group.js index 5c941f0f8..1ab28935d 100644 --- a/src/controls/legend/group.js +++ b/src/controls/legend/group.js @@ -28,7 +28,8 @@ const Group = function Group(viewer, options = {}) { zIndexStart = 0.1, opacityControl = false, zoomToExtent = false, - description + description, + localization } = options; const stateCls = { @@ -79,8 +80,7 @@ const Group = function Group(viewer, options = {}) { } }) : false; - const moreInfoButton = (opacityControl || zoomToExtent || description || (abstract && !showAbstractInLegend)) ? createMoreInfoButton({ viewer, - group: thisGroup }) : false; + const moreInfoButton = (opacityControl || zoomToExtent || description || (abstract && !showAbstractInLegend)) ? createMoreInfoButton({ viewer, group: thisGroup, localization }) : false; const SubGroupHeader = function SubGroupHeader() { const expandButton = Button({ @@ -395,7 +395,7 @@ const Group = function Group(viewer, options = {}) { const thisParent = this; const label = group.labelOpacitySlider ? group.labelOpacitySlider : ''; const layerProperties = LayerProperties({ - group, viewer, thisParent, labelOpacitySlider: label + group, viewer, thisParent, labelOpacitySlider: label, localization }); slidenav.setSecondary(layerProperties); slidenav.slideToSecondary(); diff --git a/src/controls/legend/moreinfobutton.js b/src/controls/legend/moreinfobutton.js index 2aa2091b6..e6cb7cdea 100644 --- a/src/controls/legend/moreinfobutton.js +++ b/src/controls/legend/moreinfobutton.js @@ -6,13 +6,18 @@ export default function createMoreInfoButton(params) { const { layer, group = {}, - viewer + viewer, + localization } = params; const popupMenuItems = []; let moreInfoButton; let popupMenu; const showPopup = group.zoomToExtent && group.extent; // In case of zoomToExtent we always want to show popupmenu + function localize(key) { + return localization.getStringByKeys({ targetParentKey: 'legend', targetKey: key }); + } + const eventOverlayProps = new CustomEvent('overlayproperties', { bubbles: true, detail: { @@ -35,7 +40,7 @@ export default function createMoreInfoButton(params) { }, render() { const labelCls = 'text-smaller padding-x-small grow pointer no-select overflow-hidden'; - return `
  • Visa ${layer ? 'lagerinformation' : 'gruppinformation'}
  • `; + return `
  • ${localize('showInfoMenuItem')} ${layer ? localize('layerInfoMenuItem') : localize('groupInfoMenuItem')}
  • `; } }); popupMenuItems.push(layerInfoMenuItem); @@ -69,7 +74,7 @@ export default function createMoreInfoButton(params) { }, render() { const labelCls = 'text-smaller padding-x-small grow pointer no-select overflow-hidden'; - return `
  • Zooma till
  • `; + return `
  • ${localize('zoomToExtentMenuItem')}
  • `; } }); popupMenuItems.push(zoomToExtentMenuItem); @@ -93,7 +98,7 @@ export default function createMoreInfoButton(params) { const features = layer.getSource().getFeatures(); exportToFile(features, format, { featureProjection: viewer.getProjection().getCode(), - filename: layer.get('title') || 'export' + filename: layer.get('title') || localize('exportLayerTitle') }); e.preventDefault(); e.stopPropagation(); @@ -103,8 +108,8 @@ export default function createMoreInfoButton(params) { render() { let exportLabel; if (exportFormatArray.length > 1) { - exportLabel = `Spara lager (.${format})`; - } else { exportLabel = 'Spara lager'; } + exportLabel = `${localize('exportLayerSave')} (.${format})`; + } else { exportLabel = localize('exportLayerSave'); } const labelCls = 'text-smaller padding-x-small grow pointer no-select overflow-hidden'; return `
  • ${exportLabel}
  • `; } @@ -118,7 +123,7 @@ export default function createMoreInfoButton(params) { onRender() { const labelEl = document.getElementById(this.getId()); labelEl.addEventListener('click', (e) => { - const doRemove = (layer.get('promptlessRemoval') === true) || window.confirm('Vill du radera lagret?'); + const doRemove = (layer.get('promptlessRemoval') === true) || window.confirm(localize('removeLayerQuestion')); if (doRemove) { viewer.getMap().removeLayer(layer); e.preventDefault(); @@ -129,7 +134,7 @@ export default function createMoreInfoButton(params) { }, render() { const labelCls = 'text-smaller padding-x-small grow pointer no-select overflow-hidden'; - return `
  • Ta bort lager
  • `; + return `
  • ${localize('removeLayer')}
  • `; } }); popupMenuItems.push(removeLayerMenuItem); @@ -188,7 +193,7 @@ export default function createMoreInfoButton(params) { 'align-self': 'center' }, icon: '#ic_more_vert_24px', - ariaLabel: 'Visa lagerinfo', + ariaLabel: localize('moreInfoButtonLabel'), tabIndex: -1 }); moreInfoButton.on('render', function onRenderButton() { diff --git a/src/controls/legend/overlay.js b/src/controls/legend/overlay.js index ced8c33f6..5c1c28e96 100644 --- a/src/controls/legend/overlay.js +++ b/src/controls/legend/overlay.js @@ -11,16 +11,21 @@ const OverlayLayer = function OverlayLayer(options) { layer, position = 'top', style, - viewer + viewer, + localization } = options; + function localize(key) { + return localization.getStringByKeys({ targetParentKey: 'legend', targetKey: key }); + } + const buttons = []; let headerIconClass = headerIconCls; const hasStylePicker = viewer.getLayerStylePicker(layer).length > 0; const layerIconCls = `round compact icon-small relative no-shrink light ${hasStylePicker ? 'style-picker' : ''}`; const cls = `${clsSettings} flex row align-center padding-left padding-right-smaller item wrap`.trim(); - const title = layer.get('title') || 'Titel saknas'; + const title = layer.get('title') || localize('layerTitleMissing'); const name = layer.get('name'); const secure = layer.get('secure'); let hasExtendedLegend = false; @@ -96,7 +101,7 @@ const OverlayLayer = function OverlayLayer(options) { height: 'calc(1.5rem + 2px)', width: 'calc(1.5rem + 2px)' }, - ariaLabel: 'Lager ikon', + ariaLabel: localize('layerIcon'), icon: headerIcon, tabIndex: -1 }); @@ -115,7 +120,7 @@ const OverlayLayer = function OverlayLayer(options) { 'padding-left': '.5rem' }, icon: getCheckIcon(layer.getVisible()), - ariaLabel: 'Växla lagersynlighet', + ariaLabel: localize('toggleLayer'), tabIndex: -1 }); @@ -135,7 +140,7 @@ const OverlayLayer = function OverlayLayer(options) { } }); - const moreInfoButton = createMoreInfoButton({ layer, viewer }); + const moreInfoButton = createMoreInfoButton({ layer, viewer, localization }); buttons.push(moreInfoButton); const ButtonsHtml = `${layerIcon.render()}${label.render()}${toggleButton.render()}${moreInfoButton.render()}`; diff --git a/src/controls/legend/overlayproperties.js b/src/controls/legend/overlayproperties.js index 57ba4556c..3880b778b 100644 --- a/src/controls/legend/overlayproperties.js +++ b/src/controls/legend/overlayproperties.js @@ -7,7 +7,8 @@ const OverlayProperties = function OverlayProperties(options = {}) { cls: clsOptions = '', group, layer, - viewer + viewer, + localization } = options; let cls = ''; let title; @@ -52,6 +53,10 @@ const OverlayProperties = function OverlayProperties(options = {}) { label }); + function localize(key) { + return localization.getStringByKeys({ targetParentKey: 'legend', targetKey: key }); + } + function hasStylePicker() { return stylePicker.length > 0; } @@ -70,7 +75,7 @@ const OverlayProperties = function OverlayProperties(options = {}) { function renderStyleSelection() { if (hasStylePicker()) { - const html = `
    Välj stil
    ${styleSelection.render()}`; + const html = `
    ${localize('renderStyleSelect')}
    ${styleSelection.render()}`; return html; } return ''; @@ -173,7 +178,7 @@ const OverlayProperties = function OverlayProperties(options = {}) { buttonTextCls: 'text-smaller', text: getStyleDisplayName(layer.get('styleName')), buttonIconCls: 'black', - ariaLabel: 'Välj stil' + ariaLabel: localize('renderStyleSelect') }); components.push(styleSelection); } diff --git a/src/controls/legend/overlays.js b/src/controls/legend/overlays.js index 552dbae1d..9abb2295a 100644 --- a/src/controls/legend/overlays.js +++ b/src/controls/legend/overlays.js @@ -20,9 +20,13 @@ const Overlays = function Overlays(options) { expanded = true, style: styleSettings = {}, viewer, - labelOpacitySlider + labelOpacitySlider, + localization } = options; + function localize(key) { + return localization.getStringByKeys({ targetParentKey: 'legend', targetKey: key }); + } const cls = `${clsSettings} o-layerswitcher-overlays flex row overflow-hidden`.trim(); const style = dom.createStyle({ width: '100%', height: '100%', 'min-width': '220px', ...styleSettings @@ -36,7 +40,7 @@ const Overlays = function Overlays(options) { const groupCmps = viewer.getGroups().reduce((acc, group) => { if (nonGroupNames.includes(group.name)) return acc; - return acc.concat(Group(viewer, group)); + return acc.concat(Group(viewer, { ...group, localization })); }, []); groupCmps.forEach((groupCmp) => { @@ -155,7 +159,7 @@ const Overlays = function Overlays(options) { const styleName = layer.get('styleName') || null; const layerStyle = styleName ? viewer.getStyle(styleName) : undefined; const overlay = Overlay({ - layer, style: layerStyle, position, viewer + layer, style: layerStyle, position, viewer, localization }); const groupName = layer.get('group'); if (rootGroupNames.includes(groupName)) { @@ -170,7 +174,7 @@ const Overlays = function Overlays(options) { updateLegend(groupCmp); } } else { - console.warn(`Group ${groupName} does not exist`); + console.warn(`${localize('addLayerWarningGroup')} ${groupName} ${localize('addLayerWarningDNE')}`); } } }; @@ -182,7 +186,7 @@ const Overlays = function Overlays(options) { }; const addGroup = function addGroup(groupOptions) { - const groupCmp = Group(viewer, groupOptions); + const groupCmp = Group(viewer, { ...groupOptions, localization }); groupCmps.push(groupCmp); if (groupCmp.type === 'grouplayer') { const parent = groupCmps.find((cmp) => cmp.name === groupCmp.parent); @@ -269,7 +273,7 @@ const Overlays = function Overlays(options) { const layer = evt.detail.layer; const parent = this; const layerProperties = LayerProperties({ - layer, viewer, parent, labelOpacitySlider + layer, viewer, parent, labelOpacitySlider, localization }); slidenav.setSecondary(layerProperties); slidenav.slideToSecondary(); diff --git a/src/controls/legend/visibleOverlays.js b/src/controls/legend/visibleOverlays.js index 15e4b3f50..80a797f23 100644 --- a/src/controls/legend/visibleOverlays.js +++ b/src/controls/legend/visibleOverlays.js @@ -17,7 +17,8 @@ const Overlays = function Overlays(options) { cls: clsSettings = '', style: styleSettings = {}, viewer, - labelOpacitySlider + labelOpacitySlider, + localization } = options; const cls = `${clsSettings} o-layerswitcher-overlays flex row overflow-auto`.trim(); @@ -106,7 +107,8 @@ const Overlays = function Overlays(options) { layer, style: layerStyle, position, - viewer + viewer, + localization }); const groupName = layer.get('group'); if (!nonGroupNames.includes(groupName)) { @@ -154,7 +156,7 @@ const Overlays = function Overlays(options) { const layer = evt.detail.layer; const parent = this; const layerProperties = LayerProperties({ - layer, viewer, parent, labelOpacitySlider + layer, viewer, parent, labelOpacitySlider, localization }); slidenav.setSecondary(layerProperties); slidenav.slideToSecondary(); diff --git a/src/loc/en_US.json b/src/loc/en_US.json index ba93dc726..b60496888 100644 --- a/src/loc/en_US.json +++ b/src/loc/en_US.json @@ -106,6 +106,39 @@ "drawCircle": "Circle", "drawFreehand": "Freehand" }, + "bookmarks": { + "title": "Bookmarks", + "close": "Close", + "bookmarkLabel": "Bookmark for" + }, + "legend": { + "placeholderText": "Search for layer", + "turnOffLayersTitle": "Turn off all layers", + "showVisibleTitle": "Show only visible layers", + "showAllVisibleTitle": "Show all layers", + "turnOnLayersTitle": "Turn on all layers", + "addLayerTitle": "Add layer", + "selectHandlerError": "Search options are missing", + "titleMissing": "Title missing", + "layerSwitcher": "Layer Switcher", + "close": "Close", + "layer": "Layer", + "addLayerWarningGroup": "Group", + "addLayerWarningDNE": "does not exist", + "layerTitleMissing": "Title missing", + "layerIcon": "Layer icon", + "toggleLayer": "Toggle layer visibility", + "showInfoMenuItem": "Show", + "layerInfoMenuItem": "layer information", + "groupInfoMenuItem": "group information", + "zoomToExtentMenuItem": "Zoom to", + "exportLayerTitle": "export", + "exportLayerSave": "Save layer", + "removeLayerQuestion": "Do you want to remove the layer?", + "removeLayer": "Remove layer", + "moreInfoButtonLabel": "Show layer info", + "renderStyleSelect": "Select style" + }, "zoom": { "zoomInButtonTooltip": "Zoom into the map", "zoomOutButtonTooltip": "Zoom out in the map" @@ -160,10 +193,5 @@ "pointTypeSquare": "Square", "pointTypeMarker": "Marker" } - }, - "bookmarks": { - "title": "Bookmarks", - "close": "Close", - "bookmarkLabel": "Bookmark for" } } \ No newline at end of file diff --git a/src/loc/sv_SE.json b/src/loc/sv_SE.json index 1f4003772..6f403d2d4 100644 --- a/src/loc/sv_SE.json +++ b/src/loc/sv_SE.json @@ -106,6 +106,39 @@ "drawCircle": "Cirkel", "drawFreehand": "Frihand" }, + "bookmarks": { + "title": "Bokmärken", + "close": "Stäng", + "bookmarkLabel": "Bokmärke för" + }, + "legend": { + "placeholderText": "Sök lager", + "turnOffLayersTitle": "Släck alla lager", + "showVisibleTitle": "Visa endast tända lager", + "showAllVisibleTitle": "Visa alla lager", + "turnOnLayersTitle": "Tänd alla lager", + "addLayerTitle": "Lägg till lager", + "selectHandlerError": "Search options are missing", + "titleMissing": "Titel saknas", + "layerSwitcher": "Lagerbytare", + "close": "Stäng", + "layer": "Lager", + "addLayerWarningGroup": "Grupp", + "addLayerWarningDNE": "finns inte", + "layerTitleMissing": "Titel saknas", + "layerIcon": "Lager ikon", + "toggleLayer": "Växla lagersynlighet", + "showInfoMenuItem": "Visa", + "layerInfoMenuItem": "lagerinformation", + "groupInfoMenuItem": "gruppinformation", + "zoomToExtentMenuItem": "Zooma till", + "exportLayerTitle": "export", + "exportLayerSave": "Spara lager", + "removeLayerQuestion": "Vill du ta bort lagret?", + "removeLayer": "Ta bort lager", + "moreInfoButtonLabel": "Visa lagerinfo", + "renderStyleSelect": "Välj stil" + }, "zoom": { "zoomInButtonTooltip": "Zooma in i kartan", "zoomOutButtonTooltip": "Zooma ut i kartan" @@ -159,10 +192,5 @@ "pointTypeSquare": "Fyrkant", "pointTypeMarker": "Markör" } - }, - "bookmarks": { - "title": "Bokmärken", - "close": "Stäng", - "bookmarkLabel": "Bokmärke för" } } \ No newline at end of file