Merge branch 'master' into feature_multiunassignment_soft_mod

Conflicts:
	hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java
This commit is contained in:
Gaurav
2016-07-25 14:05:18 +02:00
42 changed files with 1973 additions and 106 deletions

View File

@@ -1,5 +1,7 @@
Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=svg)](https://circleci.com/gh/eclipse/hawkbit) Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=svg)](https://circleci.com/gh/eclipse/hawkbit)
<img src=hawkbit_logo.png width=533 height=246 />
# Eclipse.IoT hawkBit - Update Server # Eclipse.IoT hawkBit - Update Server
[hawkBit](https://projects.eclipse.org/projects/iot.hawkbit) is an domain independent back end solution for rolling out software updates to constrained edge devices as well as more powerful controllers and gateways connected to IP based networking infrastructure. [hawkBit](https://projects.eclipse.org/projects/iot.hawkbit) is an domain independent back end solution for rolling out software updates to constrained edge devices as well as more powerful controllers and gateways connected to IP based networking infrastructure.

View File

@@ -64,7 +64,12 @@ public enum TargetFields implements FieldNameProvider {
/** /**
* The tags field. * The tags field.
*/ */
TAG("tags.name"); TAG("tags.name"),
/**
* Last time the target or DMF client polled.
*/
LASTCONTROLLERREQUESTAT("targetInfo.lastTargetQuery");
private final String fieldName; private final String fieldName;
private List<String> subEntityAttribues; private List<String> subEntityAttribues;

View File

@@ -8,12 +8,14 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; package org.eclipse.hawkbit.mgmt.rest.resource;
import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.api.Assertions.assertThat; import static org.fest.assertions.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -33,7 +35,6 @@ import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.ActionStatusFields;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
@@ -90,6 +91,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
private static final String JSON_PATH_FIELD_CONTENT = ".content"; private static final String JSON_PATH_FIELD_CONTENT = ".content";
private static final String JSON_PATH_FIELD_SIZE = ".size"; private static final String JSON_PATH_FIELD_SIZE = ".size";
private static final String JSON_PATH_FIELD_TOTAL = ".total"; private static final String JSON_PATH_FIELD_TOTAL = ".total";
private static final String JSON_PATH_FIELD_LAST_REQUEST_AT = ".lastControllerRequestAt";
// target // target
// $.field // $.field
@@ -101,6 +103,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID; private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID;
private static final String JSON_PATH_CONTROLLERID = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTROLLERID; private static final String JSON_PATH_CONTROLLERID = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTROLLERID;
private static final String JSON_PATH_DESCRIPTION = JSON_PATH_ROOT + JSON_PATH_FIELD_DESCRIPTION; private static final String JSON_PATH_DESCRIPTION = JSON_PATH_ROOT + JSON_PATH_FIELD_DESCRIPTION;
private static final String JSON_PATH_LAST_REQUEST_AT = JSON_PATH_ROOT + JSON_PATH_FIELD_LAST_REQUEST_AT;
@Test @Test
@Description("Ensures that actions list is in exptected order.") @Description("Ensures that actions list is in exptected order.")
@@ -425,6 +428,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].controllerId", equalTo(idA))) .andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].controllerId", equalTo(idA)))
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].createdBy", equalTo("bumlux"))) .andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].createdBy", equalTo("bumlux")))
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].updateStatus", equalTo("unknown"))) .andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].updateStatus", equalTo("unknown")))
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].lastControllerRequestAt", notNullValue()))
// idB // idB
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0]._links.self.href", .andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0]._links.self.href",
equalTo(linksHrefPrefix + idB))) equalTo(linksHrefPrefix + idB)))
@@ -433,6 +437,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].controllerId", equalTo(idB))) .andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].controllerId", equalTo(idB)))
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].createdBy", equalTo("bumlux"))) .andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].createdBy", equalTo("bumlux")))
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].updateStatus", equalTo("unknown"))) .andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].updateStatus", equalTo("unknown")))
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].lastControllerRequestAt", notNullValue()))
// idC // idC
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0]._links.self.href", .andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0]._links.self.href",
equalTo(linksHrefPrefix + idC))) equalTo(linksHrefPrefix + idC)))
@@ -440,7 +445,8 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].description", equalTo(idC))) .andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].description", equalTo(idC)))
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].controllerId", equalTo(idC))) .andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].controllerId", equalTo(idC)))
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].createdBy", equalTo("bumlux"))) .andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].createdBy", equalTo("bumlux")))
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].updateStatus", equalTo("unknown"))); .andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0].updateStatus", equalTo("unknown")))
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].lastControllerRequestAt", notNullValue()));
} }
@Test @Test
@@ -518,7 +524,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
// create first a target which can be retrieved by rest interface // create first a target which can be retrieved by rest interface
final String knownControllerId = "1"; final String knownControllerId = "1";
final String knownName = "someName"; final String knownName = "someName";
createSingleTarget(knownControllerId, knownName); final Target target = createSingleTarget(knownControllerId, knownName);
final String hrefPrefix = "http://localhost/rest/v1/targets/" + knownControllerId + "/"; final String hrefPrefix = "http://localhost/rest/v1/targets/" + knownControllerId + "/";
// test // test
mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId)) mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId))
@@ -526,6 +532,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName))) .andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName)))
.andExpect(jsonPath(JSON_PATH_CONTROLLERID, equalTo(knownControllerId))) .andExpect(jsonPath(JSON_PATH_CONTROLLERID, equalTo(knownControllerId)))
.andExpect(jsonPath(JSON_PATH_DESCRIPTION, equalTo(TARGET_DESCRIPTION_TEST))) .andExpect(jsonPath(JSON_PATH_DESCRIPTION, equalTo(TARGET_DESCRIPTION_TEST)))
.andExpect(jsonPath(JSON_PATH_LAST_REQUEST_AT, equalTo(target.getTargetInfo().getLastTargetQuery())))
.andExpect(jsonPath("$.pollStatus", hasKey("lastRequestAt"))) .andExpect(jsonPath("$.pollStatus", hasKey("lastRequestAt")))
.andExpect(jsonPath("$.pollStatus", hasKey("nextExpectedRequestAt"))) .andExpect(jsonPath("$.pollStatus", hasKey("nextExpectedRequestAt")))
.andExpect(jsonPath("$.pollStatus.overdue", equalTo(false))) .andExpect(jsonPath("$.pollStatus.overdue", equalTo(false)))
@@ -1075,8 +1082,6 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId)
throws InterruptedException { throws InterruptedException {
final PageRequest pageRequest = new PageRequest(0, 100, Direction.ASC, ActionStatusFields.ID.getFieldName());
Target target = entityFactory.generateTarget(knownTargetId); Target target = entityFactory.generateTarget(knownTargetId);
target = targetManagement.createTarget(target); target = targetManagement.createTarget(target);
final List<Target> targets = new ArrayList<>(); final List<Target> targets = new ArrayList<>();
@@ -1122,7 +1127,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
@Test @Test
public void assignDistributionSetToTarget() throws Exception { public void assignDistributionSetToTarget() throws Exception {
final Target target = targetManagement.createTarget(entityFactory.generateTarget("fsdfsd")); targetManagement.createTarget(entityFactory.generateTarget("fsdfsd"));
final DistributionSet set = testdataFactory.createDistributionSet("one"); final DistributionSet set = testdataFactory.createDistributionSet("one");
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS")
@@ -1299,19 +1304,20 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
+ "\"}]"; + "\"}]";
} }
private void createSingleTarget(final String controllerId, final String name) { private Target createSingleTarget(final String controllerId, final String name) {
final Target target = entityFactory.generateTarget(controllerId); final Target target = entityFactory.generateTarget(controllerId);
target.setName(name); target.setName(name);
target.setDescription(TARGET_DESCRIPTION_TEST); target.setDescription(TARGET_DESCRIPTION_TEST);
targetManagement.createTarget(target); targetManagement.createTarget(target);
controllerManagament.updateLastTargetQuery(controllerId, null); return controllerManagament.updateLastTargetQuery(controllerId, null);
} }
/** /**
* creating targets with the given amount by setting name, id etc from the * Creating targets with the given amount by setting name, id etc from the
* alphabet [a-z] using the ASCII. * alphabet [a-z] using ASCII.
* *
* @param amount * @param amount
* The number of targets to create
*/ */
private void createTargetsAlphabetical(final int amount) { private void createTargetsAlphabetical(final int amount) {
char character = 'a'; char character = 'a';
@@ -1320,15 +1326,15 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
final Target target = entityFactory.generateTarget(str); final Target target = entityFactory.generateTarget(str);
target.setName(str); target.setName(str);
target.setDescription(str); target.setDescription(str);
final Target savedTarget = targetManagement.createTarget(target); targetManagement.createTarget(target);
assertThat(savedTarget.getLastModifiedBy()).isNotNull(); controllerManagament.updateLastTargetQuery(str, null);
character++; character++;
} }
} }
/** /**
* helper method to give feedback mark an target IN_SNCY * helper method to give feedback mark an target IN_SYNC
* *
*/ */
private void feedbackToByInSync(final Long actionId) { private void feedbackToByInSync(final Long actionId) {
final Action action = deploymentManagement.findAction(actionId); final Action action = deploymentManagement.findAction(actionId);
@@ -1339,7 +1345,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
/** /**
* helper method to create a target and start an action on it. * helper method to create a target and start an action on it.
* *
* @return The targetid of the created target. * @return The targetid of the created target.
*/ */
private Target createTargetAndStartAction() { private Target createTargetAndStartAction() {
@@ -1348,7 +1354,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
final Target tA = targetManagement final Target tA = targetManagement
.createTarget(testdataFactory.generateTarget("target-id-A", "first description")); .createTarget(testdataFactory.generateTarget("target-id-A", "first description"));
// assign a distribution set so we get an active update action // assign a distribution set so we get an active update action
deploymentManagement.assignDistributionSet(dsA, Lists.newArrayList(tA)); deploymentManagement.assignDistributionSet(dsA, newArrayList(tA));
// verify active action // verify active action
final Slice<Action> actionsByTarget = deploymentManagement.findActionsByTarget(new PageRequest(0, 100), tA); final Slice<Action> actionsByTarget = deploymentManagement.findActionsByTarget(new PageRequest(0, 100), tA);
assertThat(actionsByTarget.getContent()).hasSize(1); assertThat(actionsByTarget.getContent()).hasSize(1);

View File

@@ -31,8 +31,6 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.persistence.config.PersistenceUnitProperties; import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
@@ -214,7 +212,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@CacheEvict(value = { "tenantMetadata" }, key = "#tenant.toUpperCase()", cacheManager = "directCacheManager")
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying @Modifying
public void deleteTenant(final String tenant) { public void deleteTenant(final String tenant) {
@@ -241,7 +238,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@Cacheable(value = "tenantMetadata", keyGenerator = "tenantKeyGenerator", cacheManager = "directCacheManager")
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying @Modifying
public TenantMetaData getTenantMetadata() { public TenantMetaData getTenantMetadata() {
@@ -276,7 +272,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@CachePut(value = "tenantMetadata", key = "#metaData.tenant.toUpperCase()", cacheManager = "directCacheManager")
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying @Modifying
public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) { public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) {

View File

@@ -83,6 +83,7 @@ public final class DistributionSetSpecification {
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT); targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT); targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT); targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.metadata, JoinType.LEFT);
query.distinct(true); query.distinct(true);
return predicate; return predicate;

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.specifications; package org.eclipse.hawkbit.repository.jpa.specifications;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
@@ -38,6 +39,8 @@ public final class SoftwareModuleSpecification {
return (targetRoot, query, cb) -> { return (targetRoot, query, cb) -> {
final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaSoftwareModule_.id), moduleId); final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaSoftwareModule_.id), moduleId);
targetRoot.fetch(JpaSoftwareModule_.type); targetRoot.fetch(JpaSoftwareModule_.type);
targetRoot.fetch(JpaSoftwareModule_.metadata,JoinType.LEFT);
query.distinct(true);
return predicate; return predicate;
}; };
} }

View File

