Fix missing localization (#772)

* fix typos

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* Add localization to documentation link description

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* Add localization for rollouts errorthreshold

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* Add CN to available localizations

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* fix NO TAG localization

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* Fix sonar findings

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* Make Localization configurable

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* fix sonar findings

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* fix review findings

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* fix review findings

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>

* add final

Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>
This commit is contained in:
Jeroen Laverman
2018-12-13 09:07:10 +01:00
committed by Dominic Schabel
parent 347fac7f00
commit b06928d089
16 changed files with 96 additions and 56 deletions

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.app;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.ErrorView; import org.eclipse.hawkbit.ui.ErrorView;
import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.components.NotificationUnreadButton; import org.eclipse.hawkbit.ui.components.NotificationUnreadButton;
import org.eclipse.hawkbit.ui.menu.DashboardMenu; import org.eclipse.hawkbit.ui.menu.DashboardMenu;
import org.eclipse.hawkbit.ui.push.EventPushStrategy; import org.eclipse.hawkbit.ui.push.EventPushStrategy;
@@ -43,8 +44,9 @@ public class MyUI extends AbstractHawkbitUI {
@Autowired @Autowired
MyUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, final SpringViewProvider viewProvider, MyUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, final SpringViewProvider viewProvider,
final ApplicationContext context, final DashboardMenu dashboardMenu, final ErrorView errorview, final ApplicationContext context, final DashboardMenu dashboardMenu, final ErrorView errorview,
final NotificationUnreadButton notificationUnreadButton) { final NotificationUnreadButton notificationUnreadButton, final UiProperties uiProperties) {
super(pushStrategy, eventBus, viewProvider, context, dashboardMenu, errorview, notificationUnreadButton); super(pushStrategy, eventBus, viewProvider, context, dashboardMenu, errorview, notificationUnreadButton,
uiProperties);
} }
} }

View File

@@ -29,6 +29,10 @@ spring.rabbitmq.port=5672
# Monitoring # Monitoring
endpoints.health.enabled=true endpoints.health.enabled=true
# UI Localization
hawkbit.server.ui.localization.defaultLocal=en
hawkbit.server.ui.localization.availableLocals=en,de
# UI demo account # UI demo account
hawkbit.server.ui.demo.password=admin hawkbit.server.ui.demo.password=admin
hawkbit.server.ui.demo.user=admin hawkbit.server.ui.demo.user=admin

View File

