diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index 967ceee1c..3aa994aa9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -16,6 +16,7 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; @@ -37,10 +38,12 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractTextField.TextChangeEventMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -110,6 +113,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button private LayoutClickListener nameLayoutClickListner; + private Button targetFilterStatusButton; + /** * Initialize the Campaign Status History Header. */ @@ -195,11 +200,25 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button validationIcon = createStatusIcon(); saveButton = createSaveButton(); + targetFilterStatusButton = createTargetFilterStatusButton(); + helpLink = DocumentationPageLink.TARGET_FILTER_VIEW.getLink(); closeIcon = createSearchResetIcon(); } + private Button createTargetFilterStatusButton() { + targetFilterStatusButton = SPUIComponentProvider.getButton(SPUIComponetIdProvider.TARGET_FILTER_STATUS_BUTTON, + "", "", "", false, null, SPUIButtonStyleSmall.class); + targetFilterStatusButton.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + targetFilterStatusButton.addStyleName(ValoTheme.BUTTON_BORDERLESS); + targetFilterStatusButton.setWidth("100px"); + targetFilterStatusButton.setHtmlContentAllowed(true); + targetFilterStatusButton.setVisible(false); + targetFilterStatusButton.setImmediate(true); + return targetFilterStatusButton; + } + /** * @return */ @@ -280,7 +299,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button final HorizontalLayout iconLayout = new HorizontalLayout(); iconLayout.setSizeUndefined(); iconLayout.setSpacing(false); - iconLayout.addComponents(helpLink, saveButton); + iconLayout.setStyleName(SPUIStyleDefinitions.TARGET_FILTER_SEARCH_PROGRESS_INDICATOR_STYLE); + iconLayout.addComponents(helpLink, saveButton, targetFilterStatusButton); + iconLayout.setComponentAlignment(targetFilterStatusButton, Alignment.MIDDLE_CENTER); final HorizontalLayout queryLayout = new HorizontalLayout(); queryLayout.setSizeUndefined(); @@ -310,6 +331,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button queryTextField.addTextChangeListener(new TextChangeListener() { @Override public void textChange(final TextChangeEvent event) { + enableTargetFilterStatusButton(); + updateTargetFilterStatusToProgressIndicator(); onQueryChange(event.getText()); eventBus.publish(this, CustomFilterUIEvent.FILTER_TARGET_BY_QUERY); } @@ -393,6 +416,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button textField.setWidth(900.0F, Unit.PIXELS); textField.setTextChangeEventMode(TextChangeEventMode.LAZY); textField.setTextChangeTimeout(1000); + + textField.addShortcutListener(new AbstractField.FocusShortcut(textField, KeyCode.ENTER)); return textField; } @@ -493,4 +518,20 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button return true; } + protected void enableTargetFilterStatusButton() { + targetFilterStatusButton.setVisible(true); + + } + + protected void updateTargetFilterStatusToComplete() { + targetFilterStatusButton.removeStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + targetFilterStatusButton.setVisible(false); + + } + + protected void updateTargetFilterStatusToProgressIndicator() { + targetFilterStatusButton.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + targetFilterStatusButton.setIcon(null); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java index 8538014d5..932fa848c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java @@ -63,6 +63,9 @@ public class CreateOrUpdateFilterTable extends Table { @Autowired private FilterManagementUIState filterManagementUIState; + @Autowired + private CreateOrUpdateFilterHeader createOrUpdateFilterHeader; + private LazyQueryContainer container; private static final int PROPERTY_DEPT = 3; @@ -93,6 +96,7 @@ public class CreateOrUpdateFilterTable extends Table { || custFUIEvent == CustomFilterUIEvent.TARGET_DETAILS_VIEW || custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) { populateTableData(); + // createOrUpdateFilterHeader.updateTargetFilterStatusToComplete(); } } @@ -234,4 +238,8 @@ public class CreateOrUpdateFilterTable extends Table { addGeneratedColumn(SPUILabelDefinitions.STATUS_ICON, (source, itemId, columnId) -> getStatusIcon(itemId)); } + protected void onValueChange() { + createOrUpdateFilterHeader.updateTargetFilterStatusToComplete(); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java index 2c38cc030..287bfaffd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java @@ -12,6 +12,7 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; +import org.eclipse.hawkbit.ui.filtermanagement.footer.TargetFilterCountMessageLabel; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -23,6 +24,7 @@ import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Alignment; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; @@ -55,9 +57,14 @@ public class FilterManagementView extends VerticalLayout implements View { @Autowired private FilterManagementUIState filterManagementUIState; + @Autowired + private TargetFilterCountMessageLabel targetFilterCountMessageLabel; + @Autowired private transient EventBus.SessionEventBus eventBus; + private HorizontalLayout messageLabelLayout; + @Override public void enter(final ViewChangeEvent event) { setSizeFull(); @@ -107,10 +114,25 @@ public class FilterManagementView extends VerticalLayout implements View { private void buildFilterDetailOrCreateView() { removeAllComponents(); - addComponents(createNewFilterHeader, createNewFilterTable); - setComponentAlignment(createNewFilterHeader, Alignment.TOP_LEFT); - setComponentAlignment(createNewFilterTable, Alignment.TOP_LEFT); - setExpandRatio(createNewFilterTable, 1.0f); + final VerticalLayout tableHeaderLayout = new VerticalLayout(); + tableHeaderLayout.setSizeFull(); + tableHeaderLayout.setSpacing(false); + tableHeaderLayout.setMargin(false); + tableHeaderLayout.setStyleName("table-layout"); + tableHeaderLayout.addComponent(createNewFilterHeader); + tableHeaderLayout.setComponentAlignment(createNewFilterHeader, Alignment.TOP_CENTER); + tableHeaderLayout.addComponent(createNewFilterTable); + tableHeaderLayout.setComponentAlignment(createNewFilterTable, Alignment.TOP_CENTER); + tableHeaderLayout.setExpandRatio(createNewFilterTable, 1.0f); + + addComponent(tableHeaderLayout); + setComponentAlignment(tableHeaderLayout, Alignment.TOP_CENTER); + setExpandRatio(tableHeaderLayout, 1.0f); + + final HorizontalLayout targetsCountmessageLabelLayout = addTargetFilterMessageLabel(); + addComponent(targetsCountmessageLabelLayout); + setComponentAlignment(targetsCountmessageLabelLayout, Alignment.BOTTOM_CENTER); + } private void viewListView() { @@ -121,4 +143,12 @@ public class FilterManagementView extends VerticalLayout implements View { setExpandRatio(targetFilterTable, 1.0f); } + private HorizontalLayout addTargetFilterMessageLabel() { + messageLabelLayout = new HorizontalLayout(); + messageLabelLayout.addComponent(targetFilterCountMessageLabel); + messageLabelLayout.addStyleName("footer-layout"); + messageLabelLayout.setWidth("100%"); + return messageLabelLayout; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java new file mode 100644 index 000000000..6dcaf5266 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.ui.filtermanagement.footer; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.ui.filtermanagement.CreateOrUpdateFilterTable; +import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterTable; +import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; +import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; +import org.eclipse.hawkbit.ui.utils.I18N; +import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.springframework.beans.factory.annotation.Autowired; +import org.vaadin.spring.events.EventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.spring.annotation.SpringComponent; +import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.Label; + +/** + * @author Venugopal Boodidadinne(RBEI/BSJ) + * + * Count message label which display current filter details and details + * on pinning. + */ +@SpringComponent +@ViewScope +public class TargetFilterCountMessageLabel extends Label { + + private static final long serialVersionUID = -7188528790042766877L; + + @Autowired + private CreateOrUpdateFilterTable createNewFilterTable; + + @Autowired + private TargetFilterTable targetFilterTable; + + @Autowired + private FilterManagementUIState filterManagementUIState; + + @Autowired + private transient TargetManagement targetManagement; + + @Autowired + private I18N i18n; + + @Autowired + private transient EventBus.SessionEventBus eventBus; + + /** + * PostConstruct method called by spring after bean has been initialized. + */ + @PostConstruct + public void postConstruct() { + applyStyle(); + displayTargetFilterMessage(); + eventBus.subscribe(this); + } + + @PreDestroy + void destroy() { + eventBus.unsubscribe(this); + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final CustomFilterUIEvent custFUIEvent) { + if (custFUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY + || custFUIEvent == CustomFilterUIEvent.TARGET_DETAILS_VIEW + || custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK + || custFUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW) { + displayTargetFilterMessage(); + } + } + + private void applyStyle() { + addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); + setContentMode(ContentMode.HTML); + setId(SPUIComponetIdProvider.COUNT_LABEL); + } + + private void displayTargetFilterMessage() { + long totalTargets = 0; + long shownTargets = 0; + if (filterManagementUIState.isCreateFilterViewDisplayed() || filterManagementUIState.isEditViewDisplayed()) { + if (null != filterManagementUIState.getFilterQueryValue()) { + totalTargets = targetManagement.countTargetByTargetFilterQuery(filterManagementUIState + .getFilterQueryValue()); + shownTargets = createNewFilterTable.size(); + } + final StringBuilder targetMessage = new StringBuilder(i18n.get("label.target.filtered.total")); + if (filterManagementUIState.getTargetsTruncated() != null) { + // set the icon + setIcon(FontAwesome.INFO_CIRCLE); + setDescription(i18n.get("label.target.filter.truncated", filterManagementUIState.getTargetsTruncated(), + SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + + } else { + setIcon(null); + setDescription(null); + } + targetMessage.append(totalTargets); + targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); + if (totalTargets > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + targetMessage.append(i18n.get("label.filter.shown")); + targetMessage.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + } else { + targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); + targetMessage.append(i18n.get("label.filter.shown")); + targetMessage.append(shownTargets); + } + + setCaption(targetMessage.toString()); + } else { + final StringBuilder tarFilterMessage = new StringBuilder(i18n.get("label.custom.filter.target.count")); + createMsgLable(targetFilterTable.size(), tarFilterMessage); + } + + } + + private void createMsgLable(final long totalCount, final StringBuilder message) { + message.append(totalCount); + message.append(HawkbitCommonUtil.SP_STRING_SPACE); + if (totalCount > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + message.append(i18n.get("label.filter.shown")); + message.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + } + message.append(HawkbitCommonUtil.SP_STRING_SPACE); + setCaption(message.toString()); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java index 170c7ab32..8aa1cbd0f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java @@ -706,6 +706,11 @@ public final class SPUIComponetIdProvider { */ public static final String BULK_UPLOAD_STATUS_BUTTON = "bulk.upload.notification.id"; + /** + * Target Filter Status button id. + */ + public static final String TARGET_FILTER_STATUS_BUTTON = "target.filter.status.button.id"; + /** * Target bulk upload minimize button id. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java index ab6b93c39..a7cede113 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java @@ -231,6 +231,11 @@ public final class SPUIStyleDefinitions { */ public static final String BULK_UPLOAD_PROGRESS_INDICATOR_STYLE = "app-loading"; + /** + * Target filter search progress indicator style. + */ + public static final String TARGET_FILTER_SEARCH_PROGRESS_INDICATOR_STYLE = "target-filter-search-layout"; + /** * Constructor. */ diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss index 1b58fb0c8..3738599d1 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss @@ -87,7 +87,7 @@ } - .footer-layout{ + .footer-layout , .target-filter-search-layout{ .app-loading { background-position: bottom; background-repeat: no-repeat; diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 57b807b01..1579f888f 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -125,6 +125,7 @@ label.choose.tag = Choose Tag to update label.choose.tag.color = Choose Tag Color label.filter = Filter: label.target.filter.count = Total Targets: +label.target.filtered.total = Total filtered targets : label.filter.selected = Selected: label.filter.shown = Shown: label.filter.targets = Filtered targets : diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index ffb753c58..b5a254b2a 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -124,6 +124,7 @@ label.choose.tag = Choose Tag to update label.choose.tag.color = Choose Tag Color label.filter = Filter: label.target.filter.count = Total Targets: +label.target.filtered.total = Total filtered targets : label.filter.selected = Selected: label.filter.shown = Shown: label.filter.status = Status, diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 32e7cf0e2..e1f80e6cb 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -125,6 +125,7 @@ label.choose.tag = Choose Tag to update label.choose.tag.color = Choose Tag Color label.filter = Filter: label.target.filter.count = Total Targets: +label.target.filtered.total = Total filtered targets : label.filter.selected = Selected: label.filter.shown = Shown: label.filter.targets = Filtered targets :