@@ -37,6 +37,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository") @Features("Component Tests - Repository")
@Stories("RSQL filter target") @Stories("RSQL filter target")
public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
private static final long LAST_TARGET_QUERY = 10000;
private static final long LAST_TARGET_QUERY_SMALLER = 1000;
@Before @Before
public void seuptBeforeTest() { public void seuptBeforeTest() {
@@ -48,14 +50,16 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
final TargetInfo targetInfo = target.getTargetInfo(); final TargetInfo targetInfo = target.getTargetInfo();
targetInfo.getControllerAttributes().put("revision", "1.1"); targetInfo.getControllerAttributes().put("revision", "1.1");
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING); ((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
((JpaTargetInfo) target.getTargetInfo()).setLastTargetQuery(LAST_TARGET_QUERY);
targetManagement.createTarget(target); targetManagement.createTarget(target);
final JpaTarget target2 = new JpaTarget("targetId1234"); final JpaTarget target2 = new JpaTarget("targetId1234");
target2.setDescription("targetId1234"); target2.setDescription("targetId1234");
final TargetInfo targetInfo2 = new JpaTargetInfo(target2); final TargetInfo targetInfo2 = target2.getTargetInfo();
targetInfo2.getControllerAttributes().put("revision", "1.2"); targetInfo2.getControllerAttributes().put("revision", "1.2");
target2.setTargetInfo(targetInfo2); ((JpaTargetInfo) target2.getTargetInfo()).setLastTargetQuery(LAST_TARGET_QUERY_SMALLER);
targetManagement.createTarget(target2); targetManagement.createTarget(target2);
targetManagement.createTarget(new JpaTarget("targetId1235")); targetManagement.createTarget(new JpaTarget("targetId1235"));
targetManagement.createTarget(new JpaTarget("targetId1236")); targetManagement.createTarget(new JpaTarget("targetId1236"));
@@ -166,6 +170,17 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
assertRSQLQuery(TargetFields.TAG.name() + "=out=(Tag1,notexist)", 0); assertRSQLQuery(TargetFields.TAG.name() + "=out=(Tag1,notexist)", 0);
} }
@Test
@Description("Test filter target by lastTargetQuery")
public void testFilterByLastTargetQuery() {
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "==" + LAST_TARGET_QUERY, 1);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "!=" + LAST_TARGET_QUERY, 1);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=lt=" + LAST_TARGET_QUERY, 1);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=lt=" + LAST_TARGET_QUERY_SMALLER, 0);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=gt=" + LAST_TARGET_QUERY_SMALLER, 1);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=gt=" + LAST_TARGET_QUERY, 0);
}
private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) { private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) {
final Page<Target> findTargetPage = targetManagement.findTargetsAll(rsqlParam, new PageRequest(0, 100)); final Page<Target> findTargetPage = targetManagement.findTargetsAll(rsqlParam, new PageRequest(0, 100));
final long countTargetsAll = findTargetPage.getTotalElements(); final long countTargetsAll = findTargetPage.getTotalElements();

View File

@@ -8,11 +8,17 @@
*/ */
package org.eclipse.hawkbit.ui.artifacts.smtable; package org.eclipse.hawkbit.ui.artifacts.smtable;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout;
import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleMetadatadetailslayout;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -45,6 +51,44 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
@Autowired @Autowired
private ArtifactUploadState artifactUploadState; private ArtifactUploadState artifactUploadState;
@Autowired
private transient SoftwareManagement softwareManagement;
@Autowired
private SwMetadataPopupLayout swMetadataPopupLayout;
@Autowired
private EntityFactory entityFactory;
private SoftwareModuleMetadatadetailslayout swmMetadataTable;
/**
* softwareLayout Initialize the component.
*/
@Override
protected void init() {
swmMetadataTable = new SoftwareModuleMetadatadetailslayout();
swmMetadataTable.init(getI18n(), getPermissionChecker(),softwareManagement,swMetadataPopupLayout,entityFactory);
super.init();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final MetadataEvent event) {
UI.getCurrent()
.access(() -> {
SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata();
if (softwareModuleMetadata != null
&& isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) {
if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) {
swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey());
} else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) {
swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey());
}
}
});
}
@Override @Override
protected String getEditButtonId() { protected String getEditButtonId() {
return SPUIComponentIdProvider.UPLOAD_SW_MODULE_EDIT_BUTTON; return SPUIComponentIdProvider.UPLOAD_SW_MODULE_EDIT_BUTTON;
@@ -55,8 +99,9 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
detailsTab.addTab(createDetailsLayout(), getI18n().get("caption.tab.details"), null); detailsTab.addTab(createDetailsLayout(), getI18n().get("caption.tab.details"), null);
detailsTab.addTab(createDescriptionLayout(), getI18n().get("caption.tab.description"), null); detailsTab.addTab(createDescriptionLayout(), getI18n().get("caption.tab.description"), null);
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null);
} }
@Override @Override
protected void onEdit(final ClickEvent event) { protected void onEdit(final ClickEvent event) {
final Window addSoftwareModule = softwareModuleAddUpdateWindow final Window addSoftwareModule = softwareModuleAddUpdateWindow
@@ -81,6 +126,8 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
updateSoftwareModuleDetailsLayout(HawkbitCommonUtil.SP_STRING_EMPTY, HawkbitCommonUtil.SP_STRING_EMPTY, updateSoftwareModuleDetailsLayout(HawkbitCommonUtil.SP_STRING_EMPTY, HawkbitCommonUtil.SP_STRING_EMPTY,
maxAssign); maxAssign);
} }
populateMetadataDetails();
} }
private void updateSoftwareModuleDetailsLayout(final String type, final String vendor, final String maxAssign) { private void updateSoftwareModuleDetailsLayout(final String type, final String vendor, final String maxAssign) {
@@ -141,4 +188,38 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
protected String getDetailsHeaderCaptionId() { protected String getDetailsHeaderCaptionId() {
return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID;
} }
@Override
protected void populateMetadataDetails(){
swmMetadataTable.populateSMMetadata(getSelectedBaseEntity());
}
private boolean isSoftwareModuleSelected(SoftwareModule softwareModule) {
final SoftwareModule selectedUploadSWModule = artifactUploadState.getSelectedBaseSoftwareModule().isPresent() ? artifactUploadState
.getSelectedBaseSoftwareModule().get() : null;
return softwareModule != null && selectedUploadSWModule != null
&& selectedUploadSWModule.getName().equals(softwareModule.getName())
&& selectedUploadSWModule.getVersion().equals(softwareModule.getVersion());
}
@Override
protected Boolean isMetadataIconToBeDisplayed() {
return true;
}
@Override
protected String getShowMetadataButtonId() {
SoftwareModule selectedBaseEntity = getSelectedBaseEntity();
return SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + selectedBaseEntity.getName() + "."
+ selectedBaseEntity.getVersion();
}
@Override
protected void showMetadata(ClickEvent event) {
SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId());
/* display the window */
UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule,null));
}
} }

View File

@@ -21,10 +21,14 @@ import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable;
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -38,8 +42,11 @@ import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope; import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
/** /**
@@ -59,6 +66,9 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
@Autowired @Autowired
private UploadViewAcceptCriteria uploadViewAcceptCriteria; private UploadViewAcceptCriteria uploadViewAcceptCriteria;
@Autowired
private SwMetadataPopupLayout swMetadataPopupLayout;
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SMFilterEvent filterEvent) { void onEvent(final SMFilterEvent filterEvent) {
@@ -178,10 +188,26 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
super.updateEntity(baseEntity, item); super.updateEntity(baseEntity, item);
} }
@Override
protected void addCustomGeneratedColumns() {
addGeneratedColumn(SPUILabelDefinitions.METADATA_ICON, new ColumnGenerator() {
private static final long serialVersionUID = 117186282275044399L;
@Override
public Object generateCell(final Table source, final Object itemId, final Object columnId) {
final String nameVersionStr = getNameAndVerion(itemId);
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId, nameVersionStr));
return manageMetaDataBtn;
}
});
}
@Override @Override
protected List<TableColumn> getTableVisibleColumns() { protected List<TableColumn> getTableVisibleColumns() {
final List<TableColumn> columnList = super.getTableVisibleColumns(); final List<TableColumn> columnList = super.getTableVisibleColumns();
if (!isMaximized()) { if (!isMaximized()) {
columnList.add(new TableColumn(SPUILabelDefinitions.METADATA_ICON, "", 0.1F));
return columnList; return columnList;
} }
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, i18n.get("header.vendor"), 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, i18n.get("header.vendor"), 0.1F));
@@ -211,4 +237,26 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
artifactUploadState.setNoDataAvilableSoftwareModule(!available); artifactUploadState.setNoDataAvilableSoftwareModule(!available);
} }
private Button createManageMetadataButton(String nameVersionStr) {
final Button manageMetadataBtn = SPUIComponentProvider.getButton(
SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class);
manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON);
manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon"));
return manageMetadataBtn;
}
private String getNameAndVerion(final Object itemId) {
final Item item = getItem(itemId);
final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue();
return name + "." + version;
}
private void showMetadataDetails(Long itemId, String nameVersionStr) {
SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(itemId);
/* display the window */
UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule,null));
}
} }

View File