@@ -8,8 +8,8 @@
*/ */
package org.eclipse.hawkbit.ui; package org.eclipse.hawkbit.ui;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
@@ -81,9 +81,11 @@ public abstract class AbstractHawkbitUI extends UI implements DetachListener {
private Label viewTitle; private Label viewTitle;
private final UiProperties uiProperties;
protected AbstractHawkbitUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, protected AbstractHawkbitUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus,
final SpringViewProvider viewProvider, final ApplicationContext context, final DashboardMenu dashboardMenu, final SpringViewProvider viewProvider, final ApplicationContext context, final DashboardMenu dashboardMenu,
final ErrorView errorview, final NotificationUnreadButton notificationUnreadButton) { final ErrorView errorview, final NotificationUnreadButton notificationUnreadButton, final UiProperties uiProperties) {
this.pushStrategy = pushStrategy; this.pushStrategy = pushStrategy;
this.eventBus = eventBus; this.eventBus = eventBus;
this.viewProvider = viewProvider; this.viewProvider = viewProvider;
@@ -91,6 +93,7 @@ public abstract class AbstractHawkbitUI extends UI implements DetachListener {
this.dashboardMenu = dashboardMenu; this.dashboardMenu = dashboardMenu;
this.errorview = errorview; this.errorview = errorview;
this.notificationUnreadButton = notificationUnreadButton; this.notificationUnreadButton = notificationUnreadButton;
this.uiProperties = uiProperties;
} }
@Override @Override
@@ -164,7 +167,7 @@ public abstract class AbstractHawkbitUI extends UI implements DetachListener {
navigator.addView(EMPTY_VIEW, new Navigator.EmptyView()); navigator.addView(EMPTY_VIEW, new Navigator.EmptyView());
// set locale is required for I18N class also, to get the locale from // set locale is required for I18N class also, to get the locale from
// cookie // cookie
final String locale = getLocaleId(SPUIDefinitions.getAvailableLocales()); final String locale = getLocaleId(uiProperties.getLocalization().getAvailableLocals());
setLocale(new Locale(locale)); setLocale(new Locale(locale));
if (UI.getCurrent().getErrorHandler() == null) { if (UI.getCurrent().getErrorHandler() == null) {
@@ -209,9 +212,9 @@ public abstract class AbstractHawkbitUI extends UI implements DetachListener {
* as set * as set
* @return String as preferred locale * @return String as preferred locale
*/ */
private static String getLocaleId(final Set<String> availableLocalesInApp) { private String getLocaleId(final List<String> availableLocalesInApp) {
final String[] localeChain = getLocaleChain(); final String[] localeChain = getLocaleChain();
String spLocale = SPUIDefinitions.DEFAULT_LOCALE; String spLocale = uiProperties.getLocalization().getDefaultLocal();
if (null != localeChain) { if (null != localeChain) {
// Find best matching locale // Find best matching locale
for (final String localeId : localeChain) { for (final String localeId : localeChain) {

View File

@@ -9,6 +9,8 @@
package org.eclipse.hawkbit.ui; package org.eclipse.hawkbit.ui;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -23,6 +25,8 @@ public class UiProperties implements Serializable {
private boolean gravatar; private boolean gravatar;
private final Localization localization = new Localization();
private final Links links = new Links(); private final Links links = new Links();
private final Login login = new Login(); private final Login login = new Login();
@@ -39,6 +43,41 @@ public class UiProperties implements Serializable {
this.gravatar = gravatar; this.gravatar = gravatar;
} }
/**
* Localization information
*/
public static class Localization implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Default localization
*/
private String defaultLocal = "en";
/**
* List of available localizations
*/
private List<String> availableLocals = Collections.singletonList("en");
public String getDefaultLocal() {
return defaultLocal;
}
public List<String> getAvailableLocals() {
return availableLocals;
}
public void setDefaultLocal(final String defaultLocal) {
this.defaultLocal = defaultLocal;
}
public void setAvailableLocals(final List<String> availableLocals) {
this.availableLocals = availableLocals;
}
}
/** /**
* Demo account login information. * Demo account login information.
* *
@@ -375,4 +414,8 @@ public class UiProperties implements Serializable {
return event; return event;
} }
public Localization getLocalization() {
return localization;
}
} }

View File

@@ -479,7 +479,7 @@ public class CommonDialogWindow extends Window {
if (StringUtils.isEmpty(helpLink)) { if (StringUtils.isEmpty(helpLink)) {
return; return;
} }
final Link helpLinkComponent = SPUIComponentProvider.getHelpLink(helpLink); final Link helpLinkComponent = SPUIComponentProvider.getHelpLink(i18n, helpLink);
buttonsLayout.addComponent(helpLinkComponent); buttonsLayout.addComponent(helpLinkComponent);
buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT); buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT);
} }

View File

@@ -333,17 +333,19 @@ public final class SPUIComponentProvider {
/** /**
* Generates help/documentation links from within management UI. * Generates help/documentation links from within management UI.
* *
* @param i18n
* the i18n
* @param uri * @param uri
* to documentation site * to documentation site
* *
* @return generated link * @return generated link
*/ */
public static Link getHelpLink(final String uri) { public static Link getHelpLink(final VaadinMessageSource i18n, final String uri) {
final Link link = new Link("", new ExternalResource(uri)); final Link link = new Link("", new ExternalResource(uri));
link.setTargetName("_blank"); link.setTargetName("_blank");
link.setIcon(FontAwesome.QUESTION_CIRCLE); link.setIcon(FontAwesome.QUESTION_CIRCLE);
link.setDescription("Documentation"); link.setDescription(i18n.getMessage("tooltip.documentation.link"));
return link; return link;
} }

View File

@@ -186,7 +186,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
saveButton = createSaveButton(); saveButton = createSaveButton();
searchIcon = createSearchIcon(); searchIcon = createSearchIcon();
helpLink = SPUIComponentProvider.getHelpLink(uiProperties.getLinks().getDocumentation().getTargetfilterView()); helpLink = SPUIComponentProvider.getHelpLink(i18n, uiProperties.getLinks().getDocumentation().getTargetfilterView());
closeIcon = createSearchResetIcon(); closeIcon = createSearchResetIcon();
} }

View File

@@ -612,7 +612,7 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
private Link maintenanceWindowHelpLinkControl() { private Link maintenanceWindowHelpLinkControl() {
final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView(); final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView();
return SPUIComponentProvider.getHelpLink(maintenanceWindowHelpUrl); return SPUIComponentProvider.getHelpLink(getI18n(), maintenanceWindowHelpUrl);
} }
private void initMaintenanceWindow() { private void initMaintenanceWindow() {

View File

@@ -145,7 +145,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
targetsCountLabel = getStatusCountLabel(); targetsCountLabel = getStatusCountLabel();
bulkUploader = getBulkUploadHandler(); bulkUploader = getBulkUploadHandler();
linkToSystemConfigHelp = SPUIComponentProvider linkToSystemConfigHelp = SPUIComponentProvider
.getHelpLink(uiproperties.getLinks().getDocumentation().getDeploymentView()); .getHelpLink(i18n, uiproperties.getLinks().getDocumentation().getDeploymentView());
windowCaption = new Label(i18n.getMessage("caption.bulk.upload.targets")); windowCaption = new Label(i18n.getMessage("caption.bulk.upload.targets"));
minimizeButton = getMinimizeButton(); minimizeButton = getMinimizeButton();
closeButton = getCloseButton(); closeButton = getCloseButton();

View File

@@ -582,7 +582,7 @@ public class TargetTable extends AbstractTable<Target> {
final String tagName = HawkbitCommonUtil.removePrefix(wrapperSource.getId(), final String tagName = HawkbitCommonUtil.removePrefix(wrapperSource.getId(),
SPUIDefinitions.TARGET_TAG_ID_PREFIXS); SPUIDefinitions.TARGET_TAG_ID_PREFIXS);
if (wrapperSource.getId().startsWith(SPUIDefinitions.TARGET_TAG_ID_PREFIXS)) { if (wrapperSource.getId().startsWith(SPUIDefinitions.TARGET_TAG_ID_PREFIXS)) {
if ("NO TAG".equals(tagName)) { if (getI18n().getMessage("label.no.tag").equals(tagName)) {
getNotification() getNotification()
.displayValidationError(getI18n().getMessage(UIMessageIdProvider.MESSAGE_ACTION_NOT_ALLOWED)); .displayValidationError(getI18n().getMessage(UIMessageIdProvider.MESSAGE_ACTION_NOT_ALLOWED));
return false; return false;
@@ -1033,7 +1033,7 @@ public class TargetTable extends AbstractTable<Target> {
private Link maintenanceWindowHelpLinkControl() { private Link maintenanceWindowHelpLinkControl() {
final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView(); final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView();
return SPUIComponentProvider.getHelpLink(maintenanceWindowHelpUrl); return SPUIComponentProvider.getHelpLink(getI18n(), maintenanceWindowHelpUrl);
} }
private void initMaintenanceWindow() { private void initMaintenanceWindow() {

View File

@@ -361,7 +361,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private int getErrorThresholdPercentage(final int amountGroup) { private int getErrorThresholdPercentage(final int amountGroup) {
int errorThresoldPercent = Integer.parseInt(errorThreshold.getValue()); int errorThresoldPercent = Integer.parseInt(errorThreshold.getValue());
if (errorThresholdOptionGroup.getValue().equals(ERROR_THRESHOLD_OPTIONS.COUNT.getValue())) { if (errorThresholdOptionGroup.getValue().equals(ERROR_THRESHOLD_OPTIONS.COUNT.getValue(i18n))) {
final int groupSize = (int) Math.ceil((double) totalTargetsCount / (double) amountGroup); final int groupSize = (int) Math.ceil((double) totalTargetsCount / (double) amountGroup);
final int erroThresoldCount = Integer.parseInt(errorThreshold.getValue()); final int erroThresoldCount = Integer.parseInt(errorThreshold.getValue());
errorThresoldPercent = (int) Math.ceil(((float) erroThresoldCount / (float) groupSize) * 100); errorThresoldPercent = (int) Math.ceil(((float) erroThresoldCount / (float) groupSize) * 100);
@@ -683,7 +683,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private OptionGroup createErrorThresholdOptionGroup() { private OptionGroup createErrorThresholdOptionGroup() {
final OptionGroup errorThresoldOptions = new OptionGroup(); final OptionGroup errorThresoldOptions = new OptionGroup();
for (final ERROR_THRESHOLD_OPTIONS option : ERROR_THRESHOLD_OPTIONS.values()) { for (final ERROR_THRESHOLD_OPTIONS option : ERROR_THRESHOLD_OPTIONS.values()) {
errorThresoldOptions.addItem(option.getValue()); errorThresoldOptions.addItem(option.getValue(i18n));
} }
errorThresoldOptions.setId(UIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_OPTION_ID); errorThresoldOptions.setId(UIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_OPTION_ID);
errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL); errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
@@ -696,7 +696,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) { private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) {
errorThreshold.clear(); errorThreshold.clear();
errorThreshold.removeAllValidators(); errorThreshold.removeAllValidators();
if (event.getProperty().getValue().equals(ERROR_THRESHOLD_OPTIONS.COUNT.getValue())) { if (event.getProperty().getValue().equals(ERROR_THRESHOLD_OPTIONS.COUNT.getValue(i18n))) {
errorThreshold.addValidator(new ErrorThresholdOptionValidator()); errorThreshold.addValidator(new ErrorThresholdOptionValidator());
} else { } else {
errorThreshold.addValidator(new ThresholdFieldValidator()); errorThreshold.addValidator(new ThresholdFieldValidator());
@@ -828,7 +828,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
} }
private void setDefaultSaveStartGroupOption() { private void setDefaultSaveStartGroupOption() {
errorThresholdOptionGroup.setValue(ERROR_THRESHOLD_OPTIONS.PERCENT.getValue()); errorThresholdOptionGroup.setValue(ERROR_THRESHOLD_OPTIONS.PERCENT.getValue(i18n));
} }
private static TextArea createDescription() { private static TextArea createDescription() {
@@ -1106,18 +1106,17 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private enum ERROR_THRESHOLD_OPTIONS { private enum ERROR_THRESHOLD_OPTIONS {
PERCENT("%"), PERCENT("label.errorthreshold.option.percent"),
COUNT("label.errorthreshold.option.count");
COUNT("Count");
private final String value; private final String value;
ERROR_THRESHOLD_OPTIONS(final String val) { ERROR_THRESHOLD_OPTIONS(final String value) {
value = val; this.value = value;
} }
private String getValue() { private String getValue(final VaadinMessageSource i18n) {
return value; return i18n.getMessage(value);
} }
} }
} }

View File

@@ -129,7 +129,7 @@ public class AuthenticationConfigurationView extends BaseConfigurationView
gridLayout.addComponent(anonymousDownloadAuthenticationConfigurationItem, 1, 3); gridLayout.addComponent(anonymousDownloadAuthenticationConfigurationItem, 1, 3);
final Link linkToSecurityHelp = SPUIComponentProvider final Link linkToSecurityHelp = SPUIComponentProvider
.getHelpLink(uiProperties.getLinks().getDocumentation().getSecurity()); .getHelpLink(i18n, uiProperties.getLinks().getDocumentation().getSecurity());
gridLayout.addComponent(linkToSecurityHelp, 2, 3); gridLayout.addComponent(linkToSecurityHelp, 2, 3);
gridLayout.setComponentAlignment(linkToSecurityHelp, Alignment.BOTTOM_RIGHT); gridLayout.setComponentAlignment(linkToSecurityHelp, Alignment.BOTTOM_RIGHT);

View File

@@ -74,7 +74,7 @@ public class RolloutConfigurationView extends BaseConfigurationView
hLayout.addComponent(approvalConfigurationItem); hLayout.addComponent(approvalConfigurationItem);
final Link linkToApprovalHelp = SPUIComponentProvider final Link linkToApprovalHelp = SPUIComponentProvider
.getHelpLink(uiProperties.getLinks().getDocumentation().getRollout()); .getHelpLink(i18n, uiProperties.getLinks().getDocumentation().getRollout());
hLayout.addComponent(linkToApprovalHelp); hLayout.addComponent(linkToApprovalHelp);
hLayout.setComponentAlignment(linkToApprovalHelp, Alignment.BOTTOM_RIGHT); hLayout.setComponentAlignment(linkToApprovalHelp, Alignment.BOTTOM_RIGHT);

View File

@@ -154,7 +154,7 @@ public class TenantConfigurationDashboardView extends CustomComponent implements
hlayout.addComponent(undoConfigurationBtn); hlayout.addComponent(undoConfigurationBtn);
final Link linkToSystemConfigHelp = SPUIComponentProvider final Link linkToSystemConfigHelp = SPUIComponentProvider
.getHelpLink(uiProperties.getLinks().getDocumentation().getSystemConfigurationView()); .getHelpLink(i18n, uiProperties.getLinks().getDocumentation().getSystemConfigurationView());
hlayout.addComponent(linkToSystemConfigHelp); hlayout.addComponent(linkToSystemConfigHelp);
return hlayout; return hlayout;

View File

@@ -8,25 +8,12 @@
*/ */
package org.eclipse.hawkbit.ui.utils; package org.eclipse.hawkbit.ui.utils;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Direction;
/** /**
* Class to provide the unchanged constants. * Class to provide the unchanged constants.
*/ */
public final class SPUIDefinitions { public final class SPUIDefinitions {
/**
* Available locales.
*/
private static final Set<String> AVAILABLE_LOCALES = Stream.of("en", "de").collect(Collectors.toSet());
/**
* Default locale.
*/
public static final String DEFAULT_LOCALE = "en";
/** /**
* Locale cookie name. * Locale cookie name.
*/ */
@@ -388,13 +375,4 @@ public final class SPUIDefinitions {
private SPUIDefinitions() { private SPUIDefinitions() {
} }
/**
* Get the locales
*
* @return the availableLocales
*/
public static Set<String> getAvailableLocales() {
return AVAILABLE_LOCALES;
}
} }

View File

@@ -242,6 +242,14 @@ label.scheduled = Scheduled
label.approval.decision = Approval decision label.approval.decision = Approval decision
label.approval.remark = Remark (optional) label.approval.remark = Remark (optional)
label.drop.area.upload = Drop Files to upload label.drop.area.upload = Drop Files to upload
label.errorthreshold.option.percent = %
label.errorthreshold.option.count = Count
label.targetUpdateStatus.unknown = Unknown
label.targetUpdateStatus.in_sync = In Sync
label.targetUpdateStatus.pending = Pending
label.targetUpdateStatus.error = Error
label.targetUpdateStatus.registered = Registered
# Checkbox label prefix with - checkbox # Checkbox label prefix with - checkbox
checkbox.dist.migration.required = Required Migration Step : checkbox.dist.migration.required = Required Migration Step :
@@ -279,6 +287,7 @@ tooltip.metadata.icon = Manage Metadata..
tooltip.next.maintenance.window = next on {0} tooltip.next.maintenance.window = next on {0}
tooltip.target.attributes.update.request = Request attributes update tooltip.target.attributes.update.request = Request attributes update
tooltip.target.attributes.update.requested = Update already requested tooltip.target.attributes.update.requested = Update already requested
tooltip.documentation.link=Documentation
#rollout action #rollout action
tooltip.rollout.run = Run tooltip.rollout.run = Run
@@ -313,7 +322,7 @@ message.dist.pending.action = Target {0} is already assigned with distribution
message.empty.target.tags= No Tags Created message.empty.target.tags= No Tags Created
message.empty.disttype.tags = No Distribution type tags created message.empty.disttype.tags = No Distribution type tags created
message.select.row = Please select a row to drag message.select.row = Please select a row to drag
message.error = Unknown error occured during the operation. Please contact administrator message.error = Unknown error occurred during the operation. Please contact administrator
message.dist.assigned.one = {0} is assigned to {1} message.dist.assigned.one = {0} is assigned to {1}
message.dist.assigned.many = {0} DistributionSets are assigned to {1} message.dist.assigned.many = {0} DistributionSets are assigned to {1}
message.dist.unassigned.one = {0} is unassigned from {1} message.dist.unassigned.one = {0} is unassigned from {1}
@@ -324,12 +333,12 @@ message.target.unassigned.one = {0} is unassigned from {1}
message.target.unassigned.many = {0} Targets are unassigned from {1} message.target.unassigned.many = {0} Targets are unassigned from {1}
message.target.assigned.pending = Some target(s) are already assigned.Pending for action message.target.assigned.pending = Some target(s) are already assigned.Pending for action
message.cannot.delete = Cannot be deleted message.cannot.delete = Cannot be deleted
message.check.softwaremodule = Please provide both name and verion! message.check.softwaremodule = Please provide both name and version!
message.duplicate.softwaremodule = {0} : {1} already exists! message.duplicate.softwaremodule = {0} : {1} already exists!
message.tag.delete = Please unclick the tag {0} before deleting message.tag.delete = Please deselect the tag {0} before deleting
message.dist.type.check.delete = Please unclick the distribution type {0} before deleting message.dist.type.check.delete = Please deselect the distribution type {0} before deleting
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
message.swmodule.type.check.delete = Please unclick the Software Module type {0} before deleting message.swmodule.type.check.delete = Please deselect the Software Module type {0} before deleting
message.targets.already.deleted = Few Target(s) are already deleted. Pending for action message.targets.already.deleted = Few Target(s) are already deleted. Pending for action
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
message.target.deleted.pending = Target(s) already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action