Merge branch 'master' into feature_boot_13_sec_41
Conflicts: hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java pom.xml Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
Build: [](https://circleci.com/gh/eclipse/hawkbit)
|
||||
|
||||
<img src=hawkbit_logo.png width=533 height=246 />
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* A configuration for configuring the spring {@link CacheManager} for specific
|
||||
@@ -33,9 +34,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
*
|
||||
* This is done by providing a special {@link TenantCacheResolver} which
|
||||
* generates a cache name included the current tenant.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
@@ -51,18 +49,27 @@ public class CacheAutoConfiguration extends CachingConfigurerSupport {
|
||||
@Override
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@Primary
|
||||
public TenancyCacheManager cacheManager() {
|
||||
return new TenantAwareCacheManager(new GuavaCacheManager(), tenantAware);
|
||||
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the direct cache manager to access without tenant aware check,
|
||||
* cause in sometimes it's necessary to access the cache directly
|
||||
* without having the current tenant, e.g. initial creation of
|
||||
* tenant
|
||||
*/
|
||||
@Bean(name = "directCacheManager")
|
||||
@ConditionalOnMissingBean(name = "directCacheManager")
|
||||
public CacheManager directCacheManager() {
|
||||
return new GuavaCacheManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link SimpleCacheResolver} implementation which includes the
|
||||
* {@link TenantAware#getCurrentTenant()} into the cache name before
|
||||
* resolving it.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class TenantCacheResolver extends SimpleCacheResolver {
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DownloadIdCacheAutoConfiguration {
|
||||
private CacheManager cacheManager;
|
||||
|
||||
/**
|
||||
* Bean for the downlod id cache.
|
||||
* Bean for the download id cache.
|
||||
*
|
||||
* @return the cache
|
||||
*/
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<artifactId>hawkbit-repository-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@@ -50,8 +51,14 @@ public class RedisConfiguration {
|
||||
* @return the spring redis cache manager.
|
||||
*/
|
||||
@Bean
|
||||
@Primary
|
||||
public CacheManager cacheManager() {
|
||||
return new TenantAwareCacheManager(new RedisCacheManager(redisTemplate()), tenantAware);
|
||||
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
||||
}
|
||||
|
||||
@Bean(name = "directCacheManager")
|
||||
public CacheManager directCacheManager() {
|
||||
return new RedisCacheManager(redisTemplate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,8 +16,8 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -56,7 +56,7 @@ public class EventDistributorTest {
|
||||
@Test
|
||||
public void distributeDistributedEventSendsToRedis() {
|
||||
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||
underTest.distribute(event);
|
||||
|
||||
// origin node ID should be set by distributing the event
|
||||
@@ -67,7 +67,7 @@ public class EventDistributorTest {
|
||||
@Test
|
||||
public void dontDistributeDistributedEventIfSameNode() {
|
||||
final String knownNodeId = EventDistributor.getNodeId();
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||
event.setNodeId(knownNodeId);
|
||||
|
||||
// test
|
||||
@@ -79,7 +79,7 @@ public class EventDistributorTest {
|
||||
|
||||
@Test
|
||||
public void handleDistributedMessageFromRedis() {
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||
final String knownChannel = "someChannel";
|
||||
|
||||
underTest.handleMessage(event, knownChannel);
|
||||
@@ -90,7 +90,7 @@ public class EventDistributorTest {
|
||||
|
||||
@Test
|
||||
public void handleDistributedMessageFilteredIfSameNodeId() {
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||
final String knownChannel = "someChannel";
|
||||
event.setOriginNodeId(EventDistributor.getNodeId());
|
||||
|
||||
|
||||
@@ -1,57 +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.eventbus.event;
|
||||
|
||||
/**
|
||||
* Event that contains an updated download progress for a given Action.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DownloadProgressEvent extends AbstractDistributedEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Long statusId;
|
||||
private final int progressPercent;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant for this event
|
||||
* @param statusId
|
||||
* of {@link UpdateActionStatus}
|
||||
* @param progressPercent
|
||||
* number (1-100)
|
||||
*/
|
||||
public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent) {
|
||||
// the revision of the DownloadProgressEvent is just equal the
|
||||
// progressPercentage due the
|
||||
// percentage is going from 0 to 100.
|
||||
super(statusId, tenant);
|
||||
this.statusId = statusId;
|
||||
this.progressPercent = progressPercent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the statusId
|
||||
*/
|
||||
public Long getStatusId() {
|
||||
return statusId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the progressPercent
|
||||
*/
|
||||
public int getProgressPercent() {
|
||||
return progressPercent;
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,12 @@ public enum TargetFields implements FieldNameProvider {
|
||||
/**
|
||||
* 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 List<String> subEntityAttribues;
|
||||
|
||||
@@ -93,12 +93,12 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
||||
// we set a download status only if we are aware of the
|
||||
// targetid, i.e. authenticated and not anonymous
|
||||
if (targetid != null && !"anonymous".equals(targetid)) {
|
||||
final Action action = checkAndReportDownloadByTarget(
|
||||
final ActionStatus actionStatus = checkAndReportDownloadByTarget(
|
||||
requestResponseContextHolder.getHttpServletRequest(), targetid, artifact);
|
||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||
requestResponseContextHolder.getHttpServletResponse(),
|
||||
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
||||
action.getId());
|
||||
actionStatus.getId());
|
||||
} else {
|
||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||
requestResponseContextHolder.getHttpServletResponse(),
|
||||
@@ -131,7 +131,7 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
||||
private ActionStatus checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
||||
final LocalArtifact artifact) {
|
||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||
IpUtil.getClientIpFromRequest(request, securityProperties));
|
||||
@@ -152,8 +152,8 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
||||
actionStatus.addMessage(
|
||||
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI());
|
||||
}
|
||||
controllerManagement.addInformationalActionStatus(actionStatus);
|
||||
return action;
|
||||
|
||||
return controllerManagement.addInformationalActionStatus(actionStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -156,8 +156,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
|
||||
result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
|
||||
} else {
|
||||
final Action action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(), target,
|
||||
module);
|
||||
final ActionStatus action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(),
|
||||
target, module);
|
||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||
requestResponseContextHolder.getHttpServletResponse(),
|
||||
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
||||
@@ -167,7 +167,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Action checkAndLogDownload(final HttpServletRequest request, final Target target,
|
||||
private ActionStatus checkAndLogDownload(final HttpServletRequest request, final Target target,
|
||||
final SoftwareModule module) {
|
||||
final Action action = controllerManagement
|
||||
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module);
|
||||
@@ -185,8 +185,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
statusMessage.addMessage(
|
||||
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI());
|
||||
}
|
||||
controllerManagement.addInformationalActionStatus(statusMessage);
|
||||
return action;
|
||||
|
||||
return controllerManagement.addInformationalActionStatus(statusMessage);
|
||||
}
|
||||
|
||||
private static boolean checkModule(final String fileName, final SoftwareModule module) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
@@ -63,11 +63,15 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Stories("Artifact Download Resource")
|
||||
public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMongoDB {
|
||||
|
||||
private static final int ARTIFACT_SIZE = 5 * 1024 * 1024;
|
||||
|
||||
public DdiArtifactDownloadTest() {
|
||||
LOG = LoggerFactory.getLogger(DdiArtifactDownloadTest.class);
|
||||
}
|
||||
|
||||
private volatile int downLoadProgress = 0;
|
||||
private volatile long shippedBytes = 0;
|
||||
private volatile long shippedBytesTotal = 0;
|
||||
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
|
||||
|
||||
@@ -247,6 +251,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
@Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.")
|
||||
public void downloadArtifactThroughFileName() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
shippedBytes = 0;
|
||||
shippedBytesTotal = 0;
|
||||
eventBus.register(this);
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
|
||||
@@ -260,7 +266,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
||||
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
@@ -287,6 +293,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
|
||||
// download complete
|
||||
assertThat(downLoadProgress).isEqualTo(10);
|
||||
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -324,35 +331,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
+ "anonymous as authorization is notpossible, e.g. chekc if the controller has the artifact assigned.")
|
||||
public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
eventBus.register(this);
|
||||
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = entityFactory.generateTarget("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||
|
||||
// download fails as artifact is not yet assigned to target
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Ensures that an authenticated and named controller is permitted to download.")
|
||||
public void downloadArtifactByNameByNamedController() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
shippedBytes = 0;
|
||||
shippedBytesTotal = 0;
|
||||
eventBus.register(this);
|
||||
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
@@ -367,7 +347,41 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
||||
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||
|
||||
// download fails as artifact is not yet assigned to target
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
assertThat(downLoadProgress).isEqualTo(1);
|
||||
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Ensures that an authenticated and named controller is permitted to download.")
|
||||
public void downloadArtifactByNameByNamedController() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
shippedBytes = 0;
|
||||
shippedBytesTotal = 0;
|
||||
eventBus.register(this);
|
||||
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = entityFactory.generateTarget("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
@@ -400,6 +414,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
|
||||
// download complete
|
||||
assertThat(downLoadProgress).isEqualTo(10);
|
||||
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -561,5 +576,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
||||
@Subscribe
|
||||
public void listen(final DownloadProgressEvent event) {
|
||||
downLoadProgress++;
|
||||
shippedBytes += event.getShippedBytesSinceLast();
|
||||
shippedBytesTotal = event.getShippedBytesOverall();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ public class MgmtSystemTenantServiceUsage {
|
||||
* @param tenantName
|
||||
*/
|
||||
public MgmtSystemTenantServiceUsage(final String tenantName) {
|
||||
super();
|
||||
this.tenantName = tenantName;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
*/
|
||||
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.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
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.get;
|
||||
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.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.ActionFields;
|
||||
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||
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_SIZE = ".size";
|
||||
private static final String JSON_PATH_FIELD_TOTAL = ".total";
|
||||
private static final String JSON_PATH_FIELD_LAST_REQUEST_AT = ".lastControllerRequestAt";
|
||||
|
||||
// target
|
||||
// $.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_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_LAST_REQUEST_AT = JSON_PATH_ROOT + JSON_PATH_FIELD_LAST_REQUEST_AT;
|
||||
|
||||
@Test
|
||||
@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].createdBy", equalTo("bumlux")))
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].updateStatus", equalTo("unknown")))
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].lastControllerRequestAt", notNullValue()))
|
||||
// idB
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0]._links.self.href",
|
||||
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].createdBy", equalTo("bumlux")))
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idB + ")][0].updateStatus", equalTo("unknown")))
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idA + ")][0].lastControllerRequestAt", notNullValue()))
|
||||
// idC
|
||||
.andExpect(jsonPath("$content.[?(@.name==" + idC + ")][0]._links.self.href",
|
||||
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].controllerId", equalTo(idC)))
|
||||
.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
|
||||
@@ -518,7 +524,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
||||
// create first a target which can be retrieved by rest interface
|
||||
final String knownControllerId = "1";
|
||||
final String knownName = "someName";
|
||||
createSingleTarget(knownControllerId, knownName);
|
||||
final Target target = createSingleTarget(knownControllerId, knownName);
|
||||
final String hrefPrefix = "http://localhost/rest/v1/targets/" + knownControllerId + "/";
|
||||
// test
|
||||
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_CONTROLLERID, equalTo(knownControllerId)))
|
||||
.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("nextExpectedRequestAt")))
|
||||
.andExpect(jsonPath("$.pollStatus.overdue", equalTo(false)))
|
||||
@@ -1075,8 +1082,6 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
||||
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId)
|
||||
throws InterruptedException {
|
||||
|
||||
final PageRequest pageRequest = new PageRequest(0, 100, Direction.ASC, ActionStatusFields.ID.getFieldName());
|
||||
|
||||
Target target = entityFactory.generateTarget(knownTargetId);
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
@@ -1122,7 +1127,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
||||
@Test
|
||||
public void assignDistributionSetToTarget() throws Exception {
|
||||
|
||||
final Target target = targetManagement.createTarget(entityFactory.generateTarget("fsdfsd"));
|
||||
targetManagement.createTarget(entityFactory.generateTarget("fsdfsd"));
|
||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||
|
||||
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);
|
||||
target.setName(name);
|
||||
target.setDescription(TARGET_DESCRIPTION_TEST);
|
||||
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
|
||||
* alphabet [a-z] using the ASCII.
|
||||
*
|
||||
* Creating targets with the given amount by setting name, id etc from the
|
||||
* alphabet [a-z] using ASCII.
|
||||
*
|
||||
* @param amount
|
||||
* The number of targets to create
|
||||
*/
|
||||
private void createTargetsAlphabetical(final int amount) {
|
||||
char character = 'a';
|
||||
@@ -1320,15 +1326,15 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
||||
final Target target = entityFactory.generateTarget(str);
|
||||
target.setName(str);
|
||||
target.setDescription(str);
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
assertThat(savedTarget.getLastModifiedBy()).isNotNull();
|
||||
targetManagement.createTarget(target);
|
||||
controllerManagament.updateLastTargetQuery(str, null);
|
||||
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) {
|
||||
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.
|
||||
*
|
||||
*
|
||||
* @return The targetid of the created target.
|
||||
*/
|
||||
private Target createTargetAndStartAction() {
|
||||
@@ -1348,7 +1354,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
||||
final Target tA = targetManagement
|
||||
.createTarget(testdataFactory.generateTarget("target-id-A", "first description"));
|
||||
// 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
|
||||
final Slice<Action> actionsByTarget = deploymentManagement.findActionsByTarget(new PageRequest(0, 100), tA);
|
||||
assertThat(actionsByTarget.getContent()).hasSize(1);
|
||||
|
||||
@@ -14,8 +14,8 @@ import java.util.Map;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
|
||||
@@ -58,16 +58,20 @@ public interface ControllerManagement {
|
||||
Action addCancelActionStatus(@NotNull ActionStatus actionStatus);
|
||||
|
||||
/**
|
||||
* Sends the download progress in percentage and notifies the
|
||||
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
||||
* Sends the download progress and notifies the {@link EventBus} with a
|
||||
* {@link DownloadProgressEvent}.
|
||||
*
|
||||
* @param statusId
|
||||
* the ID of the {@link ActionStatus}
|
||||
* @param progressPercent
|
||||
* the progress in percentage which must be between 0-100
|
||||
* @param requestedBytes
|
||||
* requested bytes of the request
|
||||
* @param shippedBytesSinceLast
|
||||
* since the last report
|
||||
* @param shippedBytesOverall
|
||||
* for the {@link ActionStatus}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||
void downloadProgressPercent(long statusId, int progressPercent);
|
||||
void downloadProgress(Long statusId, Long requestedBytes, Long shippedBytesSinceLast, Long shippedBytesOverall);
|
||||
|
||||
/**
|
||||
* Simple addition of a new {@link ActionStatus} entry to the {@link Action}
|
||||
@@ -75,9 +79,11 @@ public interface ControllerManagement {
|
||||
*
|
||||
* @param statusMessage
|
||||
* to add to the action
|
||||
*
|
||||
* @return create {@link ActionStatus} entity
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||
void addInformationalActionStatus(@NotNull ActionStatus statusMessage);
|
||||
ActionStatus addInformationalActionStatus(@NotNull ActionStatus statusMessage);
|
||||
|
||||
/**
|
||||
* Adds an {@link ActionStatus} entry for an update {@link Action} including
|
||||
|
||||
@@ -269,8 +269,7 @@ public interface DeploymentManagement {
|
||||
* @return the actions referring a specific rollout and a specific parent
|
||||
* rollout group in a specific status
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
List<Action> findActionsByRolloutGroupParentAndStatus(@NotNull Rollout rollout,
|
||||
@NotNull RolloutGroup rolloutGroupParent, @NotNull Action.Status actionStatus);
|
||||
|
||||
@@ -496,8 +495,7 @@ public interface DeploymentManagement {
|
||||
* the action to start now.
|
||||
* @return the action which has been started
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Action startScheduledAction(@NotNull Action action);
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,8 +61,7 @@ public interface RolloutManagement {
|
||||
* this check. This check is only applied if the last check is
|
||||
* less than (lastcheck-delay).
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||
void checkRunningRollouts(long delayBetweenChecks);
|
||||
|
||||
/**
|
||||
@@ -266,8 +265,7 @@ public interface RolloutManagement {
|
||||
* if given rollout is not in {@link RolloutStatus#RUNNING}.
|
||||
* Only running rollouts can be paused.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||
void pauseRollout(@NotNull Rollout rollout);
|
||||
|
||||
/**
|
||||
@@ -281,8 +279,7 @@ public interface RolloutManagement {
|
||||
* if given rollout is not in {@link RolloutStatus#PAUSED}. Only
|
||||
* paused rollouts can be resumed.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||
void resumeRollout(@NotNull Rollout rollout);
|
||||
|
||||
/**
|
||||
@@ -303,8 +300,7 @@ public interface RolloutManagement {
|
||||
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
||||
* ready rollouts can be started.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||
Rollout startRollout(@NotNull Rollout rollout);
|
||||
|
||||
/**
|
||||
@@ -326,8 +322,7 @@ public interface RolloutManagement {
|
||||
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
||||
* ready rollouts can be started.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||
Rollout startRolloutAsync(@NotNull Rollout rollout);
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,16 +39,14 @@ public interface SystemManagement {
|
||||
* @param tenant
|
||||
* to delete
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||
void deleteTenant(@NotNull String tenant);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return list of all tenant names in the system.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||
List<String> findTenants();
|
||||
|
||||
/**
|
||||
@@ -68,8 +66,8 @@ public interface SystemManagement {
|
||||
/**
|
||||
* Returns {@link TenantMetaData} of given and current tenant. Creates for
|
||||
* new tenants also two {@link SoftwareModuleType} (os and app) and
|
||||
* {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} {@link DistributionSetType}s
|
||||
* (os and os_app).
|
||||
* {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT}
|
||||
* {@link DistributionSetType}s (os and os_app).
|
||||
*
|
||||
* DISCLAIMER: this variant is used during initial login (where the tenant
|
||||
* is not yet in the session). Please user {@link #getTenantMetadata()} for
|
||||
|
||||
@@ -54,8 +54,7 @@ public interface TenantConfigurationManagement {
|
||||
* @return <null> if no default value is set and no database value available
|
||||
* or returns the tenant configuration value
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||
<T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey,
|
||||
Class<T> propertyType, TenantConfiguration tenantConfiguration);
|
||||
|
||||
@@ -87,8 +86,7 @@ public interface TenantConfigurationManagement {
|
||||
* if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey);
|
||||
|
||||
/**
|
||||
@@ -114,8 +112,7 @@ public interface TenantConfigurationManagement {
|
||||
* if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey,
|
||||
Class<T> propertyType);
|
||||
|
||||
@@ -139,7 +136,6 @@ public interface TenantConfigurationManagement {
|
||||
* if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||
<T> T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class<T> propertyType);
|
||||
}
|
||||
|
||||
@@ -20,15 +20,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||
public interface TenantStatsManagement {
|
||||
|
||||
/**
|
||||
* Service for stats of a single tenant. Opens a new transaction and as a
|
||||
* result can an be used for multiple tenants, i.e. to allow in one session
|
||||
* to collect data of all tenants in the system.
|
||||
* Service for stats of the current tenant.
|
||||
*
|
||||
* @param tenant
|
||||
* to collect for
|
||||
* @return collected statistics
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||
TenantUsage getStatsOfTenant(String tenant);
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
TenantUsage getStatsOfTenant();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.repository.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
|
||||
|
||||
/**
|
||||
* Event that contains an updated download progress for a given ActionStatus
|
||||
* that was written for a download request.
|
||||
*
|
||||
*/
|
||||
public class DownloadProgressEvent extends AbstractDistributedEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Long statusId;
|
||||
private final long requestedBytes;
|
||||
private final long shippedBytesSinceLast;
|
||||
private final long shippedBytesOverall;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant for this event
|
||||
* @param statusId
|
||||
* of ActionStatus that was written for the download request
|
||||
* @param requestedBytes
|
||||
* bytes requested
|
||||
* @param shippedBytesSinceLast
|
||||
* bytes since last event
|
||||
* @param shippedBytesOverall
|
||||
* on the download request
|
||||
*/
|
||||
public DownloadProgressEvent(final String tenant, final Long statusId, final Long requestedBytes,
|
||||
final Long shippedBytesSinceLast, final Long shippedBytesOverall) {
|
||||
// the revision of the DownloadProgressEvent is just equal the
|
||||
// shippedBytesOverall as this is a growing number.
|
||||
super(shippedBytesOverall, tenant);
|
||||
this.statusId = statusId;
|
||||
this.requestedBytes = requestedBytes;
|
||||
this.shippedBytesSinceLast = shippedBytesSinceLast;
|
||||
this.shippedBytesOverall = shippedBytesOverall;
|
||||
}
|
||||
|
||||
public Long getStatusId() {
|
||||
return statusId;
|
||||
}
|
||||
|
||||
public long getRequestedBytes() {
|
||||
return requestedBytes;
|
||||
}
|
||||
|
||||
public long getShippedBytesSinceLast() {
|
||||
return shippedBytesSinceLast;
|
||||
}
|
||||
|
||||
public long getShippedBytesOverall() {
|
||||
return shippedBytesOverall;
|
||||
}
|
||||
}
|
||||
@@ -39,12 +39,6 @@ public interface Action extends TenantAwareBaseEntity {
|
||||
return Status.CANCELING.equals(getStatus()) || Status.CANCELED.equals(getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current {@link Status#DOWNLOAD} progress if known by the update
|
||||
* server.
|
||||
*/
|
||||
int getDownloadProgressPercent();
|
||||
|
||||
/**
|
||||
* @return current {@link Status} of the {@link Action}.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,12 @@ public interface ActionStatus extends TenantAwareBaseEntity {
|
||||
*/
|
||||
void addMessage(String message);
|
||||
|
||||
/**
|
||||
* @return current {@link Status#DOWNLOAD} progress if known by the update
|
||||
* server.
|
||||
*/
|
||||
int getDownloadProgressPercent();
|
||||
|
||||
/**
|
||||
* @return list of message entries that can be added to the
|
||||
* {@link ActionStatus}.
|
||||
|
||||
@@ -106,7 +106,7 @@ public class TenantUsage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { // NOSONAR - as this is generated code
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (actions ^ (actions >>> 32));
|
||||
@@ -118,15 +118,14 @@ public class TenantUsage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) { // NOSONAR - as this is generated
|
||||
// code
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
if (!(obj instanceof TenantUsage)) {
|
||||
return false;
|
||||
}
|
||||
final TenantUsage other = (TenantUsage) obj;
|
||||
@@ -154,7 +153,7 @@ public class TenantUsage {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SystemUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
|
||||
return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
|
||||
+ ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]";
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManage
|
||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -71,6 +72,8 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* General configuration for hawkBit's Repository.
|
||||
*
|
||||
@@ -85,6 +88,9 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
|
||||
@EnableScheduling
|
||||
@EntityScan("org.eclipse.hawkbit.repository.jpa.model")
|
||||
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
/**
|
||||
* @return the {@link SystemSecurityContext} singleton bean which make it
|
||||
* accessible in beans which cannot access the service directly,
|
||||
@@ -249,7 +255,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TenantStatsManagement tenantStatsManagement() {
|
||||
return new JpaTenantStatsManagement();
|
||||
final TenantStatsManagement mgmt = new JpaTenantStatsManagement();
|
||||
eventBus.register(mgmt);
|
||||
return mgmt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -451,8 +451,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Override
|
||||
@Modifying
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
public void addInformationalActionStatus(final ActionStatus statusMessage) {
|
||||
actionStatusRepository.save((JpaActionStatus) statusMessage);
|
||||
public ActionStatus addInformationalActionStatus(final ActionStatus statusMessage) {
|
||||
return actionStatusRepository.save((JpaActionStatus) statusMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -469,8 +469,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadProgressPercent(final long statusId, final int progressPercent) {
|
||||
cacheWriteNotify.downloadProgressPercent(statusId, progressPercent);
|
||||
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||
final Long shippedBytesOverall) {
|
||||
cacheWriteNotify.downloadProgress(statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
||||
final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
|
||||
|
||||
boolean updated = false;
|
||||
if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) {
|
||||
if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) {
|
||||
type.setDescription(sm.getDescription());
|
||||
updated = true;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.Constants;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
||||
@@ -26,18 +27,20 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||
import org.eclipse.hawkbit.repository.report.model.SystemUsageReport;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||
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.interceptor.KeyGenerator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
@@ -108,7 +111,10 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
private SystemManagementCacheKeyGenerator currentTenantCacheKeyGenerator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
private SystemSecurityContext systemSecurityContext;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager txManager;
|
||||
|
||||
@Override
|
||||
public SystemUsageReport getSystemUsageStatistics() {
|
||||
@@ -147,7 +153,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
final List<String> tenants = findTenants();
|
||||
|
||||
tenants.forEach(tenant -> tenantAware.runAsTenant(tenant, () -> {
|
||||
report.addTenantData(systemStatsManagement.getStatsOfTenant(tenant));
|
||||
report.addTenantData(systemStatsManagement.getStatsOfTenant());
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
@@ -159,39 +165,57 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "tenantMetadata", key = "#tenant.toUpperCase()")
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Modifying
|
||||
public TenantMetaData getTenantMetadata(final String tenant) {
|
||||
final TenantMetaData result = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
|
||||
|
||||
// Create if it does not exist
|
||||
if (result == null) {
|
||||
try {
|
||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
|
||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
||||
applicationContext.getBean("currentTenantKeyGenerator");
|
||||
return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant));
|
||||
return createInitialTenantMetaData(tenant);
|
||||
|
||||
} finally {
|
||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creating the initial tenant meta-data in a new transaction. Due the
|
||||
* {@link MultiTenantJpaTransactionManager} is using the current tenant to
|
||||
* set the necessary tenant discriminator to the query. This is not working
|
||||
* if we don't have a current tenant set. Due the
|
||||
* {@link #getTenantMetadata(String)} is maybe called without having a
|
||||
* current tenant we need to re-open a new transaction so the
|
||||
* {@link MultiTenantJpaTransactionManager} is called again and set the
|
||||
* tenant for this transaction.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant to be created
|
||||
* @return the initial created {@link TenantMetaData}
|
||||
*/
|
||||
private TenantMetaData createInitialTenantMetaData(final String tenant) {
|
||||
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
|
||||
def.setName("initial-tenant-creation");
|
||||
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
return systemSecurityContext.runAsSystemAsTenant(
|
||||
() -> new TransactionTemplate(txManager, def).execute(status -> tenantMetaDataRepository
|
||||
.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant))),
|
||||
tenant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> findTenants() {
|
||||
return tenantMetaDataRepository.findAll().stream().map(md -> md.getTenant()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = { "tenantMetadata" }, key = "#tenant.toUpperCase()")
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Modifying
|
||||
public void deleteTenant(final String tenant) {
|
||||
cacheManager.evictCaches(tenant);
|
||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
||||
tenantAware.runAsTenant(tenant, () -> {
|
||||
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant.toUpperCase());
|
||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||
@@ -214,7 +238,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "tenantMetadata", keyGenerator = "tenantKeyGenerator")
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Modifying
|
||||
public TenantMetaData getTenantMetadata() {
|
||||
@@ -226,7 +249,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator")
|
||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager")
|
||||
// set transaction to not supported, due we call this in
|
||||
// BaseEntity#prePersist methods
|
||||
// and it seems that JPA committing the transaction when executing this
|
||||
@@ -249,7 +272,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
}
|
||||
|
||||
@Override
|
||||
@CachePut(value = "tenantMetadata", key = "#metaData.tenant.toUpperCase()")
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Modifying
|
||||
public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import java.util.Optional;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
||||
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -35,9 +35,14 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
|
||||
@Autowired
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
|
||||
public TenantUsage getStatsOfTenant(final String tenant) {
|
||||
public TenantUsage getStatsOfTenant() {
|
||||
final String tenant = tenantAware.getCurrentTenant();
|
||||
|
||||
final TenantUsage result = new TenantUsage(tenant);
|
||||
|
||||
result.setTargets(targetRepository.count());
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.cache;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.cache.CacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.math.DoubleMath;
|
||||
|
||||
/**
|
||||
* An service which combines the functionality for functional use cases to write
|
||||
@@ -30,10 +32,6 @@ import com.google.common.eventbus.EventBus;
|
||||
*/
|
||||
@Service
|
||||
public class CacheWriteNotify {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int DOWNLOAD_PROGRESS_MAX = 100;
|
||||
|
||||
@Autowired
|
||||
@@ -46,20 +44,29 @@ public class CacheWriteNotify {
|
||||
private TenantAware tenantAware;
|
||||
|
||||
/**
|
||||
* writes the download progress in percentage into the cache
|
||||
* writes the download progress into the cache
|
||||
* {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the
|
||||
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
||||
*
|
||||
* @param statusId
|
||||
* the ID of the {@link ActionStatus}
|
||||
* @param progressPercent
|
||||
* the progress in percentage which must be between 0-100
|
||||
* @param requestedBytes
|
||||
* requested bytes of the request
|
||||
* @param shippedBytesSinceLast
|
||||
* since last event
|
||||
* @param shippedBytesOverall
|
||||
* for the download request
|
||||
*/
|
||||
public void downloadProgressPercent(final long statusId, final int progressPercent) {
|
||||
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||
final Long shippedBytesOverall) {
|
||||
|
||||
final Cache cache = cacheManager.getCache(Action.class.getName());
|
||||
final Cache cache = cacheManager.getCache(ActionStatus.class.getName());
|
||||
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
|
||||
CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
|
||||
|
||||
final int progressPercent = DoubleMath.roundToInt(shippedBytesOverall * 100.0 / requestedBytes,
|
||||
RoundingMode.DOWN);
|
||||
|
||||
if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
|
||||
cache.put(cacheKey, progressPercent);
|
||||
} else {
|
||||
@@ -69,7 +76,8 @@ public class CacheWriteNotify {
|
||||
cache.evict(cacheKey);
|
||||
}
|
||||
|
||||
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent));
|
||||
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, requestedBytes,
|
||||
shippedBytesSinceLast, shippedBytesOverall));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,10 +27,7 @@ import javax.persistence.NamedEntityGraphs;
|
||||
import javax.persistence.NamedSubgraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -89,13 +86,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
/**
|
||||
* Note: filled only in {@link Status#DOWNLOAD}.
|
||||
*/
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
|
||||
private int downloadProgressPercent;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
@@ -120,15 +110,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDownloadProgressPercent() {
|
||||
return downloadProgressPercent;
|
||||
}
|
||||
|
||||
public void setDownloadProgressPercent(final int downloadProgressPercent) {
|
||||
this.downloadProgressPercent = downloadProgressPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
|
||||
@@ -24,7 +24,10 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
@@ -63,6 +66,13 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
||||
@Column(name = "detail_message", length = 512)
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Note: filled only in {@link Status#DOWNLOAD}.
|
||||
*/
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
|
||||
private int downloadProgressPercent;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ActionStatus} object.
|
||||
*
|
||||
@@ -105,6 +115,11 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
||||
// JPA default constructor.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDownloadProgressPercent() {
|
||||
return downloadProgressPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getOccurredAt() {
|
||||
return occurredAt;
|
||||
|
||||
@@ -83,6 +83,7 @@ public final class DistributionSetSpecification {
|
||||
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
|
||||
targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
|
||||
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
|
||||
targetRoot.fetch(JpaDistributionSet_.metadata, JoinType.LEFT);
|
||||
query.distinct(true);
|
||||
|
||||
return predicate;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.specifications;
|
||||
|
||||
import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||
@@ -38,6 +39,8 @@ public final class SoftwareModuleSpecification {
|
||||
return (targetRoot, query, cb) -> {
|
||||
final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaSoftwareModule_.id), moduleId);
|
||||
targetRoot.fetch(JpaSoftwareModule_.type);
|
||||
targetRoot.fetch(JpaSoftwareModule_.metadata,JoinType.LEFT);
|
||||
query.distinct(true);
|
||||
return predicate;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.Random;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
||||
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||
import org.junit.Test;
|
||||
@@ -29,6 +30,15 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Stories("System Management")
|
||||
public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that you can create a tenant without setting the necessary security context which holds a current tenant")
|
||||
public void createInitialTenantWithoutSecurityContext() {
|
||||
securityRule.clear();
|
||||
final String tenantToBeCreated = "newTenantToCreate";
|
||||
final TenantMetaData tenantMetadata = systemManagement.getTenantMetadata(tenantToBeCreated);
|
||||
assertThat(tenantMetadata).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
|
||||
public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception {
|
||||
|
||||
@@ -13,8 +13,8 @@ import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -59,15 +59,14 @@ public class CacheWriteNotifyTest {
|
||||
@Test
|
||||
public void downloadgProgressIsCachedAndEventSent() {
|
||||
final long knownStatusId = 1;
|
||||
final int knownPercentage = 23;
|
||||
|
||||
when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock);
|
||||
when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock);
|
||||
when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
|
||||
|
||||
underTest.downloadProgressPercent(knownStatusId, knownPercentage);
|
||||
underTest.downloadProgress(knownStatusId, 500L, 100L, 100L);
|
||||
|
||||
verify(cacheManagerMock).getCache(eq(Action.class.getName()));
|
||||
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage);
|
||||
verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName()));
|
||||
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, 20);
|
||||
verify(eventBusMock).post(any(DownloadProgressEvent.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("RSQL filter target")
|
||||
public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
private static final long LAST_TARGET_QUERY = 10000;
|
||||
private static final long LAST_TARGET_QUERY_SMALLER = 1000;
|
||||
|
||||
@Before
|
||||
public void seuptBeforeTest() {
|
||||
@@ -48,14 +50,16 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
final TargetInfo targetInfo = target.getTargetInfo();
|
||||
targetInfo.getControllerAttributes().put("revision", "1.1");
|
||||
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
|
||||
|
||||
((JpaTargetInfo) target.getTargetInfo()).setLastTargetQuery(LAST_TARGET_QUERY);
|
||||
targetManagement.createTarget(target);
|
||||
|
||||
final JpaTarget target2 = new JpaTarget("targetId1234");
|
||||
target2.setDescription("targetId1234");
|
||||
final TargetInfo targetInfo2 = new JpaTargetInfo(target2);
|
||||
final TargetInfo targetInfo2 = target2.getTargetInfo();
|
||||
targetInfo2.getControllerAttributes().put("revision", "1.2");
|
||||
target2.setTargetInfo(targetInfo2);
|
||||
((JpaTargetInfo) target2.getTargetInfo()).setLastTargetQuery(LAST_TARGET_QUERY_SMALLER);
|
||||
targetManagement.createTarget(target2);
|
||||
|
||||
targetManagement.createTarget(new JpaTarget("targetId1235"));
|
||||
targetManagement.createTarget(new JpaTarget("targetId1236"));
|
||||
|
||||
@@ -166,6 +170,17 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
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) {
|
||||
final Page<Target> findTargetPage = targetManagement.findTargetsAll(rsqlParam, new PageRequest(0, 100));
|
||||
final long countTargetsAll = findTargetPage.getTotalElements();
|
||||
|
||||
@@ -63,7 +63,7 @@ public class WithSpringAuthorityRule implements TestRule {
|
||||
}
|
||||
return oldContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param annotation
|
||||
*/
|
||||
@@ -129,6 +129,14 @@ public class WithSpringAuthorityRule implements TestRule {
|
||||
private void after(final SecurityContext oldContext) {
|
||||
SecurityContextHolder.setContext(oldContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the current security context.
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -87,7 +88,7 @@ public final class RestResourceConversionHelper {
|
||||
* @param controllerManagement
|
||||
* to write progress updates to
|
||||
* @param statusId
|
||||
* of the UpdateActionStatus
|
||||
* of the {@link ActionStatus}
|
||||
*
|
||||
* @return http code
|
||||
*
|
||||
@@ -293,6 +294,7 @@ public final class RestResourceConversionHelper {
|
||||
|
||||
long toRead = length;
|
||||
boolean toContinue = true;
|
||||
long shippedSinceLastEvent = 0;
|
||||
|
||||
while (toContinue) {
|
||||
final int r = from.read(buf);
|
||||
@@ -304,9 +306,11 @@ public final class RestResourceConversionHelper {
|
||||
if (toRead > 0) {
|
||||
to.write(buf, 0, r);
|
||||
total += r;
|
||||
shippedSinceLastEvent += r;
|
||||
} else {
|
||||
to.write(buf, 0, (int) toRead + r);
|
||||
total += toRead + r;
|
||||
shippedSinceLastEvent += toRead + r;
|
||||
toContinue = false;
|
||||
}
|
||||
|
||||
@@ -316,7 +320,8 @@ public final class RestResourceConversionHelper {
|
||||
// every 10 percent an event
|
||||
if (newPercent == 100 || newPercent > progressPercent + 10) {
|
||||
progressPercent = newPercent;
|
||||
controllerManagement.downloadProgressPercent(statusId, progressPercent);
|
||||
controllerManagement.downloadProgress(statusId, length, shippedSinceLastEvent, total);
|
||||
shippedSinceLastEvent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,8 +224,10 @@ public final class SpPermission {
|
||||
/*
|
||||
* Spring security eval expressions.
|
||||
*/
|
||||
private static final String HAS_AUTH_PREFIX = "hasAuthority('";
|
||||
private static final String HAS_AUTH_SUFFIX = "')";
|
||||
private static final String BRACKET_OPEN = "(";
|
||||
private static final String BRACKET_CLOSE = ")";
|
||||
private static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'";
|
||||
private static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE;
|
||||
private static final String HAS_AUTH_AND = " and ";
|
||||
|
||||
/**
|
||||
@@ -257,99 +259,6 @@ public final class SpPermission {
|
||||
*/
|
||||
public static final String HAS_AUTH_OR = " or ";
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#UPDATE_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#SYSTEM_ADMIN}.
|
||||
*/
|
||||
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DELETE_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||
* {@link SpPermission#UPDATE_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_REPOSITORY}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DELETE_REPOSITORY}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#UPDATE_REPOSITORY}.
|
||||
*/
|
||||
public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||
* {@link SpPermission#READ_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAnyRole expression to check if the spring
|
||||
* context contains the anoynmous role or the controller specific role
|
||||
* {@link SpPermission#CONTROLLER_ROLE}.
|
||||
*/
|
||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||
+ "')";
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if the spring
|
||||
* context contains the role to allow controllers to download specific
|
||||
* role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}.
|
||||
*/
|
||||
public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAnyRole expression to check if the spring
|
||||
* context contains system code role
|
||||
@@ -359,47 +268,168 @@ public final class SpPermission {
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
||||
* {@link SpPermission#CREATE_TARGET}.
|
||||
* context contains {@link SpPermission#UPDATE_TARGET} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT}
|
||||
* context contains {@link SpPermission#SYSTEM_ADMIN} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_TARGET} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR
|
||||
+ IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_TARGET} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DELETE_TARGET} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||
* {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
|
||||
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_REPOSITORY} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DELETE_REPOSITORY} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#UPDATE_REPOSITORY} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||
* {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
|
||||
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAnyRole expression to check if the spring
|
||||
* context contains the anoynmous role or the controller specific role
|
||||
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
|
||||
*/
|
||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||
+ "')";
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if the spring
|
||||
* context contains the role to allow controllers to download specific
|
||||
* role {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE}
|
||||
*/
|
||||
public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
||||
* {@link SpPermission#CREATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||
+ CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
|
||||
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
||||
* {@link SpPermission#READ_TARGET}
|
||||
* {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = HAS_AUTH_PREFIX
|
||||
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX;
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
|
||||
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
||||
* {@link SpPermission#UPDATE_TARGET}.
|
||||
* {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET
|
||||
+ HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#TENANT_CONFIGURATION}
|
||||
* context contains {@link SpPermission#TENANT_CONFIGURATION} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#SYSTEM_MONITOR}
|
||||
* context contains {@link SpPermission#SYSTEM_MONITOR} or
|
||||
* {@link #IS_SYSTEM_CODE}.
|
||||
*/
|
||||
public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX;
|
||||
public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX
|
||||
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||
|
||||
private SpringEvalExpressions() {
|
||||
// utility class
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.eclipse.hawkbit.security;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
@@ -80,32 +81,37 @@ public class SecurityContextTenantAware implements TenantAware {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object another) {
|
||||
return delegate.equals(another);
|
||||
if (delegate != null) {
|
||||
return delegate.equals(another);
|
||||
} else if (another == null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
return (delegate != null) ? delegate.toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
return (delegate != null) ? delegate.hashCode() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
return (delegate != null) ? delegate.getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return delegate.getAuthorities();
|
||||
return (delegate != null) ? delegate.getAuthorities() : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return delegate.getCredentials();
|
||||
return (delegate != null) ? delegate.getCredentials() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,16 +121,19 @@ public class SecurityContextTenantAware implements TenantAware {
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return delegate.getPrincipal();
|
||||
return (delegate != null) ? delegate.getPrincipal() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return delegate.isAuthenticated();
|
||||
return (delegate != null) ? delegate.isAuthenticated() : true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
|
||||
public void setAuthenticated(final boolean isAuthenticated) {
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
delegate.setAuthenticated(isAuthenticated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ public class SystemSecurityContext {
|
||||
* The security context will be switched to the system code and back after
|
||||
* the callable is called.
|
||||
*
|
||||
* The system code is executed for a current tenant by using the
|
||||
* {@link TenantAware#getCurrentTenant()}.
|
||||
*
|
||||
* @param callable
|
||||
* the callable to call within the system security context
|
||||
* @return the return value of the {@link Callable#call()} method.
|
||||
@@ -67,12 +70,36 @@ public class SystemSecurityContext {
|
||||
// Exception squid:S2221 - Callable declares Exception
|
||||
@SuppressWarnings("squid:S2221")
|
||||
public <T> T runAsSystem(final Callable<T> callable) {
|
||||
return runAsSystemAsTenant(callable, tenantAware.getCurrentTenant());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a given {@link Callable} within a system security context, which is
|
||||
* permitted to call secured system code. Often the system needs to call
|
||||
* secured methods by it's own without relying on the current security
|
||||
* context e.g. if the current security context does not contain the
|
||||
* necessary permission it's necessary to execute code as system code to
|
||||
* execute necessary methods and functionality.
|
||||
*
|
||||
* The security context will be switched to the system code and back after
|
||||
* the callable is called.
|
||||
*
|
||||
* The system code is executed for a specific given tenant by using the
|
||||
* {@link TenantAware}.
|
||||
*
|
||||
* @param callable
|
||||
* the callable to call within the system security context
|
||||
* @param tenant
|
||||
* the tenant to act as system code
|
||||
* @return the return value of the {@link Callable#call()} method.
|
||||
*/
|
||||
public <T> T runAsSystemAsTenant(final Callable<T> callable, final String tenant) {
|
||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||
try {
|
||||
logger.debug("entering system code execution");
|
||||
return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), () -> {
|
||||
return tenantAware.runAsTenant(tenant, () -> {
|
||||
try {
|
||||
setSystemContext(oldContext);
|
||||
setSystemContext(SecurityContextHolder.getContext());
|
||||
return callable.call();
|
||||
} catch (final Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
@@ -100,6 +127,13 @@ public class SystemSecurityContext {
|
||||
SecurityContextHolder.setContext(securityContextImpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of the Spring's {@link Authentication} object which is
|
||||
* used within a system security code block and wraps the original
|
||||
* authentication object. The wrapped object contains the necessary
|
||||
* {@link SpringEvalExpressions#SYSTEM_ROLE} which is allowed to execute all
|
||||
* secured methods.
|
||||
*/
|
||||
public static class SystemCodeAuthentication implements Authentication {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -200,6 +200,10 @@
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
|
||||
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.artifacts.smtable;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
@@ -18,18 +20,17 @@ import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
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.addons.lazyquerycontainer.BeanQueryFactory;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
|
||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
@@ -38,8 +39,6 @@ import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
@@ -66,8 +65,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
@Autowired
|
||||
private transient EntityFactory entityFactory;
|
||||
|
||||
private Label mandatoryLabel;
|
||||
|
||||
private TextField nameTextField;
|
||||
|
||||
private TextField versionTextField;
|
||||
@@ -80,14 +77,20 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
|
||||
private CommonDialogWindow window;
|
||||
|
||||
private String oldDescriptionValue;
|
||||
|
||||
private String oldVendorValue;
|
||||
|
||||
private Boolean editSwModule = Boolean.FALSE;
|
||||
|
||||
private Long baseSwModuleId;
|
||||
|
||||
private FormLayout formLayout;
|
||||
|
||||
/**
|
||||
* Initialize Distribution Add and Edit Window.
|
||||
*/
|
||||
@PostConstruct
|
||||
void init() {
|
||||
createRequiredComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create window for new software module.
|
||||
*
|
||||
@@ -95,11 +98,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
* module.
|
||||
*/
|
||||
public CommonDialogWindow createAddSoftwareModuleWindow() {
|
||||
|
||||
editSwModule = Boolean.FALSE;
|
||||
createRequiredComponents();
|
||||
createWindow();
|
||||
return window;
|
||||
return createUpdateSoftwareModuleWindow(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,17 +109,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
* @return reference of {@link com.vaadin.ui.Window} to update software
|
||||
* module.
|
||||
*/
|
||||
public Window createUpdateSoftwareModuleWindow(final Long baseSwModuleId) {
|
||||
|
||||
editSwModule = Boolean.TRUE;
|
||||
public CommonDialogWindow createUpdateSoftwareModuleWindow(final Long baseSwModuleId) {
|
||||
this.baseSwModuleId = baseSwModuleId;
|
||||
createRequiredComponents();
|
||||
createWindow();
|
||||
/* populate selected target values to edit. */
|
||||
resetComponents();
|
||||
populateValuesOfSwModule();
|
||||
nameTextField.setEnabled(false);
|
||||
versionTextField.setEnabled(false);
|
||||
typeComboBox.setEnabled(false);
|
||||
createWindow();
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -145,13 +138,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
||||
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION);
|
||||
addDescriptionTextChangeListener();
|
||||
addVendorTextChangeListener();
|
||||
|
||||
/* Label for mandatory symbol */
|
||||
mandatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
||||
mandatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
mandatoryLabel.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
|
||||
typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true,
|
||||
null, i18n.get("upload.swmodule.type"));
|
||||
@@ -159,46 +145,34 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY);
|
||||
typeComboBox.setNewItemsAllowed(Boolean.FALSE);
|
||||
typeComboBox.setImmediate(Boolean.TRUE);
|
||||
|
||||
populateTypeNameCombo();
|
||||
|
||||
resetOldValues();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void populateTypeNameCombo() {
|
||||
typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer(
|
||||
new BeanQueryFactory<SoftwareModuleTypeBeanQuery>(SoftwareModuleTypeBeanQuery.class)));
|
||||
typeComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||
|
||||
}
|
||||
|
||||
private void resetOldValues() {
|
||||
oldDescriptionValue = null;
|
||||
oldVendorValue = null;
|
||||
private void resetComponents() {
|
||||
|
||||
vendorTextField.clear();
|
||||
nameTextField.clear();
|
||||
versionTextField.clear();
|
||||
descTextArea.clear();
|
||||
typeComboBox.clear();
|
||||
editSwModule = Boolean.FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the window content and get an instance of customDialogWindow
|
||||
*
|
||||
*/
|
||||
private void createWindow() {
|
||||
|
||||
final Label madatoryStarLabel = new Label("*");
|
||||
madatoryStarLabel.setStyleName("v-caption v-required-field-indicator");
|
||||
madatoryStarLabel.setWidth(null);
|
||||
|
||||
/*
|
||||
* The main layout of the window contains mandatory info, textboxes
|
||||
* (controller Id, name & description) and action buttons layout
|
||||
*/
|
||||
addStyleName("lay-color");
|
||||
setSizeUndefined();
|
||||
|
||||
final FormLayout formLayout = new FormLayout();
|
||||
formLayout.addComponent(mandatoryLabel);
|
||||
formLayout = new FormLayout();
|
||||
formLayout.setCaption(null);
|
||||
formLayout.addComponent(typeComboBox);
|
||||
formLayout.addComponent(nameTextField);
|
||||
formLayout.addComponent(versionTextField);
|
||||
@@ -207,24 +181,17 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
|
||||
setCompositionRoot(formLayout);
|
||||
|
||||
/* add main layout to the window */
|
||||
window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null);
|
||||
window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), null, null, formLayout, i18n);
|
||||
window.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
||||
nameTextField.focus();
|
||||
|
||||
nameTextField.setEnabled(!editSwModule);
|
||||
versionTextField.setEnabled(!editSwModule);
|
||||
typeComboBox.setEnabled(!editSwModule);
|
||||
|
||||
typeComboBox.focus();
|
||||
}
|
||||
|
||||
private void addDescriptionTextChangeListener() {
|
||||
descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event)));
|
||||
}
|
||||
|
||||
private void addVendorTextChangeListener() {
|
||||
vendorTextField.addTextChangeListener(event -> window.setSaveButtonEnabled(hasVendorChanged(event)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new SW module.
|
||||
*/
|
||||
private void addNewBaseSoftware() {
|
||||
final String name = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
||||
final String version = HawkbitCommonUtil.trimAndNullIfEmpty(versionTextField.getValue());
|
||||
@@ -232,10 +199,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||
final String type = typeComboBox.getValue() != null ? typeComboBox.getValue().toString() : null;
|
||||
|
||||
if (!mandatoryCheck(name, version, type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (HawkbitCommonUtil.isDuplicate(name, version, type)) {
|
||||
uiNotifcation.displayValidationError(
|
||||
i18n.get("message.duplicate.softwaremodule", new Object[] { name, version }));
|
||||
@@ -248,8 +211,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
new Object[] { newBaseSoftwareModule.getName() + ":" + newBaseSoftwareModule.getVersion() }));
|
||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.NEW_ENTITY, newBaseSoftwareModule));
|
||||
}
|
||||
// close the window
|
||||
closeThisWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,13 +230,16 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
|
||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.UPDATED_ENTITY, newSWModule));
|
||||
}
|
||||
closeThisWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* fill the data of a softwareModule in the content of the window
|
||||
*/
|
||||
private void populateValuesOfSwModule() {
|
||||
if (baseSwModuleId == null) {
|
||||
return;
|
||||
}
|
||||
editSwModule = Boolean.TRUE;
|
||||
final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId);
|
||||
nameTextField.setValue(swModle.getName());
|
||||
versionTextField.setValue(swModle.getVersion());
|
||||
@@ -283,49 +247,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getVendor()));
|
||||
descTextArea.setValue(swModle.getDescription() == null ? HawkbitCommonUtil.SP_STRING_EMPTY
|
||||
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getDescription()));
|
||||
oldDescriptionValue = descTextArea.getValue();
|
||||
oldVendorValue = vendorTextField.getValue();
|
||||
if (swModle.getType().isDeleted()) {
|
||||
typeComboBox.addItem(swModle.getType().getName());
|
||||
}
|
||||
typeComboBox.setValue(swModle.getType().getName());
|
||||
window.setSaveButtonEnabled(Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to close window.
|
||||
*/
|
||||
private void closeThisWindow() {
|
||||
window.close();
|
||||
UI.getCurrent().removeWindow(window);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation check - Mandatory.
|
||||
*
|
||||
* @param name
|
||||
* as String
|
||||
* @param version
|
||||
* as version
|
||||
* @return boolena as flag
|
||||
*/
|
||||
private boolean mandatoryCheck(final String name, final String version, final String type) {
|
||||
boolean isValid = true;
|
||||
if (name == null || version == null || type == null) {
|
||||
if (name == null) {
|
||||
nameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
}
|
||||
if (version == null) {
|
||||
versionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
}
|
||||
if (type == null) {
|
||||
typeComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
||||
}
|
||||
|
||||
uiNotifcation.displayValidationError(i18n.get("message.mandatory.check"));
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private void saveOrUpdate() {
|
||||
@@ -336,12 +261,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasDescriptionChanged(final TextChangeEvent event) {
|
||||
return !(event.getText().equals(oldDescriptionValue) && vendorTextField.getValue().equals(oldVendorValue));
|
||||
}
|
||||
|
||||
private boolean hasVendorChanged(final TextChangeEvent event) {
|
||||
return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue));
|
||||
public FormLayout getFormLayout() {
|
||||
return formLayout;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,11 +8,17 @@
|
||||
*/
|
||||
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.SoftwareModuleMetadata;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
|
||||
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
|
||||
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.distributions.event.MetadataEvent;
|
||||
import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -45,6 +51,44 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
|
||||
@Autowired
|
||||
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
|
||||
protected String getEditButtonId() {
|
||||
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(createDescriptionLayout(), getI18n().get("caption.tab.description"), null);
|
||||
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
|
||||
detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onEdit(final ClickEvent event) {
|
||||
final Window addSoftwareModule = softwareModuleAddUpdateWindow
|
||||
@@ -81,6 +126,8 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
|
||||
updateSoftwareModuleDetailsLayout(HawkbitCommonUtil.SP_STRING_EMPTY, HawkbitCommonUtil.SP_STRING_EMPTY,
|
||||
maxAssign);
|
||||
}
|
||||
|
||||
populateMetadataDetails();
|
||||
}
|
||||
|
||||
private void updateSoftwareModuleDetailsLayout(final String type, final String vendor, final String maxAssign) {
|
||||
@@ -141,4 +188,38 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
|
||||
protected String getDetailsHeaderCaptionId() {
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.common.table.AbstractNamedVersionTable;
|
||||
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.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.TableColumn;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||
@@ -38,13 +42,15 @@ import com.vaadin.data.Item;
|
||||
import com.vaadin.event.dd.DragAndDropEvent;
|
||||
import com.vaadin.event.dd.DropHandler;
|
||||
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Header of Software module table.
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
@@ -60,6 +66,9 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
|
||||
@Autowired
|
||||
private UploadViewAcceptCriteria uploadViewAcceptCriteria;
|
||||
|
||||
@Autowired
|
||||
private SwMetadataPopupLayout swMetadataPopupLayout;
|
||||
|
||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||
void onEvent(final SMFilterEvent filterEvent) {
|
||||
@@ -179,10 +188,26 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
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
|
||||
protected List<TableColumn> getTableVisibleColumns() {
|
||||
final List<TableColumn> columnList = super.getTableVisibleColumns();
|
||||
if (!isMaximized()) {
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.METADATA_ICON, "", 0.1F));
|
||||
return columnList;
|
||||
}
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, i18n.get("header.vendor"), 0.1F));
|
||||
@@ -212,4 +237,26 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtype;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum;
|
||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants;
|
||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
||||
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
@@ -34,12 +32,10 @@ import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.shared.ui.colorpicker.Color;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button.ClickEvent;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.OptionGroup;
|
||||
import com.vaadin.ui.components.colorpicker.ColorChangeListener;
|
||||
import com.vaadin.ui.components.colorpicker.ColorSelector;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
@@ -48,8 +44,7 @@ import com.vaadin.ui.themes.ValoTheme;
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
implements ColorChangeListener, ColorSelector {
|
||||
public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout {
|
||||
|
||||
private static final long serialVersionUID = -5169398523815919367L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class);
|
||||
@@ -69,7 +64,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
@Override
|
||||
protected void addListeners() {
|
||||
super.addListeners();
|
||||
optiongroup.addValueChangeListener(this::createOptionValueChanged);
|
||||
optiongroup.addValueChangeListener(this::optionValueChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,7 +90,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "",
|
||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
|
||||
tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC);
|
||||
tagDesc.setImmediate(true);
|
||||
tagDesc.setNullRepresentation("");
|
||||
@@ -113,10 +107,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWindow() {
|
||||
reset();
|
||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null);
|
||||
protected String getWindowCaption() {
|
||||
return i18n.get("caption.add.type");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,15 +118,16 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
* ValueChangeEvent
|
||||
*/
|
||||
@Override
|
||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
||||
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||
|
||||
super.createOptionValueChanged(event);
|
||||
super.optionValueChanged(event);
|
||||
|
||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||
assignOptiongroup.setEnabled(false);
|
||||
} else {
|
||||
assignOptiongroup.setEnabled(true);
|
||||
}
|
||||
assignOptiongroup.select(singleAssignStr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,12 +164,11 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
if (null != selectedTypeTag) {
|
||||
tagDesc.setValue(selectedTypeTag.getDescription());
|
||||
typeKey.setValue(selectedTypeTag.getKey());
|
||||
if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) {
|
||||
assignOptiongroup.setValue(multiAssignStr);
|
||||
} else {
|
||||
if (selectedTypeTag.getMaxAssignments() == 1) {
|
||||
assignOptiongroup.setValue(singleAssignStr);
|
||||
} else {
|
||||
assignOptiongroup.setValue(multiAssignStr);
|
||||
}
|
||||
|
||||
setColorPickerComponentsColor(selectedTypeTag.getColour());
|
||||
}
|
||||
}
|
||||
@@ -198,10 +190,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
|
||||
@Override
|
||||
protected void save(final ClickEvent event) {
|
||||
if (!mandatoryValuesPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SoftwareModuleType existingSMTypeByKey = swTypeManagementService
|
||||
.findSoftwareModuleTypeByKey(typeKey.getValue());
|
||||
final SoftwareModuleType existingSMTypeByName = swTypeManagementService
|
||||
@@ -211,7 +199,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
createNewSWModuleType();
|
||||
}
|
||||
} else {
|
||||
|
||||
updateSWModuleType(existingSMTypeByName);
|
||||
}
|
||||
}
|
||||
@@ -233,22 +220,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
SoftwareModuleType newSWType = entityFactory.generateSoftwareModuleType(typeKeyValue, typeNameValue,
|
||||
typeDescValue, assignNumber);
|
||||
newSWType.setColour(colorPicked);
|
||||
|
||||
if (null != typeDescValue) {
|
||||
newSWType.setDescription(typeDescValue);
|
||||
}
|
||||
|
||||
newSWType.setDescription(typeDescValue);
|
||||
newSWType.setColour(colorPicked);
|
||||
|
||||
newSWType = swTypeManagementService.createSoftwareModuleType(newSWType);
|
||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() }));
|
||||
closeWindow();
|
||||
eventBus.publish(this,
|
||||
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType));
|
||||
|
||||
} else {
|
||||
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,51 +237,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
||||
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
||||
if (null != typeNameValue) {
|
||||
existingType.setName(typeNameValue);
|
||||
|
||||
existingType.setDescription(null != typeDescValue ? typeDescValue : null);
|
||||
|
||||
existingType.setDescription(typeDescValue);
|
||||
existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()));
|
||||
swTypeManagementService.updateSoftwareModuleType(existingType);
|
||||
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() }));
|
||||
closeWindow();
|
||||
eventBus.publish(this,
|
||||
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType));
|
||||
|
||||
} else {
|
||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open color picker on click of preview button. Auto select the color based
|
||||
* on target tag if already selected.
|
||||
*/
|
||||
@Override
|
||||
protected void previewButtonClicked() {
|
||||
if (!tagPreviewBtnClicked) {
|
||||
final String selectedOption = (String) optiongroup.getValue();
|
||||
if (StringUtils.isNotEmpty(selectedOption) && selectedOption.equalsIgnoreCase(updateTypeStr)) {
|
||||
if (null != tagNameComboBox.getValue()) {
|
||||
final SoftwareModuleType typeSelected = swTypeManagementService
|
||||
.findSoftwareModuleTypeByName(tagNameComboBox.getValue().toString());
|
||||
if (null != typeSelected) {
|
||||
getColorPickerLayout().setSelectedColor(typeSelected.getColour() != null
|
||||
? ColorPickerHelper.rgbToColorConverter(typeSelected.getColour())
|
||||
: ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||
}
|
||||
} else {
|
||||
getColorPickerLayout().setSelectedColor(
|
||||
ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||
}
|
||||
}
|
||||
getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor());
|
||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
||||
} else {
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
}
|
||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Set;
|
||||
|
||||
import org.eclipse.hawkbit.ui.common.CoordinatesToColor;
|
||||
import org.eclipse.hawkbit.ui.management.tag.SpColorPickerPreview;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
|
||||
import com.vaadin.shared.ui.colorpicker.Color;
|
||||
import com.vaadin.ui.AbstractColorPicker.Coordinates2Color;
|
||||
@@ -47,6 +48,7 @@ public class ColorPickerLayout extends GridLayout {
|
||||
|
||||
setColumns(2);
|
||||
setRows(4);
|
||||
setId(SPUIComponentIdProvider.COLOR_PICKER_LAYOUT);
|
||||
|
||||
init();
|
||||
|
||||
@@ -71,6 +73,7 @@ public class ColorPickerLayout extends GridLayout {
|
||||
colorSelect.setWidth("220px");
|
||||
|
||||
redSlider = createRGBSlider("", "red");
|
||||
redSlider.setId(SPUIComponentIdProvider.COLOR_PICKER_RED_SLIDER);
|
||||
greenSlider = createRGBSlider("", "green");
|
||||
blueSlider = createRGBSlider("", "blue");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,32 +10,69 @@ package org.eclipse.hawkbit.ui.common;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
||||
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
|
||||
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.vaadin.data.Container.ItemSetChangeEvent;
|
||||
import com.vaadin.data.Container.ItemSetChangeListener;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.data.Property.ValueChangeListener;
|
||||
import com.vaadin.data.Validator;
|
||||
import com.vaadin.data.validator.NullValidator;
|
||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
||||
import com.vaadin.event.FieldEvents.TextChangeListener;
|
||||
import com.vaadin.event.FieldEvents.TextChangeNotifier;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.ui.AbstractComponent;
|
||||
import com.vaadin.ui.AbstractField;
|
||||
import com.vaadin.ui.AbstractLayout;
|
||||
import com.vaadin.ui.AbstractOrderedLayout;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Button.ClickListener;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Field;
|
||||
import com.vaadin.ui.GridLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Link;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* Superclass for pop-up-windows including a minimize and close icon in the
|
||||
* upper right corner and a save and cancel button at the bottom.
|
||||
*
|
||||
* Table pop-up-windows including a minimize and close icon in the upper right
|
||||
* corner and a save and cancel button at the bottom. Is not intended to reuse.
|
||||
*
|
||||
*/
|
||||
public class CommonDialogWindow extends Window {
|
||||
public class CommonDialogWindow extends Window implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1321949234316858703L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final VerticalLayout mainLayout = new VerticalLayout();
|
||||
|
||||
@@ -57,6 +94,14 @@ public class CommonDialogWindow extends Window {
|
||||
|
||||
private final ClickListener cancelButtonClickListener;
|
||||
|
||||
private final ClickListener close = event -> close();
|
||||
|
||||
private final transient Map<Component, Object> orginalValues;
|
||||
|
||||
private final List<AbstractField<?>> allComponents;
|
||||
|
||||
private final I18N i18n;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -72,38 +117,273 @@ public class CommonDialogWindow extends Window {
|
||||
* the cancelButtonClickListener
|
||||
*/
|
||||
public CommonDialogWindow(final String caption, final Component content, final String helpLink,
|
||||
final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener) {
|
||||
final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener,
|
||||
final AbstractLayout layout, final I18N i18n) {
|
||||
checkNotNull(saveButtonClickListener);
|
||||
checkNotNull(cancelButtonClickListener);
|
||||
this.caption = caption;
|
||||
this.content = content;
|
||||
this.helpLink = helpLink;
|
||||
this.saveButtonClickListener = saveButtonClickListener;
|
||||
this.cancelButtonClickListener = cancelButtonClickListener;
|
||||
|
||||
this.orginalValues = new HashMap<>();
|
||||
this.allComponents = getAllComponents(layout);
|
||||
this.i18n = i18n;
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
orginalValues.clear();
|
||||
removeListeners();
|
||||
allComponents.clear();
|
||||
this.saveButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
for (final AbstractField<?> field : allComponents) {
|
||||
removeTextListener(field);
|
||||
removeValueChangeListener(field);
|
||||
removeItemSetChangeistener(field);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeItemSetChangeistener(final AbstractField<?> field) {
|
||||
if (!(field instanceof Table)) {
|
||||
return;
|
||||
}
|
||||
for (final Object listener : field.getListeners(ItemSetChangeEvent.class)) {
|
||||
if (listener instanceof ChangeListener) {
|
||||
((Table) field).removeItemSetChangeListener((ChangeListener) listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTextListener(final AbstractField<?> field) {
|
||||
if (!(field instanceof TextChangeNotifier)) {
|
||||
return;
|
||||
}
|
||||
for (final Object listener : field.getListeners(TextChangeEvent.class)) {
|
||||
if (listener instanceof ChangeListener) {
|
||||
((TextChangeNotifier) field).removeTextChangeListener((ChangeListener) listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeValueChangeListener(final AbstractField<?> field) {
|
||||
for (final Object listener : field.getListeners(ValueChangeEvent.class)) {
|
||||
if (listener instanceof ChangeListener) {
|
||||
field.removeValueChangeListener((ChangeListener) listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void init() {
|
||||
|
||||
if (content instanceof AbstractOrderedLayout) {
|
||||
((AbstractOrderedLayout) content).setSpacing(true);
|
||||
((AbstractOrderedLayout) content).setMargin(true);
|
||||
}
|
||||
if (content instanceof GridLayout) {
|
||||
addStyleName("marginTop");
|
||||
}
|
||||
|
||||
if (null != content) {
|
||||
mainLayout.addComponent(content);
|
||||
mainLayout.setExpandRatio(content, 1.0F);
|
||||
}
|
||||
|
||||
createMandatoryLabel();
|
||||
|
||||
final HorizontalLayout buttonLayout = createActionButtonsLayout();
|
||||
mainLayout.addComponent(buttonLayout);
|
||||
mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER);
|
||||
|
||||
setCaption(caption);
|
||||
setCaptionAsHtml(true);
|
||||
setContent(mainLayout);
|
||||
setResizable(false);
|
||||
center();
|
||||
setModal(true);
|
||||
addStyleName("fontsize");
|
||||
setOrginaleValues();
|
||||
addListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the original values in a Map so we can use them for detecting
|
||||
* changes
|
||||
*/
|
||||
public final void setOrginaleValues() {
|
||||
for (final AbstractField<?> field : allComponents) {
|
||||
Object value = field.getValue();
|
||||
|
||||
if (field instanceof Table) {
|
||||
value = Sets.newHashSet(((Table) field).getContainerDataSource().getItemIds());
|
||||
}
|
||||
orginalValues.put(field, value);
|
||||
}
|
||||
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null));
|
||||
}
|
||||
|
||||
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) {
|
||||
if (field instanceof TextChangeNotifier) {
|
||||
((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field));
|
||||
}
|
||||
|
||||
if (field instanceof Table) {
|
||||
((Table) field).addItemSetChangeListener(new ChangeListener(field));
|
||||
} else {
|
||||
field.addValueChangeListener(new ChangeListener(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent,
|
||||
final Object newValue) {
|
||||
return isMandatoryFieldNotEmptyAndValid(currentChangedComponent, newValue)
|
||||
&& isValuesChanged(currentChangedComponent, newValue);
|
||||
}
|
||||
|
||||
private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) {
|
||||
for (final AbstractField<?> field : allComponents) {
|
||||
Object originalValue = orginalValues.get(field);
|
||||
if (field instanceof CheckBox && originalValue == null) {
|
||||
originalValue = Boolean.FALSE;
|
||||
}
|
||||
final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field);
|
||||
|
||||
if (!isValueEquals(field, originalValue, currentValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValueEquals(final AbstractField<?> field, final Object orginalValue, final Object currentValue) {
|
||||
if (Set.class.equals(field.getType())) {
|
||||
return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection<?>) orginalValue),
|
||||
CollectionUtils.emptyIfNull((Collection<?>) currentValue));
|
||||
}
|
||||
|
||||
if (String.class.equals(field.getType())) {
|
||||
return Objects.equals(Strings.emptyToNull((String) orginalValue),
|
||||
Strings.emptyToNull((String) currentValue));
|
||||
}
|
||||
|
||||
return Objects.equals(orginalValue, currentValue);
|
||||
}
|
||||
|
||||
private Object getCurrentVaue(final Component currentChangedComponent, final Object newValue,
|
||||
final AbstractField<?> field) {
|
||||
Object currentValue = field.getValue();
|
||||
if (field instanceof Table) {
|
||||
currentValue = ((Table) field).getContainerDataSource().getItemIds();
|
||||
}
|
||||
|
||||
if (field.equals(currentChangedComponent)) {
|
||||
currentValue = newValue;
|
||||
}
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
private boolean shouldMandatoryLabelShown() {
|
||||
for (final AbstractField<?> field : allComponents) {
|
||||
if (field.isRequired()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isMandatoryFieldNotEmptyAndValid(final Component currentChangedComponent, final Object newValue) {
|
||||
|
||||
boolean valid = true;
|
||||
final List<AbstractField<?>> requiredComponents = allComponents.stream().filter(field -> field.isRequired())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList()));
|
||||
|
||||
for (final AbstractField field : requiredComponents) {
|
||||
Object value = getCurrentVaue(currentChangedComponent, newValue, field);
|
||||
|
||||
if (String.class.equals(field.getType())) {
|
||||
value = Strings.emptyToNull((String) value);
|
||||
}
|
||||
|
||||
if (Set.class.equals(field.getType())) {
|
||||
value = emptyToNull((Collection<?>) value);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to loop through the entire loop for validity testing.
|
||||
// Otherwise the UI will only mark the
|
||||
// first field with errors and then stop. If there are several
|
||||
// fields with errors, this is bad.
|
||||
field.setValue(value);
|
||||
if (!field.isValid()) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
private static Object emptyToNull(final Collection<?> c) {
|
||||
return (c == null || c.isEmpty()) ? null : c;
|
||||
}
|
||||
|
||||
private boolean hasNullValidator(final Component component) {
|
||||
|
||||
if (component instanceof AbstractField<?>) {
|
||||
final AbstractField<?> fieldComponent = (AbstractField<?>) component;
|
||||
for (final Validator validator : fieldComponent.getValidators()) {
|
||||
if (validator instanceof NullValidator) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<AbstractField<?>> getAllComponents(final AbstractLayout abstractLayout) {
|
||||
final List<AbstractField<?>> components = new ArrayList<>();
|
||||
|
||||
final Iterator<Component> iterate = abstractLayout.iterator();
|
||||
while (iterate.hasNext()) {
|
||||
final Component c = iterate.next();
|
||||
if (c instanceof AbstractLayout) {
|
||||
components.addAll(getAllComponents((AbstractLayout) c));
|
||||
}
|
||||
|
||||
if (c instanceof AbstractField) {
|
||||
components.add((AbstractField<?>) c);
|
||||
}
|
||||
|
||||
if (c instanceof FlexibleOptionGroupItemComponent) {
|
||||
components.add(((FlexibleOptionGroupItemComponent) c).getOwner());
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
private HorizontalLayout createActionButtonsLayout() {
|
||||
@@ -111,23 +391,45 @@ public class CommonDialogWindow extends Window {
|
||||
buttonsLayout = new HorizontalLayout();
|
||||
buttonsLayout.setSizeFull();
|
||||
buttonsLayout.setSpacing(true);
|
||||
buttonsLayout.setSpacing(true);
|
||||
buttonsLayout.addStyleName("actionButtonsMargin");
|
||||
|
||||
createSaveButton();
|
||||
|
||||
createCancelButton();
|
||||
buttonsLayout.addStyleName("actionButtonsMargin");
|
||||
|
||||
addHelpLink();
|
||||
|
||||
return buttonsLayout;
|
||||
}
|
||||
|
||||
private void createMandatoryLabel() {
|
||||
|
||||
if (!shouldMandatoryLabelShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
||||
mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY);
|
||||
|
||||
if (content instanceof TargetAddUpdateWindowLayout) {
|
||||
((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel);
|
||||
} else if (content instanceof SoftwareModuleAddUpdateWindow) {
|
||||
((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel);
|
||||
} else if (content instanceof AbstractCreateUpdateTagLayout) {
|
||||
((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel);
|
||||
}
|
||||
|
||||
mainLayout.addComponent(mandatoryLabel);
|
||||
}
|
||||
|
||||
private void createCancelButton() {
|
||||
cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true,
|
||||
FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class);
|
||||
FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class);
|
||||
cancelButton.setSizeUndefined();
|
||||
cancelButton.addStyleName("default-color");
|
||||
cancelButton.addClickListener(cancelButtonClickListener);
|
||||
if (cancelButtonClickListener != null) {
|
||||
cancelButton.addClickListener(cancelButtonClickListener);
|
||||
}
|
||||
|
||||
buttonsLayout.addComponent(cancelButton);
|
||||
buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT);
|
||||
@@ -136,10 +438,11 @@ public class CommonDialogWindow extends Window {
|
||||
|
||||
private void createSaveButton() {
|
||||
saveButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.SAVE_BUTTON, "Save", "", "", true,
|
||||
FontAwesome.SAVE, SPUIButtonStyleBorderWithIcon.class);
|
||||
FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class);
|
||||
saveButton.setSizeUndefined();
|
||||
saveButton.addStyleName("default-color");
|
||||
saveButton.addClickListener(saveButtonClickListener);
|
||||
saveButton.setEnabled(false);
|
||||
buttonsLayout.addComponent(saveButton);
|
||||
buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT);
|
||||
buttonsLayout.setExpandRatio(saveButton, 1.0F);
|
||||
@@ -155,6 +458,58 @@ public class CommonDialogWindow extends Window {
|
||||
buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT);
|
||||
}
|
||||
|
||||
public AbstractComponent getButtonsLayout() {
|
||||
return this.buttonsLayout;
|
||||
}
|
||||
|
||||
private class ChangeListener implements ValueChangeListener, TextChangeListener, ItemSetChangeListener {
|
||||
|
||||
private final Field<?> field;
|
||||
|
||||
public ChangeListener(final Field<?> field) {
|
||||
super();
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void textChange(final TextChangeEvent event) {
|
||||
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChange(final ValueChangeEvent event) {
|
||||
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, field.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void containerItemSetChange(final ItemSetChangeEvent event) {
|
||||
if (!(field instanceof Table)) {
|
||||
return;
|
||||
}
|
||||
final Table table = (Table) field;
|
||||
saveButton.setEnabled(
|
||||
isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the component manually to the allComponents-List and adds a
|
||||
* ValueChangeListener to it. Necessary in Update Distribution Type as the
|
||||
* CheckBox concerned is an ItemProperty...
|
||||
*
|
||||
* @param component
|
||||
* AbstractField
|
||||
*/
|
||||
public void updateAllComponents(final AbstractField component) {
|
||||
|
||||
allComponents.add(component);
|
||||
component.addValueChangeListener(new ChangeListener(component));
|
||||
}
|
||||
|
||||
public VerticalLayout getMainLayout() {
|
||||
return mainLayout;
|
||||
}
|
||||
|
||||
public void setSaveButtonEnabled(final boolean enabled) {
|
||||
saveButton.setEnabled(enabled);
|
||||
}
|
||||
@@ -162,9 +517,4 @@ public class CommonDialogWindow extends Window {
|
||||
public void setCancelButtonEnabled(final boolean enabled) {
|
||||
cancelButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public HorizontalLayout getButtonsLayout() {
|
||||
return buttonsLayout;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
final Button cancelButton = SPUIComponentProvider.getButton(null, cancelLabel, "", null, false, null,
|
||||
SPUIButtonStyleTiny.class);
|
||||
cancelButton.addClickListener(this);
|
||||
cancelButton.setId(SPUIComponentIdProvider.CANCEL_BUTTON);
|
||||
window.setModal(true);
|
||||
window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_SYLE);
|
||||
if (this.callback == null) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,6 +63,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
|
||||
private Button editButton;
|
||||
|
||||
private Button manageMetadataBtn;
|
||||
|
||||
private TabSheet detailsTab;
|
||||
|
||||
private VerticalLayout detailsLayout;
|
||||
@@ -136,9 +138,15 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
SPUIButtonStyleSmallNoBorder.class);
|
||||
editButton.setId(getEditButtonId());
|
||||
editButton.addClickListener(this::onEdit);
|
||||
|
||||
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.setImmediate(true);
|
||||
detailsTab.setWidth(98, Unit.PERCENTAGE);
|
||||
@@ -156,6 +164,10 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
if (hasEditPermission()) {
|
||||
nameEditLayout.addComponent(editButton);
|
||||
nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT);
|
||||
if (isMetadataIconToBeDisplayed()) {
|
||||
nameEditLayout.addComponent(manageMetadataBtn);
|
||||
nameEditLayout.setComponentAlignment(manageMetadataBtn, Alignment.TOP_RIGHT);
|
||||
}
|
||||
}
|
||||
nameEditLayout.setExpandRatio(caption, 1.0F);
|
||||
nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
||||
@@ -201,6 +213,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
private void populateData(final T selectedBaseEntity) {
|
||||
this.selectedBaseEntity = selectedBaseEntity;
|
||||
editButton.setEnabled(selectedBaseEntity != null);
|
||||
manageMetadataBtn.setEnabled(selectedBaseEntity != null);
|
||||
if (selectedBaseEntity == null) {
|
||||
setName(getDefaultCaption(), StringUtils.EMPTY);
|
||||
} else {
|
||||
@@ -209,6 +222,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
populateLog();
|
||||
populateDescription();
|
||||
populateDetailsWidget();
|
||||
populateMetadataDetails();
|
||||
}
|
||||
|
||||
protected void populateLog() {
|
||||
@@ -281,8 +295,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
descriptionLayout = getTabLayout();
|
||||
return descriptionLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Default caption of header to be displayed when no data row selected in
|
||||
* table.
|
||||
*
|
||||
@@ -327,6 +341,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
}
|
||||
|
||||
protected abstract void populateDetailsWidget();
|
||||
|
||||
protected abstract void populateMetadataDetails();
|
||||
|
||||
protected Long getSelectedBaseEntityId() {
|
||||
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 getShowMetadataButtonId();
|
||||
|
||||
protected abstract Boolean isMetadataIconToBeDisplayed();
|
||||
|
||||
protected abstract void showMetadata(Button.ClickEvent event);
|
||||
|
||||
}
|
||||
|
||||
@@ -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, "") ));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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, "")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,8 @@ import com.vaadin.ui.Button.ClickEvent;
|
||||
*/
|
||||
public abstract class AbstractFilterMultiButtonClick extends AbstractFilterButtonClickBehaviour {
|
||||
|
||||
protected final Set<Button> alreadyClickedButtons = new HashSet<>();
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected final transient Set<Button> alreadyClickedButtons = new HashSet<>();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -95,9 +95,6 @@ public abstract class AbstractTable<E extends NamedEntity, I> extends Table {
|
||||
if (values == null) {
|
||||
values = Collections.emptySet();
|
||||
}
|
||||
if (values.contains(null)) {
|
||||
LOG.warn("Null values in table content. How could this happen?");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,6 @@ import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Abstract class for target/ds tag token layout.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractTagToken<T extends BaseEntity> implements Serializable {
|
||||
|
||||
@@ -58,9 +54,9 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
|
||||
|
||||
protected IndexedContainer container;
|
||||
|
||||
protected final Map<Long, TagData> tagDetails = new HashMap<>();
|
||||
protected final transient Map<Long, TagData> tagDetails = new HashMap<>();
|
||||
|
||||
protected final Map<Long, TagData> tokensAdded = new HashMap<>();
|
||||
protected final transient Map<Long, TagData> tokensAdded = new HashMap<>();
|
||||
|
||||
protected CssLayout tokenLayout = new CssLayout();
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator;
|
||||
@@ -33,10 +32,8 @@ import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.server.Resource;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Button.ClickListener;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Link;
|
||||
@@ -140,24 +137,6 @@ public final class SPUIComponentProvider {
|
||||
return SPUILabelDecorator.getDeocratedLabel(name, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get window component.
|
||||
*
|
||||
* @param caption
|
||||
* window caption
|
||||
* @param id
|
||||
* window id
|
||||
* @param type
|
||||
* type of window
|
||||
* @return Window
|
||||
*/
|
||||
public static CommonDialogWindow getWindow(final String caption, final String id, final String type,
|
||||
final Component content, final ClickListener saveButtonClickListener,
|
||||
final ClickListener cancelButtonClickListener, final String helpLink) {
|
||||
return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener,
|
||||
cancelButtonClickListener, helpLink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get window component.
|
||||
*
|
||||
@@ -204,6 +183,8 @@ public final class SPUIComponentProvider {
|
||||
/**
|
||||
* Get Label UI component. *
|
||||
*
|
||||
* @param caption
|
||||
* set the caption of the textArea
|
||||
* @param style
|
||||
* set style
|
||||
* @param styleName
|
||||
|
||||
@@ -8,39 +8,60 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.customrenderers.client.renderers;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.vaadin.client.renderers.ButtonRenderer;
|
||||
import com.vaadin.client.ui.VButton;
|
||||
import com.vaadin.client.widget.grid.RendererCellReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* Renders button with provided HTML content.
|
||||
* Used to display button with icons.
|
||||
*
|
||||
* Renders button with provided HTML content. Used to display button with icons.
|
||||
*/
|
||||
public class HtmlButtonRenderer extends ButtonRenderer {
|
||||
|
||||
public static final String DISABLE_VALUE = "_Disabled_";
|
||||
|
||||
@Override
|
||||
public void render(RendererCellReference cell, String text, Button button) {
|
||||
public void render(final RendererCellReference cell, final String text, final Button button) {
|
||||
final boolean buttonEnable = isButtonEnable(cell.getElement().getClassName());
|
||||
if (text != null) {
|
||||
button.setHTML(text);
|
||||
}
|
||||
applystyles(button);
|
||||
applystyles(button, buttonEnable);
|
||||
// this is to allow the button to disappear, if the text is null
|
||||
button.setVisible(text != null);
|
||||
button.getElement().setId("rollout.action.button.id");
|
||||
button.getElement().setId(SPUIComponentIdProvider.ROLLOUT_ACTION_ID + "." + cell.getColumnIndex());
|
||||
button.setEnabled(buttonEnable);
|
||||
}
|
||||
|
||||
private void applystyles(Button button) {
|
||||
/**
|
||||
* see here https://vaadin.com/forum#!/thread/9418390/9765924
|
||||
*
|
||||
* @param text
|
||||
* the button text
|
||||
* @return is button enable.
|
||||
*/
|
||||
private static boolean isButtonEnable(final String text) {
|
||||
return !text.contains(DISABLE_VALUE);
|
||||
}
|
||||
|
||||
private void applystyles(final Button button, final boolean buttonEnable) {
|
||||
|
||||
button.setStyleName(VButton.CLASSNAME);
|
||||
button.addStyleName(getStyle("tiny"));
|
||||
button.addStyleName(getStyle("borderless"));
|
||||
button.addStyleName(getStyle("icon-only"));
|
||||
button.addStyleName(getStyle("borderless-colored"));
|
||||
button.addStyleName(getStyle("button-no-border"));
|
||||
button.addStyleName(getStyle("action-type-padding"));
|
||||
|
||||
if (buttonEnable) {
|
||||
return;
|
||||
}
|
||||
button.addStyleName("v-disabled");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String getStyle(final String style) {
|
||||
return new StringBuilder(style).append(" ").append(VButton.CLASSNAME).append("-").append(style).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class HtmlButtonRenderer extends ButtonRenderer {
|
||||
* @param listener
|
||||
* RendererClickListener
|
||||
*/
|
||||
public HtmlButtonRenderer(RendererClickListener listener) {
|
||||
public HtmlButtonRenderer(final RendererClickListener listener) {
|
||||
super(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.decorators;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.vaadin.server.Resource;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Button with icon decorator.
|
||||
*
|
||||
* Decorator class for a borderless Button with an icon.
|
||||
*/
|
||||
public class SPUIButtonStyleBorderWithIcon implements SPUIButtonDecorator {
|
||||
public class SPUIButtonStyleNoBorderWithIcon implements SPUIButtonDecorator {
|
||||
|
||||
private Button button;
|
||||
|
||||
@@ -24,23 +25,25 @@ public class SPUIButtonStyleBorderWithIcon implements SPUIButtonDecorator {
|
||||
public Button decorate(final Button button, final String style, final boolean setStyle, final Resource icon) {
|
||||
|
||||
this.button = button;
|
||||
|
||||
setButtonStyle(style, setStyle);
|
||||
setButtonIcon(icon);
|
||||
button.setSizeFull();
|
||||
|
||||
button.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
button.setSizeFull();
|
||||
button.addStyleName(ValoTheme.BUTTON_BORDERLESS_COLORED);
|
||||
setOrAddButtonStyle(style, setStyle);
|
||||
|
||||
setButtonIcon(icon);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private void setButtonStyle(final String style, final boolean setStyle) {
|
||||
private void setOrAddButtonStyle(final String style, final boolean setStyle) {
|
||||
|
||||
if (style == null) {
|
||||
if (StringUtils.isEmpty(style)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (setStyle) {
|
||||
// overwrite all other styles
|
||||
button.setStyleName(style);
|
||||
} else {
|
||||
button.addStyleName(style);
|
||||
@@ -9,9 +9,12 @@
|
||||
package org.eclipse.hawkbit.ui.decorators;
|
||||
|
||||
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.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
|
||||
import com.vaadin.ui.AbstractLayout;
|
||||
import com.vaadin.ui.Button.ClickListener;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Window;
|
||||
@@ -42,27 +45,36 @@ public final class SPUIWindowDecorator {
|
||||
* window type
|
||||
* @return Window
|
||||
*/
|
||||
public static CommonDialogWindow getDeocratedWindow(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 ClickListener cancelButtonClickListener, final String helpLink) {
|
||||
final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout,
|
||||
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,
|
||||
cancelButtonClickListener);
|
||||
if (null != id) {
|
||||
window.setId(id);
|
||||
}
|
||||
if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) {
|
||||
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;
|
||||
}
|
||||
} else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) {
|
||||
window.setDraggable(true);
|
||||
window.setClosable(true);
|
||||
}
|
||||
}
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decorates window based on type.
|
||||
*
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.eclipse.hawkbit.ui.distributions.disttype;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
@@ -16,7 +17,6 @@ import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants;
|
||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
@@ -49,8 +49,6 @@ import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.components.colorpicker.ColorChangeListener;
|
||||
import com.vaadin.ui.components.colorpicker.ColorSelector;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
@@ -58,8 +56,7 @@ import com.vaadin.ui.themes.ValoTheme;
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
implements ColorChangeListener, ColorSelector {
|
||||
public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout {
|
||||
|
||||
private static final long serialVersionUID = -5169398523815877767L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class);
|
||||
@@ -82,8 +79,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
private Table sourceTable;
|
||||
private Table selectedTable;
|
||||
|
||||
private IndexedContainer selectedTablecontainer;
|
||||
private IndexedContainer sourceTablecontainer;
|
||||
private IndexedContainer selectedTableContainer;
|
||||
private IndexedContainer sourceTableContainer;
|
||||
|
||||
private IndexedContainer originalSelectedTableContainer;
|
||||
|
||||
private Map<CheckBox, Boolean> mandatoryCheckboxMap;
|
||||
|
||||
@Override
|
||||
protected void createRequiredComponents() {
|
||||
@@ -103,7 +104,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "",
|
||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
|
||||
tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC);
|
||||
tagDesc.setImmediate(true);
|
||||
tagDesc.setNullRepresentation("");
|
||||
@@ -159,9 +159,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
return twinColumnLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void buildSelectedTable() {
|
||||
|
||||
selectedTable = new Table();
|
||||
@@ -176,13 +173,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
selectedTable.addStyleName("dist_type_twin-table");
|
||||
selectedTable.setSizeFull();
|
||||
createSelectedTableContainer();
|
||||
selectedTable.setContainerDataSource(selectedTablecontainer);
|
||||
selectedTable.setContainerDataSource(selectedTableContainer);
|
||||
addTooltTipToSelectedTable();
|
||||
selectedTable.setImmediate(true);
|
||||
selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY);
|
||||
selectedTable.setColumnHeaders(i18n.get("header.dist.twintable.selected"), STAR);
|
||||
selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75f);
|
||||
selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25f);
|
||||
selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75F);
|
||||
selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25F);
|
||||
selectedTable.setRequired(true);
|
||||
}
|
||||
|
||||
private void addTooltTipToSelectedTable() {
|
||||
@@ -218,14 +216,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
sourceTable.addStyleName(ValoTheme.TABLE_SMALL);
|
||||
sourceTable.setImmediate(true);
|
||||
// sourceTable
|
||||
sourceTable.setSizeFull();
|
||||
sourceTable.addStyleName("dist_type_twin-table");
|
||||
sourceTable.setSortEnabled(false);
|
||||
sourceTablecontainer = new IndexedContainer();
|
||||
sourceTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||
sourceTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||
sourceTable.setContainerDataSource(sourceTablecontainer);
|
||||
sourceTableContainer = new IndexedContainer();
|
||||
sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||
sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||
sourceTable.setContainerDataSource(sourceTableContainer);
|
||||
|
||||
sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME });
|
||||
sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available"));
|
||||
@@ -237,20 +234,29 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
|
||||
private void createSelectedTableContainer() {
|
||||
|
||||
selectedTablecontainer = new IndexedContainer();
|
||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
||||
selectedTableContainer = new IndexedContainer();
|
||||
selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||
selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||
selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
||||
}
|
||||
|
||||
private void createOriginalSelectedTableContainer() {
|
||||
|
||||
originalSelectedTableContainer = new IndexedContainer();
|
||||
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addSMType() {
|
||||
|
||||
final Set<Long> selectedIds = (Set<Long>) sourceTable.getValue();
|
||||
if (null != selectedIds && !selectedIds.isEmpty()) {
|
||||
for (final Long id : selectedIds) {
|
||||
addTargetTableData(id);
|
||||
}
|
||||
if (selectedIds == null) {
|
||||
return;
|
||||
}
|
||||
for (final Long id : selectedIds) {
|
||||
addTargetTableData(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,23 +264,24 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Set<Long> selectedIds = (Set<Long>) selectedTable.getValue();
|
||||
if (null != selectedIds && !selectedIds.isEmpty()) {
|
||||
for (final Long id : selectedIds) {
|
||||
addSourceTableData(id);
|
||||
selectedTable.removeItem(id);
|
||||
}
|
||||
if (selectedIds == null) {
|
||||
return;
|
||||
}
|
||||
for (final Long id : selectedIds) {
|
||||
addSourceTableData(id);
|
||||
selectedTable.removeItem(id);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void getSourceTableData() {
|
||||
|
||||
sourceTablecontainer.removeAllItems();
|
||||
sourceTableContainer.removeAllItems();
|
||||
final Iterable<SoftwareModuleType> moduleTypeBeans = softwareManagement
|
||||
.findSoftwareModuleTypesAll(new PageRequest(0, 1_000));
|
||||
Item saveTblitem;
|
||||
for (final SoftwareModuleType swTypeTag : moduleTypeBeans) {
|
||||
saveTblitem = sourceTablecontainer.addItem(swTypeTag.getId());
|
||||
saveTblitem = sourceTableContainer.addItem(swTypeTag.getId());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription());
|
||||
}
|
||||
@@ -307,11 +314,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
private void getSelectedTableItemData(final Long id) {
|
||||
|
||||
Item saveTblitem;
|
||||
if (null != selectedTablecontainer) {
|
||||
saveTblitem = selectedTablecontainer.addItem(id);
|
||||
if (selectedTableContainer != null) {
|
||||
saveTblitem = selectedTableContainer.addItem(id);
|
||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(
|
||||
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox());
|
||||
final CheckBox mandatoryCheckBox = new CheckBox();
|
||||
window.updateAllComponents(mandatoryCheckBox);
|
||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox);
|
||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(
|
||||
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue());
|
||||
}
|
||||
@@ -320,10 +329,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addSourceTableData(final Long selectedId) {
|
||||
|
||||
if (null != sourceTablecontainer) {
|
||||
if (sourceTableContainer != null) {
|
||||
Item saveTblitem;
|
||||
saveTblitem = sourceTablecontainer.addItem(selectedId);
|
||||
selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME);
|
||||
saveTblitem = sourceTableContainer.addItem(selectedId);
|
||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource()
|
||||
.getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource()
|
||||
@@ -353,20 +361,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
final SoftwareModuleType swModuleType = softwareManagement.findSoftwareModuleTypeByName(distTypeName);
|
||||
checkMandatoryAndAddMandatoryModuleType(newDistType, isMandatory, swModuleType);
|
||||
}
|
||||
if (null != typeDescValue) {
|
||||
newDistType.setDescription(typeDescValue);
|
||||
}
|
||||
|
||||
newDistType.setDescription(typeDescValue);
|
||||
newDistType.setColour(colorPicked);
|
||||
newDistType = distributionSetManagement.createDistributionSetType(newDistType);
|
||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() }));
|
||||
closeWindow();
|
||||
eventBus.publish(this,
|
||||
new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType));
|
||||
|
||||
} else {
|
||||
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +388,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
if (null != typeNameValue) {
|
||||
updateDistSetType.setName(typeNameValue);
|
||||
updateDistSetType.setKey(typeKeyValue);
|
||||
updateDistSetType.setDescription(null != typeDescValue ? typeDescValue : null);
|
||||
updateDistSetType.setDescription(typeDescValue);
|
||||
|
||||
if (distributionSetManagement.countDistributionSetsByType(existingType) <= 0 && null != itemIds
|
||||
&& !itemIds.isEmpty()) {
|
||||
@@ -404,21 +406,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
distributionSetManagement.updateDistributionSetType(updateDistSetType);
|
||||
uiNotification
|
||||
.displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() }));
|
||||
closeWindow();
|
||||
eventBus.publish(this,
|
||||
new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType));
|
||||
|
||||
} else {
|
||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType,
|
||||
final Boolean isMandatory, final SoftwareModuleType swModuleType) {
|
||||
if (isMandatory) {
|
||||
updateDistSetType.addMandatoryModuleType(swModuleType);
|
||||
|
||||
} else {
|
||||
updateDistSetType.addOptionalModuleType(swModuleType);
|
||||
}
|
||||
@@ -440,32 +438,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
return distSetType;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.vaadin.ui.components.colorpicker.HasColorChangeListener#
|
||||
* addColorChangeListener(com.vaadin
|
||||
* .ui.components.colorpicker.ColorChangeListener)
|
||||
*/
|
||||
@Override
|
||||
public void addColorChangeListener(final ColorChangeListener listener) {
|
||||
|
||||
LOG.info("in side addColorChangeListener() ");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.vaadin.ui.components.colorpicker.HasColorChangeListener#
|
||||
* removeColorChangeListener(com.
|
||||
* vaadin.ui.components.colorpicker.ColorChangeListener)
|
||||
*/
|
||||
@Override
|
||||
public void removeColorChangeListener(final ColorChangeListener listener) {
|
||||
|
||||
LOG.info("in side removeColorChangeListener() ");
|
||||
}
|
||||
|
||||
/**
|
||||
* reset the components.
|
||||
*/
|
||||
@@ -484,9 +456,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
* ValueChangeEvent
|
||||
*/
|
||||
@Override
|
||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
||||
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||
|
||||
super.createOptionValueChanged(event);
|
||||
super.optionValueChanged(event);
|
||||
|
||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||
selectedTable.getContainerDataSource().removeAllItems();
|
||||
@@ -552,18 +524,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
if (null != selectedTypeTag) {
|
||||
tagDesc.setValue(selectedTypeTag.getDescription());
|
||||
typeKey.setValue(selectedTypeTag.getKey());
|
||||
|
||||
if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) {
|
||||
distTypeSelectLayout.setEnabled(true);
|
||||
selectedTable.setEnabled(true);
|
||||
window.setSaveButtonEnabled(true);
|
||||
} else {
|
||||
uiNotification.displayValidationError(
|
||||
selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update"));
|
||||
distTypeSelectLayout.setEnabled(false);
|
||||
selectedTable.setEnabled(false);
|
||||
window.setSaveButtonEnabled(false);
|
||||
}
|
||||
|
||||
createOriginalSelectedTableContainer();
|
||||
for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) {
|
||||
addTargetTableforUpdate(swModuleType, false);
|
||||
}
|
||||
@@ -583,65 +554,41 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) {
|
||||
|
||||
Item saveTblitem;
|
||||
if (null != selectedTablecontainer) {
|
||||
saveTblitem = selectedTablecontainer.addItem(swModuleType.getId());
|
||||
sourceTable.removeItem(swModuleType.getId());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory));
|
||||
if (selectedTableContainer == null) {
|
||||
return;
|
||||
}
|
||||
final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId());
|
||||
sourceTable.removeItem(swModuleType.getId());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
||||
final CheckBox mandatoryCheckbox = new CheckBox("", mandatory);
|
||||
mandatoryCheckbox.setId(swModuleType.getName());
|
||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox);
|
||||
|
||||
final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId());
|
||||
originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
||||
originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox);
|
||||
|
||||
window.updateAllComponents(mandatoryCheckbox);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save(final ClickEvent event) {
|
||||
|
||||
if (mandatoryValuesPresent()) {
|
||||
final DistributionSetType existingDistTypeByKey = distributionSetManagement
|
||||
.findDistributionSetTypeByKey(typeKey.getValue());
|
||||
final DistributionSetType existingDistTypeByName = distributionSetManagement
|
||||
.findDistributionSetTypeByName(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTypeStr)) {
|
||||
if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) {
|
||||
createNewDistributionSetType();
|
||||
}
|
||||
} else {
|
||||
updateDistributionSetType(existingDistTypeByKey);
|
||||
final DistributionSetType existingDistTypeByKey = distributionSetManagement
|
||||
.findDistributionSetTypeByKey(typeKey.getValue());
|
||||
final DistributionSetType existingDistTypeByName = distributionSetManagement
|
||||
.findDistributionSetTypeByName(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTypeStr)) {
|
||||
if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) {
|
||||
createNewDistributionSetType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWindow() {
|
||||
reset();
|
||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void previewButtonClicked() {
|
||||
if (!tagPreviewBtnClicked) {
|
||||
final String selectedOption = (String) optiongroup.getValue();
|
||||
if (null != selectedOption && selectedOption.equalsIgnoreCase(updateTypeStr)
|
||||
&& null != tagNameComboBox.getValue()) {
|
||||
|
||||
final DistributionSetType existedDistType = distributionSetManagement
|
||||
.findDistributionSetTypeByKey(tagNameComboBox.getValue().toString());
|
||||
if (null != existedDistType) {
|
||||
getColorPickerLayout().setSelectedColor(existedDistType.getColour() != null
|
||||
? ColorPickerHelper.rgbToColorConverter(existedDistType.getColour())
|
||||
: ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||
} else {
|
||||
getColorPickerLayout().setSelectedColor(
|
||||
ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||
}
|
||||
}
|
||||
getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor());
|
||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
||||
} else {
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
updateDistributionSetType(existingDistTypeByKey);
|
||||
}
|
||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWindowCaption() {
|
||||
return i18n.get("caption.add.type");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,18 +14,22 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
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.SoftwareModuleIdName;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
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.tagdetails.DistributionTagToken;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
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.SoftwareModuleAssignmentDiscardEvent;
|
||||
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
|
||||
@@ -64,7 +68,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
private static final String SOFT_MODULE = "softwareModule";
|
||||
|
||||
private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule";
|
||||
|
||||
|
||||
@Autowired
|
||||
private ManageDistUIState manageDistUIState;
|
||||
|
||||
@@ -79,12 +83,37 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
|
||||
@Autowired
|
||||
private transient DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private DsMetadataPopupLayout dsMetadataPopupLayout;
|
||||
|
||||
@Autowired
|
||||
private EntityFactory entityFactory;
|
||||
|
||||
private SoftwareModuleDetailsTable softwareModuleTable;
|
||||
|
||||
private DistributionSetMetadatadetailslayout dsMetadataTable;
|
||||
|
||||
private VerticalLayout tagsLayout;
|
||||
|
||||
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.
|
||||
@@ -94,6 +123,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
softwareModuleTable = new SoftwareModuleDetailsTable();
|
||||
softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(),
|
||||
manageDistUIState);
|
||||
dsMetadataTable = new DistributionSetMetadatadetailslayout();
|
||||
dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement,
|
||||
dsMetadataPopupLayout,entityFactory);
|
||||
super.init();
|
||||
}
|
||||
|
||||
@@ -107,8 +139,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
populateDetails();
|
||||
populateModule();
|
||||
populateTags();
|
||||
populateMetadataDetails();
|
||||
}
|
||||
|
||||
|
||||
private void populateModule() {
|
||||
softwareModuleTable.populateModule(getSelectedBaseEntity());
|
||||
showUnsavedAssignment();
|
||||
@@ -238,7 +271,12 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
updateDistributionSetDetailsLayout(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void populateMetadataDetails(){
|
||||
dsMetadataTable.populateDSMetadata(getSelectedBaseEntity());
|
||||
}
|
||||
|
||||
private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) {
|
||||
final VerticalLayout detailsTabLayout = getDetailsLayout();
|
||||
detailsTabLayout.removeAllComponents();
|
||||
@@ -259,8 +297,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
|
||||
@Override
|
||||
protected void onEdit(final ClickEvent event) {
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
||||
distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId());
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId());
|
||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||
UI.getCurrent().addWindow(newDistWindow);
|
||||
newDistWindow.setVisible(Boolean.TRUE);
|
||||
@@ -294,6 +331,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null);
|
||||
detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null);
|
||||
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
|
||||
detailsTab.addTab(dsMetadataTable, getI18n().get("caption.metadata"), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -353,7 +391,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
|
||||
@Override
|
||||
protected String getTabSheetId() {
|
||||
return null;
|
||||
return SPUIComponentIdProvider.DISTRIBUTIONSET_DETAILS_TABSHEET_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -361,4 +399,30 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.AbstractTable;
|
||||
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.DistributionsViewAcceptCriteria;
|
||||
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.SPUILabelDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.TableColumn;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -57,8 +60,10 @@ import com.vaadin.data.Item;
|
||||
import com.vaadin.event.dd.DragAndDropEvent;
|
||||
import com.vaadin.event.dd.DropHandler;
|
||||
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.UI;
|
||||
@@ -98,6 +103,9 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
@Autowired
|
||||
private transient TargetManagement targetManagement;
|
||||
|
||||
@Autowired
|
||||
private DsMetadataPopupLayout dsMetadataPopupLayout;
|
||||
|
||||
/**
|
||||
* Initialize the component.
|
||||
*/
|
||||
@@ -181,6 +189,10 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
protected void publishEntityAfterValueChange(final DistributionSet distributionSet) {
|
||||
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, distributionSet));
|
||||
eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION);
|
||||
if(distributionSet!=null){
|
||||
manageDistUIState.setLastSelectedEntity(new DistributionSetIdName(distributionSet.getId(),
|
||||
distributionSet.getName(),distributionSet.getVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -468,5 +480,51 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
protected void setDataAvailable(final boolean 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public class DistributionSetTableHeader extends AbstractTableHeader {
|
||||
|
||||
@Override
|
||||
protected void addNewItem(final ClickEvent event) {
|
||||
final Window newDistWindow = addUpdateWindowLayout.getWindow();
|
||||
final Window newDistWindow = addUpdateWindowLayout.getWindow(null);
|
||||
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
||||
UI.getCurrent().addWindow(newDistWindow);
|
||||
newDistWindow.setVisible(Boolean.TRUE);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,11 +8,16 @@
|
||||
*/
|
||||
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.SoftwareModuleMetadata;
|
||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
|
||||
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
||||
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.distributions.event.MetadataEvent;
|
||||
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
@@ -44,6 +49,50 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
|
||||
|
||||
@Autowired
|
||||
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)
|
||||
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(createDescriptionLayout(), getI18n().get("caption.tab.description"), null);
|
||||
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
|
||||
}
|
||||
detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultCaption() {
|
||||
@@ -93,7 +143,7 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
|
||||
|
||||
@Override
|
||||
protected String getTabSheetId() {
|
||||
return null;
|
||||
return SPUIComponentIdProvider.DIST_SW_MODULE_DETAILS_TABSHEET_ID;
|
||||
}
|
||||
|
||||
private void populateDetails() {
|
||||
@@ -139,11 +189,41 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
|
||||
@Override
|
||||
protected void populateDetailsWidget() {
|
||||
populateDetails();
|
||||
populateMetadataDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDetailsHeaderCaptionId() {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import com.vaadin.shared.ui.window.WindowMode;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.JavaScript;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.UI;
|
||||
@@ -77,6 +78,9 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
|
||||
|
||||
@Autowired
|
||||
private ArtifactDetailsLayout artifactDetailsLayout;
|
||||
|
||||
@Autowired
|
||||
private SwMetadataPopupLayout swMetadataPopupLayout;
|
||||
|
||||
/**
|
||||
* Initialize the filter layout.
|
||||
@@ -175,16 +179,19 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
|
||||
protected void addCustomGeneratedColumns() {
|
||||
|
||||
addGeneratedColumn(SPUILabelDefinitions.ARTIFACT_ICON, new ColumnGenerator() {
|
||||
|
||||
private static final long serialVersionUID = -5982361782989980277L;
|
||||
|
||||
@Override
|
||||
public Object generateCell(final Table source, final Object itemId, final Object columnId) {
|
||||
HorizontalLayout iconLayout = new HorizontalLayout();
|
||||
// add artifactory details popup
|
||||
final String nameVersionStr = getNameAndVerion(itemId);
|
||||
final Button showArtifactDtlsBtn = createShowArtifactDtlsButton(nameVersionStr);
|
||||
final Button manageMetaDataBtn = createManageMetadataButton(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
|
||||
protected void publishEntityAfterValueChange(final SoftwareModule selectedLastEntity) {
|
||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity));
|
||||
if(selectedLastEntity!=null){
|
||||
manageDistUIState.setSelectedBaseSwModuleId(selectedLastEntity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,12 +320,21 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
|
||||
private Button createShowArtifactDtlsButton(final String nameVersionStr) {
|
||||
final Button showArtifactDtlsBtn = SPUIComponentProvider.getButton(
|
||||
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.setDescription(i18n.get("tooltip.artifact.icon"));
|
||||
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) {
|
||||
final Item item = getItem(itemId);
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class TargetFilterTable extends Table {
|
||||
setStyleName("sp-table");
|
||||
setSizeFull();
|
||||
setImmediate(true);
|
||||
setHeight(100.0f, Unit.PERCENTAGE);
|
||||
setHeight(100.0F, Unit.PERCENTAGE);
|
||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_SMALL);
|
||||
addCustomGeneratedColumns();
|
||||
|
||||
@@ -20,17 +20,16 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
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.google.common.base.Strings;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.data.Property.ValueChangeListener;
|
||||
import com.vaadin.server.Page;
|
||||
@@ -87,7 +86,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
protected CommonDialogWindow window;
|
||||
|
||||
protected Label colorLabel;
|
||||
protected Label madatoryLabel;
|
||||
protected TextField tagName;
|
||||
protected TextArea tagDesc;
|
||||
protected Button tagColorPreviewBtn;
|
||||
@@ -99,17 +97,13 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
protected GridLayout mainLayout;
|
||||
protected VerticalLayout contentLayout;
|
||||
|
||||
protected boolean tagPreviewBtnClicked = false;
|
||||
protected boolean tagPreviewBtnClicked;
|
||||
|
||||
private String colorPicked;
|
||||
protected String tagNameValue;
|
||||
protected String tagDescValue;
|
||||
|
||||
protected void createWindow() {
|
||||
reset();
|
||||
setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null));
|
||||
}
|
||||
protected abstract String getWindowCaption();
|
||||
|
||||
/**
|
||||
* Save new tag / update new tag.
|
||||
@@ -142,7 +136,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
setSizeUndefined();
|
||||
createRequiredComponents();
|
||||
buildLayout();
|
||||
createWindow();
|
||||
addListeners();
|
||||
eventBus.subscribe(this);
|
||||
}
|
||||
@@ -157,7 +150,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
createTagStr = i18n.get("label.create.tag");
|
||||
updateTagStr = i18n.get("label.update.tag");
|
||||
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null);
|
||||
madatoryLabel = getMandatoryLabel();
|
||||
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null);
|
||||
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
||||
|
||||
@@ -169,7 +161,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"),
|
||||
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
|
||||
tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC);
|
||||
tagDesc.setImmediate(true);
|
||||
tagDesc.setNullRepresentation("");
|
||||
@@ -178,6 +169,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
i18n.get("label.combobox.tag"));
|
||||
tagNameComboBox.addStyleName(SPUIDefinitions.FILTER_TYPE_COMBO_STYLE);
|
||||
tagNameComboBox.setImmediate(true);
|
||||
tagNameComboBox.setId(SPUIComponentIdProvider.DIST_TAG_COMBO);
|
||||
|
||||
tagColorPreviewBtn = new Button();
|
||||
tagColorPreviewBtn.setId(SPUIComponentIdProvider.TAG_COLOR_PREVIEW_ID);
|
||||
@@ -200,7 +192,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
|
||||
formLayout.addComponent(optiongroup);
|
||||
formLayout.addComponent(comboLayout);
|
||||
formLayout.addComponent(madatoryLabel);
|
||||
formLayout.addComponent(tagName);
|
||||
formLayout.addComponent(tagDesc);
|
||||
formLayout.addStyleName("form-lastrow");
|
||||
@@ -215,6 +206,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
mainLayout.setSizeFull();
|
||||
mainLayout.addComponent(contentLayout, 0, 0);
|
||||
|
||||
colorPickerLayout.setVisible(false);
|
||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
||||
|
||||
setCompositionRoot(mainLayout);
|
||||
tagName.focus();
|
||||
}
|
||||
@@ -234,13 +229,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
protected void previewButtonClicked() {
|
||||
if (!tagPreviewBtnClicked) {
|
||||
setColor();
|
||||
mainLayout.getComponent(1, 0);
|
||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
||||
} else {
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
}
|
||||
|
||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
||||
colorPickerLayout.setVisible(tagPreviewBtnClicked);
|
||||
}
|
||||
|
||||
private void setColor() {
|
||||
@@ -270,12 +262,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
}
|
||||
}
|
||||
|
||||
protected Label getMandatoryLabel() {
|
||||
final Label label = new Label(i18n.get("label.mandatory.field"));
|
||||
label.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
||||
return label;
|
||||
}
|
||||
|
||||
private void tagNameChosen(final ValueChangeEvent event) {
|
||||
final String tagSelected = (String) event.getProperty().getValue();
|
||||
if (null != tagSelected) {
|
||||
@@ -283,6 +269,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
} else {
|
||||
resetTagNameField();
|
||||
}
|
||||
window.setOrginaleValues();
|
||||
}
|
||||
|
||||
protected void resetTagNameField() {
|
||||
@@ -290,7 +277,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
tagName.clear();
|
||||
tagDesc.clear();
|
||||
restoreComponentStyles();
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
||||
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
||||
tagPreviewBtnClicked = false;
|
||||
@@ -327,7 +313,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR);
|
||||
colorPickerLayout.getSelPreview()
|
||||
.setColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
window.setOrginaleValues();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,9 +328,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
// hide target name combo
|
||||
comboLayout.removeComponent(comboLabel);
|
||||
comboLayout.removeComponent(tagNameComboBox);
|
||||
mainLayout.removeComponent(colorPickerLayout);
|
||||
|
||||
// Default green color
|
||||
colorPickerLayout.setVisible(false);
|
||||
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
||||
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
||||
tagPreviewBtnClicked = false;
|
||||
@@ -389,6 +375,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
*/
|
||||
protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc,
|
||||
final String taregtTagColor) {
|
||||
|
||||
tagName.removeStyleName(SPUIDefinitions.TAG_NAME);
|
||||
tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC);
|
||||
getTargetDynamicStyles(taregtTagColor);
|
||||
@@ -435,11 +422,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview);
|
||||
colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor());
|
||||
}
|
||||
}
|
||||
|
||||
protected void closeWindow() {
|
||||
window.close();
|
||||
UI.getCurrent().removeWindow(window);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,6 +431,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
||||
|
||||
optiongroup = new OptionGroup("Select Action");
|
||||
optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP);
|
||||
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
||||
optiongroup.addStyleName("custom-option-group");
|
||||
optiongroup.setNullSelectionAllowed(false);
|
||||
@@ -472,27 +456,17 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColorChangeListener(final ColorChangeListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeColorChangeListener(final ColorChangeListener listener) {
|
||||
}
|
||||
|
||||
public ColorPickerLayout getColorPickerLayout() {
|
||||
return colorPickerLayout;
|
||||
}
|
||||
|
||||
public CommonDialogWindow getWindow() {
|
||||
reset();
|
||||
window = SPUIWindowDecorator.getWindow(getWindowCaption(), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this,
|
||||
this::save, this::discard, null, mainLayout, i18n);
|
||||
return window;
|
||||
}
|
||||
|
||||
public void setWindow(final CommonDialogWindow window) {
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value change listeners implementations of sliders.
|
||||
*/
|
||||
@@ -565,7 +539,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
tagManagement.updateDistributionSetTag((DistributionSetTag) targetObj);
|
||||
}
|
||||
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() }));
|
||||
closeWindow();
|
||||
} else {
|
||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||
}
|
||||
@@ -587,27 +560,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
getPreviewButtonColor(previewColor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected Boolean mandatoryValuesPresent() {
|
||||
if (Strings.isNullOrEmpty(tagName.getValue())) {
|
||||
if (optiongroup.getValue().equals(createTagStr)) {
|
||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
||||
}
|
||||
if (optiongroup.getValue().equals(updateTagStr)) {
|
||||
if (null == tagNameComboBox.getValue()) {
|
||||
displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME));
|
||||
} else {
|
||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
protected Boolean checkIsDuplicate(final Tag existingTag) {
|
||||
if (existingTag != null) {
|
||||
displayValidationError(i18n.get("message.tag.duplicate.check", new Object[] { existingTag.getName() }));
|
||||
@@ -644,4 +596,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
||||
return formLayout;
|
||||
}
|
||||
|
||||
public GridLayout getMainLayout() {
|
||||
return mainLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColorChangeListener(final ColorChangeListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeColorChangeListener(final ColorChangeListener listener) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.shared.ui.colorpicker.Color;
|
||||
@@ -33,12 +31,10 @@ import com.vaadin.ui.components.colorpicker.ColorSelector;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* Superclass defining common properties and methods for creating/updating
|
||||
* types.
|
||||
*
|
||||
*/
|
||||
public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
|
||||
private static final long serialVersionUID = 5732904956185988397L;
|
||||
|
||||
@@ -52,7 +48,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
@Override
|
||||
protected void addListeners() {
|
||||
super.addListeners();
|
||||
optiongroup.addValueChangeListener(this::createOptionValueChanged);
|
||||
optiongroup.addValueChangeListener(this::optionValueChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +57,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
createTypeStr = i18n.get("label.create.type");
|
||||
updateTypeStr = i18n.get("label.update.type");
|
||||
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null);
|
||||
madatoryLabel = getMandatoryLabel();
|
||||
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null);
|
||||
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
||||
|
||||
@@ -137,7 +132,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
* @param event
|
||||
* ValueChangeEvent
|
||||
*/
|
||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
||||
@Override
|
||||
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||
|
||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||
tagName.clear();
|
||||
@@ -151,7 +147,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
} else {
|
||||
typeKey.setEnabled(true);
|
||||
tagName.setEnabled(true);
|
||||
window.setSaveButtonEnabled(true);
|
||||
tagName.clear();
|
||||
tagDesc.clear();
|
||||
typeKey.clear();
|
||||
@@ -203,6 +198,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
||||
|
||||
optiongroup = new OptionGroup("Select Action");
|
||||
optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP);
|
||||
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
||||
optiongroup.addStyleName("custom-option-group");
|
||||
optiongroup.setNullSelectionAllowed(false);
|
||||
@@ -285,24 +281,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean mandatoryValuesPresent() {
|
||||
if (Strings.isNullOrEmpty(tagName.getValue()) || Strings.isNullOrEmpty(typeKey.getValue())) {
|
||||
if (optiongroup.getValue().equals(createTypeStr)) {
|
||||
displayValidationError(SPUILabelDefinitions.MISSING_TYPE_NAME_KEY);
|
||||
}
|
||||
if (optiongroup.getValue().equals(updateTypeStr)) {
|
||||
if (null == tagNameComboBox.getValue()) {
|
||||
displayValidationError(i18n.get("message.error.missing.tagName"));
|
||||
} else {
|
||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save(final ClickEvent event) {
|
||||
// is implemented in the inherited class
|
||||
|
||||
@@ -27,11 +27,11 @@ import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
|
||||
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.management.event.ManagementUIEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
@@ -50,15 +50,14 @@ import org.vaadin.spring.events.EventBus;
|
||||
import org.vaadin.spring.events.EventScope;
|
||||
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.data.Item;
|
||||
import com.vaadin.data.util.HierarchicalContainer;
|
||||
import com.vaadin.event.Action.Handler;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
@@ -74,11 +73,13 @@ import com.vaadin.ui.themes.ValoTheme;
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
public class ActionHistoryTable extends TreeTable {
|
||||
|
||||
private static final long serialVersionUID = -1631514704696786653L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryTable.class);
|
||||
private static final String BUTTON_CANCEL = "button.cancel";
|
||||
private static final String BUTTON_OK = "button.ok";
|
||||
private static final long serialVersionUID = -1631514704696786653L;
|
||||
|
||||
@Autowired
|
||||
private I18N i18n;
|
||||
|
||||
@@ -95,14 +96,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
private ManagementUIState managementUIState;
|
||||
|
||||
private Container hierarchicalContainer;
|
||||
private boolean alreadyHasMessages = false;
|
||||
private boolean alreadyHasMessages;
|
||||
|
||||
private Target target;
|
||||
|
||||
com.vaadin.event.Action actionCancel;
|
||||
com.vaadin.event.Action actionForce;
|
||||
com.vaadin.event.Action actionForceQuit;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryTable.class);
|
||||
private static final String STATUS_ICON_GREEN = "statusIconGreen";
|
||||
|
||||
/**
|
||||
@@ -110,10 +107,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
actionCancel = new com.vaadin.event.Action(i18n.get("message.cancel.action"));
|
||||
actionForceQuit = new com.vaadin.event.Action(i18n.get("message.forcequit.action"));
|
||||
actionForceQuit.setIcon(FontAwesome.WARNING);
|
||||
actionForce = new com.vaadin.event.Action(i18n.get("message.force.action"));
|
||||
initializeTableSettings();
|
||||
buildComponent();
|
||||
restorePreviousState();
|
||||
@@ -150,11 +143,12 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
}
|
||||
|
||||
private void setColumnExpandRatioForMinimisedTable() {
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.3f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.15f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.3f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.15f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.3F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.15F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.3F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.15F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTIONS_COLUMN, 0.2F);
|
||||
}
|
||||
|
||||
private void initializeTableSettings() {
|
||||
@@ -164,14 +158,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
setMultiSelect(false);
|
||||
setSortEnabled(true);
|
||||
setColumnReorderingAllowed(true);
|
||||
setHeight(100.0f, Unit.PERCENTAGE);
|
||||
setWidth(100.0f, Unit.PERCENTAGE);
|
||||
setHeight(100.0F, Unit.PERCENTAGE);
|
||||
setWidth(100.0F, Unit.PERCENTAGE);
|
||||
setImmediate(true);
|
||||
setStyleName("sp-table");
|
||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_SMALL);
|
||||
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_FORCED, Align.CENTER);
|
||||
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_STATUS, Align.CENTER);
|
||||
setColumnAlignment(SPUIDefinitions.ACTIONS_COLUMN, Align.CENTER);
|
||||
// listeners for child
|
||||
addExpandListener(event -> {
|
||||
expandParentActionRow(event.getItemId());
|
||||
@@ -181,11 +176,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
collapseParentActionRow(event.getItemId());
|
||||
managementUIState.getExpandParentActionRowId().remove(event.getItemId());
|
||||
});
|
||||
/*
|
||||
* Add the cancel action handler for active actions. To be used to
|
||||
* cancel the action.
|
||||
*/
|
||||
addActionHandler(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,6 +194,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
null);
|
||||
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_MSGS_HIDDEN, List.class, null);
|
||||
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, String.class, null);
|
||||
|
||||
}
|
||||
|
||||
private List<Object> getVisbleColumns() {
|
||||
@@ -213,6 +204,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_DATETIME);
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_STATUS);
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_FORCED);
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTIONS_COLUMN);
|
||||
|
||||
if (managementUIState.isActionHistoryMaximized()) {
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME);
|
||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_MSGS);
|
||||
@@ -242,12 +235,12 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
|
||||
private void getcontainerData() {
|
||||
hierarchicalContainer.removeAllItems();
|
||||
|
||||
|
||||
if (target != null) {
|
||||
/* service method to create action history for target */
|
||||
final List<ActionWithStatusCount> actionHistory = deploymentManagement
|
||||
.findActionsWithStatusCountByTargetOrderByIdDesc(target);
|
||||
|
||||
.findActionsWithStatusCountByTargetOrderByIdDesc(target);
|
||||
|
||||
addDetailsToContainer(actionHistory);
|
||||
}
|
||||
}
|
||||
@@ -300,23 +293,22 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
* add distribution name to the item which will be displayed in the
|
||||
* table. The name should not exceed certain limit.
|
||||
*/
|
||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(actionWithStatusCount.getDsName() + ":" +
|
||||
actionWithStatusCount.getDsVersion());
|
||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST)
|
||||
.setValue(actionWithStatusCount.getDsName() + ":" + actionWithStatusCount.getDsVersion());
|
||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).setValue(action);
|
||||
|
||||
/* Default no child */
|
||||
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(), false);
|
||||
|
||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
||||
.setValue(SPDateTimeUtil.getFormattedDate((actionWithStatusCount.getAction().getLastModifiedAt() != null)
|
||||
? actionWithStatusCount.getAction().getLastModifiedAt()
|
||||
: actionWithStatusCount.getAction().getLastModifiedAt()));
|
||||
.setValue(SPDateTimeUtil.getFormattedDate(actionWithStatusCount.getAction().getLastModifiedAt()));
|
||||
|
||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME)
|
||||
.setValue(actionWithStatusCount.getRolloutName());
|
||||
|
||||
if (actionWithStatusCount.getActionStatusCount() > 0) {
|
||||
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(), true);
|
||||
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,12 +342,18 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
return getForcedColumn(itemId);
|
||||
}
|
||||
});
|
||||
|
||||
addGeneratedColumn(SPUIDefinitions.ACTIONS_COLUMN, new Table.ColumnGenerator() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component generateCell(final Table source, final Object itemId, final Object columnId) {
|
||||
return createActionBarColumn(itemId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
private Component getForcedColumn(final Object itemId) {
|
||||
final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(itemId)
|
||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue();
|
||||
@@ -372,10 +370,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
return actionLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
private Component getActiveColumn(final Object itemId) {
|
||||
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
||||
@@ -397,10 +391,44 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
return activeStatusIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
private HorizontalLayout createActionBarColumn(final Object itemId) {
|
||||
final HorizontalLayout actionBar = new HorizontalLayout();
|
||||
final Item item = hierarchicalContainer.getItem(itemId);
|
||||
final Long actionId = (Long) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN).getValue();
|
||||
final String activeValue = (String) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN)
|
||||
.getValue();
|
||||
final Action actionWithActiveStatus = (Action) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED)
|
||||
.getValue();
|
||||
|
||||
if (actionWithActiveStatus == null) {
|
||||
return null;
|
||||
}
|
||||
final boolean isActionActive = target != null && SPUIDefinitions.ACTIVE.equals(activeValue);
|
||||
|
||||
final Button actionCancel = SPUIComponentProvider.getButton(
|
||||
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_CANCEL_ID, "", i18n.get("message.cancel.action"),
|
||||
ValoTheme.BUTTON_TINY, true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||
actionCancel.setEnabled(isActionActive && !actionWithActiveStatus.isCancelingOrCanceled());
|
||||
actionCancel.addClickListener(event -> confirmAndCancelAction(actionId));
|
||||
|
||||
final Button actionForce = SPUIComponentProvider.getButton(
|
||||
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_FORCE_ID, "", i18n.get("message.force.action"),
|
||||
ValoTheme.BUTTON_TINY, true, FontAwesome.BOLT, SPUIButtonStyleSmallNoBorder.class);
|
||||
actionForce.setEnabled(
|
||||
isActionActive && !actionWithActiveStatus.isForce() && !actionWithActiveStatus.isCancelingOrCanceled());
|
||||
actionForce.addClickListener(event -> confirmAndForceAction(actionId));
|
||||
|
||||
final Button actionForceQuit = SPUIComponentProvider.getButton(
|
||||
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_FORCE_QUIT_ID, "", i18n.get("message.forcequit.action"),
|
||||
ValoTheme.BUTTON_TINY + " redicon", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||
actionForceQuit.setEnabled(isActionActive && actionWithActiveStatus.isCancelingOrCanceled());
|
||||
actionForceQuit.addClickListener(event -> confirmAndForceQuitAction(actionId));
|
||||
|
||||
actionBar.addComponents(actionCancel, actionForce, actionForceQuit);
|
||||
|
||||
return actionBar;
|
||||
}
|
||||
|
||||
private Component getStatusColumn(final Object itemId) {
|
||||
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
||||
@@ -427,11 +455,11 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
final Pageable pageReq = new PageRequest(0, 1000,
|
||||
new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()));
|
||||
final Page<ActionStatus> actionStatusList;
|
||||
if (managementUIState.isActionHistoryMaximized()) {
|
||||
actionStatusList = deploymentManagement.findActionStatusByActionWithMessages(pageReq, action);
|
||||
} else {
|
||||
actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, action);
|
||||
}
|
||||
if (managementUIState.isActionHistoryMaximized()) {
|
||||
actionStatusList = deploymentManagement.findActionStatusByActionWithMessages(pageReq, action);
|
||||
} else {
|
||||
actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, action);
|
||||
}
|
||||
final List<ActionStatus> content = actionStatusList.getContent();
|
||||
/*
|
||||
* Since the recent action status and messages are already
|
||||
@@ -449,9 +477,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
*/
|
||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).setValue("");
|
||||
|
||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST)
|
||||
.setValue(action.getDistributionSet().getName() + ":"
|
||||
+ action.getDistributionSet().getVersion());
|
||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(
|
||||
action.getDistributionSet().getName() + ":" + action.getDistributionSet().getVersion());
|
||||
|
||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
||||
.setValue(SPDateTimeUtil.getFormattedDate(actionStatus.getCreatedAt()));
|
||||
@@ -637,14 +664,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
|
||||
private void setColumnExpantRatioOnTableMaximize() {
|
||||
/* set messages column can expand the rest of the available space */
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.2f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, 0.1f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_MSGS, 0.35f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.15f);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.2F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, 0.1F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_MSGS, 0.35F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.15F);
|
||||
setColumnExpandRatio(SPUIDefinitions.ACTIONS_COLUMN, 0.2F);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -706,46 +734,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
setColumnExpandRatioForMinimisedTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAction(final com.vaadin.event.Action action, final Object sender, final Object target) {
|
||||
/* Get the actionId details of the cancel item or row */
|
||||
final Item item = hierarchicalContainer.getItem(target);
|
||||
final Long actionId = (Long) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN).getValue();
|
||||
if (action.equals(actionCancel)) {
|
||||
if (actionId != null) {
|
||||
confirmAndCancelAction(actionId);
|
||||
}
|
||||
} else if (action.equals(actionForce)) {
|
||||
confirmAndForceAction(actionId);
|
||||
} else if (action.equals(actionForceQuit)) {
|
||||
confirmAndForceQuitAction(actionId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.vaadin.event.Action[] getActions(final Object target, final Object sender) {
|
||||
final List<com.vaadin.event.Action> actions = Lists.newArrayList();
|
||||
if (target != null) {
|
||||
/* Check if the row or item belongs to active action */
|
||||
final String activeValue = (String) hierarchicalContainer.getItem(target)
|
||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).getValue();
|
||||
if (SPUIDefinitions.ACTIVE.equals(activeValue)) {
|
||||
final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(target)
|
||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue();
|
||||
if (!actionWithActiveStatus.isForce()) {
|
||||
actions.add(actionForce);
|
||||
}
|
||||
if (!actionWithActiveStatus.isCancelingOrCanceled()) {
|
||||
actions.add(actionCancel);
|
||||
} else {
|
||||
actions.add(actionForceQuit);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return actions.toArray(new com.vaadin.event.Action[actions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show confirmation window and if ok then only, force the action.
|
||||
*
|
||||
@@ -756,21 +744,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
/* Display the confirmation */
|
||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.force.action.confirmbox"),
|
||||
i18n.get("message.force.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||
if (ok) {
|
||||
/* cancel the action */
|
||||
deploymentManagement.forceTargetAction(actionId);
|
||||
|
||||
/*
|
||||
* Refresh the action history table to show latest
|
||||
* change of the action cancellation and update the
|
||||
* Target Details
|
||||
*/
|
||||
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.force.action.success"));
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
deploymentManagement.forceTargetAction(actionId);
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.force.action.success"));
|
||||
});
|
||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||
|
||||
confirmDialog.getWindow().bringToFront();
|
||||
}
|
||||
|
||||
@@ -778,22 +760,19 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
/* Display the confirmation */
|
||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.forcequit.action.confirmbox"),
|
||||
i18n.get("message.forcequit.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||
if (ok) {
|
||||
final boolean cancelResult = forceQuitActiveAction(actionId);
|
||||
if (cancelResult) {
|
||||
/*
|
||||
* Refresh the action history table to show latest
|
||||
* change of the action cancellation and update the
|
||||
* Target Details
|
||||
*/
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.forcequit.action.success"));
|
||||
} else {
|
||||
notification.displayValidationError(i18n.get("message.forcequit.action.failed"));
|
||||
}
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
} , FontAwesome.WARNING);
|
||||
final boolean cancelResult = forceQuitActiveAction(actionId);
|
||||
if (cancelResult) {
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.forcequit.action.success"));
|
||||
} else {
|
||||
notification.displayValidationError(i18n.get("message.forcequit.action.failed"));
|
||||
}
|
||||
}, FontAwesome.WARNING);
|
||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||
|
||||
confirmDialog.getWindow().bringToFront();
|
||||
}
|
||||
|
||||
@@ -804,21 +783,21 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
||||
* as Id if the action needs to be cancelled.
|
||||
*/
|
||||
private void confirmAndCancelAction(final Long actionId) {
|
||||
if (actionId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.cancel.action.confirmbox"),
|
||||
i18n.get("message.cancel.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||
if (ok) {
|
||||
final boolean cancelResult = cancelActiveAction(actionId);
|
||||
if (cancelResult) {
|
||||
/*
|
||||
* Refresh the action history table to show latest
|
||||
* change of the action cancellation and update the
|
||||
* Target Details
|
||||
*/
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.cancel.action.success"));
|
||||
} else {
|
||||
notification.displayValidationError(i18n.get("message.cancel.action.failed"));
|
||||
}
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
final boolean cancelResult = cancelActiveAction(actionId);
|
||||
if (cancelResult) {
|
||||
populateAndupdateTargetDetails(target);
|
||||
notification.displaySuccess(i18n.get("message.cancel.action.success"));
|
||||
} else {
|
||||
notification.displayValidationError(i18n.get("message.cancel.action.failed"));
|
||||
}
|
||||
});
|
||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.management.dstable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -26,6 +24,7 @@ import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
@@ -43,26 +42,18 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.data.Property.ValueChangeListener;
|
||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
||||
import com.vaadin.event.FieldEvents.TextChangeListener;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* WindowContent for adding/editing a Distribution
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
@@ -92,24 +83,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
|
||||
private TextField distNameTextField;
|
||||
private TextField distVersionTextField;
|
||||
private Label madatoryLabel;
|
||||
private TextArea descTextArea;
|
||||
private CheckBox reqMigStepCheckbox;
|
||||
private ComboBox distsetTypeNameComboBox;
|
||||
private boolean editDistribution = Boolean.FALSE;
|
||||
private Long editDistId;
|
||||
private CommonDialogWindow addDistributionWindow;
|
||||
private String originalDistName;
|
||||
private String originalDistVersion;
|
||||
private String originalDistDescription;
|
||||
private Boolean originalReqMigStep;
|
||||
private String originalDistSetType;
|
||||
private final List<Component> changedComponents = new ArrayList<>();
|
||||
private ValueChangeListener reqMigStepCheckboxListerner;
|
||||
private TextChangeListener descTextAreaListener;
|
||||
private TextChangeListener distNameTextFieldListener;
|
||||
private TextChangeListener distVersionTextFieldListener;
|
||||
private ValueChangeListener distsetTypeNameComboBoxListener;
|
||||
private CommonDialogWindow window;
|
||||
|
||||
private FormLayout formLayout;
|
||||
|
||||
@@ -123,16 +102,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
}
|
||||
|
||||
private void buildLayout() {
|
||||
|
||||
/*
|
||||
* The main layout of the window contains mandatory info, textboxes
|
||||
* (controller Id, name & description) and action buttons layout
|
||||
*/
|
||||
addStyleName("lay-color");
|
||||
setSizeUndefined();
|
||||
|
||||
formLayout = new FormLayout();
|
||||
formLayout.addComponent(madatoryLabel);
|
||||
formLayout.addComponent(distsetTypeNameComboBox);
|
||||
formLayout.addComponent(distNameTextField);
|
||||
formLayout.addComponent(distVersionTextField);
|
||||
@@ -140,7 +113,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
formLayout.addComponent(reqMigStepCheckbox);
|
||||
|
||||
setCompositionRoot(formLayout);
|
||||
|
||||
distNameTextField.focus();
|
||||
}
|
||||
|
||||
@@ -164,6 +136,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
distsetTypeNameComboBox.setImmediate(true);
|
||||
distsetTypeNameComboBox.setNullSelectionAllowed(false);
|
||||
distsetTypeNameComboBox.setId(SPUIComponentIdProvider.DIST_ADD_DISTSETTYPE);
|
||||
populateDistSetTypeNameCombo();
|
||||
|
||||
descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style",
|
||||
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
||||
@@ -171,10 +144,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC);
|
||||
descTextArea.setNullRepresentation("");
|
||||
|
||||
/* Label for mandatory symbol */
|
||||
madatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
||||
madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
||||
|
||||
reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"),
|
||||
"dist-checkbox-style", null, false, "");
|
||||
reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL);
|
||||
@@ -200,27 +169,17 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
return disttypeContainer;
|
||||
}
|
||||
|
||||
private void enableSaveButton() {
|
||||
addDistributionWindow.setSaveButtonEnabled(true);
|
||||
}
|
||||
|
||||
private DistributionSetType getDefaultDistributionSetType() {
|
||||
final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata();
|
||||
return tenantMetaData.getDefaultDsType();
|
||||
}
|
||||
|
||||
private void disableSaveButton() {
|
||||
addDistributionWindow.setSaveButtonEnabled(false);
|
||||
}
|
||||
|
||||
private void saveDistribution() {
|
||||
/* add new or update target */
|
||||
if (editDistribution) {
|
||||
updateDistribution();
|
||||
} else {
|
||||
addNewDistribution();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +191,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
final String distSetTypeName = HawkbitCommonUtil
|
||||
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
||||
|
||||
if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) {
|
||||
if (duplicateCheck(name, version)) {
|
||||
final DistributionSet currentDS = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
||||
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
||||
@@ -250,23 +209,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
notificationMessage.displayValidationError(
|
||||
i18n.get("message.distribution.no.update", currentDS.getName() + ":" + currentDS.getVersion()));
|
||||
}
|
||||
closeThisWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
reqMigStepCheckboxListerner = event -> checkValueChanged(originalReqMigStep, event);
|
||||
descTextAreaListener = event -> checkValueChanged(originalDistDescription, event);
|
||||
distNameTextFieldListener = event -> checkValueChanged(originalDistName, event);
|
||||
distVersionTextFieldListener = event -> checkValueChanged(originalDistVersion, event);
|
||||
distsetTypeNameComboBoxListener = event -> checkValueChanged(originalDistSetType, event);
|
||||
reqMigStepCheckbox.addValueChangeListener(reqMigStepCheckboxListerner);
|
||||
descTextArea.addTextChangeListener(descTextAreaListener);
|
||||
distNameTextField.addTextChangeListener(distNameTextFieldListener);
|
||||
distVersionTextField.addTextChangeListener(distVersionTextFieldListener);
|
||||
distsetTypeNameComboBox.addValueChangeListener(distsetTypeNameComboBoxListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new Distribution set.
|
||||
*/
|
||||
@@ -277,7 +222,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
final String distSetTypeName = HawkbitCommonUtil
|
||||
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
||||
|
||||
if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) {
|
||||
if (duplicateCheck(name, version)) {
|
||||
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
||||
DistributionSet newDist = entityFactory.generateDistributionSet();
|
||||
@@ -287,21 +232,11 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
|
||||
notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success",
|
||||
new Object[] { newDist.getName(), newDist.getVersion() }));
|
||||
/* close the window */
|
||||
closeThisWindow();
|
||||
|
||||
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.NEW_ENTITY, newDist));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close window.
|
||||
*/
|
||||
private void closeThisWindow() {
|
||||
addDistributionWindow.close();
|
||||
UI.getCurrent().removeWindow(addDistributionWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Values for Distribution set.
|
||||
*
|
||||
@@ -345,47 +280,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mandatory Check.
|
||||
*
|
||||
* @param name
|
||||
* as String
|
||||
* @param version
|
||||
* as String
|
||||
* @param selectedJVM
|
||||
* as String
|
||||
* @param selectedAgentHub
|
||||
* as String
|
||||
* @param selectedOs
|
||||
* as String
|
||||
* @return boolean as flag
|
||||
*/
|
||||
private boolean mandatoryCheck(final String name, final String version, final String distSetTypeName) {
|
||||
|
||||
if (name == null || version == null || distSetTypeName == null) {
|
||||
if (name == null) {
|
||||
distNameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
}
|
||||
if (version == null) {
|
||||
distVersionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
}
|
||||
if (distSetTypeName == null) {
|
||||
distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
||||
}
|
||||
|
||||
notificationMessage.displayValidationError(i18n.get("message.mandatory.check"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void discardDistribution() {
|
||||
/* Just close this window */
|
||||
distsetTypeNameComboBox.removeValueChangeListener(distsetTypeNameComboBoxListener);
|
||||
closeThisWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all the fields.
|
||||
*/
|
||||
@@ -398,139 +292,52 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
||||
distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
||||
descTextArea.clear();
|
||||
reqMigStepCheckbox.clear();
|
||||
if (addDistributionWindow != null) {
|
||||
addDistributionWindow.setSaveButtonEnabled(true);
|
||||
}
|
||||
removeListeners();
|
||||
changedComponents.clear();
|
||||
|
||||
}
|
||||
|
||||
private void populateRequiredComponents() {
|
||||
populateDistSetTypeNameCombo();
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
reqMigStepCheckbox.removeValueChangeListener(reqMigStepCheckboxListerner);
|
||||
descTextArea.removeTextChangeListener(descTextAreaListener);
|
||||
distNameTextField.removeTextChangeListener(distNameTextFieldListener);
|
||||
distVersionTextField.removeTextChangeListener(distVersionTextFieldListener);
|
||||
}
|
||||
|
||||
public void setOriginalDistName(final String originalDistName) {
|
||||
this.originalDistName = originalDistName;
|
||||
}
|
||||
|
||||
public void setOriginalDistVersion(final String originalDistVersion) {
|
||||
this.originalDistVersion = originalDistVersion;
|
||||
}
|
||||
|
||||
public void setOriginalDistDescription(final String originalDistDescription) {
|
||||
this.originalDistDescription = originalDistDescription;
|
||||
}
|
||||
|
||||
private void checkValueChanged(final String originalValue, final TextChangeEvent event) {
|
||||
if (editDistribution) {
|
||||
final String newValue = event.getText();
|
||||
if (!originalValue.equalsIgnoreCase(newValue)) {
|
||||
changedComponents.add(event.getComponent());
|
||||
} else {
|
||||
changedComponents.remove(event.getComponent());
|
||||
}
|
||||
enableDisableSaveButton();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkValueChanged(final Boolean originalValue, final ValueChangeEvent event) {
|
||||
if (editDistribution) {
|
||||
if (!originalValue.equals(event.getProperty().getValue())) {
|
||||
changedComponents.add(reqMigStepCheckbox);
|
||||
} else {
|
||||
changedComponents.remove(reqMigStepCheckbox);
|
||||
}
|
||||
enableDisableSaveButton();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkValueChanged(final String originalValue, final ValueChangeEvent event) {
|
||||
if (editDistribution) {
|
||||
if (!originalValue.equals(event.getProperty().getValue())) {
|
||||
changedComponents.add(distsetTypeNameComboBox);
|
||||
} else {
|
||||
changedComponents.remove(distsetTypeNameComboBox);
|
||||
}
|
||||
enableDisableSaveButton();
|
||||
}
|
||||
}
|
||||
|
||||
private void enableDisableSaveButton() {
|
||||
if (changedComponents.isEmpty()) {
|
||||
disableSaveButton();
|
||||
} else {
|
||||
enableSaveButton();
|
||||
}
|
||||
}
|
||||
|
||||
private void setOriginalReqMigStep(final Boolean originalReqMigStep) {
|
||||
this.originalReqMigStep = originalReqMigStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* populate data.
|
||||
*
|
||||
* @param editDistId
|
||||
*/
|
||||
public void populateValuesOfDistribution(final Long editDistId) {
|
||||
private void populateValuesOfDistribution(final Long editDistId) {
|
||||
this.editDistId = editDistId;
|
||||
editDistribution = Boolean.TRUE;
|
||||
addDistributionWindow.setSaveButtonEnabled(false);
|
||||
|
||||
if (editDistId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
||||
if (distSet != null) {
|
||||
distNameTextField.setValue(distSet.getName());
|
||||
distVersionTextField.setValue(distSet.getVersion());
|
||||
if (distSet.getType().isDeleted()) {
|
||||
distsetTypeNameComboBox.addItem(distSet.getType().getName());
|
||||
}
|
||||
distsetTypeNameComboBox.setValue(distSet.getType().getName());
|
||||
reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep());
|
||||
if (distSet.getDescription() != null) {
|
||||
descTextArea.setValue(distSet.getDescription());
|
||||
}
|
||||
setOriginalDistName(distSet.getName());
|
||||
setOriginalDistVersion(distSet.getVersion());
|
||||
setOriginalDistDescription(distSet.getDescription());
|
||||
setOriginalReqMigStep(distSet.isRequiredMigrationStep());
|
||||
setOriginalDistSetTYpe(distSet.getType().getName());
|
||||
addListeners();
|
||||
if (distSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
editDistribution = Boolean.TRUE;
|
||||
distNameTextField.setValue(distSet.getName());
|
||||
distVersionTextField.setValue(distSet.getVersion());
|
||||
if (distSet.getType().isDeleted()) {
|
||||
distsetTypeNameComboBox.addItem(distSet.getType().getName());
|
||||
}
|
||||
distsetTypeNameComboBox.setValue(distSet.getType().getName());
|
||||
reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep());
|
||||
if (distSet.getDescription() != null) {
|
||||
descTextArea.setValue(distSet.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
public CommonDialogWindow getWindow() {
|
||||
public CommonDialogWindow getWindow(final Long editDistId) {
|
||||
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
||||
populateRequiredComponents();
|
||||
resetComponents();
|
||||
addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(),
|
||||
null);
|
||||
addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
||||
|
||||
return addDistributionWindow;
|
||||
populateDistSetTypeNameCombo();
|
||||
populateValuesOfDistribution(editDistId);
|
||||
window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), null, null, formLayout, i18n);
|
||||
window.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate DistributionSet Type name combo.
|
||||
*/
|
||||
public void populateDistSetTypeNameCombo() {
|
||||
private void populateDistSetTypeNameCombo() {
|
||||
distsetTypeNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer());
|
||||
distsetTypeNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||
distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param originalDistSetTYpe
|
||||
* the originalDistSetTYpe to set
|
||||
*/
|
||||
public void setOriginalDistSetTYpe(final String originalDistSetType) {
|
||||
this.originalDistSetType = originalDistSetType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,11 +8,18 @@
|
||||
*/
|
||||
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.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
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.tagdetails.DistributionTagToken;
|
||||
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.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
@@ -46,16 +53,48 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
||||
|
||||
@Autowired
|
||||
private DistributionTagToken distributionTagToken;
|
||||
|
||||
@Autowired
|
||||
private transient DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private DsMetadataPopupLayout dsMetadataPopupLayout;
|
||||
|
||||
@Autowired
|
||||
private EntityFactory entityFactory;
|
||||
|
||||
private SoftwareModuleDetailsTable softwareModuleTable;
|
||||
|
||||
private DistributionSetMetadatadetailslayout dsMetadataTable;
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
softwareModuleTable = new SoftwareModuleDetailsTable();
|
||||
softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null);
|
||||
|
||||
dsMetadataTable = new DistributionSetMetadatadetailslayout();
|
||||
dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement,
|
||||
dsMetadataPopupLayout,entityFactory);
|
||||
|
||||
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)
|
||||
void onEvent(final DistributionTableEvent distributionTableEvent) {
|
||||
onBaseEntityEvent(distributionTableEvent);
|
||||
@@ -73,12 +112,12 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
||||
detailsTab.addTab(createSoftwareModuleTab(), getI18n().get("caption.softwares.distdetail.tab"), null);
|
||||
detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null);
|
||||
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
|
||||
detailsTab.addTab(dsMetadataTable, getI18n().get("caption.metadata"), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEdit(final ClickEvent event) {
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
||||
distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId());
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId());
|
||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||
UI.getCurrent().addWindow(newDistWindow);
|
||||
newDistWindow.setVisible(Boolean.TRUE);
|
||||
@@ -114,8 +153,15 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
||||
protected void populateDetailsWidget() {
|
||||
softwareModuleTable.populateModule(getSelectedBaseEntity());
|
||||
populateDetails(getSelectedBaseEntity());
|
||||
populateMetadataDetails();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void populateMetadataDetails(){
|
||||
dsMetadataTable.populateDSMetadata(getSelectedBaseEntity());
|
||||
}
|
||||
|
||||
private void populateDetails(final DistributionSet ds) {
|
||||
if (ds != null) {
|
||||
@@ -160,5 +206,30 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
||||
protected String getDetailsHeaderCaptionId() {
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
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.BaseEntityEventType;
|
||||
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.DistributionTableFilterEvent;
|
||||
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.Component;
|
||||
import com.vaadin.ui.DragAndDropWrapper;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.UI;
|
||||
|
||||
@@ -86,12 +90,18 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
|
||||
|
||||
@Autowired
|
||||
private ManagementViewAcceptCriteria managementViewAcceptCriteria;
|
||||
|
||||
|
||||
@Autowired
|
||||
private transient TargetManagement targetService;
|
||||
|
||||
@Autowired
|
||||
private DsMetadataPopupLayout dsMetadataPopupLayout;
|
||||
|
||||
@Autowired
|
||||
private transient DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private EntityFactory entityFactory;
|
||||
|
||||
private String notAllowedMsg;
|
||||
|
||||
@@ -219,10 +229,35 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
|
||||
|
||||
@Override
|
||||
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
|
||||
protected boolean isFirstRowSelectedOnLoad() {
|
||||
@@ -246,6 +281,10 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
|
||||
@Override
|
||||
protected void publishEntityAfterValueChange(final DistributionSet selectedLastEntity) {
|
||||
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity));
|
||||
if(selectedLastEntity!=null){
|
||||
managementUIState.setLastSelectedDistribution(new DistributionSetIdName(selectedLastEntity.getId(),
|
||||
selectedLastEntity.getName(),selectedLastEntity.getVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -264,7 +303,7 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
|
||||
if (isMaximized()) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -657,5 +696,12 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ public class DistributionTableHeader extends AbstractTableHeader {
|
||||
|
||||
@Override
|
||||
protected void addNewItem(final ClickEvent event) {
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(null);
|
||||
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
||||
UI.getCurrent().addWindow(newDistWindow);
|
||||
newDistWindow.setVisible(Boolean.TRUE);
|
||||
|
||||
@@ -32,9 +32,7 @@ import com.vaadin.ui.Button.ClickEvent;
|
||||
import com.vaadin.ui.UI;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for Create/Update Tag Layout of distribution set
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
@@ -87,16 +85,13 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat
|
||||
*/
|
||||
@Override
|
||||
public void save(final ClickEvent event) {
|
||||
if (mandatoryValuesPresent()) {
|
||||
final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTagStr)) {
|
||||
if (!checkIsDuplicate(existingDistTag)) {
|
||||
createNewTag();
|
||||
}
|
||||
} else {
|
||||
|
||||
updateExistingTag(existingDistTag);
|
||||
final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTagStr)) {
|
||||
if (!checkIsDuplicate(existingDistTag)) {
|
||||
createNewTag();
|
||||
}
|
||||
} else {
|
||||
updateExistingTag(existingDistTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,4 +176,9 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat
|
||||
setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(),
|
||||
permChecker.hasUpdateDistributionPermission());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWindowCaption() {
|
||||
return i18n.get("caption.add.tag");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import javax.annotation.PostConstruct;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroup;
|
||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||
@@ -98,6 +99,7 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout {
|
||||
addComponent(forceLabel);
|
||||
|
||||
final FlexibleOptionGroupItemComponent softItem = actionTypeOptionGroup.getItemComponent(ActionTypeOption.SOFT);
|
||||
softItem.setId(SPUIComponentIdProvider.ACTION_DETAILS_SOFT_ID);
|
||||
softItem.setStyleName(STYLE_DIST_WINDOW_ACTIONTYPE);
|
||||
addComponent(softItem);
|
||||
final Label softLabel = new Label();
|
||||
|
||||
@@ -87,6 +87,22 @@ public class ManagementUIState implements ManagmentEntityState<DistributionSetId
|
||||
private boolean customFilterSelected;
|
||||
|
||||
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
|
||||
|
||||
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.management.tag;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.vaadin.data.Property;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
@@ -44,7 +46,7 @@ public final class SpColorPickerPreview extends ColorPickerPreview implements Te
|
||||
try {
|
||||
final Field textField = ColorPickerPreview.class.getDeclaredField("field");
|
||||
textField.setAccessible(true);
|
||||
((TextField) textField.get(this)).setId("color-preview-field");
|
||||
((TextField) textField.get(this)).setId(SPUIComponentIdProvider.COLOR_PREVIEW_FIELD);
|
||||
((TextField) textField.get(this)).addTextChangeListener(this);
|
||||
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
|
||||
Throwables.propagate(e);
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
@@ -31,30 +32,23 @@ import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
|
||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
||||
import com.vaadin.event.FieldEvents.TextChangeListener;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.VaadinSessionScope;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Add and Update Target.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@VaadinSessionScope
|
||||
public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
private static final long serialVersionUID = -6659290471705262389L;
|
||||
|
||||
|
||||
@Autowired
|
||||
private I18N i18n;
|
||||
|
||||
@@ -66,122 +60,61 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
|
||||
@Autowired
|
||||
private transient UINotification uINotification;
|
||||
|
||||
|
||||
@Autowired
|
||||
private transient EntityFactory entityFactory;
|
||||
|
||||
|
||||
private TextField controllerIDTextField;
|
||||
private TextField nameTextField;
|
||||
private TextArea descTextArea;
|
||||
private Label madatoryLabel;
|
||||
private boolean editTarget = Boolean.FALSE;
|
||||
private String controllerId;
|
||||
private FormLayout formLayout;
|
||||
private CommonDialogWindow window;
|
||||
|
||||
private String oldTargetName;
|
||||
private String oldTargetDesc;
|
||||
|
||||
/**
|
||||
* Initialize the Add Update Window Component for Target.
|
||||
*/
|
||||
public void init() {
|
||||
/* create components */
|
||||
createRequiredComponents();
|
||||
/* display components in layout */
|
||||
buildLayout();
|
||||
/* register all listeners related to the Window */
|
||||
addListeners();
|
||||
setCompositionRoot(formLayout);
|
||||
}
|
||||
|
||||
private void createRequiredComponents() {
|
||||
/* Textfield for controller Id */
|
||||
controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null,
|
||||
i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||
controllerIDTextField = SPUIComponentProvider.getTextField(i18n.get("prompt.target.id"), "",
|
||||
ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true,
|
||||
SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||
controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID);
|
||||
|
||||
/* Textfield for target name */
|
||||
nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null,
|
||||
i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||
nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY,
|
||||
false, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||
nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME);
|
||||
|
||||
/* Textarea for target description */
|
||||
descTextArea = SPUIComponentProvider.getTextArea( i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTFIELD_TINY, false, null,
|
||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style",
|
||||
ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.description"),
|
||||
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||
descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC);
|
||||
descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY);
|
||||
|
||||
/* Label for mandatory symbol */
|
||||
madatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
||||
madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
||||
}
|
||||
|
||||
private void buildLayout() {
|
||||
|
||||
|
||||
/*
|
||||
* The main layout of the window contains mandatory info, textboxes
|
||||
* (controller Id, name & description) and action buttons layout
|
||||
*/
|
||||
setSizeUndefined();
|
||||
formLayout = new FormLayout();
|
||||
formLayout.addComponent(madatoryLabel);
|
||||
formLayout.addComponent(controllerIDTextField);
|
||||
formLayout.addComponent(nameTextField);
|
||||
formLayout.addComponent(descTextArea);
|
||||
|
||||
if (Boolean.TRUE.equals(editTarget)) {
|
||||
madatoryLabel.setVisible(Boolean.FALSE);
|
||||
}
|
||||
|
||||
controllerIDTextField.focus();
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
|
||||
addTargetNameChangeListner();
|
||||
addTargetDescChangeListner();
|
||||
}
|
||||
|
||||
private void addTargetNameChangeListner() {
|
||||
nameTextField.addTextChangeListener(new TextChangeListener() {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1761855781481115921L;
|
||||
|
||||
@Override
|
||||
public void textChange(final TextChangeEvent event) {
|
||||
if (event.getText().equals(oldTargetName) && descTextArea.getValue().equals(oldTargetDesc)) {
|
||||
window.setSaveButtonEnabled(false);
|
||||
} else {
|
||||
window.setSaveButtonEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addTargetDescChangeListner() {
|
||||
descTextArea.addTextChangeListener(new TextChangeListener() {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 5770734934988115068L;
|
||||
|
||||
@Override
|
||||
public void textChange(final TextChangeEvent event) {
|
||||
if (event.getText().equals(oldTargetDesc) && nameTextField.getValue().equals(oldTargetName)) {
|
||||
window.setSaveButtonEnabled(false);
|
||||
} else {
|
||||
window.setSaveButtonEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Target if modified.
|
||||
*/
|
||||
@@ -199,10 +132,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
uINotification.displaySuccess(i18n.get("message.update.success", new Object[] { latestTarget.getName() }));
|
||||
// publishing through event bus
|
||||
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.UPDATED_ENTITY, latestTarget));
|
||||
|
||||
/* close the window */
|
||||
closeThisWindow();
|
||||
/* update details in table */
|
||||
}
|
||||
|
||||
private void saveTargetListner() {
|
||||
@@ -213,13 +142,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
}
|
||||
}
|
||||
|
||||
private void discardTargetListner() {
|
||||
closeThisWindow();
|
||||
}
|
||||
|
||||
private void addNewTarget() {
|
||||
final String newControlllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerIDTextField.getValue());
|
||||
if (mandatoryCheck(newControlllerId) && duplicateCheck(newControlllerId)) {
|
||||
if (duplicateCheck(newControlllerId)) {
|
||||
final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
||||
final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||
|
||||
@@ -236,15 +161,20 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
|
||||
/* display success msg */
|
||||
uINotification.displaySuccess(i18n.get("message.save.success", new Object[] { newTarget.getName() }));
|
||||
/* close the window */
|
||||
closeThisWindow();
|
||||
}
|
||||
}
|
||||
|
||||
public Window getWindow() {
|
||||
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null);
|
||||
window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.target"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), null, null, formLayout, i18n);
|
||||
return window;
|
||||
}
|
||||
|
||||
public Window getWindow(final String entityId) {
|
||||
populateValuesOfTarget(entityId);
|
||||
getWindow();
|
||||
window.addStyleName("target-update-window");
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -254,39 +184,23 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
public void resetComponents() {
|
||||
nameTextField.clear();
|
||||
nameTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
controllerIDTextField.setEnabled(true);
|
||||
controllerIDTextField.setReadOnly(false);
|
||||
controllerIDTextField.setEnabled(Boolean.TRUE);
|
||||
controllerIDTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
controllerIDTextField.clear();
|
||||
descTextArea.clear();
|
||||
editTarget = Boolean.FALSE;
|
||||
}
|
||||
|
||||
private void closeThisWindow() {
|
||||
editTarget = Boolean.FALSE;
|
||||
window.close();
|
||||
UI.getCurrent().removeWindow(window);
|
||||
}
|
||||
|
||||
private void setTargetValues(final Target target, final String name, final String description) {
|
||||
target.setName(name == null ? target.getControllerId() : name);
|
||||
target.setDescription(description);
|
||||
}
|
||||
|
||||
private boolean mandatoryCheck(final String newControlllerId) {
|
||||
if (newControlllerId == null) {
|
||||
controllerIDTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||
uINotification.displayValidationError("Mandatory details are missing");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean duplicateCheck(final String newControlllerId) {
|
||||
final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim());
|
||||
if (existingTarget != null) {
|
||||
uINotification.displayValidationError(i18n.get("message.target.duplicate.check"));
|
||||
uINotification.displayValidationError(
|
||||
i18n.get("message.target.duplicate.check", new Object[] { newControlllerId }));
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -296,22 +210,21 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
||||
/**
|
||||
* @param controllerId
|
||||
*/
|
||||
public void populateValuesOfTarget(final String controllerId) {
|
||||
private void populateValuesOfTarget(final String controllerId) {
|
||||
resetComponents();
|
||||
this.controllerId = controllerId;
|
||||
editTarget = Boolean.TRUE;
|
||||
final Target target = targetManagement.findTargetByControllerID(controllerId);
|
||||
controllerIDTextField.setValue(target.getControllerId());
|
||||
controllerIDTextField.setReadOnly(Boolean.TRUE);
|
||||
controllerIDTextField.setEnabled(Boolean.FALSE);
|
||||
nameTextField.setValue(target.getName());
|
||||
if (target.getDescription() != null) {
|
||||
descTextArea.setValue(target.getDescription());
|
||||
}
|
||||
window.setSaveButtonEnabled(Boolean.FALSE);
|
||||
}
|
||||
|
||||
oldTargetDesc = descTextArea.getValue();
|
||||
oldTargetName = nameTextField.getValue();
|
||||
window.addStyleName("target-update-window");
|
||||
public FormLayout getFormLayout() {
|
||||
return formLayout;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import com.google.common.base.Strings;
|
||||
public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
||||
private static final long serialVersionUID = -5645680058303167558L;
|
||||
private Sort sort = new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
|
||||
private Collection<TargetUpdateStatus> status = null;
|
||||
private transient Collection<TargetUpdateStatus> status = null;
|
||||
private String[] targetTags = null;
|
||||
private Long distributionId = null;
|
||||
private String searchText = null;
|
||||
|
||||
@@ -106,8 +106,13 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
||||
if (getSelectedBaseEntity() == null) {
|
||||
return;
|
||||
}
|
||||
targetAddUpdateWindowLayout.getWindow(getSelectedBaseEntity().getControllerId());
|
||||
// targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId());
|
||||
openWindow();
|
||||
}
|
||||
|
||||
private void openWindow() {
|
||||
final Window newDistWindow = targetAddUpdateWindowLayout.getWindow();
|
||||
targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId());
|
||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||
UI.getCurrent().addWindow(newDistWindow);
|
||||
newDistWindow.setVisible(Boolean.TRUE);
|
||||
@@ -248,4 +253,24 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -102,15 +102,13 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
||||
|
||||
@Override
|
||||
public void save(final ClickEvent event) {
|
||||
if (mandatoryValuesPresent()) {
|
||||
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTagStr)) {
|
||||
if (!checkIsDuplicate(existingTag)) {
|
||||
createNewTag();
|
||||
}
|
||||
} else {
|
||||
updateExistingTag(existingTag);
|
||||
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
||||
if (optiongroup.getValue().equals(createTagStr)) {
|
||||
if (!checkIsDuplicate(existingTag)) {
|
||||
createNewTag();
|
||||
}
|
||||
} else {
|
||||
updateExistingTag(existingTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +129,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
||||
}
|
||||
newTargetTag = tagManagement.createTargetTag(newTargetTag);
|
||||
displaySuccess(newTargetTag.getName());
|
||||
closeWindow();
|
||||
} else {
|
||||
displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME));
|
||||
}
|
||||
@@ -150,4 +147,9 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
||||
setOptionGroupDefaultValue(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWindowCaption() {
|
||||
return i18n.get("caption.add.tag");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.UiProperties;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||
import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout;
|
||||
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption;
|
||||
@@ -56,8 +57,10 @@ import com.vaadin.data.Container;
|
||||
import com.vaadin.data.Item;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
import com.vaadin.data.Validator;
|
||||
import com.vaadin.data.util.converter.StringToIntegerConverter;
|
||||
import com.vaadin.data.validator.IntegerRangeValidator;
|
||||
import com.vaadin.data.validator.RegexpValidator;
|
||||
import com.vaadin.data.validator.NullValidator;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
@@ -66,13 +69,10 @@ import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.OptionGroup;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* Rollout add or update popup layout.
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
@@ -86,8 +86,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
private static final String MESSAGE_ENTER_NUMBER = "message.enter.number";
|
||||
|
||||
private static final String NUMBER_REGEXP = "[-]?[0-9]*\\.?,?[0-9]+";
|
||||
|
||||
@Autowired
|
||||
private ActionTypeOptionGroupLayout actionTypeOptionGroupLayout;
|
||||
|
||||
@@ -115,8 +113,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
@Autowired
|
||||
private transient EventBus.SessionEventBus eventBus;
|
||||
|
||||
private Label mandatoryLabel;
|
||||
|
||||
private TextField rolloutName;
|
||||
|
||||
private ComboBox distributionSet;
|
||||
@@ -135,7 +131,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
private OptionGroup errorThresholdOptionGroup;
|
||||
|
||||
private CommonDialogWindow addUpdateRolloutWindow;
|
||||
private CommonDialogWindow window;
|
||||
|
||||
private Boolean editRolloutEnabled;
|
||||
|
||||
@@ -147,22 +143,28 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
private TextArea targetFilterQuery;
|
||||
|
||||
private final NullValidator nullValidator = new NullValidator(null, false);
|
||||
|
||||
/**
|
||||
* Create components and layout.
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
setSizeUndefined();
|
||||
createRequiredComponents();
|
||||
buildLayout();
|
||||
}
|
||||
|
||||
public CommonDialogWindow getWindow() {
|
||||
public CommonDialogWindow getWindow(final Long rolloutId) {
|
||||
window = getWindow();
|
||||
populateData(rolloutId);
|
||||
return window;
|
||||
}
|
||||
|
||||
addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(),
|
||||
uiProperties.getLinks().getDocumentation().getRolloutView());
|
||||
return addUpdateRolloutWindow;
|
||||
public CommonDialogWindow getWindow() {
|
||||
resetComponents();
|
||||
return SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null,
|
||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null,
|
||||
uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,10 +181,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
setDefaultSaveStartGroupOption();
|
||||
totalTargetsLabel.setVisible(false);
|
||||
groupSizeLabel.setVisible(false);
|
||||
removeComponent(targetFilterQuery);
|
||||
if (getComponent(1, 3) == null) {
|
||||
addComponent(targetFilterQueryCombo, 1, 3);
|
||||
}
|
||||
removeComponent(1, 2);
|
||||
addComponent(targetFilterQueryCombo, 1, 2);
|
||||
actionTypeOptionGroupLayout.selectDefaultOption();
|
||||
totalTargetsCount = 0L;
|
||||
rolloutForEdit = null;
|
||||
@@ -206,37 +206,60 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
setSizeUndefined();
|
||||
setRows(9);
|
||||
setColumns(3);
|
||||
setStyleName("marginTop");
|
||||
|
||||
addComponent(mandatoryLabel, 1, 0, 2, 0);
|
||||
addComponent(getLabel("textfield.name"), 0, 1);
|
||||
addComponent(rolloutName, 1, 1);
|
||||
addComponent(getLabel("prompt.distribution.set"), 0, 2);
|
||||
addComponent(distributionSet, 1, 2);
|
||||
addComponent(getLabel("prompt.target.filter"), 0, 3);
|
||||
addComponent(targetFilterQueryCombo, 1, 3);
|
||||
addComponent(totalTargetsLabel, 2, 3);
|
||||
addComponent(getLabel("prompt.number.of.groups"), 0, 4);
|
||||
addComponent(noOfGroups, 1, 4);
|
||||
addComponent(groupSizeLabel, 2, 4);
|
||||
addComponent(getLabel("prompt.tigger.threshold"), 0, 5);
|
||||
addComponent(triggerThreshold, 1, 5);
|
||||
addComponent(getPercentHintLabel(), 2, 5);
|
||||
addComponent(getLabel("prompt.error.threshold"), 0, 6);
|
||||
addComponent(errorThreshold, 1, 6);
|
||||
addComponent(errorThresholdOptionGroup, 2, 6);
|
||||
addComponent(getLabel("textfield.description"), 0, 7);
|
||||
addComponent(description, 1, 7, 2, 7);
|
||||
addComponent(actionTypeOptionGroupLayout, 0, 8, 2, 8);
|
||||
addComponent(getMandatoryLabel("textfield.name"), 0, 0);
|
||||
addComponent(rolloutName, 1, 0);
|
||||
rolloutName.addValidator(nullValidator);
|
||||
|
||||
addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1);
|
||||
addComponent(distributionSet, 1, 1);
|
||||
distributionSet.addValidator(nullValidator);
|
||||
|
||||
addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2);
|
||||
addComponent(targetFilterQueryCombo, 1, 2);
|
||||
targetFilterQueryCombo.addValidator(nullValidator);
|
||||
targetFilterQuery.removeValidator(nullValidator);
|
||||
|
||||
addComponent(totalTargetsLabel, 2, 2);
|
||||
|
||||
addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3);
|
||||
addComponent(noOfGroups, 1, 3);
|
||||
noOfGroups.addValidator(nullValidator);
|
||||
|
||||
addComponent(groupSizeLabel, 2, 3);
|
||||
|
||||
addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4);
|
||||
addComponent(triggerThreshold, 1, 4);
|
||||
triggerThreshold.addValidator(nullValidator);
|
||||
|
||||
addComponent(getPercentHintLabel(), 2, 4);
|
||||
|
||||
addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5);
|
||||
addComponent(errorThreshold, 1, 5);
|
||||
errorThreshold.addValidator(nullValidator);
|
||||
addComponent(errorThresholdOptionGroup, 2, 5);
|
||||
|
||||
addComponent(getLabel("textfield.description"), 0, 6);
|
||||
addComponent(description, 1, 6, 2, 6);
|
||||
addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7);
|
||||
|
||||
rolloutName.focus();
|
||||
}
|
||||
|
||||
private Label getMandatoryLabel(final String key) {
|
||||
final Label mandatoryLabel = getLabel(i18n.get(key));
|
||||
mandatoryLabel.setContentMode(ContentMode.HTML);
|
||||
mandatoryLabel.setValue(mandatoryLabel.getValue().concat(" <span style='color:#ed473b'>*</span>"));
|
||||
return mandatoryLabel;
|
||||
}
|
||||
|
||||
private Label getLabel(final String key) {
|
||||
return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE);
|
||||
}
|
||||
|
||||
private TextField getTextfield(final String key) {
|
||||
return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get(key), true,
|
||||
return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get(key), true,
|
||||
SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||
}
|
||||
|
||||
@@ -248,7 +271,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
}
|
||||
|
||||
private void createRequiredComponents() {
|
||||
mandatoryLabel = createMandatoryLabel();
|
||||
rolloutName = createRolloutNameField();
|
||||
distributionSet = createDistributionSetCombo();
|
||||
populateDistributionSet();
|
||||
@@ -258,7 +280,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
noOfGroups = createNoOfGroupsField();
|
||||
groupSizeLabel = createGroupSizeLabel();
|
||||
triggerThreshold = createTriggerThresold();
|
||||
triggerThreshold = createTriggerThreshold();
|
||||
errorThreshold = createErrorThreshold();
|
||||
description = createDescription();
|
||||
errorThresholdOptionGroup = createErrorThresholdOptionGroup();
|
||||
@@ -307,11 +329,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
|
||||
errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP);
|
||||
errorThresoldOptions.setSizeUndefined();
|
||||
errorThresoldOptions.addValueChangeListener(this::onErrorThresoldOptionChange);
|
||||
errorThresoldOptions.addValueChangeListener(this::listenerOnErrorThresoldOptionChange);
|
||||
return errorThresoldOptions;
|
||||
}
|
||||
|
||||
private void onErrorThresoldOptionChange(final ValueChangeEvent event) {
|
||||
private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) {
|
||||
errorThreshold.clear();
|
||||
errorThreshold.removeAllValidators();
|
||||
if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) {
|
||||
@@ -324,17 +346,17 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
private ComboBox createTargetFilterQueryCombo() {
|
||||
final ComboBox targetFilter = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL,
|
||||
true, "", i18n.get("prompt.target.filter"));
|
||||
false, "", i18n.get("prompt.target.filter"));
|
||||
targetFilter.setImmediate(true);
|
||||
targetFilter.setPageLength(7);
|
||||
targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||
targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID);
|
||||
targetFilter.setSizeUndefined();
|
||||
targetFilter.addValueChangeListener(event -> onTargetFilterChange());
|
||||
targetFilter.addValueChangeListener(this::onTargetFilterChange);
|
||||
return targetFilter;
|
||||
}
|
||||
|
||||
private void onTargetFilterChange() {
|
||||
private void onTargetFilterChange(final ValueChangeEvent event) {
|
||||
final String filterQueryString = getTargetFilterQuery();
|
||||
if (!Strings.isNullOrEmpty(filterQueryString)) {
|
||||
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString);
|
||||
@@ -344,7 +366,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
totalTargetsCount = 0L;
|
||||
totalTargetsLabel.setVisible(false);
|
||||
}
|
||||
onGroupNumberChange();
|
||||
onGroupNumberChange(event);
|
||||
}
|
||||
|
||||
private String getTotalTargetMessage() {
|
||||
@@ -368,10 +390,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
targetFilterQF);
|
||||
}
|
||||
|
||||
private void onDiscard() {
|
||||
closeThisWindow();
|
||||
}
|
||||
|
||||
private void onRolloutSave() {
|
||||
if (editRolloutEnabled) {
|
||||
editRollout();
|
||||
@@ -381,7 +399,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
}
|
||||
|
||||
private void editRollout() {
|
||||
if (mandatoryCheckForEdit() && validateFields() && duplicateCheckForEdit() && null != rolloutForEdit) {
|
||||
if (duplicateCheckForEdit() && rolloutForEdit != null) {
|
||||
rolloutForEdit.setName(rolloutName.getValue());
|
||||
rolloutForEdit.setDescription(description.getValue());
|
||||
final DistributionSetIdName distributionSetIdName = (DistributionSetIdName) distributionSet.getValue();
|
||||
@@ -399,7 +417,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
final Rollout updatedRollout = rolloutManagement.updateRollout(rolloutForEdit);
|
||||
uiNotification
|
||||
.displaySuccess(i18n.get("message.update.success", new Object[] { updatedRollout.getName() }));
|
||||
closeThisWindow();
|
||||
eventBus.publish(this, RolloutEvent.UPDATE_ROLLOUT);
|
||||
}
|
||||
}
|
||||
@@ -427,11 +444,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
}
|
||||
|
||||
private void createRollout() {
|
||||
if (mandatoryCheck() && validateFields() && duplicateCheck()) {
|
||||
if (duplicateCheck()) {
|
||||
final Rollout rolloutToCreate = saveRollout();
|
||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { rolloutToCreate.getName() }));
|
||||
eventBus.publish(this, RolloutEvent.CREATE_ROLLOUT);
|
||||
closeThisWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,48 +504,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void closeThisWindow() {
|
||||
addUpdateRolloutWindow.close();
|
||||
UI.getCurrent().removeWindow(addUpdateRolloutWindow);
|
||||
}
|
||||
|
||||
private boolean mandatoryCheck() {
|
||||
final DistributionSetIdName ds = getDistributionSetSelected();
|
||||
final String targetFilter = (String) targetFilterQueryCombo.getValue();
|
||||
final String triggerThresoldValue = triggerThreshold.getValue();
|
||||
final String errorThresoldValue = errorThreshold.getValue();
|
||||
if (hasNoNameOrTargetFilter(targetFilter) || ds == null
|
||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
||||
|| isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) {
|
||||
uiNotification.displayValidationError(i18n.get("message.mandatory.check"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mandatoryCheckForEdit() {
|
||||
final DistributionSetIdName ds = getDistributionSetSelected();
|
||||
final String targetFilter = targetFilterQuery.getValue();
|
||||
final String triggerThresoldValue = triggerThreshold.getValue();
|
||||
final String errorThresoldValue = errorThreshold.getValue();
|
||||
if (hasNoNameOrTargetFilter(targetFilter) || ds == null
|
||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
||||
|| isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) {
|
||||
uiNotification.displayValidationError(i18n.get("message.mandatory.check"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasNoNameOrTargetFilter(final String targetFilter) {
|
||||
return getRolloutName() == null || targetFilter == null;
|
||||
}
|
||||
|
||||
private boolean isThresholdValueMissing(final String triggerThresoldValue, final String errorThresoldValue) {
|
||||
return HawkbitCommonUtil.trimAndNullIfEmpty(triggerThresoldValue) == null
|
||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(errorThresoldValue) == null;
|
||||
}
|
||||
|
||||
private boolean duplicateCheck() {
|
||||
if (rolloutManagement.findRolloutByName(getRolloutName()) != null) {
|
||||
uiNotification.displayValidationError(
|
||||
@@ -555,17 +529,23 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
private TextField createErrorThreshold() {
|
||||
final TextField errorField = getTextfield("prompt.error.threshold");
|
||||
errorField.setNullRepresentation("");
|
||||
errorField.addValidator(new ThresholdFieldValidator());
|
||||
errorField.setConverter(new StringToIntegerConverter());
|
||||
errorField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||
errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID);
|
||||
errorField.setMaxLength(7);
|
||||
errorField.setSizeUndefined();
|
||||
return errorField;
|
||||
}
|
||||
|
||||
private TextField createTriggerThresold() {
|
||||
private TextField createTriggerThreshold() {
|
||||
final TextField thresholdField = getTextfield("prompt.tigger.threshold");
|
||||
thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID);
|
||||
thresholdField.setNullRepresentation("");
|
||||
thresholdField.addValidator(new ThresholdFieldValidator());
|
||||
thresholdField.setConverter(new StringToIntegerConverter());
|
||||
thresholdField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||
thresholdField.setSizeUndefined();
|
||||
thresholdField.setMaxLength(3);
|
||||
return thresholdField;
|
||||
@@ -577,12 +557,15 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
noOfGroupsField.addValidator(new GroupNumberValidator());
|
||||
noOfGroupsField.setSizeUndefined();
|
||||
noOfGroupsField.setMaxLength(3);
|
||||
noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange());
|
||||
noOfGroupsField.setConverter(new StringToIntegerConverter());
|
||||
noOfGroupsField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||
noOfGroupsField.addValueChangeListener(this::onGroupNumberChange);
|
||||
noOfGroupsField.setNullRepresentation("");
|
||||
return noOfGroupsField;
|
||||
}
|
||||
|
||||
private void onGroupNumberChange() {
|
||||
if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) {
|
||||
private void onGroupNumberChange(final ValueChangeEvent event) {
|
||||
if (event.getProperty().getValue() != null && noOfGroups.isValid()) {
|
||||
groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize())));
|
||||
groupSizeLabel.setVisible(true);
|
||||
} else {
|
||||
@@ -591,8 +574,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
}
|
||||
|
||||
private ComboBox createDistributionSetCombo() {
|
||||
final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, true, "",
|
||||
i18n.get("prompt.distribution.set"));
|
||||
final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, false,
|
||||
"", i18n.get("prompt.distribution.set"));
|
||||
dsSet.setImmediate(true);
|
||||
dsSet.setPageLength(7);
|
||||
dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||
@@ -612,7 +595,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
return new LazyQueryContainer(
|
||||
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME),
|
||||
distributionQF);
|
||||
|
||||
}
|
||||
|
||||
private TextField createRolloutNameField() {
|
||||
@@ -622,44 +604,42 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
return rolloutNameField;
|
||||
}
|
||||
|
||||
private Label createMandatoryLabel() {
|
||||
final Label madatoryLbl = new Label(i18n.get("label.mandatory.field"));
|
||||
madatoryLbl.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
||||
return madatoryLbl;
|
||||
}
|
||||
|
||||
private String getRolloutName() {
|
||||
return HawkbitCommonUtil.trimAndNullIfEmpty(rolloutName.getValue());
|
||||
}
|
||||
|
||||
private DistributionSetIdName getDistributionSetSelected() {
|
||||
return (DistributionSetIdName) distributionSet.getValue();
|
||||
}
|
||||
|
||||
class ErrorThresoldOptionValidator implements Validator {
|
||||
private static final long serialVersionUID = 9049939751976326550L;
|
||||
|
||||
@Override
|
||||
public void validate(final Object value) {
|
||||
try {
|
||||
if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
||||
|| HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null) {
|
||||
if (isNoOfGroupsOrTargetFilterEmpty()) {
|
||||
uiNotification
|
||||
.displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing"));
|
||||
} else {
|
||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
||||
final int groupSize = getGroupSize();
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize)
|
||||
.validate(Integer.valueOf(value.toString()));
|
||||
if (value != null) {
|
||||
final int groupSize = getGroupSize();
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0,
|
||||
groupSize).validate(Integer.valueOf(value.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// suppress the need of preserve original exception, will blow
|
||||
// up the
|
||||
// log and not necessary here
|
||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
||||
LOG.error(ex.getMessage());
|
||||
catch (final InvalidValueException ex) {
|
||||
// we have to throw the exception here, otherwise the UI won't
|
||||
// show the vaadin validation error!
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNoOfGroupsOrTargetFilterEmpty() {
|
||||
return HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
||||
|| (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null
|
||||
&& targetFilterQuery.getValue() == null);
|
||||
}
|
||||
}
|
||||
|
||||
private int getGroupSize() {
|
||||
@@ -672,15 +652,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
@Override
|
||||
public void validate(final Object value) {
|
||||
try {
|
||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
|
||||
.validate(Integer.valueOf(value.toString()));
|
||||
if (value != null) {
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
|
||||
.validate(Integer.valueOf(value.toString()));
|
||||
}
|
||||
}
|
||||
// suppress the need of preserve original exception, will blow
|
||||
// up the
|
||||
// log and not necessary here
|
||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
||||
LOG.error(ex.getMessage());
|
||||
catch (final InvalidValueException ex) {
|
||||
// we have to throw the exception here, otherwise the UI won't
|
||||
// show the vaadin validation error!
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -691,15 +674,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
@Override
|
||||
public void validate(final Object value) {
|
||||
try {
|
||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
|
||||
.validate(Integer.valueOf(value.toString()));
|
||||
if (value != null) {
|
||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
|
||||
.validate(Integer.valueOf(value.toString()));
|
||||
}
|
||||
}
|
||||
// suppress the need of preserve original exception, will blow
|
||||
// up the
|
||||
// log and not necessary here
|
||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
||||
LOG.error(ex.getMessage());
|
||||
catch (final InvalidValueException ex) {
|
||||
// we have to throw the exception here, otherwise the UI won't
|
||||
// show the vaadin validation error!
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -711,15 +697,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
* @param rolloutId
|
||||
* rollout id
|
||||
*/
|
||||
public void populateData(final Long rolloutId) {
|
||||
resetComponents();
|
||||
private void populateData(final Long rolloutId) {
|
||||
if (rolloutId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
editRolloutEnabled = Boolean.TRUE;
|
||||
rolloutForEdit = rolloutManagement.findRolloutById(rolloutId);
|
||||
rolloutName.setValue(rolloutForEdit.getName());
|
||||
description.setValue(rolloutForEdit.getDescription());
|
||||
distributionSet.setValue(DistributionSetIdName.generate(rolloutForEdit.getDistributionSet()));
|
||||
final List<RolloutGroup> rolloutGroups = rolloutForEdit.getRolloutGroups();
|
||||
setThresoldValues(rolloutGroups);
|
||||
setThresholdValues(rolloutGroups);
|
||||
setActionType(rolloutForEdit);
|
||||
if (rolloutForEdit.getStatus() != RolloutStatus.READY) {
|
||||
disableRequiredFieldsOnEdit();
|
||||
@@ -727,12 +716,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
|
||||
noOfGroups.setEnabled(false);
|
||||
targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery());
|
||||
removeComponent(targetFilterQueryCombo);
|
||||
addComponent(targetFilterQuery, 1, 3);
|
||||
removeComponent(1, 2);
|
||||
targetFilterQueryCombo.removeValidator(nullValidator);
|
||||
addComponent(targetFilterQuery, 1, 2);
|
||||
targetFilterQuery.addValidator(nullValidator);
|
||||
|
||||
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery());
|
||||
totalTargetsLabel.setValue(getTotalTargetMessage());
|
||||
totalTargetsLabel.setVisible(true);
|
||||
|
||||
window.setOrginaleValues();
|
||||
}
|
||||
|
||||
private void disableRequiredFieldsOnEdit() {
|
||||
@@ -771,8 +764,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
/**
|
||||
* @param rolloutGroups
|
||||
*/
|
||||
private void setThresoldValues(final List<RolloutGroup> rolloutGroups) {
|
||||
if (null != rolloutGroups && !rolloutGroups.isEmpty()) {
|
||||
private void setThresholdValues(final List<RolloutGroup> rolloutGroups) {
|
||||
if (rolloutGroups != null && !rolloutGroups.isEmpty()) {
|
||||
errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp());
|
||||
triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp());
|
||||
noOfGroups.setValue(String.valueOf(rolloutGroups.size()));
|
||||
@@ -798,7 +791,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum ERRORTHRESOLDOPTIONS {
|
||||
@@ -816,6 +808,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_OPEN_TAG;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +29,7 @@ import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
|
||||
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer;
|
||||
@@ -47,29 +49,21 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||
import org.vaadin.peter.contextmenu.ContextMenu;
|
||||
import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItem;
|
||||
import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItemClickEvent;
|
||||
import org.vaadin.spring.events.EventScope;
|
||||
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.data.Item;
|
||||
import com.vaadin.data.util.PropertyValueGenerator;
|
||||
import com.vaadin.data.util.converter.Converter;
|
||||
import com.vaadin.server.AbstractClientConnector;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent;
|
||||
import com.vaadin.ui.renderers.HtmlRenderer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Rollout list grid component.
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
@@ -79,11 +73,9 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
|
||||
private static final String UPDATE_OPTION = "Update";
|
||||
|
||||
private static final String RESUME_OPTION = "Resume";
|
||||
|
||||
private static final String PAUSE_OPTION = "Pause";
|
||||
|
||||
private static final String START_OPTION = "Start";
|
||||
private static final String RUN_OPTION = "Run";
|
||||
|
||||
private static final String DS_TYPE = "type";
|
||||
|
||||
@@ -145,6 +137,7 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
final LazyQueryContainer rolloutContainer = (LazyQueryContainer) getContainerDataSource();
|
||||
final Item item = rolloutContainer.getItem(rolloutChangeEvent.getRolloutId());
|
||||
if (item == null) {
|
||||
refreshGrid();
|
||||
return;
|
||||
}
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
||||
@@ -159,7 +152,6 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
}
|
||||
item.getItemProperty(ROLLOUT_RENDERER_DATA)
|
||||
.setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,9 +190,15 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS,
|
||||
TotalTargetCountStatus.class, null, false, false);
|
||||
|
||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class,
|
||||
FontAwesome.CIRCLE_O.getHtml(), false, false);
|
||||
rolloutGridContainer.addContainerProperty(RUN_OPTION, String.class, FontAwesome.PLAY.getHtml(), false, false);
|
||||
|
||||
rolloutGridContainer.addContainerProperty(PAUSE_OPTION, String.class, FontAwesome.PAUSE.getHtml(), false,
|
||||
false);
|
||||
|
||||
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||
rolloutGridContainer.addContainerProperty(UPDATE_OPTION, String.class, FontAwesome.EDIT.getHtml(), false,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,8 +219,16 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMinimumWidth(40);
|
||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMaximumWidth(100);
|
||||
|
||||
getColumn(SPUILabelDefinitions.ACTION).setMinimumWidth(75);
|
||||
getColumn(SPUILabelDefinitions.ACTION).setMaximumWidth(75);
|
||||
getColumn(RUN_OPTION).setMinimumWidth(25);
|
||||
getColumn(RUN_OPTION).setMaximumWidth(25);
|
||||
|
||||
getColumn(PAUSE_OPTION).setMinimumWidth(25);
|
||||
getColumn(PAUSE_OPTION).setMaximumWidth(25);
|
||||
|
||||
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||
getColumn(UPDATE_OPTION).setMinimumWidth(25);
|
||||
getColumn(UPDATE_OPTION).setMaximumWidth(25);
|
||||
}
|
||||
|
||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setMinimumWidth(280);
|
||||
|
||||
@@ -232,9 +238,9 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
@Override
|
||||
protected void setColumnHeaderNames() {
|
||||
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.get("header.name"));
|
||||
getColumn(DS_TYPE).setHeaderCaption("Type");
|
||||
getColumn(SW_MODULES).setHeaderCaption("swModules");
|
||||
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption("IsRequiredMigrationStep");
|
||||
getColumn(DS_TYPE).setHeaderCaption(i18n.get("header.type"));
|
||||
getColumn(SW_MODULES).setHeaderCaption(i18n.get("header.swmodules"));
|
||||
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption(i18n.get("header.migrations.step"));
|
||||
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setHeaderCaption(i18n.get("header.distributionset"));
|
||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setHeaderCaption(i18n.get("header.numberofgroups"));
|
||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setHeaderCaption(i18n.get("header.total.targets"));
|
||||
@@ -246,7 +252,16 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
||||
.setHeaderCaption(i18n.get("header.detail.status"));
|
||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setHeaderCaption(i18n.get("header.status"));
|
||||
getColumn(SPUILabelDefinitions.ACTION).setHeaderCaption(i18n.get("upload.action"));
|
||||
|
||||
getColumn(RUN_OPTION).setHeaderCaption(i18n.get("header.action.run"));
|
||||
getColumn(PAUSE_OPTION).setHeaderCaption(i18n.get("header.action.pause"));
|
||||
|
||||
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||
getColumn(UPDATE_OPTION).setHeaderCaption(i18n.get("header.action.update"));
|
||||
}
|
||||
|
||||
final HeaderCell join = getDefaultHeaderRow().join(RUN_OPTION, PAUSE_OPTION, UPDATE_OPTION);
|
||||
join.setText(i18n.get("header.action"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -266,7 +281,13 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
||||
columnList.add(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS);
|
||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS);
|
||||
columnList.add(SPUILabelDefinitions.ACTION);
|
||||
|
||||
columnList.add(RUN_OPTION);
|
||||
columnList.add(PAUSE_OPTION);
|
||||
|
||||
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||
columnList.add(UPDATE_OPTION);
|
||||
}
|
||||
|
||||
columnList.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
||||
columnList.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
||||
@@ -292,7 +313,6 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
for (final Object propertyId : columnsToBeHidden) {
|
||||
getColumn(propertyId).setHidden(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,12 +330,21 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
createRolloutStatusToFontMap();
|
||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setRenderer(new HtmlLabelRenderer(), new RolloutStatusConverter());
|
||||
|
||||
getColumn(SPUILabelDefinitions.ACTION).setRenderer(new HtmlButtonRenderer(this::onClickOfActionBtn));
|
||||
|
||||
final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class);
|
||||
customObjectRenderer.addClickListener(this::onClickOfRolloutName);
|
||||
getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer);
|
||||
|
||||
getColumn(RUN_OPTION)
|
||||
.setRenderer(new HtmlButtonRenderer(clickEvent -> startOrResumeRollout((Long) clickEvent.getItemId())));
|
||||
|
||||
getColumn(PAUSE_OPTION)
|
||||
.setRenderer(new HtmlButtonRenderer(clickEvent -> pauseRollout((Long) clickEvent.getItemId())));
|
||||
|
||||
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||
getColumn(UPDATE_OPTION)
|
||||
.setRenderer(new HtmlButtonRenderer(clickEvent -> updateRollout((Long) clickEvent.getItemId())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createRolloutStatusToFontMap() {
|
||||
@@ -337,18 +366,7 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
}
|
||||
|
||||
private void alignColumns() {
|
||||
setCellStyleGenerator(new CellStyleGenerator() {
|
||||
private static final long serialVersionUID = 5573570647129792429L;
|
||||
|
||||
@Override
|
||||
public String getStyle(final CellReference cellReference) {
|
||||
final String[] coulmnNames = { SPUILabelDefinitions.VAR_STATUS, SPUILabelDefinitions.ACTION };
|
||||
if (Arrays.asList(coulmnNames).contains(cellReference.getPropertyId())) {
|
||||
return "centeralign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
setCellStyleGenerator(new RollouStatusCellStyleGenerator(getContainerDataSource()));
|
||||
}
|
||||
|
||||
private void onClickOfRolloutName(final RendererClickEvent event) {
|
||||
@@ -362,83 +380,44 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUPS);
|
||||
}
|
||||
|
||||
private void onClickOfActionBtn(final RendererClickEvent event) {
|
||||
final ContextMenu contextMenu = createContextMenu((Long) event.getItemId());
|
||||
contextMenu.setAsContextMenuOf((AbstractClientConnector) event.getComponent());
|
||||
contextMenu.open(event.getClientX(), event.getClientY());
|
||||
}
|
||||
|
||||
private ContextMenu createContextMenu(final Long rolloutId) {
|
||||
final ContextMenu context = new ContextMenu();
|
||||
context.addItemClickListener(this::menuItemClicked);
|
||||
private void pauseRollout(final Long rolloutId) {
|
||||
final Item row = getContainerDataSource().getItem(rolloutId);
|
||||
|
||||
final RolloutStatus rolloutStatus = (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS)
|
||||
.getValue();
|
||||
|
||||
switch (rolloutStatus) {
|
||||
case READY:
|
||||
final ContextMenuItem startItem = context.addItem(START_OPTION);
|
||||
startItem.setData(new ContextMenuData(rolloutId, ACTION.START));
|
||||
break;
|
||||
case RUNNING:
|
||||
final ContextMenuItem pauseItem = context.addItem(PAUSE_OPTION);
|
||||
pauseItem.setData(new ContextMenuData(rolloutId, ACTION.PAUSE));
|
||||
break;
|
||||
case PAUSED:
|
||||
final ContextMenuItem resumeItem = context.addItem(RESUME_OPTION);
|
||||
resumeItem.setData(new ContextMenuData(rolloutId, ACTION.RESUME));
|
||||
break;
|
||||
case STARTING:
|
||||
case CREATING:
|
||||
case ERROR_CREATING:
|
||||
case ERROR_STARTING:
|
||||
// do not provide any action on these statuses
|
||||
return context;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
getUpdateMenuItem(context, rolloutId);
|
||||
return context;
|
||||
}
|
||||
|
||||
private void getUpdateMenuItem(final ContextMenu context, final Long rolloutId) {
|
||||
// Add 'Update' option only if user has update permission
|
||||
if (!permissionChecker.hasRolloutUpdatePermission()) {
|
||||
if (!RolloutStatus.RUNNING.equals(rolloutStatus)) {
|
||||
return;
|
||||
}
|
||||
final ContextMenuItem cancelItem = context.addItem(UPDATE_OPTION);
|
||||
cancelItem.setData(new ContextMenuData(rolloutId, ACTION.UPDATE));
|
||||
|
||||
final String rolloutName = (String) row.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
|
||||
|
||||
rolloutManagement.pauseRollout(rolloutManagement.findRolloutById(rolloutId));
|
||||
uiNotification.displaySuccess(i18n.get("message.rollout.paused", rolloutName));
|
||||
}
|
||||
|
||||
private void menuItemClicked(final ContextMenuItemClickEvent event) {
|
||||
final ContextMenuItem item = (ContextMenuItem) event.getSource();
|
||||
final ContextMenuData contextMenuData = (ContextMenuData) item.getData();
|
||||
final Item row = getContainerDataSource().getItem(contextMenuData.getRolloutId());
|
||||
private void startOrResumeRollout(final Long rolloutId) {
|
||||
final Item row = getContainerDataSource().getItem(rolloutId);
|
||||
|
||||
final RolloutStatus rolloutStatus = (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS)
|
||||
.getValue();
|
||||
final String rolloutName = (String) row.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
|
||||
switch (contextMenuData.getAction()) {
|
||||
case PAUSE:
|
||||
rolloutManagement.pauseRollout(rolloutManagement.findRolloutById(contextMenuData.getRolloutId()));
|
||||
uiNotification.displaySuccess(i18n.get("message.rollout.paused", rolloutName));
|
||||
break;
|
||||
case RESUME:
|
||||
rolloutManagement.resumeRollout(rolloutManagement.findRolloutById(contextMenuData.getRolloutId()));
|
||||
uiNotification.displaySuccess(i18n.get("message.rollout.resumed", rolloutName));
|
||||
break;
|
||||
case START:
|
||||
|
||||
if (RolloutStatus.READY.equals(rolloutStatus)) {
|
||||
rolloutManagement.startRolloutAsync(rolloutManagement.findRolloutByName(rolloutName));
|
||||
uiNotification.displaySuccess(i18n.get("message.rollout.started", rolloutName));
|
||||
break;
|
||||
case UPDATE:
|
||||
onUpdate(contextMenuData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (RolloutStatus.PAUSED.equals(rolloutStatus)) {
|
||||
rolloutManagement.resumeRollout(rolloutManagement.findRolloutById(rolloutId));
|
||||
uiNotification.displaySuccess(i18n.get("message.rollout.resumed", rolloutName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void onUpdate(final ContextMenuData contextMenuData) {
|
||||
addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId());
|
||||
final Window addTargetWindow = addUpdateRolloutWindow.getWindow();
|
||||
private void updateRollout(final Long rolloutId) {
|
||||
final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(rolloutId);
|
||||
addTargetWindow.setCaption(i18n.get("caption.update.rollout"));
|
||||
UI.getCurrent().addWindow(addTargetWindow);
|
||||
addTargetWindow.setVisible(Boolean.TRUE);
|
||||
@@ -448,29 +427,6 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
((LazyQueryContainer) getContainerDataSource()).refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generator to generate fontIcon by String.
|
||||
*/
|
||||
public final class FontIconGenerator extends PropertyValueGenerator<String> {
|
||||
|
||||
private static final long serialVersionUID = 2544026030795375748L;
|
||||
private final FontAwesome fontIcon;
|
||||
|
||||
public FontIconGenerator(final FontAwesome icon) {
|
||||
this.fontIcon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(final Item item, final Object itemId, final Object propertyId) {
|
||||
return fontIcon.getHtml();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getType() {
|
||||
return String.class;
|
||||
}
|
||||
}
|
||||
|
||||
private String getDescription(final CellReference cell) {
|
||||
if (SPUILabelDefinitions.VAR_STATUS.equals(cell.getPropertyId())) {
|
||||
return cell.getProperty().getValue().toString().toLowerCase();
|
||||
@@ -524,61 +480,70 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
enum ACTION {
|
||||
PAUSE, RESUME, START, UPDATE
|
||||
}
|
||||
private static class RollouStatusCellStyleGenerator implements CellStyleGenerator {
|
||||
|
||||
/**
|
||||
* Represents data of context menu item.
|
||||
*
|
||||
*/
|
||||
public static class ContextMenuData {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* Contains all expected rollout status per column to enable or disable
|
||||
* the button.
|
||||
*/
|
||||
private static final Map<String, RolloutStatus> EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON = new HashMap<>();
|
||||
private final Container.Indexed containerDataSource;
|
||||
|
||||
private Long rolloutId;
|
||||
|
||||
private ACTION action;
|
||||
static {
|
||||
EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.put(RUN_OPTION, RolloutStatus.READY);
|
||||
EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.put(PAUSE_OPTION, RolloutStatus.RUNNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rollout if and action.
|
||||
* Constructor
|
||||
*
|
||||
* @param rolloutId
|
||||
* id of rollout
|
||||
* @param action
|
||||
* user action {@link ACTION}
|
||||
* @param containerDataSource
|
||||
* the container
|
||||
*/
|
||||
public ContextMenuData(final Long rolloutId, final ACTION action) {
|
||||
this.action = action;
|
||||
this.rolloutId = rolloutId;
|
||||
public RollouStatusCellStyleGenerator(final Container.Indexed containerDataSource) {
|
||||
this.containerDataSource = containerDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rolloutId
|
||||
*/
|
||||
public Long getRolloutId() {
|
||||
return rolloutId;
|
||||
@Override
|
||||
public String getStyle(final CellReference cellReference) {
|
||||
if (SPUILabelDefinitions.VAR_STATUS.equals(cellReference.getPropertyId())) {
|
||||
return "centeralign";
|
||||
}
|
||||
return convertRolloutStatusToString(cellReference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rolloutId
|
||||
* the rolloutId to set
|
||||
*/
|
||||
public void setRolloutId(final Long rolloutId) {
|
||||
this.rolloutId = rolloutId;
|
||||
private String convertRolloutStatusToString(final CellReference cellReference) {
|
||||
final Object propertyId = cellReference.getPropertyId();
|
||||
final RolloutStatus expectedRolloutStatus = EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.get(propertyId);
|
||||
if (expectedRolloutStatus == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (RUN_OPTION.equals(cellReference.getPropertyId())) {
|
||||
return getStatus(cellReference, RolloutStatus.READY, RolloutStatus.PAUSED);
|
||||
}
|
||||
|
||||
if (PAUSE_OPTION.equals(cellReference.getPropertyId())) {
|
||||
return getStatus(cellReference, RolloutStatus.RUNNING);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the action
|
||||
*/
|
||||
public ACTION getAction() {
|
||||
return action;
|
||||
private String getStatus(final CellReference cellReference, final RolloutStatus... expectedRolloutStatus) {
|
||||
final RolloutStatus currentRolloutStatus = getRolloutStatus(cellReference.getItemId());
|
||||
|
||||
if (Arrays.asList(expectedRolloutStatus).contains(currentRolloutStatus)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return org.eclipse.hawkbit.ui.customrenderers.client.renderers.HtmlButtonRenderer.DISABLE_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param action
|
||||
* the action to set
|
||||
*/
|
||||
public void setAction(final ACTION action) {
|
||||
this.action = action;
|
||||
private RolloutStatus getRolloutStatus(final Object itemId) {
|
||||
final Item row = containerDataSource.getItem(itemId);
|
||||
return (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS).getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,7 +649,6 @@ public class RolloutListGrid extends AbstractGrid {
|
||||
public Class<String> getPresentationType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,6 @@ public class RolloutListHeader extends AbstractGridHeader {
|
||||
|
||||
@Override
|
||||
protected void addNewItem(final ClickEvent event) {
|
||||
addUpdateRolloutWindow.resetComponents();
|
||||
final Window addTargetWindow = addUpdateRolloutWindow.getWindow();
|
||||
UI.getCurrent().addWindow(addTargetWindow);
|
||||
addTargetWindow.setVisible(Boolean.TRUE);
|
||||
|
||||
@@ -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 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 CLOSE_BRACE = "\"; }';";
|
||||
|
||||
@@ -176,6 +176,10 @@ public final class SPUIComponentIdProvider {
|
||||
* ID - Dist jvm combo.
|
||||
*/
|
||||
public static final String DIST_MODULE_COMBO = "dist.module.combo.";
|
||||
/**
|
||||
* ID for Distribution Tag ComboBox
|
||||
*/
|
||||
public static final String DIST_TAG_COMBO = "dist.tag.combo";
|
||||
/**
|
||||
* ID-Dist.PIN.
|
||||
*/
|
||||
@@ -242,6 +246,11 @@ public final class SPUIComponentIdProvider {
|
||||
*/
|
||||
public static final String DISCARD_SW_MODULE_TYPE = "save.actions.popup.discard.sw.module.type";
|
||||
|
||||
/**
|
||||
* Action history table cancel Id.
|
||||
*/
|
||||
public static final String ACTION_DETAILS_SOFT_ID = "action.details.soft.group";
|
||||
|
||||
/**
|
||||
* ID - Label.
|
||||
*/
|
||||
@@ -289,6 +298,21 @@ public final class SPUIComponentIdProvider {
|
||||
*/
|
||||
public static final String ACTION_HISTORY_TABLE_ID = "action.history.tableId";
|
||||
|
||||
/**
|
||||
* Action history table cancel Id.
|
||||
*/
|
||||
public static final String ACTION_HISTORY_TABLE_CANCEL_ID = "action.history.table.action.cancel";
|
||||
|
||||
/**
|
||||
* Action history table force Id.
|
||||
*/
|
||||
public static final String ACTION_HISTORY_TABLE_FORCE_ID = "action.history.table.action.force";
|
||||
|
||||
/**
|
||||
* Action history table force quit Id.
|
||||
*/
|
||||
public static final String ACTION_HISTORY_TABLE_FORCE_QUIT_ID = "action.history.table.action.force.quit";
|
||||
|
||||
/**
|
||||
* Target filter wrapper id.
|
||||
*/
|
||||
@@ -302,6 +326,22 @@ public final class SPUIComponentIdProvider {
|
||||
* tag color preview button id.
|
||||
*/
|
||||
public static final String TAG_COLOR_PREVIEW_ID = "tag.color.preview";
|
||||
/**
|
||||
* Id for ColorPickerLayout
|
||||
*/
|
||||
public static final String COLOR_PICKER_LAYOUT = "color.picker.layout";
|
||||
/**
|
||||
* Id for ColorPickerLayout's red slider
|
||||
*/
|
||||
public static final String COLOR_PICKER_RED_SLIDER = "color.picker.red.slider";
|
||||
/**
|
||||
* Id for Color preview field with the color code
|
||||
*/
|
||||
public static final String COLOR_PREVIEW_FIELD = "color-preview-field";
|
||||
/**
|
||||
* Id for OptionGroup Create/Update tag
|
||||
*/
|
||||
public static final String OPTION_GROUP = "create.update.tag";
|
||||
/**
|
||||
* Confirmation dialogue OK button id.
|
||||
*/
|
||||
@@ -817,19 +857,26 @@ public final class SPUIComponentIdProvider {
|
||||
* Rollout target filter query combo id.
|
||||
*/
|
||||
public static final String ROLLOUT_TARGET_FILTER_COMBO_ID = "rollout.target.filter.combo.id";
|
||||
|
||||
/**
|
||||
* Rollout action button id.
|
||||
*/
|
||||
public static final String ROLLOUT_ACTION_BUTTON_ID = "rollout.action.button.id";
|
||||
public static final String ROLLOUT_ACTION_ID = "rollout.action.button.id";
|
||||
|
||||
/**
|
||||
* Rollout start button id.
|
||||
*/
|
||||
public static final String ROLLOUT_RUN_BUTTON_ID = ROLLOUT_ACTION_ID + ".9";
|
||||
|
||||
/**
|
||||
* Rollout pause button id.
|
||||
*/
|
||||
public static final String ROLLOUT_PAUSE_BUTTON_ID = "rollout.pause.button.id";
|
||||
public static final String ROLLOUT_PAUSE_BUTTON_ID = ROLLOUT_ACTION_ID + ".10";
|
||||
|
||||
/**
|
||||
* Rollout resume button id.
|
||||
*/
|
||||
public static final String ROLLOUT_RESUME_BUTTON_ID = "rollout.resume.button.id";
|
||||
public static final String ROLLOUT_UPDATE_BUTTON_ID = ROLLOUT_ACTION_ID + ".11";
|
||||
|
||||
/**
|
||||
* Rollout save or start option group id.
|
||||
@@ -915,6 +962,75 @@ public final class SPUIComponentIdProvider {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public static final String SELECT_DIST_TYPE = "select-dist-type";
|
||||
|
||||
/**
|
||||
* /* Private Constructor.
|
||||
*/
|
||||
|
||||
@@ -87,6 +87,11 @@ public final class SPUIDefinitions {
|
||||
*/
|
||||
public static final String ACTION_HIS_TBL_STATUS = "Status";
|
||||
|
||||
/**
|
||||
* Actions column.
|
||||
*/
|
||||
public static final String ACTIONS_COLUMN = "Actions";
|
||||
|
||||
/**
|
||||
* Action history messages of particular action update.
|
||||
*/
|
||||
@@ -344,15 +349,6 @@ public final class SPUIDefinitions {
|
||||
* New Target tag color lable id.
|
||||
*/
|
||||
public static final String NEW_TARGET_TAG_COLOR = "target.tag.add.color";
|
||||
/**
|
||||
* New Target tag save icon id.
|
||||
*/
|
||||
// public static final String NEW_TARGET_TAG_SAVE = "target.tag.add.save";
|
||||
/**
|
||||
* New Target tag discard icon id.
|
||||
*/
|
||||
// public static final String NEW_TARGET_TAG_DISRACD =
|
||||
// "target.tag.add.discard";
|
||||
/**
|
||||
* New Target tag add icon id.
|
||||
*/
|
||||
@@ -1016,6 +1012,21 @@ public final class SPUIDefinitions {
|
||||
* Rollout action column property.
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -560,6 +560,11 @@ public final class SPUILabelDefinitions {
|
||||
* Rollout group installed percentage column property.
|
||||
*/
|
||||
public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage";
|
||||
|
||||
/**
|
||||
* Add metadata icon.
|
||||
*/
|
||||
public static final String METADATA_ICON = "metadataDls";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
||||
@@ -136,6 +136,11 @@ public final class SPUIStyleDefinitions {
|
||||
* Artifact Details icon in Distribution View.
|
||||
*/
|
||||
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.
|
||||
@@ -293,6 +298,10 @@ public final class SPUIStyleDefinitions {
|
||||
* Status pending icon.
|
||||
*/
|
||||
public static final String STATUS_ICON_PENDING = "statusIconPending";
|
||||
/**
|
||||
* Grid style.
|
||||
*/
|
||||
public static final String METADATA_GRID = "metadata-grid";
|
||||
|
||||
/**
|
||||
* Footer layout style.
|
||||
|
||||
@@ -293,8 +293,4 @@
|
||||
padding-bottom: 12px !important;
|
||||
}
|
||||
|
||||
.v-button-default-color {
|
||||
color: #551f62;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,4 +53,12 @@
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.marginTop {
|
||||
margin-top: 20px !important;
|
||||
}
|
||||
|
||||
.metadata-table-margin {
|
||||
margin-top:3px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -164,5 +164,6 @@
|
||||
|
||||
.actionButtonsMargin {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.action-type-padding{
|
||||
padding: 0 0px !important;
|
||||
}
|
||||
|
||||
.rollout-caption-links{
|
||||
font-weight: 400;
|
||||
height: 25px ;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user