@@ -0,0 +1,487 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.common;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.SelectionEvent;
import com.vaadin.server.FontAwesome;
import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent;
import com.vaadin.ui.themes.ValoTheme;
/**
*
* Abstract pop up layout
*
* @param <E>
* E id the entity for which metadata is displayed
* @param <M>
* M is the metadata
*
*/
public abstract class AbstractMetadataPopupLayout<E extends NamedVersionedEntity, M extends MetaData>
extends CustomComponent {
private static final String DELETE_BUTTON = "DELETE_BUTTON";
private static final long serialVersionUID = -1491218218453167613L;
private static final String VALUE = "value";
private static final String KEY = "key";
@Autowired
protected I18N i18n;
@Autowired
private UINotification uiNotification;
@Autowired
protected transient EventBus.SessionEventBus eventBus;
private TextField keyTextField;
private TextArea valueTextArea;
private Button addIcon;
private Grid metaDataGrid;
private Label headerCaption;
private CommonDialogWindow metadataWindow;
private E selectedEntity;
private HorizontalLayout mainLayout;
@PostConstruct
private void init() {
createComponents();
buildLayout();
}
/**
* Returns metadata popup.
*
* @param entity
* entity for which metadata data is displayed
* @param metaData
* metadata to be selected
* @return @link{CommonDialogWindow}
*/
public CommonDialogWindow getWindow(final E entity, final M metaData) {
selectedEntity = entity;
final String nameVersion = HawkbitCommonUtil.getFormattedNameVersion(entity.getName(), entity.getVersion());
metadataWindow = SPUIWindowDecorator.getWindow(getMetadataCaption(nameVersion), null,
SPUIDefinitions.CUSTOM_METADATA_WINDOW, this, event -> onSave(), event -> onCancel(), null, mainLayout,
i18n);
metadataWindow.setId(SPUIComponentIdProvider.METADATA_POPUP_ID);
metadataWindow.setHeight(550, Unit.PIXELS);
metadataWindow.setWidth(800, Unit.PIXELS);
metadataWindow.getMainLayout().setSizeFull();
metadataWindow.getButtonsLayout().setHeight("45px");
setUpDetails(entity.getId(), metaData);
return metadataWindow;
}
public E getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity(final E selectedEntity) {
this.selectedEntity = selectedEntity;
}
protected abstract void checkForDuplicate(E entity, String value);
protected abstract M createMetadata(E entity, String key, String value);
protected abstract M updateMetadata(E entity, String key, String value);
protected abstract List<M> getMetadataList();
protected abstract void deleteMetadata(E entity, String key, String value);
protected abstract boolean hasCreatePermission();
protected abstract boolean hasUpdatePermission();
private void createComponents() {
keyTextField = createKeyTextField();
valueTextArea = createValueTextField();
metaDataGrid = createMetadataGrid();
addIcon = createAddIcon();
headerCaption = createHeaderCaption();
}
private void buildLayout() {
final HorizontalLayout headerLayout = new HorizontalLayout();
headerLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
headerLayout.setSpacing(false);
headerLayout.setMargin(false);
headerLayout.setSizeFull();
headerLayout.addComponent(headerCaption);
if (hasCreatePermission()) {
headerLayout.addComponents(addIcon);
headerLayout.setComponentAlignment(addIcon, Alignment.MIDDLE_RIGHT);
}
headerLayout.setExpandRatio(headerCaption, 1.0F);
final HorizontalLayout headerWrapperLayout = new HorizontalLayout();
headerWrapperLayout.addStyleName("bordered-layout" + " " + "no-border-bottom" + " " + "metadata-table-margin");
headerWrapperLayout.addComponent(headerLayout);
headerWrapperLayout.setWidth("100%");
headerLayout.setHeight("30px");
final VerticalLayout tableLayout = new VerticalLayout();
tableLayout.setSizeFull();
tableLayout.setHeight("100%");
tableLayout.addComponent(headerWrapperLayout);
tableLayout.addComponent(metaDataGrid);
tableLayout.addStyleName("table-layout");
tableLayout.setExpandRatio(metaDataGrid, 1.0F);
final VerticalLayout metadataFieldsLayout = new VerticalLayout();
metadataFieldsLayout.setSizeFull();
metadataFieldsLayout.setHeight("100%");
metadataFieldsLayout.addComponent(keyTextField);
metadataFieldsLayout.addComponent(valueTextArea);
metadataFieldsLayout.setSpacing(true);
metadataFieldsLayout.setExpandRatio(valueTextArea, 1F);
mainLayout = new HorizontalLayout();
mainLayout.addComponent(tableLayout);
mainLayout.addComponent(metadataFieldsLayout);
mainLayout.setExpandRatio(tableLayout, 0.5F);
mainLayout.setExpandRatio(metadataFieldsLayout, 0.5F);
mainLayout.setSizeFull();
mainLayout.setSpacing(true);
setCompositionRoot(mainLayout);
setSizeFull();
}
private TextField createKeyTextField() {
final TextField keyField = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "",
ValoTheme.TEXTFIELD_TINY, true, "", i18n.get("textfield.key"), true, 128);
keyField.setId(SPUIComponentIdProvider.METADATA_KEY_FIELD_ID);
keyField.addTextChangeListener(event -> onKeyChange(event));
keyField.setTextChangeEventMode(TextChangeEventMode.EAGER);
keyField.setWidth("100%");
return keyField;
}
private TextArea createValueTextField() {
valueTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.value"), null, ValoTheme.TEXTAREA_TINY,
true, null, i18n.get("textfield.value"), 4000);
valueTextArea.setId(SPUIComponentIdProvider.METADATA_VALUE_ID);
valueTextArea.setNullRepresentation("");
valueTextArea.setSizeFull();
valueTextArea.setHeight(100, Unit.PERCENTAGE);
valueTextArea.addTextChangeListener(event -> onValueChange(event));
valueTextArea.setTextChangeEventMode(TextChangeEventMode.EAGER);
return valueTextArea;
}
private Grid createMetadataGrid() {
final Grid metadataGrid = new Grid();
metadataGrid.addStyleName(SPUIStyleDefinitions.METADATA_GRID);
metadataGrid.setImmediate(true);
metadataGrid.setHeight("100%");
metadataGrid.setWidth("100%");
metadataGrid.setId(SPUIComponentIdProvider.METDATA_TABLE_ID);
metadataGrid.setSelectionMode(SelectionMode.SINGLE);
metadataGrid.setColumnReorderingAllowed(true);
metadataGrid.setContainerDataSource(getMetadataContainer());
metadataGrid.getColumn(KEY).setHeaderCaption(i18n.get("header.key"));
metadataGrid.getColumn(VALUE).setHeaderCaption(i18n.get("header.value"));
metadataGrid.getColumn(VALUE).setHidden(true);
metadataGrid.addSelectionListener(event -> onRowClick(event));
metadataGrid.getColumn(DELETE_BUTTON).setHeaderCaption("");
metadataGrid.getColumn(DELETE_BUTTON).setRenderer(new HtmlButtonRenderer(event -> onDelete(event)));
metadataGrid.getColumn(DELETE_BUTTON).setWidth(50);
metadataGrid.getColumn(KEY).setExpandRatio(1);
return metadataGrid;
}
private void onDelete(final RendererClickEvent event) {
final Item item = metaDataGrid.getContainerDataSource().getItem(event.getItemId());
final String key = (String) item.getItemProperty(KEY).getValue();
final String value = (String) item.getItemProperty(VALUE).getValue();
final ConfirmationDialog confirmDialog = new ConfirmationDialog(
i18n.get("caption.metadata.delete.action.confirmbox"), i18n.get("message.confirm.delete.metadata", key),
i18n.get("button.ok"), i18n.get("button.cancel"), ok -> {
if (ok) {
deleteMetadata(getSelectedEntity(), key, value);
uiNotification.displaySuccess(i18n.get("message.metadata.deleted.successfully", key));
final Object selectedRow = metaDataGrid.getSelectedRow();
metaDataGrid.getContainerDataSource().removeItem(event.getItemId());
// force grid to refresh
metaDataGrid.clearSortOrder();
if (!metaDataGrid.getContainerDataSource().getItemIds().isEmpty()) {
if (selectedRow != null) {
if (selectedRow.equals(event.getItemId())) {
metaDataGrid.select(metaDataGrid.getContainerDataSource().getIdByIndex(0));
} else {
metaDataGrid.select(selectedRow);
}
}
} else {
keyTextField.clear();
valueTextArea.clear();
metaDataGrid.select(null);
if (hasCreatePermission()) {
keyTextField.setEnabled(true);
valueTextArea.setEnabled(true);
addIcon.setEnabled(false);
}
}
}
});
UI.getCurrent().addWindow(confirmDialog.getWindow());
confirmDialog.getWindow().bringToFront();
}
private Button createAddIcon() {
addIcon = SPUIComponentProvider.getButton(SPUIComponentIdProvider.METADTA_ADD_ICON_ID, i18n.get("button.save"),
null, null, false, FontAwesome.PLUS, SPUIButtonStyleSmallNoBorder.class);
addIcon.addClickListener(event -> onAdd(event));
return addIcon;
}
private Label createHeaderCaption() {
final Label captionLabel = SPUIComponentProvider.getLabel(i18n.get("caption.metadata"),
SPUILabelDefinitions.SP_WIDGET_CAPTION);
return captionLabel;
}
private IndexedContainer getMetadataContainer() {
final IndexedContainer swcontactContainer = new IndexedContainer();
swcontactContainer.addContainerProperty(KEY, String.class, "");
swcontactContainer.addContainerProperty(VALUE, String.class, "");
swcontactContainer.addContainerProperty(DELETE_BUTTON, String.class, FontAwesome.TRASH_O.getHtml());
return swcontactContainer;
}
private void popualateKeyValue(final Object metadataCompositeKey) {
if (metadataCompositeKey != null) {
final Item item = metaDataGrid.getContainerDataSource().getItem(metadataCompositeKey);
keyTextField.setValue((String) item.getItemProperty(KEY).getValue());
valueTextArea.setValue((String) item.getItemProperty(VALUE).getValue());
keyTextField.setEnabled(false);
if (hasUpdatePermission()) {
valueTextArea.setEnabled(true);
}
}
}
private void populateGrid() {
final List<M> metadataList = getMetadataList();
for (final M metaData : metadataList) {
addItemToGrid(metaData.getKey(), metaData.getValue());
}
}
private void addItemToGrid(final String key, final String value) {
final IndexedContainer metadataContainer = (IndexedContainer) metaDataGrid.getContainerDataSource();
final Item item = metadataContainer.addItem(key);
item.getItemProperty(VALUE).setValue(value);
item.getItemProperty(KEY).setValue(key);
}
private void updateItemInGrid(final String key) {
final IndexedContainer metadataContainer = (IndexedContainer) metaDataGrid.getContainerDataSource();
final Item item = metadataContainer.getItem(key);
item.getItemProperty(VALUE).setValue(valueTextArea.getValue());
}
private void onAdd(final ClickEvent event) {
metaDataGrid.deselect(metaDataGrid.getSelectedRow());
valueTextArea.clear();
keyTextField.clear();
keyTextField.setEnabled(true);
valueTextArea.setEnabled(true);
addIcon.setEnabled(true);
}
private void onSave() {
final String key = keyTextField.getValue();
final String value = valueTextArea.getValue();
if (mandatoryCheck()) {
final E entity = selectedEntity;
if (metaDataGrid.getSelectedRow() == null) {
if (!duplicateCheck(entity)) {
final M metadata = createMetadata(entity, key, value);
uiNotification.displaySuccess(i18n.get("message.metadata.saved", metadata.getKey()));
addItemToGrid(metadata.getKey(), metadata.getValue());
metaDataGrid.scrollToEnd();
metaDataGrid.select(metadata.getKey());
addIcon.setEnabled(true);
metadataWindow.setSaveButtonEnabled(false);
if (!hasUpdatePermission()) {
valueTextArea.setEnabled(false);
}
}
} else {
final M metadata = updateMetadata(entity, key, value);
uiNotification.displaySuccess(i18n.get("message.metadata.updated", metadata.getKey()));
updateItemInGrid(metadata.getKey());
metaDataGrid.select(metadata.getKey());
addIcon.setEnabled(true);
metadataWindow.setSaveButtonEnabled(false);
}
}
}
private boolean mandatoryCheck() {
if (keyTextField.getValue().isEmpty()) {
uiNotification.displayValidationError(i18n.get("message.key.missing"));
return false;
}
if (valueTextArea.getValue().isEmpty()) {
uiNotification.displayValidationError(i18n.get("message.value.missing"));
return false;
}
return true;
}
private boolean duplicateCheck(final E entity) {
try {
checkForDuplicate(entity, keyTextField.getValue());
} catch (final EntityNotFoundException exception) {
return false;
}
uiNotification.displayValidationError(i18n.get("message.metadata.duplicate.check", keyTextField.getValue()));
return true;
}
private String getMetadataCaption(final String nameVersionStr) {
final StringBuilder caption = new StringBuilder();
caption.append(HawkbitCommonUtil.DIV_DESCRIPTION + i18n.get("caption.metadata.popup") + " "
+ HawkbitCommonUtil.getBoldHTMLText(nameVersionStr));
caption.append(HawkbitCommonUtil.DIV_CLOSE);
return caption.toString();
}
private void onCancel() {
metadataWindow.close();
UI.getCurrent().removeWindow(metadataWindow);
}
private void onKeyChange(final TextChangeEvent event) {
if (hasCreatePermission() || hasUpdatePermission()) {
if (!valueTextArea.getValue().isEmpty() && !event.getText().isEmpty()) {
metadataWindow.setSaveButtonEnabled(true);
} else {
metadataWindow.setSaveButtonEnabled(false);
}
}
}
private void onRowClick(final SelectionEvent event) {
final Set<Object> itemsSelected = event.getSelected();
if (!itemsSelected.isEmpty()) {
final Object itemSelected = itemsSelected.stream().findFirst().isPresent()
? itemsSelected.stream().findFirst().get() : null;
popualateKeyValue(itemSelected);
addIcon.setEnabled(true);
} else {
keyTextField.clear();
valueTextArea.clear();
if (hasCreatePermission()) {
keyTextField.setEnabled(true);
valueTextArea.setEnabled(true);
addIcon.setEnabled(false);
} else {
keyTextField.setEnabled(false);
valueTextArea.setEnabled(false);
}
}
metadataWindow.setSaveButtonEnabled(false);
}
private void onValueChange(final TextChangeEvent event) {
if (hasCreatePermission() || hasUpdatePermission()) {
if (!keyTextField.getValue().isEmpty() && !event.getText().isEmpty()) {
metadataWindow.setSaveButtonEnabled(true);
} else {
metadataWindow.setSaveButtonEnabled(false);
}
}
}
private void setUpDetails(final Long swId, final M metaData) {
resetDetails();
if (swId != null) {
metaDataGrid.getContainerDataSource().removeAllItems();
populateGrid();
metaDataGrid.getSelectionModel().reset();
if (!metaDataGrid.getContainerDataSource().getItemIds().isEmpty()) {
if (metaData == null) {
metaDataGrid.select(metaDataGrid.getContainerDataSource().getIdByIndex(0));
} else {
metaDataGrid.select(metaData.getKey());
}
} else if (hasCreatePermission()) {
keyTextField.setEnabled(true);
valueTextArea.setEnabled(true);
addIcon.setEnabled(false);
}
}
}
private void resetDetails() {
keyTextField.clear();
valueTextArea.clear();
keyTextField.setEnabled(false);
valueTextArea.setEnabled(false);
metadataWindow.setSaveButtonEnabled(false);
addIcon.setEnabled(true);
}
}

View File

