diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/ConfigurationContactEntryKeysController.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ConfigurationContactEntryKeysController.java
new file mode 100644
index 000000000..11e5e8334
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ConfigurationContactEntryKeysController.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui.contentsections;
+
+import org.libreccm.api.IdentifierParser;
+import org.libreccm.l10n.GlobalizationHelper;
+import org.libreccm.l10n.LocalizedString;
+import org.libreccm.security.AuthorizationRequired;
+import org.librecms.assets.ContactEntryKey;
+import org.librecms.assets.ContactEntryKeyRepository;
+import org.librecms.contentsection.ContentSection;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.mvc.Controller;
+import javax.mvc.Models;
+import javax.transaction.Transactional;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+/**
+ * Controller for managing the available {@link ContactEntryKey}s.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Controller
+@Path("/{sectionIdentifier}/configuration/contactentrykeys")
+public class ConfigurationContactEntryKeysController {
+
+ /**
+ * Checks admin permissions for the current content section.
+ */
+ @Inject
+ private AdminPermissionsChecker adminPermissionsChecker;
+
+ @Inject
+ private ContactEntryKeysTableModel tableModel;
+
+ @Inject
+ private ContactEntryKeyRepository contactEntryKeyRepo;
+
+ /**
+ * Model for the current content section.
+ */
+ @Inject
+ private ContentSectionModel sectionModel;
+
+ /**
+ * Provides common functions for controllers working with content sections.
+ */
+ @Inject
+ private ContentSectionsUi sectionsUi;
+
+ /**
+ * Provides functions for working with {@link LocalizedString}s.
+ */
+ @Inject
+ private GlobalizationHelper globalizationHelper;
+
+ /**
+ * Used to parse identifiers.
+ */
+ @Inject
+ private IdentifierParser identifierParser;
+
+ @Inject
+ private Models models;
+
+ @Inject
+ private SelectedContactEntryKeyModel selectedEntryModel;
+
+ @GET
+ @Path("/")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String listContactEntryKeys(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerContentTypes(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ tableModel.setContactEntrykeys(
+ contactEntryKeyRepo
+ .findAll()
+ .stream()
+ .map(this::buildContactEntryKeyListItemModel)
+ .collect(Collectors.toList())
+ );
+
+ return "org/librecms/ui/contentsection/configuration/contactentrykeys.xhtml";
+ }
+
+ private ContactEntryKeysTableRowModel buildContactEntryKeyListItemModel(
+ final ContactEntryKey contactEntryKey
+ ) {
+ final ContactEntryKeysTableRowModel model
+ = new ContactEntryKeysTableRowModel();
+
+ model.setEntryKey(contactEntryKey.getEntryKey());
+ model.setKeyId(contactEntryKey.getKeyId());
+ model.setLabel(
+ globalizationHelper.getValueFromLocalizedString(
+ contactEntryKey.getLabel()
+ )
+ );
+
+ return model;
+ }
+
+ @GET
+ @Path("/{contactEntryKey}")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String showContactEntryKey(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @PathParam("contactEntryKey") final String entryKey
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ final Optional contactEntryKeyResult
+ = contactEntryKeyRepo.findByEntryKey(entryKey);
+ if (!contactEntryKeyResult.isPresent()) {
+ return showContactEntryKeyNotFound(
+ section, entryKey
+ );
+ }
+
+ final ContactEntryKey contactEntryKey = contactEntryKeyResult.get();
+ selectedEntryModel.setEntryId(contactEntryKey.getKeyId());
+ selectedEntryModel.setKey(contactEntryKey.getEntryKey());
+
+ final List availableLocales = globalizationHelper
+ .getAvailableLocales();
+
+ selectedEntryModel.setLabels(
+ contactEntryKey
+ .getLabel()
+ .getValues()
+ .entrySet()
+ .stream()
+ .collect(
+ Collectors.toMap(
+ entry -> entry.getKey().toString(),
+ entry -> entry.getValue()
+ )
+ )
+ );
+ final Set labelLocales = contactEntryKey
+ .getLabel()
+ .getAvailableLocales();
+ selectedEntryModel.setUnusedLabelLocales(
+ availableLocales
+ .stream()
+ .filter(locale -> !labelLocales.contains(locale))
+ .map(Locale::toString)
+ .collect(Collectors.toList())
+ );
+
+ return "org/librecms/ui/contentsection/configuration/contactentrykey.xhtml";
+ }
+
+ @POST
+ @Path("/@add")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String addContactEntryKey(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @FormParam("contactEntryKey") final String entryKey
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ if (!contactEntryKeyRepo.findByEntryKey(entryKey).isPresent()) {
+ final ContactEntryKey contactEntryKey = new ContactEntryKey();
+ contactEntryKey.setEntryKey(entryKey);
+ contactEntryKeyRepo.save(contactEntryKey);
+ }
+
+ return String.format(
+ "redirect:/%s/configuration/contactentrykeys",
+ sectionIdentifierParam
+ );
+ }
+
+ @POST
+ @Path("/{contactEntryKey}/@delete")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String deleteContactEntryKey(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @PathParam("contactEntryKey") final String entryKey
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ final Optional contactEntryKeyResult
+ = contactEntryKeyRepo.findByEntryKey(entryKey);
+ if (!contactEntryKeyResult.isPresent()) {
+ return showContactEntryKeyNotFound(
+ section, entryKey
+ );
+ }
+
+ final ContactEntryKey contactEntryKey = contactEntryKeyResult.get();
+ contactEntryKeyRepo.delete(contactEntryKey);
+
+ return String.format(
+ "redirect:/%s/configuration/contactentrykeys",
+ sectionIdentifierParam
+ );
+ }
+
+ @POST
+ @Path("/{contactEntryKey}/label/@add")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String addEntryLabel(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @PathParam("contactEntryKey") final String entryKey,
+ @FormParam("locale") final String localeParam,
+ @FormParam("value") final String value
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ final Optional contactEntryKeyResult
+ = contactEntryKeyRepo.findByEntryKey(entryKey);
+ if (!contactEntryKeyResult.isPresent()) {
+ return showContactEntryKeyNotFound(
+ section, entryKey
+ );
+ }
+
+ final ContactEntryKey contactEntryKey = contactEntryKeyResult.get();
+ contactEntryKey.getLabel().addValue(new Locale(localeParam), value);
+ contactEntryKeyRepo.save(contactEntryKey);
+
+ return String.format(
+ "redirect:/%s/configuration/contactentrykeys/%s",
+ sectionIdentifierParam,
+ entryKey
+ );
+ }
+
+ @POST
+ @Path("/{contactEntryKey}/label/@add/{locale}")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String editEntryLabel(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @PathParam("contactEntryKey") final String entryKey,
+ @PathParam("locale") final String localeParam,
+ @FormParam("value") final String value
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ final Optional contactEntryKeyResult
+ = contactEntryKeyRepo.findByEntryKey(entryKey);
+ if (!contactEntryKeyResult.isPresent()) {
+ return showContactEntryKeyNotFound(
+ section, entryKey
+ );
+ }
+
+ final ContactEntryKey contactEntryKey = contactEntryKeyResult.get();
+ contactEntryKey.getLabel().addValue(new Locale(localeParam), value);
+ contactEntryKeyRepo.save(contactEntryKey);
+
+ return String.format(
+ "redirect:/%s/configuration/contactentrykeys/%s",
+ sectionIdentifierParam,
+ entryKey
+ );
+ }
+
+ @POST
+ @Path("/{contactEntryKey}/label/@remove/{locale}")
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String removeEntryLabel(
+ @PathParam("sectionIdentifier") final String sectionIdentifierParam,
+ @PathParam("contactEntryKey") final String entryKey,
+ @FormParam("locale") final String localeParam
+ ) {
+ final Optional sectionResult = sectionsUi
+ .findContentSection(sectionIdentifierParam);
+ if (!sectionResult.isPresent()) {
+ sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
+ }
+ final ContentSection section = sectionResult.get();
+ sectionModel.setSection(section);
+ if (!adminPermissionsChecker.canAdministerLifecycles(section)) {
+ return sectionsUi.showAccessDenied(
+ "sectionIdentifier", sectionIdentifierParam
+ );
+ }
+
+ final Optional contactEntryKeyResult
+ = contactEntryKeyRepo.findByEntryKey(entryKey);
+ if (!contactEntryKeyResult.isPresent()) {
+ return showContactEntryKeyNotFound(
+ section, entryKey
+ );
+ }
+
+ final ContactEntryKey contactEntryKey = contactEntryKeyResult.get();
+ contactEntryKey.getLabel().removeValue(new Locale(localeParam));
+ contactEntryKeyRepo.save(contactEntryKey);
+
+ return String.format(
+ "redirect:/%s/configuration/contactentrykeys/%s",
+ sectionIdentifierParam,
+ entryKey
+ );
+ }
+
+ private String showContactEntryKeyNotFound(
+ final ContentSection section, final String entryKey
+ ) {
+ models.put("sectionIdentifier", section.getLabel());
+ models.put("entryKey", entryKey);
+
+ return "org/librecms/ui/contentsection/configuration/contactentrykey-not-found.xhtml";
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableModel.java
new file mode 100644
index 000000000..c3649bef1
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableModel.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui.contentsections;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Named;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Named("CmsContactEntryKeysTableModel")
+public class ContactEntryKeysTableModel {
+
+ private List contactEntrykeys;
+
+ public List getContactEntrykeys() {
+ return Collections.unmodifiableList(contactEntrykeys);
+ }
+
+ protected void setContactEntrykeys(
+ List contactEntrykeys) {
+ this.contactEntrykeys = new ArrayList<>(contactEntrykeys);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableRowModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableRowModel.java
new file mode 100644
index 000000000..b5b3c4230
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/ContactEntryKeysTableRowModel.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui.contentsections;
+
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ContactEntryKeysTableRowModel {
+
+ private long keyId;
+
+ private String entryKey;
+
+ private String label;
+
+ public long getKeyId() {
+ return keyId;
+ }
+
+ protected void setKeyId(final long keyId) {
+ this.keyId = keyId;
+ }
+
+ public String getEntryKey() {
+ return entryKey;
+ }
+
+ protected void setEntryKey(final String entryKey) {
+ this.entryKey = entryKey;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ protected void setLabel(final String label) {
+ this.label = label;
+ }
+
+
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/SelectedContactEntryKeyModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/SelectedContactEntryKeyModel.java
new file mode 100644
index 000000000..4586858ba
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/SelectedContactEntryKeyModel.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui.contentsections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Named;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Named("CmsSelectedContactEntryKeyModel")
+public class SelectedContactEntryKeyModel {
+
+ private long entryId;
+
+ private String key;
+
+ private List unusedLabelLocales;
+
+ private Map labels;
+
+ public long getEntryId() {
+ return entryId;
+ }
+
+ protected void setEntryId(long entryId) {
+ this.entryId = entryId;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ protected void setKey(String key) {
+ this.key = key;
+ }
+
+ public List getUnusedLabelLocales() {
+ return Collections.unmodifiableList(unusedLabelLocales);
+ }
+
+ protected void setUnusedLabelLocales(final List unusedLabelLocales) {
+ this.unusedLabelLocales = new ArrayList<>(unusedLabelLocales);
+ }
+
+ public Map getLabels() {
+ return Collections.unmodifiableMap(labels);
+ }
+
+ protected void setLabels(final Map labels) {
+ this.labels = new HashMap<>(labels);
+ }
+
+
+
+}
diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/configuration/index.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/configuration/index.xhtml
index e4e4b1396..78355d968 100644
--- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/configuration/index.xhtml
+++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/configuration/index.xhtml
@@ -113,6 +113,29 @@
+
+
+
+
+
+
+
+
+
+ #{CmsAdminMessages['contentsection.configuration.contactentrykeys.description']}
+
+
+
diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties
index fbd40a8ef..cf846df6f 100644
--- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties
+++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties
@@ -794,3 +794,5 @@ contentsection.assets.asset_type.not_available.message=No asset type {1} availab
contentsection.assets.createstep.not_available.title=No create step available
contentsection.assets.createstep.breadcrumb=Create {0} asset
contentsection.assets.createstep.not_available.message=Unable to create new asset of type {2} in folder {1} of content section{0}. Create step for asset type {2} not available.
+contentsection.configuration.contactentrykeys.title=Contact Entry Keys
+contentsection.configuration.contactentrykeys.description=Configure the possible keys for contact data entries.
diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties
index f4a4b47dc..223b24cd4 100644
--- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties
+++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties
@@ -795,3 +795,5 @@ contentsection.assets.asset_type.not_available.message=Kein Asset Typ {1} f\u00f
contentsection.assets.createstep.not_available.title=Kein Formular zum Erstellen verf\u00fcgbar
contentsection.assets.createstep.breadcrumb={0} asset anlegen
contentsection.assets.createstep.not_available.message=Anlegen eines Assets vom Type {2} in Ordner {1} der Content Section {0} nicht m\u00f6glich. Formular zum Anlegen von Assets des Types {2} nicht verf\u00fcgbar.
+contentsection.configuration.contactentrykeys.title=Kontaktdaten-Schl\u00fcssel
+contentsection.configuration.contactentrykeys.description=Verwalten der m\u00f6glichen Kontaktdaten-Angaben.
diff --git a/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/svgIcon.xhtml b/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/svgIcon.xhtml
index c8751f49e..3e03e0f51 100644
--- a/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/svgIcon.xhtml
+++ b/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/svgIcon.xhtml
@@ -6,9 +6,13 @@
+
-