@@ -190,6 +190,7 @@ public class CommonDialogWindow extends Window implements Serializable {
if (null != content) { if (null != content) {
mainLayout.addComponent(content); mainLayout.addComponent(content);
mainLayout.setExpandRatio(content, 1.0F);
} }
createMandatoryLabel(); createMandatoryLabel();
@@ -199,6 +200,7 @@ public class CommonDialogWindow extends Window implements Serializable {
mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER); mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER);
setCaption(caption); setCaption(caption);
setCaptionAsHtml(true);
setContent(mainLayout); setContent(mainLayout);
setResizable(false); setResizable(false);
center(); center();
@@ -224,7 +226,21 @@ public class CommonDialogWindow extends Window implements Serializable {
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null)); saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null));
} }
private final void addListeners() { protected void addListeners() {
addComponenetListeners();
addCloseListenerForSaveButton();
addCloseListenerForCancelButton();
}
protected void addCloseListenerForSaveButton() {
saveButton.addClickListener(close);
}
protected void addCloseListenerForCancelButton() {
cancelButton.addClickListener(close);
}
protected void addComponenetListeners() {
for (final AbstractField<?> field : allComponents) { for (final AbstractField<?> field : allComponents) {
if (field instanceof TextChangeNotifier) { if (field instanceof TextChangeNotifier) {
((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field));
@@ -236,9 +252,6 @@ public class CommonDialogWindow extends Window implements Serializable {
field.addValueChangeListener(new ChangeListener(field)); field.addValueChangeListener(new ChangeListener(field));
} }
} }
saveButton.addClickListener(close);
cancelButton.addClickListener(close);
} }
private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent, private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent,
@@ -378,6 +391,7 @@ public class CommonDialogWindow extends Window implements Serializable {
buttonsLayout = new HorizontalLayout(); buttonsLayout = new HorizontalLayout();
buttonsLayout.setSizeFull(); buttonsLayout.setSizeFull();
buttonsLayout.setSpacing(true); buttonsLayout.setSpacing(true);
buttonsLayout.setSpacing(true);
buttonsLayout.addStyleName("actionButtonsMargin"); buttonsLayout.addStyleName("actionButtonsMargin");
createSaveButton(); createSaveButton();
@@ -412,6 +426,7 @@ public class CommonDialogWindow extends Window implements Serializable {
cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true, cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true,
FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class); FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class);
cancelButton.setSizeUndefined(); cancelButton.setSizeUndefined();
cancelButton.addStyleName("default-color");
if (cancelButtonClickListener != null) { if (cancelButtonClickListener != null) {
cancelButton.addClickListener(cancelButtonClickListener); cancelButton.addClickListener(cancelButtonClickListener);
} }
@@ -425,6 +440,7 @@ public class CommonDialogWindow extends Window implements Serializable {
saveButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.SAVE_BUTTON, "Save", "", "", true, saveButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.SAVE_BUTTON, "Save", "", "", true,
FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class); FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class);
saveButton.setSizeUndefined(); saveButton.setSizeUndefined();
saveButton.addStyleName("default-color");
saveButton.addClickListener(saveButtonClickListener); saveButton.addClickListener(saveButtonClickListener);
saveButton.setEnabled(false); saveButton.setEnabled(false);
buttonsLayout.addComponent(saveButton); buttonsLayout.addComponent(saveButton);
@@ -490,4 +506,15 @@ public class CommonDialogWindow extends Window implements Serializable {
component.addValueChangeListener(new ChangeListener(component)); component.addValueChangeListener(new ChangeListener(component));
} }
public VerticalLayout getMainLayout() {
return mainLayout;
}
public void setSaveButtonEnabled(final boolean enabled) {
saveButton.setEnabled(enabled);
}
public void setCancelButtonEnabled(final boolean enabled) {
cancelButton.setEnabled(enabled);
}
} }

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.common;
import org.eclipse.hawkbit.ui.utils.I18N;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
public class CustomCommonDialogWindow extends CommonDialogWindow {
private static final long serialVersionUID = -4453608850403359992L;
public CustomCommonDialogWindow(final String caption, final Component content, final String helpLink,
final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener,
final AbstractLayout layout, final I18N i18n) {
super(caption, content, helpLink, saveButtonClickListener, cancelButtonClickListener, layout, i18n);
}
@Override
protected void addListeners() {
addComponenetListeners();
addCloseListenerForCancelButton();
}
}

View File

@@ -63,6 +63,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
private Button editButton; private Button editButton;
private Button manageMetadataBtn;
private TabSheet detailsTab; private TabSheet detailsTab;
private VerticalLayout detailsLayout; private VerticalLayout detailsLayout;
@@ -136,9 +138,15 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
SPUIButtonStyleSmallNoBorder.class); SPUIButtonStyleSmallNoBorder.class);
editButton.setId(getEditButtonId()); editButton.setId(getEditButtonId());
editButton.addClickListener(this::onEdit); editButton.addClickListener(this::onEdit);
editButton.setEnabled(false); editButton.setEnabled(false);
manageMetadataBtn = SPUIComponentProvider.getButton("", "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class);
manageMetadataBtn.setId(getEditButtonId());
manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon"));
manageMetadataBtn.addClickListener(this::showMetadata);
manageMetadataBtn.setEnabled(false);
detailsTab = SPUIComponentProvider.getDetailsTabSheet(); detailsTab = SPUIComponentProvider.getDetailsTabSheet();
detailsTab.setImmediate(true); detailsTab.setImmediate(true);
detailsTab.setWidth(98, Unit.PERCENTAGE); detailsTab.setWidth(98, Unit.PERCENTAGE);
@@ -156,6 +164,10 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
if (hasEditPermission()) { if (hasEditPermission()) {
nameEditLayout.addComponent(editButton); nameEditLayout.addComponent(editButton);
nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT); nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT);
if (isMetadataIconToBeDisplayed()) {
nameEditLayout.addComponent(manageMetadataBtn);
nameEditLayout.setComponentAlignment(manageMetadataBtn, Alignment.TOP_RIGHT);
}
} }
nameEditLayout.setExpandRatio(caption, 1.0F); nameEditLayout.setExpandRatio(caption, 1.0F);
nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
@@ -201,6 +213,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
private void populateData(final T selectedBaseEntity) { private void populateData(final T selectedBaseEntity) {
this.selectedBaseEntity = selectedBaseEntity; this.selectedBaseEntity = selectedBaseEntity;
editButton.setEnabled(selectedBaseEntity != null); editButton.setEnabled(selectedBaseEntity != null);
manageMetadataBtn.setEnabled(selectedBaseEntity != null);
if (selectedBaseEntity == null) { if (selectedBaseEntity == null) {
setName(getDefaultCaption(), StringUtils.EMPTY); setName(getDefaultCaption(), StringUtils.EMPTY);
} else { } else {
@@ -209,6 +222,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
populateLog(); populateLog();
populateDescription(); populateDescription();
populateDetailsWidget(); populateDetailsWidget();
populateMetadataDetails();
} }
protected void populateLog() { protected void populateLog() {
@@ -281,8 +295,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
descriptionLayout = getTabLayout(); descriptionLayout = getTabLayout();
return descriptionLayout; return descriptionLayout;
} }
/** /**
* Default caption of header to be displayed when no data row selected in * Default caption of header to be displayed when no data row selected in
* table. * table.
* *
@@ -327,6 +341,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
} }
protected abstract void populateDetailsWidget(); protected abstract void populateDetailsWidget();
protected abstract void populateMetadataDetails();
protected Long getSelectedBaseEntityId() { protected Long getSelectedBaseEntityId() {
return selectedBaseEntity == null ? null : selectedBaseEntity.getId(); return selectedBaseEntity == null ? null : selectedBaseEntity.getId();
@@ -336,4 +352,10 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
protected abstract String getName(); protected abstract String getName();
protected abstract String getShowMetadataButtonId();
protected abstract Boolean isMetadataIconToBeDisplayed();
protected abstract void showMetadata(Button.ClickEvent event);
} }

View File

@@ -0,0 +1,192 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.common.detailslayout;
import java.util.List;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
/**
*
* DistributionSet Metadata details layout.
*
*/
@SpringComponent
@VaadinSessionScope
public class DistributionSetMetadatadetailslayout extends Table{
private static final long serialVersionUID = 2913758299611837718L;
private DistributionSetManagement distributionSetManagement;
private DsMetadataPopupLayout dsMetadataPopupLayout;
private static final String METADATA_KEY = "Key";
private static final String VIEW ="view";
private SpPermissionChecker permissionChecker;
private transient EntityFactory entityFactory;
private I18N i18n;
private Long selectedDistSetId;
/**
*
* @param i18n
* @param permissionChecker
* @param distributionSetManagement
* @param dsMetadataPopupLayout
*/
public void init(final I18N i18n, final SpPermissionChecker permissionChecker,
final DistributionSetManagement distributionSetManagement,
final DsMetadataPopupLayout dsMetadataPopupLayout,
final EntityFactory entityFactory) {
this.i18n = i18n;
this.permissionChecker = permissionChecker;
this.distributionSetManagement = distributionSetManagement;
this.dsMetadataPopupLayout = dsMetadataPopupLayout;
this.entityFactory = entityFactory;
createDSMetadataTable();
addCustomGeneratedColumns();
}
/**
* Populate software module metadata.
*
* @param distributionSet
*/
public void populateDSMetadata(final DistributionSet distributionSet) {
removeAllItems();
if (null == distributionSet) {
return;
}
selectedDistSetId = distributionSet.getId();
final List<DistributionSetMetadata> dsMetadataList = distributionSet.getMetadata();
if (null != dsMetadataList && !dsMetadataList.isEmpty()) {
dsMetadataList.forEach(dsMetadata -> setDSMetadataProperties(dsMetadata));
}
}
/**
* Create metadata .
*
* @param metadataKeyName
*/
public void createMetadata(final String metadataKeyName){
final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource();
final Item item = metadataContainer.addItem(metadataKeyName);
item.getItemProperty(METADATA_KEY).setValue(metadataKeyName);
}
/**
* Delete metadata.
*
* @param metadataKeyName
*/
public void deleteMetadata(final String metadataKeyName){
final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource();
metadataContainer.removeItem(metadataKeyName);
}
private void createDSMetadataTable() {
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
addStyleName(ValoTheme.TABLE_NO_STRIPES);
addStyleName(SPUIStyleDefinitions.SW_MODULE_TABLE);
addStyleName("details-layout");
setSelectable(false);
setImmediate(true);
setContainerDataSource(getDistSetContainer());
setColumnHeaderMode(ColumnHeaderMode.EXPLICIT);
addDSMetadataTableHeader();
setSizeFull();
//same as height of other tabs in details tabsheet
setHeight(116,Unit.PIXELS);
}
private IndexedContainer getDistSetContainer() {
final IndexedContainer container = new IndexedContainer();
container.addContainerProperty(METADATA_KEY, String.class, "");
setColumnExpandRatio(METADATA_KEY, 0.7f);
setColumnAlignment(METADATA_KEY, Align.LEFT);
if (permissionChecker.hasUpdateDistributionPermission()) {
container.addContainerProperty(VIEW, Label.class, "");
setColumnExpandRatio(VIEW, 0.2F);
setColumnAlignment(VIEW, Align.RIGHT);
}
return container;
}
private void addDSMetadataTableHeader() {
setColumnHeader(METADATA_KEY, i18n.get("header.key"));
}
private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata){
final Item item = getContainerDataSource().addItem(dsMetadata.getKey());
item.getItemProperty(METADATA_KEY).setValue(dsMetadata.getKey());
}
private void addCustomGeneratedColumns() {
addGeneratedColumn(METADATA_KEY,
(source, itemId, columnId) -> customMetadataDetailButton((String) itemId));
}
private Button customMetadataDetailButton(final String metadataKey) {
final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View "
+ metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class);
viewIcon.setData(metadataKey);
viewIcon.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link"
+ " " + "text-style");
viewIcon.addClickListener(event -> showMetadataDetails(selectedDistSetId, metadataKey));
return viewIcon;
}
private static String getDetailLinkId(final String name) {
return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name)
.toString();
}
private void showMetadataDetails(final Long selectedDistSetId , final String metadataKey) {
DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId);
/* display the window */
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(distSet,
entityFactory.generateDistributionSetMetadata(distSet, metadataKey, "") ));
}
}

View File

@@ -0,0 +1,170 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.common.detailslayout;
import java.util.List;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
/**
*
* SoftwareModule Metadata details layout.
*
*/
@SpringComponent
@ViewScope
public class SoftwareModuleMetadatadetailslayout extends Table {
private static final long serialVersionUID = 2913758299611838818L;
private static final String METADATA_KEY = "Key";
private SpPermissionChecker permissionChecker;
private SoftwareManagement softwareManagement;
private SwMetadataPopupLayout swMetadataPopupLayout;
private I18N i18n;
private Long selectedSWModuleId;
private transient EntityFactory entityFactory;
public void init(final I18N i18n, final SpPermissionChecker permissionChecker,
final SoftwareManagement softwareManagement, final SwMetadataPopupLayout swMetadataPopupLayout,
final EntityFactory entityFactory) {
this.i18n = i18n;
this.permissionChecker = permissionChecker;
this.softwareManagement = softwareManagement;
this.swMetadataPopupLayout = swMetadataPopupLayout;
this.entityFactory = entityFactory;
createSWMMetadataTable();
addCustomGeneratedColumns();
}
/**
* Populate software module metadata table.
*
* @param swModule
*/
public void populateSMMetadata(final SoftwareModule swModule) {
removeAllItems();
if (null == swModule) {
return;
}
selectedSWModuleId = swModule.getId();
final List<SoftwareModuleMetadata> swMetadataList = swModule.getMetadata();
if (null != swMetadataList && !swMetadataList.isEmpty()) {
swMetadataList.forEach(swMetadata -> setSWMetadataProperties(swMetadata));
}
}
/**
* Create metadata.
*
* @param metadataKeyName
*/
public void createMetadata(final String metadataKeyName) {
final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource();
final Item item = metadataContainer.addItem(metadataKeyName);
item.getItemProperty(METADATA_KEY).setValue(metadataKeyName);
}
/**
* Delete metadata.
*
* @param metadataKeyName
*/
public void deleteMetadata(final String metadataKeyName) {
final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource();
metadataContainer.removeItem(metadataKeyName);
}
private void createSWMMetadataTable() {
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
addStyleName(ValoTheme.TABLE_NO_STRIPES);
addStyleName(SPUIStyleDefinitions.SW_MODULE_TABLE);
setSelectable(false);
setImmediate(true);
setContainerDataSource(getSwModuleMetadataContainer());
setColumnHeaderMode(ColumnHeaderMode.EXPLICIT);
addSMMetadataTableHeader();
setSizeFull();
//same as height of other tabs in details tabsheet
setHeight(116,Unit.PIXELS);
}
private IndexedContainer getSwModuleMetadataContainer() {
final IndexedContainer container = new IndexedContainer();
container.addContainerProperty(METADATA_KEY, String.class, "");
setColumnAlignment(METADATA_KEY, Align.LEFT);
return container;
}
private void addSMMetadataTableHeader() {
setColumnHeader(METADATA_KEY, i18n.get("header.key"));
}
private void setSWMetadataProperties(final SoftwareModuleMetadata swMetadata) {
final Item item = getContainerDataSource().addItem(swMetadata.getKey());
item.getItemProperty(METADATA_KEY).setValue(swMetadata.getKey());
}
private void addCustomGeneratedColumns() {
addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId));
}
private Button customMetadataDetailButton(final String metadataKey) {
final Button viewLink = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View"
+ metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class);
viewLink.setData(metadataKey);
if (permissionChecker.hasUpdateDistributionPermission()) {
viewLink.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link"
+ " " + "text-style");
viewLink.addClickListener(event -> showMetadataDetails(selectedSWModuleId, metadataKey));
}
return viewLink;
}
private static String getDetailLinkId(final String name) {
return new StringBuilder(SPUIComponentIdProvider.SW_METADATA_DETAIL_LINK).append('.').append(name).toString();
}
private void showMetadataDetails(final Long selectedSWModuleId, final String metadataKey) {
SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId);
/* display the window */
UI.getCurrent().addWindow(
swMetadataPopupLayout.getWindow(swmodule,
entityFactory.generateSoftwareModuleMetadata(swmodule, metadataKey, "")));
}
}

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.ui.decorators; package org.eclipse.hawkbit.ui.decorators;
import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
import org.eclipse.hawkbit.ui.common.CustomCommonDialogWindow;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
@@ -47,25 +48,33 @@ public final class SPUIWindowDecorator {
public static CommonDialogWindow getWindow(final String caption, final String id, final String type, public static CommonDialogWindow getWindow(final String caption, final String id, final String type,
final Component content, final ClickListener saveButtonClickListener, final Component content, final ClickListener saveButtonClickListener,
final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout, final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout,
final I18N i18n) { final I18N i18n) {
CommonDialogWindow window = null;
if (SPUIDefinitions.CUSTOM_METADATA_WINDOW.equals(type)) {
window = new CustomCommonDialogWindow(caption, content, helpLink, saveButtonClickListener,
cancelButtonClickListener, layout, i18n);
window.setDraggable(true);
window.setClosable(true);
} else {
window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener,
cancelButtonClickListener, layout, i18n);
if (null != id) {
window.setId(id);
}
if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) {
window.setDraggable(false);
window.setClosable(true);
window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION);
final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) {
cancelButtonClickListener, layout, i18n); window.setDraggable(true);
if (null != id) { window.setClosable(true);
window.setId(id); }
} }
if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { return window;
window.setDraggable(false); }
window.setClosable(true);
window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION);
} else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) {
window.setDraggable(true);
window.setClosable(true);
}
return window;
}
/** /**
* Decorates window based on type. * Decorates window based on type.
* *

View File

@@ -14,18 +14,22 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName; import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType;
import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout;
import org.eclipse.hawkbit.ui.common.detailslayout.DistributionSetMetadatadetailslayout;
import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable;
import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent;
import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleAssignmentDiscardEvent; import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleAssignmentDiscardEvent;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
@@ -78,12 +82,37 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
@Autowired @Autowired
private transient DistributionSetManagement distributionSetManagement; private transient DistributionSetManagement distributionSetManagement;
@Autowired
private DsMetadataPopupLayout dsMetadataPopupLayout;
@Autowired
private EntityFactory entityFactory;
private SoftwareModuleDetailsTable softwareModuleTable; private SoftwareModuleDetailsTable softwareModuleTable;
private DistributionSetMetadatadetailslayout dsMetadataTable;
private VerticalLayout tagsLayout; private VerticalLayout tagsLayout;
private final Map<String, StringBuilder> assignedSWModule = new HashMap<>(); private final Map<String, StringBuilder> assignedSWModule = new HashMap<>();
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final MetadataEvent event) {
UI.getCurrent()
.access(() -> {
DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata();
if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) {
if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) {
dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey());
} else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) {
dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey());
}
}
});
}
/** /**
* softwareLayout Initialize the component. * softwareLayout Initialize the component.
@@ -93,6 +122,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
softwareModuleTable = new SoftwareModuleDetailsTable(); softwareModuleTable = new SoftwareModuleDetailsTable();
softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(), softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(),
manageDistUIState); manageDistUIState);
dsMetadataTable = new DistributionSetMetadatadetailslayout();
dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement,
dsMetadataPopupLayout,entityFactory);
super.init(); super.init();
} }
@@ -106,6 +138,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
populateDetails(); populateDetails();
populateModule(); populateModule();
populateTags(); populateTags();
populateMetadataDetails();
} }
private void populateModule() { private void populateModule() {
@@ -248,7 +281,12 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
updateDistributionSetDetailsLayout(null, null); updateDistributionSetDetailsLayout(null, null);
} }
} }
@Override
protected void populateMetadataDetails(){
dsMetadataTable.populateDSMetadata(getSelectedBaseEntity());
}
private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) { private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) {
final VerticalLayout detailsTabLayout = getDetailsLayout(); final VerticalLayout detailsTabLayout = getDetailsLayout();
detailsTabLayout.removeAllComponents(); detailsTabLayout.removeAllComponents();
@@ -303,6 +341,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null); detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null);
detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null); detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null);
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
detailsTab.addTab(dsMetadataTable, getI18n().get("caption.metadata"), null);
} }
@Override @Override
@@ -362,7 +401,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
@Override @Override
protected String getTabSheetId() { protected String getTabSheetId() {
return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_TABSHEET; return SPUIComponentIdProvider.DISTRIBUTIONSET_DETAILS_TABSHEET_ID;
} }
@Override @Override
@@ -370,4 +409,30 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID;
} }
@Override
protected Boolean isMetadataIconToBeDisplayed() {
return true;
}
@Override
protected String getShowMetadataButtonId() {
DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState
.getLastSelectedDistribution().get() : null;
return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "."
+ lastselectedDistDS.getVersion();
}
private boolean isDistributionSetSelected(DistributionSet ds) {
DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState
.getLastSelectedDistribution().get() : null;
return ds != null && lastselectedDistDS != null && lastselectedDistDS.getName().equals(ds.getName())
&& lastselectedDistDS.getVersion().endsWith(ds.getVersion());
}
@Override
protected void showMetadata(ClickEvent event) {
DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId());
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null));
}
} }

View File

@@ -30,6 +30,8 @@ import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable;
import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.AbstractTable;
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent;
import org.eclipse.hawkbit.ui.distributions.event.DistributionsViewAcceptCriteria; import org.eclipse.hawkbit.ui.distributions.event.DistributionsViewAcceptCriteria;
import org.eclipse.hawkbit.ui.distributions.event.DragEvent; import org.eclipse.hawkbit.ui.distributions.event.DragEvent;
@@ -42,6 +44,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -57,8 +60,10 @@ import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope; import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.Table; import com.vaadin.ui.Table;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
@@ -98,6 +103,9 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
@Autowired @Autowired
private transient TargetManagement targetManagement; private transient TargetManagement targetManagement;
@Autowired
private DsMetadataPopupLayout dsMetadataPopupLayout;
/** /**
* Initialize the component. * Initialize the component.
*/ */
@@ -181,6 +189,10 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
protected void publishEntityAfterValueChange(final DistributionSet distributionSet) { protected void publishEntityAfterValueChange(final DistributionSet distributionSet) {
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, distributionSet)); eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, distributionSet));
eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION); eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION);
if(distributionSet!=null){
manageDistUIState.setLastSelectedEntity(new DistributionSetIdName(distributionSet.getId(),
distributionSet.getName(),distributionSet.getVersion()));
}
} }
@Override @Override
@@ -468,5 +480,51 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
protected void setDataAvailable(final boolean available) { protected void setDataAvailable(final boolean available) {
manageDistUIState.setNoDataAvailableDist(!available); manageDistUIState.setNoDataAvailableDist(!available);
} }
@Override
protected void addCustomGeneratedColumns() {
addGeneratedColumn(SPUILabelDefinitions.METADATA_ICON, new ColumnGenerator() {
private static final long serialVersionUID = 117186282275065399L;
@Override
public Object generateCell(final Table source, final Object itemId, final Object columnId) {
final String nameVersionStr = getNameAndVerion(itemId);
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
manageMetaDataBtn.addClickListener(event -> showMetadataDetails(((DistributionSetIdName) itemId).getId()));
return manageMetaDataBtn;
}
});
}
@Override
protected List<TableColumn> getTableVisibleColumns() {
final List<TableColumn> columnList = super.getTableVisibleColumns();
if (!isMaximized()) {
columnList.add(new TableColumn(SPUILabelDefinitions.METADATA_ICON, "", 0.1F));
}
return columnList;
}
private Button createManageMetadataButton(String nameVersionStr) {
final Button manageMetadataBtn = SPUIComponentProvider.getButton(
SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class);
manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON);
manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon"));
return manageMetadataBtn;
}
private void showMetadataDetails(Long itemId) {
DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(itemId);
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null));
}
private String getNameAndVerion(final Object itemId) {
final Item item = getItem(itemId);
final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue();
return name + "." + version;
}
} }

View File

@@ -0,0 +1,97 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.distributions.dstable;
import java.util.List;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent.MetadataUIEvent;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
/**
* Pop up layout to display distribution metadata.
*/
@SpringComponent
@ViewScope
public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout<DistributionSet, DistributionSetMetadata> {
private static final long serialVersionUID = -7778944849012048106L;
@Autowired
private transient DistributionSetManagement distributionSetManagement;
@Autowired
private EntityFactory entityFactory;
@Autowired
protected SpPermissionChecker permChecker;
@Override
protected void checkForDuplicate(DistributionSet entity, String value) {
distributionSetManagement.findOne(entity, value);
}
/**
* Create metadata for DistributionSet.
*/
@Override
protected DistributionSetMetadata createMetadata(DistributionSet entity, String key, String value) {
DistributionSetMetadata dsMetaData = distributionSetManagement.createDistributionSetMetadata(entityFactory
.generateDistributionSetMetadata(entity, key, value));
setSelectedEntity(dsMetaData.getDistributionSet());
eventBus.publish(this, new MetadataEvent(MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA, dsMetaData));
return dsMetaData;
}
/**
* Update metadata for DistributionSet.
*/
@Override
protected DistributionSetMetadata updateMetadata(DistributionSet entity, String key, String value) {
DistributionSetMetadata dsMetaData = distributionSetManagement.updateDistributionSetMetadata(entityFactory
.generateDistributionSetMetadata(entity, key, value));
setSelectedEntity(dsMetaData.getDistributionSet());
return dsMetaData;
}
@Override
protected List<DistributionSetMetadata> getMetadataList() {
return getSelectedEntity().getMetadata();
}
/**
* Update metadata for DistributionSet.
*/
@Override
protected void deleteMetadata(DistributionSet entity, String key, String value) {
DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value);
distributionSetManagement.deleteDistributionSetMetadata(entity, key);
eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA, dsMetaData));
}
@Override
protected boolean hasCreatePermission() {
return permChecker.hasCreateDistributionPermission();
}
@Override
protected boolean hasUpdatePermission() {
return permChecker.hasUpdateDistributionPermission();
}
}

View File

@@ -0,0 +1,52 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.distributions.event;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
/**
*
* Metadata Events.
*
*/
public class MetadataEvent {
public enum MetadataUIEvent {
CREATE_DISTRIBUTION_SET_METADATA, DELETE_DISTRIBUTION_SET_METADATA, DELETE_SOFTWARE_MODULE_METADATA, CREATE_SOFTWARE_MODULE_METADATA;
}
private MetadataUIEvent metadataUIEvent;
private DistributionSetMetadata distributionSetMetadata;
private SoftwareModuleMetadata softwareModuleMetadata;
public MetadataEvent(MetadataUIEvent metadataUIEvent, final DistributionSetMetadata distributionSetMetadata) {
this.metadataUIEvent = metadataUIEvent;
this.distributionSetMetadata = distributionSetMetadata;
}
public MetadataEvent(MetadataUIEvent metadataUIEvent, final SoftwareModuleMetadata softwareModuleMetadata) {
this.metadataUIEvent = metadataUIEvent;
this.softwareModuleMetadata = softwareModuleMetadata;
}
public MetadataUIEvent getMetadataUIEvent() {
return metadataUIEvent;
}
public DistributionSetMetadata getDistributionSetMetadata() {
return distributionSetMetadata;
}
public SoftwareModuleMetadata getSoftwareModuleMetadata() {
return softwareModuleMetadata;
}
}

View File

@@ -1,18 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.distributions.event;
/**
*
*
*/
public enum SwModuleUIEvent {
HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DELETED_ALL_SOFWARE;
}

View File

@@ -0,0 +1,104 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ui.distributions.smtable;
import java.util.List;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent.MetadataUIEvent;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
/**
* Pop up layout to display software module metadata.
*
*/
@SpringComponent
@ViewScope
public class SwMetadataPopupLayout extends AbstractMetadataPopupLayout<SoftwareModule, SoftwareModuleMetadata> {
private static final long serialVersionUID = -1252090014161012563L;
@Autowired
private transient SoftwareManagement softwareManagement;
@Autowired
private ArtifactUploadState artifactUploadState;
@Autowired
private EntityFactory entityFactory;
@Autowired
private ManageDistUIState manageDistUIState;
@Autowired
protected SpPermissionChecker permChecker;
@Override
protected void checkForDuplicate(SoftwareModule entity, String value) {
softwareManagement.findSoftwareModuleMetadata(entity, value);
}
/**
* Create metadata for SWModule.
*/
@Override
protected SoftwareModuleMetadata createMetadata(SoftwareModule entity, String key, String value) {
SoftwareModuleMetadata swMetadata = softwareManagement.createSoftwareModuleMetadata(entityFactory
.generateSoftwareModuleMetadata(entity, key, value));
setSelectedEntity(swMetadata.getSoftwareModule());
eventBus.publish(this, new MetadataEvent(MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA, swMetadata));
return swMetadata;
}
/**
* Update metadata for SWModule.
*/
@Override
protected SoftwareModuleMetadata updateMetadata(SoftwareModule entity, String key, String value) {
SoftwareModuleMetadata swMetadata = softwareManagement.updateSoftwareModuleMetadata(entityFactory
.generateSoftwareModuleMetadata(entity, key, value));
setSelectedEntity(swMetadata.getSoftwareModule());
return swMetadata;
}
@Override
protected List<SoftwareModuleMetadata> getMetadataList() {
return getSelectedEntity().getMetadata();
}
/**
* delete metadata for SWModule.
*/
@Override
protected void deleteMetadata(SoftwareModule entity, String key, String value) {
SoftwareModuleMetadata swMetadata = entityFactory.generateSoftwareModuleMetadata(entity, key, value);
softwareManagement.deleteSoftwareModuleMetadata(entity, key);
eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA, swMetadata));
}
@Override
protected boolean hasCreatePermission() {
return permChecker.hasCreateDistributionPermission();
}
@Override
protected boolean hasUpdatePermission() {
return permChecker.hasUpdateDistributionPermission();
}
}

View File

@@ -8,11 +8,16 @@
*/ */
package org.eclipse.hawkbit.ui.distributions.smtable; package org.eclipse.hawkbit.ui.distributions.smtable;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout;
import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleMetadatadetailslayout;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
@@ -44,6 +49,50 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
@Autowired @Autowired
private ManageDistUIState manageDistUIState; private ManageDistUIState manageDistUIState;
@Autowired
private transient SoftwareManagement softwareManagement;
@Autowired
private SwMetadataPopupLayout swMetadataPopupLayout;
@Autowired
private EntityFactory entityFactory;
private SoftwareModuleMetadatadetailslayout swmMetadataTable;
/**
* softwareLayout Initialize the component.
*/
@Override
protected void init() {
swmMetadataTable = new SoftwareModuleMetadatadetailslayout();
swmMetadataTable.init(getI18n(), getPermissionChecker(),softwareManagement,swMetadataPopupLayout,entityFactory);
super.init();
}
/**
* MetadataEvent.
*
* @param event
* as instance of {@link MetadataEvent}
*/
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final MetadataEvent event) {
UI.getCurrent()
.access(() -> {
SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata();
if (softwareModuleMetadata != null
&& isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) {
if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) {
swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey());
} else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) {
swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey());
}
}
});
}
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SoftwareModuleEvent softwareModuleEvent) { void onEvent(final SoftwareModuleEvent softwareModuleEvent) {
@@ -69,7 +118,8 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
detailsTab.addTab(createDetailsLayout(), getI18n().get("caption.tab.details"), null); detailsTab.addTab(createDetailsLayout(), getI18n().get("caption.tab.details"), null);
detailsTab.addTab(createDescriptionLayout(), getI18n().get("caption.tab.description"), null); detailsTab.addTab(createDescriptionLayout(), getI18n().get("caption.tab.description"), null);
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
} detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null);
}
@Override @Override
protected String getDefaultCaption() { protected String getDefaultCaption() {
@@ -93,7 +143,7 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
@Override @Override
protected String getTabSheetId() { protected String getTabSheetId() {
return null; return SPUIComponentIdProvider.DIST_SW_MODULE_DETAILS_TABSHEET_ID;
} }
private void populateDetails() { private void populateDetails() {
@@ -139,11 +189,41 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
@Override @Override
protected void populateDetailsWidget() { protected void populateDetailsWidget() {
populateDetails(); populateDetails();
populateMetadataDetails();
} }
@Override @Override
protected String getDetailsHeaderCaptionId() { protected String getDetailsHeaderCaptionId() {
return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID;
} }
@Override
protected void populateMetadataDetails() {
swmMetadataTable.populateSMMetadata(getSelectedBaseEntity());
}
private boolean isSoftwareModuleSelected(SoftwareModule softwareModule) {
final Long selectedDistSWModuleId = manageDistUIState.getSelectedBaseSwModuleId().isPresent() ? manageDistUIState
.getSelectedBaseSwModuleId().get() : null;
return softwareModule != null && selectedDistSWModuleId != null
&& selectedDistSWModuleId.equals(softwareModule.getId());
}
@Override
protected Boolean isMetadataIconToBeDisplayed() {
return true;
}
@Override
protected String getShowMetadataButtonId() {
SoftwareModule selectedBaseEntity = getSelectedBaseEntity();
return SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + selectedBaseEntity.getName() + "."
+ selectedBaseEntity.getVersion();
}
@Override
protected void showMetadata(ClickEvent event) {
SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId());
UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, null));
}
} }

View File

@@ -51,6 +51,7 @@ import com.vaadin.shared.ui.window.WindowMode;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope; import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button; import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.JavaScript; import com.vaadin.ui.JavaScript;
import com.vaadin.ui.Table; import com.vaadin.ui.Table;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
@@ -77,6 +78,9 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
@Autowired @Autowired
private ArtifactDetailsLayout artifactDetailsLayout; private ArtifactDetailsLayout artifactDetailsLayout;
@Autowired
private SwMetadataPopupLayout swMetadataPopupLayout;
/** /**
* Initialize the filter layout. * Initialize the filter layout.
@@ -175,16 +179,19 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
protected void addCustomGeneratedColumns() { protected void addCustomGeneratedColumns() {
addGeneratedColumn(SPUILabelDefinitions.ARTIFACT_ICON, new ColumnGenerator() { addGeneratedColumn(SPUILabelDefinitions.ARTIFACT_ICON, new ColumnGenerator() {
private static final long serialVersionUID = -5982361782989980277L; private static final long serialVersionUID = -5982361782989980277L;
@Override @Override
public Object generateCell(final Table source, final Object itemId, final Object columnId) { public Object generateCell(final Table source, final Object itemId, final Object columnId) {
HorizontalLayout iconLayout = new HorizontalLayout();
// add artifactory details popup // add artifactory details popup
final String nameVersionStr = getNameAndVerion(itemId); final String nameVersionStr = getNameAndVerion(itemId);
final Button showArtifactDtlsBtn = createShowArtifactDtlsButton(nameVersionStr); final Button showArtifactDtlsBtn = createShowArtifactDtlsButton(nameVersionStr);
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
showArtifactDtlsBtn.addClickListener(event -> showArtifactDetailsWindow((Long) itemId, nameVersionStr)); showArtifactDtlsBtn.addClickListener(event -> showArtifactDetailsWindow((Long) itemId, nameVersionStr));
return showArtifactDtlsBtn; manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId));
iconLayout.addComponent(showArtifactDtlsBtn);
iconLayout.addComponent(manageMetaDataBtn);
return iconLayout;
} }
}); });
} }
@@ -207,6 +214,9 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
@Override @Override
protected void publishEntityAfterValueChange(final SoftwareModule selectedLastEntity) { protected void publishEntityAfterValueChange(final SoftwareModule selectedLastEntity) {
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity));
if(selectedLastEntity!=null){
manageDistUIState.setSelectedBaseSwModuleId(selectedLastEntity.getId());
}
} }
@Override @Override
@@ -310,12 +320,21 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
private Button createShowArtifactDtlsButton(final String nameVersionStr) { private Button createShowArtifactDtlsButton(final String nameVersionStr) {
final Button showArtifactDtlsBtn = SPUIComponentProvider.getButton( final Button showArtifactDtlsBtn = SPUIComponentProvider.getButton(
SPUIComponentIdProvider.SW_TABLE_ATRTIFACT_DETAILS_ICON + "." + nameVersionStr, "", "", null, false, SPUIComponentIdProvider.SW_TABLE_ATRTIFACT_DETAILS_ICON + "." + nameVersionStr, "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); FontAwesome.FILE_O, SPUIButtonStyleSmallNoBorder.class);
showArtifactDtlsBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON); showArtifactDtlsBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON);
showArtifactDtlsBtn.setDescription(i18n.get("tooltip.artifact.icon")); showArtifactDtlsBtn.setDescription(i18n.get("tooltip.artifact.icon"));
return showArtifactDtlsBtn; return showArtifactDtlsBtn;
} }
private Button createManageMetadataButton(String nameVersionStr) {
final Button manageMetadataBtn = SPUIComponentProvider.getButton(
SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class);
manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON);
manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon"));
return manageMetadataBtn;
}
private String getNameAndVerion(final Object itemId) { private String getNameAndVerion(final Object itemId) {
final Item item = getItem(itemId); final Item item = getItem(itemId);
final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
@@ -388,4 +407,9 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
} }
private void showMetadataDetails(Long itemId) {
SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(itemId);
UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule,null));
}
} }

View File

@@ -8,11 +8,18 @@
*/ */
package org.eclipse.hawkbit.ui.management.dstable; package org.eclipse.hawkbit.ui.management.dstable;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout;
import org.eclipse.hawkbit.ui.common.detailslayout.DistributionSetMetadatadetailslayout;
import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable;
import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout;
import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
@@ -46,16 +53,48 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
@Autowired @Autowired
private DistributionTagToken distributionTagToken; private DistributionTagToken distributionTagToken;
@Autowired
private transient DistributionSetManagement distributionSetManagement;
@Autowired
private DsMetadataPopupLayout dsMetadataPopupLayout;
@Autowired
private EntityFactory entityFactory;
private SoftwareModuleDetailsTable softwareModuleTable; private SoftwareModuleDetailsTable softwareModuleTable;
private DistributionSetMetadatadetailslayout dsMetadataTable;
@Override @Override
protected void init() { protected void init() {
softwareModuleTable = new SoftwareModuleDetailsTable(); softwareModuleTable = new SoftwareModuleDetailsTable();
softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null); softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null);
dsMetadataTable = new DistributionSetMetadatadetailslayout();
dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement,
dsMetadataPopupLayout,entityFactory);
super.init(); super.init();
} }
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final MetadataEvent event) {
UI.getCurrent()
.access(() -> {
DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata();
if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) {
if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) {
dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey());
} else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) {
dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey());
}
}
});
}
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final DistributionTableEvent distributionTableEvent) { void onEvent(final DistributionTableEvent distributionTableEvent) {
onBaseEntityEvent(distributionTableEvent); onBaseEntityEvent(distributionTableEvent);
@@ -73,6 +112,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null); detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null);
detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null); detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null);
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
detailsTab.addTab(dsMetadataTable, getI18n().get("caption.metadata"), null);
} }
@Override @Override
@@ -113,8 +153,15 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
protected void populateDetailsWidget() { protected void populateDetailsWidget() {
softwareModuleTable.populateModule(getSelectedBaseEntity()); softwareModuleTable.populateModule(getSelectedBaseEntity());
populateDetails(getSelectedBaseEntity()); populateDetails(getSelectedBaseEntity());
populateMetadataDetails();
} }
@Override
protected void populateMetadataDetails(){
dsMetadataTable.populateDSMetadata(getSelectedBaseEntity());
}
private void populateDetails(final DistributionSet ds) { private void populateDetails(final DistributionSet ds) {
if (ds != null) { if (ds != null) {
@@ -159,5 +206,30 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
protected String getDetailsHeaderCaptionId() { protected String getDetailsHeaderCaptionId() {
return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID;
} }
@Override
protected Boolean isMetadataIconToBeDisplayed() {
return true;
}
@Override
protected String getShowMetadataButtonId() {
DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState
.getLastSelectedDistribution().get() : null;
return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "."
+ lastselectedDistDS.getVersion();
}
private boolean isDistributionSetSelected(DistributionSet ds) {
DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState
.getLastSelectedDistribution().get() : null;
return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName())
&& lastselectedManageDS.getVersion().endsWith(ds.getVersion());
}
@Override
protected void showMetadata(ClickEvent event) {
DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId());
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null));
}
} }

View File

@@ -18,6 +18,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -29,6 +30,8 @@ import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable;
import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.AbstractTable;
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.event.DistributionTableFilterEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableFilterEvent;
import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.management.event.DragEvent;
@@ -63,6 +66,7 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component; import com.vaadin.ui.Component;
import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table; import com.vaadin.ui.Table;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
@@ -86,12 +90,18 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
@Autowired @Autowired
private ManagementViewAcceptCriteria managementViewAcceptCriteria; private ManagementViewAcceptCriteria managementViewAcceptCriteria;
@Autowired @Autowired
private transient TargetManagement targetService; private transient TargetManagement targetService;
@Autowired
private DsMetadataPopupLayout dsMetadataPopupLayout;
@Autowired @Autowired
private transient DistributionSetManagement distributionSetManagement; private transient DistributionSetManagement distributionSetManagement;
@Autowired
private EntityFactory entityFactory;
private String notAllowedMsg; private String notAllowedMsg;
@@ -219,10 +229,35 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
@Override @Override
public Object generateCell(final Table source, final Object itemId, final Object columnId) { public Object generateCell(final Table source, final Object itemId, final Object columnId) {
return getPinButton(itemId); HorizontalLayout iconLayout = new HorizontalLayout();
final String nameVersionStr = getNameAndVerion(itemId);
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
manageMetaDataBtn.addClickListener(event -> showMetadataDetails(itemId));
iconLayout.addComponent((Button)getPinButton(itemId));
iconLayout.addComponent(manageMetaDataBtn);
return iconLayout;
} }
}); });
} }
private String getNameAndVerion(final Object itemId) {
final Item item = getItem(itemId);
final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue();
return name + "." + version;
}
private Button createManageMetadataButton(String nameVersionStr) {
final Button manageMetadataBtn = SPUIComponentProvider.getButton(
SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false,
FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class);
manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON);
manageMetadataBtn.addStyleName(SPUIStyleDefinitions.DS_METADATA_ICON);
manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon"));
return manageMetadataBtn;
}
@Override @Override
protected boolean isFirstRowSelectedOnLoad() { protected boolean isFirstRowSelectedOnLoad() {
@@ -246,6 +281,10 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
@Override @Override
protected void publishEntityAfterValueChange(final DistributionSet selectedLastEntity) { protected void publishEntityAfterValueChange(final DistributionSet selectedLastEntity) {
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity));
if(selectedLastEntity!=null){
managementUIState.setLastSelectedDistribution(new DistributionSetIdName(selectedLastEntity.getId(),
selectedLastEntity.getName(),selectedLastEntity.getVersion()));
}
} }
@Override @Override
@@ -264,7 +303,7 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
if (isMaximized()) { if (isMaximized()) {
return columnList; return columnList;
} }
columnList.add(new TableColumn(SPUILabelDefinitions.PIN_COLUMN, StringUtils.EMPTY, 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.PIN_COLUMN, StringUtils.EMPTY, 0.2F));
return columnList; return columnList;
} }
@@ -657,5 +696,12 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
managementUIState.setNoDataAvailableDistribution(!available); managementUIState.setNoDataAvailableDistribution(!available);
} }
private void showMetadataDetails(Object itemId) {
final DistributionSetIdName distIdName = (DistributionSetIdName) getContainerDataSource().getItem(itemId)
.getItemProperty(SPUILabelDefinitions.VAR_DIST_ID_NAME).getValue();
DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(distIdName.getId());
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null));
}
} }

View File

@@ -87,6 +87,22 @@ public class ManagementUIState implements ManagmentEntityState<DistributionSetId
private boolean customFilterSelected; private boolean customFilterSelected;
private boolean bulkUploadWindowMinimised; private boolean bulkUploadWindowMinimised;
private DistributionSetIdName lastSelectedDistribution;
/**
* @return the lastSelectedDistribution
*/
public Optional<DistributionSetIdName> getLastSelectedDistribution() {
return Optional.ofNullable(lastSelectedDistribution);
}
public void setLastSelectedDistribution(final DistributionSetIdName value) {
this.lastSelectedDistribution = value;
}
/** /**
* @return the bulkUploadWindowMinimised * @return the bulkUploadWindowMinimised

View File

@@ -253,4 +253,24 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID;
} }
@Override
protected String getShowMetadataButtonId() {
return null;
}
@Override
protected Boolean isMetadataIconToBeDisplayed() {
return false;
}
@Override
protected void showMetadata(ClickEvent event) {
//No implementation required
}
@Override
protected void populateMetadataDetails() {
//No implementation required
}
} }

View File

@@ -82,9 +82,9 @@ public final class HawkbitCommonUtil {
private static final String JS_DRAG_COUNT_REM_CHILD = " if(x) { document.head.removeChild(x); } "; private static final String JS_DRAG_COUNT_REM_CHILD = " if(x) { document.head.removeChild(x); } ";
private static final String DIV_DESCRIPTION = "<div id=\"desc-length\"><p id=\"desciption-p\">"; public static final String DIV_DESCRIPTION = "<div id=\"desc-length\"><p id=\"desciption-p\">";
private static final String DIV_CLOSE = "</p></div>"; public static final String DIV_CLOSE = "</p></div>";
private static final String DRAG_COUNT_ELEMENT = "var x = document.getElementById('sp-drag-count'); "; private static final String DRAG_COUNT_ELEMENT = "var x = document.getElementById('sp-drag-count'); ";
private static final String CLOSE_BRACE = "\"; }';"; private static final String CLOSE_BRACE = "\"; }';";

View File

@@ -518,10 +518,6 @@ public final class SPUIComponentIdProvider {
* Tab sheet id. * Tab sheet id.
*/ */
public static final String TARGET_DETAILS_TABSHEET = "target.details.tabsheet"; public static final String TARGET_DETAILS_TABSHEET = "target.details.tabsheet";
/**
* Tab sheet id.
*/
public static final String DISTRIBUTION_DETAILS_TABSHEET = "distribution.details.tabsheet.";
/** /**
* Combobox id. * Combobox id.
@@ -962,6 +958,70 @@ public final class SPUIComponentIdProvider {
*/ */
public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id";
/**
* Software module table - Manage metadata id.
*/
public static final String SW_TABLE_MANAGE_METADATA_ID = "swtable.manage.metadata.id";
/**
* Metadata key id.
*/
public static final String METADATA_KEY_FIELD_ID = "metadata.key.id";
/**
* Metadata value id.
*/
public static final String METADATA_VALUE_ID = "metadata.value.id";
/**
* Metadata save id.
*/
public static final String METADTA_SAVE_ICON_ID = "metadata.save.icon.id";
/**
* Metadata discard id.
*/
public static final String METADTA_DISCARD_ICON_ID = "metadata.discard.icon.id";
/**
* Metadata add icon id.
*/
public static final String METADTA_ADD_ICON_ID = "metadata.add.icon.id";
/**
* Metadata table id.
*/
public static final String METDATA_TABLE_ID = "metadata.table.id";
/**
* Distribution set table - Manage metadata id.
*/
public static final String DS_TABLE_MANAGE_METADATA_ID = "dstable.manage.metadata.id";
/**
* DistributionSet - Metadata button id.
*/
public static final String DS_METADATA_DETAIL_LINK = "distributionset.metadata.detail.link";
/**
* Metadata popup id.
*/
public static final String METADATA_POPUP_ID = "metadata.popup.id";
/**
* DistributionSet table details tab id in Distributions .
*/
public static final String DISTRIBUTIONSET_DETAILS_TABSHEET_ID = "distributionset.details.tabsheet";
/**
* Software module table details tab id in Distributions .
*/
public static final String DIST_SW_MODULE_DETAILS_TABSHEET_ID = "dist.sw.module.details.tabsheet";
/**
* Software Module - Metadata button id.
*/
public static final String SW_METADATA_DETAIL_LINK = "softwaremodule.metadata.detail.link";
/** /**
* Table multiselect for selecting DistType * Table multiselect for selecting DistType
*/ */

View File

@@ -1017,6 +1017,21 @@ public final class SPUIDefinitions {
* Rollout action column property. * Rollout action column property.
*/ */
public static final String ROLLOUT_ACTION = "rollout-action"; public static final String ROLLOUT_ACTION = "rollout-action";
/**
* DistributionSet Metadata tab Id
*/
public static final String DISTRIBUTIONSET_METADATA_TAB_ID = "distSet.metadata.tab.id";
/**
* SoftwareModule Metadata tab Id
*/
public static final String SOFTWAREMODULE_METADATA_TAB_ID = "swModule.metadata.tab.id";
/***
* Custom window for metadata.
*/
public static final String CUSTOM_METADATA_WINDOW = "custom.metadata.window";
/** /**
* /** Constructor. * /** Constructor.

View File

@@ -560,6 +560,11 @@ public final class SPUILabelDefinitions {
* Rollout group installed percentage column property. * Rollout group installed percentage column property.
*/ */
public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage"; public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage";
/**
* Add metadata icon.
*/
public static final String METADATA_ICON = "metadataDls";
/** /**
* Constructor. * Constructor.

View File

@@ -136,6 +136,11 @@ public final class SPUIStyleDefinitions {
* Artifact Details icon in Distribution View. * Artifact Details icon in Distribution View.
*/ */
public static final String ARTIFACT_DTLS_ICON = "swm-artifact-dtls-icon"; public static final String ARTIFACT_DTLS_ICON = "swm-artifact-dtls-icon";
/**
* Distribution metadata icon style.
*/
public static final String DS_METADATA_ICON = "ds-metadata-icon";
/** /**
* Target table style. * Target table style.
@@ -293,6 +298,10 @@ public final class SPUIStyleDefinitions {
* Status pending icon. * Status pending icon.
*/ */
public static final String STATUS_ICON_PENDING = "statusIconPending"; public static final String STATUS_ICON_PENDING = "statusIconPending";
/**
* Grid style.
*/
public static final String METADATA_GRID = "metadata-grid";
/** /**
* Footer layout style. * Footer layout style.

View File

@@ -57,4 +57,8 @@
margin-top: 20px !important; margin-top: 20px !important;
} }
.metadata-table-margin {
margin-top:3px;
}
} }

View File

@@ -182,6 +182,7 @@
float: right; float: right;
} }
.v-button-generatedColumnPadding { .v-button-generatedColumnPadding {
height: 28px; height: 28px;
padding: 0 6px !important; padding: 0 6px !important;
@@ -189,5 +190,31 @@
border-radius: 4px; border-radius: 4px;
} }
.metadata-grid {
tr {
.icon-only {
visibility: hidden;
color: $discard-icon-color;
}
}
tr.v-grid-row-selected{
.icon-only .v-icon {
color : $widget-bg;
}
}
tr.v-grid-row-selected:hover {
.icon-only {
visibility: visible;
color: $widget-bg !important;
}
}
tr:hover {
.icon-only {
visibility: visible;
}
}
}
} }

View File

@@ -48,9 +48,6 @@
.distributionPin { .distributionPin {
line-height: 15px; line-height: 15px;
background-color: none; background-color: none;
margin-bottom: 0 !important;
margin-right: 0 !important;
padding: 0;
font-weight: normal; font-weight: normal;
} }
@@ -143,4 +140,8 @@
line-height: 21px; line-height: 21px;
border: 1px solid $widget-border-color; border: 1px solid $widget-border-color;
} }
.ds-metadata-icon{
line-height:15px;
}
} }

View File

@@ -139,5 +139,4 @@ $v-included-components: remove($v-included-components, form);
background-position: bottom; background-position: bottom;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
} }

View File

@@ -57,6 +57,7 @@ caption.new.softwaremodule.jvm = Configure New Runtime
caption.new.softwaremodule.os = Configure New OS caption.new.softwaremodule.os = Configure New OS
caption.filter.simple = Simple Filter caption.filter.simple = Simple Filter
caption.filter.custom = Custom Filter caption.filter.custom = Custom Filter
caption.metadata = Metadata
caption.add.softwaremodule = Configure Software Module caption.add.softwaremodule = Configure Software Module
caption.add.new.dist = Configure New Distribution caption.add.new.dist = Configure New Distribution
@@ -89,6 +90,9 @@ caption.force.action.confirmbox = Confirm Force Active Action
caption.confirm.abort.action = Confirm Abort Action caption.confirm.abort.action = Confirm Abort Action
caption.filter.delete.confirmbox = Confirm Filter Delete Action caption.filter.delete.confirmbox = Confirm Filter Delete Action
caption.metadata.popup = Metadata of
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
# Labels prefix with - label # Labels prefix with - label
label.dist.details.type = Type : label.dist.details.type = Type :
@@ -176,6 +180,7 @@ textfield.version = Version
textfield.vendor = Vendor textfield.vendor = Vendor
textfield.description = Description textfield.description = Description
textfield.customfiltername = Filter name textfield.customfiltername = Filter name
textfield.value = Value
ui.version = Powered by Bosch IoT Software Provisioning ui.version = Powered by Bosch IoT Software Provisioning
prompt.target.id = Controller ID prompt.target.id = Controller ID
@@ -194,6 +199,7 @@ tooltip.timeforced.item=Soft update until a specific time and then the action wi
tooltip.check.for.mandatory=Check to make Mandatory tooltip.check.for.mandatory=Check to make Mandatory
tooltip.artifact.icon=Show Artifact Details tooltip.artifact.icon=Show Artifact Details
tooltip.click.to.edit = Click to edit tooltip.click.to.edit = Click to edit
tooltip.metadata.icon = Manage Metadata
# Notification messages prefix with - message # Notification messages prefix with - message
message.save.success = {0} saved successfully message.save.success = {0} saved successfully
@@ -373,6 +379,13 @@ message.dist.discard.success = All Distributions are discarded successfully !
message.assign.discard.success = All assignments are discarded successfully ! message.assign.discard.success = All assignments are discarded successfully !
message.target.ds.assign.success = Assignments saved successfully ! message.target.ds.assign.success = Assignments saved successfully !
message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists! message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists!
message.key.missing = Key is missing !
message.value.missing = Value is missing !
message.metadata.saved = Metadata with key {0} successfully saved !
message.metadata.updated = Metadata with key {0} successfully updated !
message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value
message.metadata.deleted.successfully = Metadata with key {0} successfully deleted !
message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ?
# Login view # Login view
notification.login.title=Welcome to Bosch IoT Software Provisioning. notification.login.title=Welcome to Bosch IoT Software Provisioning.
@@ -438,14 +451,8 @@ header.distributionset = Distribution set
header.numberofgroups = No. of groups header.numberofgroups = No. of groups
header.detail.status = Detail status header.detail.status = Detail status
header.total.targets = Total targets header.total.targets = Total targets
header.type = Type header.key = Key
header.swmodules = SwModules header.value = Value
header.migrations.step=IsRequiredMigrationStep
header.action=Actions
header.action.run=Run
header.action.pause=Pause
header.action.update=Edit
distribution.details.header = Distribution set distribution.details.header = Distribution set
target.details.header = Target target.details.header = Target

View File

@@ -14,6 +14,7 @@
# Button names prefix with - button # Button names prefix with - button
button.save = Save button.save = Save
button.delete = Delete button.delete = Delete
button.discard = Discard
button.discard.all = Discard All button.discard.all = Discard All
button.delete.all = Delete All button.delete.all = Delete All
button.assign.all = Save Assign button.assign.all = Save Assign
@@ -55,6 +56,8 @@ caption.error = Error
caption.new.softwaremodule.application = Configure New Application caption.new.softwaremodule.application = Configure New Application
caption.new.softwaremodule.jvm = Configure New Runtime caption.new.softwaremodule.jvm = Configure New Runtime
caption.new.softwaremodule.os = Configure New OS caption.new.softwaremodule.os = Configure New OS
caption.metadata = Metadata
caption.add.softwaremodule = Configure Software Module caption.add.softwaremodule = Configure Software Module
caption.add.new.dist = Configure New Distribution caption.add.new.dist = Configure New Distribution
@@ -88,6 +91,8 @@ caption.filter.custom = Custom Filter
caption.filter.delete.confirmbox = Confirm Filter Delete Action caption.filter.delete.confirmbox = Confirm Filter Delete Action
caption.confirm.abort.action = Confirm Abort Action caption.confirm.abort.action = Confirm Abort Action
caption.metadata.popup = Metadata of
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
# Labels prefix with - label # Labels prefix with - label
label.dist.details.type = Type : label.dist.details.type = Type :
@@ -174,6 +179,7 @@ textfield.version = Version
textfield.vendor = Vendor textfield.vendor = Vendor
textfield.description = Description textfield.description = Description
textfield.customfiltername = Filter name textfield.customfiltername = Filter name
textfield.value = Value
ui.version = Powered by Bosch IoT Software Provisioning ui.version = Powered by Bosch IoT Software Provisioning
prompt.target.id = Controller ID prompt.target.id = Controller ID
@@ -192,6 +198,7 @@ tooltip.timeforced.item=Soft update until a specific time and then the action wi
tooltip.check.for.mandatory=Check to make Mandatory tooltip.check.for.mandatory=Check to make Mandatory
tooltip.artifact.icon=Show Artifact Details tooltip.artifact.icon=Show Artifact Details
tooltip.click.to.edit = Click to edit tooltip.click.to.edit = Click to edit
tooltip.metadata.icon = Manage Metadata
# Notification messages prefix with - message # Notification messages prefix with - message
@@ -361,6 +368,14 @@ message.dist.type.discard.success = All Distribution Types are discarded success
message.dist.discard.success = All Distributions are discarded successfully ! message.dist.discard.success = All Distributions are discarded successfully !
message.assign.discard.success = All assignments are discarded successfully ! message.assign.discard.success = All assignments are discarded successfully !
message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists! message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists!
message.key.missing = Key is missing !
message.value.missing = Value is missing !
message.metadata.saved = Metadata with key {0} successfully saved !
message.metadata.updated = Metadata with key {0} successfully updated !
message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value
message.metadata.deleted.successfully = Metadata with key {0} successfully deleted !
message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ?
# Login view # Login view
notification.login.title=Welcome to Bosch IoT Software Provisioning. notification.login.title=Welcome to Bosch IoT Software Provisioning.
@@ -448,6 +463,8 @@ header.caption.softwaremodule = SoftwareModule
header.caption.unassign = Unassign header.caption.unassign = Unassign
message.sw.unassigned = Software Module {0} successfully unassigned message.sw.unassigned = Software Module {0} successfully unassigned
header.caption.upload.details = Upload details header.caption.upload.details = Upload details
header.key = Key
header.value = Value
combo.type.tag.name = Type tag name combo.type.tag.name = Type tag name
label.yes = Yes label.yes = Yes

View File

@@ -14,6 +14,7 @@
# Button names prefix with - button # Button names prefix with - button
button.save = Save button.save = Save
button.delete = Delete button.delete = Delete
button.discard = Discard
button.discard.all = Discard All button.discard.all = Discard All
button.delete.all = Delete All button.delete.all = Delete All
button.assign.all = Save Assign button.assign.all = Save Assign
@@ -57,6 +58,7 @@ caption.new.softwaremodule.jvm = Configure New Runtime
caption.new.softwaremodule.os = Configure New OS caption.new.softwaremodule.os = Configure New OS
caption.filter.simple = Simple Filter caption.filter.simple = Simple Filter
caption.filter.custom = Custom Filter caption.filter.custom = Custom Filter
caption.metadata = Metadata
caption.add.softwaremodule = Configure Software Module caption.add.softwaremodule = Configure Software Module
caption.add.new.dist = Configure New Distribution caption.add.new.dist = Configure New Distribution
@@ -86,6 +88,9 @@ caption.cancel.action.confirmbox = Confirm Action Cancellation
caption.forced.datefield = Force update at time caption.forced.datefield = Force update at time
caption.force.action.confirmbox = Confirm Force Active Action caption.force.action.confirmbox = Confirm Force Active Action
caption.filter.delete.confirmbox = Confirm Filter Delete Action caption.filter.delete.confirmbox = Confirm Filter Delete Action
caption.metadata.popup = Metadata of
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
caption.confirm.abort.action = Confirm Abort Action caption.confirm.abort.action = Confirm Abort Action
# Labels prefix with - label # Labels prefix with - label
@@ -174,6 +179,7 @@ textfield.version = Version
textfield.vendor = Vendor textfield.vendor = Vendor
textfield.description = Description textfield.description = Description
textfield.customfiltername = Filter name textfield.customfiltername = Filter name
textfield.value = Value
ui.version = Powered by Bosch IoT Software Provisioning ui.version = Powered by Bosch IoT Software Provisioning
prompt.target.id = Controller ID prompt.target.id = Controller ID
@@ -192,6 +198,8 @@ tooltip.timeforced.item=Soft update until a specific time and then the action wi
tooltip.check.for.mandatory=Check to make Mandatory tooltip.check.for.mandatory=Check to make Mandatory
tooltip.artifact.icon=Show Artifact Details tooltip.artifact.icon=Show Artifact Details
tooltip.click.to.edit = Click to edit tooltip.click.to.edit = Click to edit
tooltip.metadata.icon = Manage Metadata
# Notification messages prefix with - message # Notification messages prefix with - message
message.save.success = {0} saved successfully message.save.success = {0} saved successfully
@@ -356,6 +364,13 @@ message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully
message.dist.type.discard.success = All Distribution Types are discarded successfully ! message.dist.type.discard.success = All Distribution Types are discarded successfully !
message.dist.discard.success = All Distributions are discarded successfully ! message.dist.discard.success = All Distributions are discarded successfully !
message.assign.discard.success = All assignments are discarded successfully ! message.assign.discard.success = All assignments are discarded successfully !
message.key.missing = Key is missing !
message.value.missing = Value is missing !
message.metadata.saved = Metadata with key {0} successfully saved !
message.metadata.updated = Metadata with key {0} successfully updated !
message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value
message.metadata.deleted.successfully = Metadata with key {0} successfully deleted !
message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ?
# Login view # Login view
notification.login.title=Welcome to Bosch IoT Software Provisioning. notification.login.title=Welcome to Bosch IoT Software Provisioning.
@@ -445,6 +460,8 @@ header.caption.mandatory = Mandatory
header.caption.typename = SoftwareModuleType header.caption.typename = SoftwareModuleType
header.caption.softwaremodule = SoftwareModule header.caption.softwaremodule = SoftwareModule
header.caption.upload.details = Upload details header.caption.upload.details = Upload details
header.key = Key
header.value = Value
combo.type.tag.name = Type tag name combo.type.tag.name = Type tag name
label.yes = Yes label.yes = Yes

BIN
hawkbit_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

10
pom.xml
View File

@@ -68,8 +68,7 @@
<jackson.version>2.5.5</jackson.version> <jackson.version>2.5.5</jackson.version>
<hibernate-validator.version>5.2.4.Final</hibernate-validator.version> <hibernate-validator.version>5.2.4.Final</hibernate-validator.version>
<spring-cloud-connectors.version>1.2.0.RELEASE</spring-cloud-connectors.version> <spring-cloud-connectors.version>1.2.0.RELEASE</spring-cloud-connectors.version>
<spring-amqp.version>1.6.0.RELEASE</spring-amqp.version> <spring-amqp.version>1.6.1.RELEASE</spring-amqp.version>
<rabbitmq.version>3.6.2</rabbitmq.version>
<spring-hateoas.version>0.18.0.RELEASE</spring-hateoas.version> <spring-hateoas.version>0.18.0.RELEASE</spring-hateoas.version>
<!-- Support for MongoDB 3 --> <!-- Support for MongoDB 3 -->
<spring-data-releasetrain.version>Fowler-SR1</spring-data-releasetrain.version> <spring-data-releasetrain.version>Fowler-SR1</spring-data-releasetrain.version>
@@ -111,7 +110,7 @@
<jlorem.version>1.1</jlorem.version> <jlorem.version>1.1</jlorem.version>
<json-simple.version>1.1.1</json-simple.version> <json-simple.version>1.1.1</json-simple.version>
<commons-lang3.version>3.4</commons-lang3.version> <commons-lang3.version>3.4</commons-lang3.version>
<commons-collections4.version>4.0</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<json.version>20141113</json.version> <json.version>20141113</json.version>
<rsql-parser.version>2.0.0</rsql-parser.version> <rsql-parser.version>2.0.0</rsql-parser.version>
<!-- Misc libraries versions - END --> <!-- Misc libraries versions - END -->
@@ -528,11 +527,6 @@
<artifactId>org.eclipse.persistence.jpa</artifactId> <artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${eclipselink.version}</version> <version>${eclipselink.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>${rabbitmq.version}</version>
</dependency>
<!-- RSQL / FIQL parser --> <!-- RSQL / FIQL parser -->
<dependency> <dependency>
<groupId>cz.jirutka.rsql</groupId> <groupId>cz.jirutka.rsql</groupId>